mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
refactor(manga): Slowly using flow
This commit is contained in:
parent
50cad86c0c
commit
2ef1195a90
3 changed files with 145 additions and 134 deletions
|
@ -194,7 +194,7 @@ class MangaDetailsController :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val manga: Manga? get() = if (presenter.isMangaLateInitInitialized()) presenter.manga else null
|
private val manga: Manga? get() = presenter.currentManga.value
|
||||||
private var colorAnimator: ValueAnimator? = null
|
private var colorAnimator: ValueAnimator? = null
|
||||||
override val presenter: MangaDetailsPresenter
|
override val presenter: MangaDetailsPresenter
|
||||||
private var coverColor: Int? = null
|
private var coverColor: Int? = null
|
||||||
|
@ -674,7 +674,7 @@ class MangaDetailsController :
|
||||||
returningFromReader = false
|
returningFromReader = false
|
||||||
runBlocking {
|
runBlocking {
|
||||||
val itemAnimator = binding.recycler.itemAnimator
|
val itemAnimator = binding.recycler.itemAnimator
|
||||||
val chapters = withTimeoutOrNull(1000) { presenter.getChaptersNow() } ?: return@runBlocking
|
val chapters = withTimeoutOrNull(1000) { presenter.setAndGetChapters() } ?: return@runBlocking
|
||||||
binding.recycler.itemAnimator = null
|
binding.recycler.itemAnimator = null
|
||||||
tabletAdapter?.notifyItemChanged(0)
|
tabletAdapter?.notifyItemChanged(0)
|
||||||
adapter?.setChapters(chapters)
|
adapter?.setChapters(chapters)
|
||||||
|
@ -821,15 +821,15 @@ class MangaDetailsController :
|
||||||
updateMenuVisibility(activityBinding?.toolbar?.menu)
|
updateMenuVisibility(activityBinding?.toolbar?.menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateChapters(chapters: List<ChapterItem>) {
|
fun updateChapters(fetchFromSource: Boolean = false) {
|
||||||
view ?: return
|
view ?: return
|
||||||
binding.swipeRefresh.isRefreshing = presenter.isLoading
|
binding.swipeRefresh.isRefreshing = presenter.isLoading
|
||||||
if (presenter.chapters.isEmpty() && fromCatalogue && !presenter.hasRequested) {
|
if (presenter.chapters.isEmpty() && fromCatalogue && !presenter.hasRequested && fetchFromSource) {
|
||||||
launchUI { binding.swipeRefresh.isRefreshing = true }
|
launchUI { binding.swipeRefresh.isRefreshing = true }
|
||||||
presenter.fetchChaptersFromSource()
|
presenter.refreshChapters()
|
||||||
}
|
}
|
||||||
tabletAdapter?.notifyItemChanged(0)
|
tabletAdapter?.notifyItemChanged(0)
|
||||||
adapter?.setChapters(chapters)
|
adapter?.setChapters(presenter.chapters)
|
||||||
addMangaHeader()
|
addMangaHeader()
|
||||||
colorToolbar(binding.recycler.canScrollVertically(-1))
|
colorToolbar(binding.recycler.canScrollVertically(-1))
|
||||||
updateMenuVisibility(activityBinding?.toolbar?.menu)
|
updateMenuVisibility(activityBinding?.toolbar?.menu)
|
||||||
|
|
|
@ -34,6 +34,7 @@ import eu.kanade.tachiyomi.data.track.EnhancedTrackService
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||||
|
import eu.kanade.tachiyomi.network.HttpException
|
||||||
import eu.kanade.tachiyomi.network.NetworkPreferences
|
import eu.kanade.tachiyomi.network.NetworkPreferences
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
|
@ -76,11 +77,15 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
import kotlinx.coroutines.flow.updateAndGet
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
@ -127,11 +132,15 @@ class MangaDetailsPresenter(
|
||||||
|
|
||||||
private val networkPreferences: NetworkPreferences by injectLazy()
|
private val networkPreferences: NetworkPreferences by injectLazy()
|
||||||
|
|
||||||
// private val currentMangaInternal: MutableStateFlow<Manga?> = MutableStateFlow(null)
|
private val currentMangaInternal = MutableStateFlow<Manga?>(null)
|
||||||
// val currentManga get() = currentMangaInternal.asStateFlow()
|
val currentManga = currentMangaInternal.asStateFlow()
|
||||||
|
|
||||||
lateinit var manga: Manga
|
/**
|
||||||
fun isMangaLateInitInitialized() = ::manga.isInitialized
|
* Unsafe, call only after currentManga is no longer null
|
||||||
|
*/
|
||||||
|
var manga: Manga
|
||||||
|
get() = currentManga.value!!
|
||||||
|
set(value) { currentMangaInternal.value = value }
|
||||||
|
|
||||||
private val customMangaManager: CustomMangaManager by injectLazy()
|
private val customMangaManager: CustomMangaManager by injectLazy()
|
||||||
private val mangaShortcutManager: MangaShortcutManager by injectLazy()
|
private val mangaShortcutManager: MangaShortcutManager by injectLazy()
|
||||||
|
@ -151,8 +160,12 @@ class MangaDetailsPresenter(
|
||||||
|
|
||||||
var trackList: List<TrackItem> = emptyList()
|
var trackList: List<TrackItem> = emptyList()
|
||||||
|
|
||||||
var chapters: List<ChapterItem> = emptyList()
|
private val currentChaptersInternal = MutableStateFlow<List<ChapterItem>>(emptyList())
|
||||||
private set
|
val currentChapters = currentChaptersInternal.asStateFlow()
|
||||||
|
|
||||||
|
var chapters: List<ChapterItem>
|
||||||
|
get() = currentChapters.value
|
||||||
|
private set(value) { currentChaptersInternal.value = value }
|
||||||
|
|
||||||
var allChapters: List<ChapterItem> = emptyList()
|
var allChapters: List<ChapterItem> = emptyList()
|
||||||
private set
|
private set
|
||||||
|
@ -186,7 +199,7 @@ class MangaDetailsPresenter(
|
||||||
val controller = view ?: return
|
val controller = view ?: return
|
||||||
|
|
||||||
isLockedFromSearch = controller.shouldLockIfNeeded && SecureActivityDelegate.shouldBeLocked()
|
isLockedFromSearch = controller.shouldLockIfNeeded && SecureActivityDelegate.shouldBeLocked()
|
||||||
if (!::manga.isInitialized) runBlocking { refreshMangaFromDb() }
|
if (currentManga.value == null) runBlocking { refreshMangaFromDb() }
|
||||||
syncData()
|
syncData()
|
||||||
|
|
||||||
presenterScope.launchUI {
|
presenterScope.launchUI {
|
||||||
|
@ -204,6 +217,22 @@ class MangaDetailsPresenter(
|
||||||
presenterScope.launchIO {
|
presenterScope.launchIO {
|
||||||
downloadManager.queueState.collectLatest(::onQueueUpdate)
|
downloadManager.queueState.collectLatest(::onQueueUpdate)
|
||||||
}
|
}
|
||||||
|
presenterScope.launchUI {
|
||||||
|
currentManga.collectLatest {
|
||||||
|
if (it == null) return@collectLatest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
presenterScope.launchIO {
|
||||||
|
currentChapters.collectLatest { chapters ->
|
||||||
|
allChapters = if (!isScanlatorFiltered()) chapters else getChapter.awaitAll(mangaId, false).map { it.toModel() }
|
||||||
|
|
||||||
|
allChapterScanlators = allChapters.mapNotNull { it.chapter.scanlator }.toSet()
|
||||||
|
|
||||||
|
withUIContext {
|
||||||
|
controller.updateChapters(allChapters.isEmpty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
runBlocking {
|
runBlocking {
|
||||||
tracks = getTrack.awaitAllByMangaId(mangaId)
|
tracks = getTrack.awaitAllByMangaId(mangaId)
|
||||||
|
@ -229,8 +258,7 @@ class MangaDetailsPresenter(
|
||||||
controller.updateHeader()
|
controller.updateHeader()
|
||||||
refreshAll()
|
refreshAll()
|
||||||
} else {
|
} else {
|
||||||
runBlocking { getChapters() }
|
runBlocking { chapters = getChapters() }
|
||||||
controller.updateChapters(this.chapters)
|
|
||||||
getHistory()
|
getHistory()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,16 +271,14 @@ class MangaDetailsPresenter(
|
||||||
|
|
||||||
fun fetchChapters(andTracking: Boolean = true) {
|
fun fetchChapters(andTracking: Boolean = true) {
|
||||||
presenterScope.launch {
|
presenterScope.launch {
|
||||||
getChapters()
|
setCurrentChapters(getChapters())
|
||||||
if (andTracking) fetchTracks()
|
if (andTracking) fetchTracks()
|
||||||
withContext(Dispatchers.Main) { view?.updateChapters(chapters) }
|
|
||||||
getHistory()
|
getHistory()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setCurrentManga(manga: Manga?) {
|
fun setCurrentManga(manga: Manga?) {
|
||||||
// currentMangaInternal.update { manga }
|
currentMangaInternal.update { manga }
|
||||||
this.manga = manga!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use flow to "sync" data instead
|
// TODO: Use flow to "sync" data instead
|
||||||
|
@ -264,20 +290,18 @@ class MangaDetailsPresenter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getChaptersNow(): List<ChapterItem> {
|
// TODO: Use getChapter.subscribe() flow instead
|
||||||
getChapters()
|
suspend fun setAndGetChapters(): List<ChapterItem> {
|
||||||
return chapters
|
return currentChaptersInternal.updateAndGet { getChapters() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getChapters(queue: List<Download> = downloadManager.queueState.value) {
|
// TODO: Use getChapter.subscribe() flow instead
|
||||||
val chapters = getChapter.awaitAll(mangaId, isScanlatorFiltered()).map { it.toModel() }
|
private fun setCurrentChapters(chapters: List<ChapterItem>) {
|
||||||
allChapters = if (!isScanlatorFiltered()) chapters else getChapter.awaitAll(mangaId, false).map { it.toModel() }
|
currentChaptersInternal.update { chapters }
|
||||||
|
}
|
||||||
|
|
||||||
// Find downloaded chapters
|
private suspend fun getChapters(): List<ChapterItem> {
|
||||||
setDownloadedChapters(chapters, queue)
|
return getChapter.awaitAll(mangaId, isScanlatorFiltered()).map { it.toModel() }
|
||||||
allChapterScanlators = allChapters.mapNotNull { it.chapter.scanlator }.toSet()
|
|
||||||
|
|
||||||
this.chapters = applyChapterFilters(chapters)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getHistory() {
|
private fun getHistory() {
|
||||||
|
@ -394,7 +418,7 @@ class MangaDetailsPresenter(
|
||||||
download = null
|
download = null
|
||||||
}
|
}
|
||||||
|
|
||||||
view?.updateChapters(this.chapters)
|
view?.updateChapters()
|
||||||
|
|
||||||
downloadManager.deleteChapters(listOf(chapter), manga, source, true)
|
downloadManager.deleteChapters(listOf(chapter), manga, source, true)
|
||||||
}
|
}
|
||||||
|
@ -412,7 +436,7 @@ class MangaDetailsPresenter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update) view?.updateChapters(this.chapters)
|
if (update) view?.updateChapters()
|
||||||
|
|
||||||
if (isEverything) {
|
if (isEverything) {
|
||||||
downloadManager.deleteManga(manga, source)
|
downloadManager.deleteManga(manga, source)
|
||||||
|
@ -432,126 +456,93 @@ class MangaDetailsPresenter(
|
||||||
if (view?.isNotOnline() == true && !manga.isLocal()) return
|
if (view?.isNotOnline() == true && !manga.isLocal()) return
|
||||||
presenterScope.launch {
|
presenterScope.launch {
|
||||||
isLoading = true
|
isLoading = true
|
||||||
var mangaError: java.lang.Exception? = null
|
val tasks = listOf(
|
||||||
var chapterError: java.lang.Exception? = null
|
async { fetchMangaFromSource() },
|
||||||
val chapters = async(Dispatchers.IO) {
|
async { fetchChaptersFromSource() },
|
||||||
try {
|
)
|
||||||
source.getChapterList(manga.copy())
|
tasks.awaitAll()
|
||||||
} catch (e: Exception) {
|
isLoading = false
|
||||||
chapterError = e
|
}
|
||||||
emptyList()
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
val nManga = async(Dispatchers.IO) {
|
|
||||||
try {
|
|
||||||
source.getMangaDetails(manga.copy())
|
|
||||||
} catch (e: java.lang.Exception) {
|
|
||||||
mangaError = e
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val networkManga = nManga.await()
|
private suspend fun fetchMangaFromSource() {
|
||||||
if (networkManga != null) {
|
try {
|
||||||
manga.prepareCoverUpdate(coverCache, networkManga, false)
|
val manga = manga.copy()
|
||||||
manga.copyFrom(networkManga)
|
val networkManga = source.getMangaDetails(manga)
|
||||||
manga.initialized = true
|
|
||||||
|
|
||||||
updateManga.await(manga.toMangaUpdate())
|
manga.prepareCoverUpdate(coverCache, networkManga, false)
|
||||||
|
manga.copyFrom(networkManga)
|
||||||
|
manga.initialized = true
|
||||||
|
|
||||||
launchIO {
|
updateManga.await(manga.toMangaUpdate())
|
||||||
val request =
|
|
||||||
ImageRequest.Builder(preferences.context).data(manga.cover())
|
|
||||||
.memoryCachePolicy(CachePolicy.DISABLED)
|
|
||||||
.diskCachePolicy(CachePolicy.WRITE_ONLY)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
if (preferences.context.imageLoader.execute(request) is SuccessResult) {
|
setCurrentManga(manga)
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
view?.setPaletteColor()
|
presenterScope.launchNonCancellableIO {
|
||||||
}
|
val request =
|
||||||
|
ImageRequest.Builder(preferences.context).data(manga.cover())
|
||||||
|
.memoryCachePolicy(CachePolicy.DISABLED)
|
||||||
|
.diskCachePolicy(CachePolicy.WRITE_ONLY)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
if (preferences.context.imageLoader.execute(request) is SuccessResult) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
view?.setPaletteColor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val finChapters = chapters.await()
|
} catch (e: Exception) {
|
||||||
if (finChapters.isNotEmpty()) {
|
if (e is HttpException && e.code == 103) return
|
||||||
val newChapters = withIOContext { syncChaptersWithSource(finChapters, manga, source) }
|
|
||||||
if (newChapters.first.isNotEmpty()) {
|
withUIContext {
|
||||||
|
view?.showError(trimException(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun fetchChaptersFromSource(manualFetch: Boolean = true) {
|
||||||
|
try {
|
||||||
|
withIOContext {
|
||||||
|
val chapters = source.getChapterList(manga.copy())
|
||||||
|
val (added, removed) = syncChaptersWithSource(chapters, manga, source)
|
||||||
|
if (added.isNotEmpty() && manualFetch) {
|
||||||
if (manga.shouldDownloadNewChapters(preferences)) {
|
if (manga.shouldDownloadNewChapters(preferences)) {
|
||||||
downloadChapters(
|
downloadChapters(added.sortedBy { it.chapter_number }.map { it.toModel() })
|
||||||
newChapters.first.sortedBy { it.chapter_number }
|
}
|
||||||
.map { it.toModel() },
|
withUIContext {
|
||||||
)
|
view?.view?.context?.let { mangaShortcutManager.updateShortcuts(it) }
|
||||||
}
|
}
|
||||||
view?.view?.context?.let { mangaShortcutManager.updateShortcuts(it) }
|
|
||||||
}
|
}
|
||||||
if (newChapters.second.isNotEmpty()) {
|
if (removed.isNotEmpty() && manualFetch) {
|
||||||
val removedChaptersId = newChapters.second.map { it.id }
|
val removedChaptersId = removed.map { it.id }
|
||||||
val removedChapters = this@MangaDetailsPresenter.chapters.filter {
|
val removedChapters = this@MangaDetailsPresenter.chapters.filter {
|
||||||
it.id in removedChaptersId && it.isDownloaded
|
it.id in removedChaptersId && it.isDownloaded
|
||||||
}
|
}
|
||||||
if (removedChapters.isNotEmpty()) {
|
if (removedChapters.isNotEmpty()) {
|
||||||
withContext(Dispatchers.Main) {
|
withUIContext {
|
||||||
view?.showChaptersRemovedPopup(
|
view?.showChaptersRemovedPopup(removedChapters)
|
||||||
removedChapters,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getChapters()
|
setCurrentChapters(getChapters())
|
||||||
|
getHistory()
|
||||||
}
|
}
|
||||||
isLoading = false
|
} catch (e: Exception) {
|
||||||
if (chapterError == null) {
|
withUIContext {
|
||||||
withContext(Dispatchers.Main) {
|
view?.showError(trimException(e))
|
||||||
view?.updateChapters(this@MangaDetailsPresenter.chapters)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (chapterError != null) {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
view?.showError(
|
|
||||||
trimException(chapterError!!),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return@launch
|
|
||||||
} else if (mangaError != null) {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
view?.showError(
|
|
||||||
trimException(mangaError!!),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getHistory()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests an updated list of chapters from the source.
|
* Requests an updated list of chapters from the source.
|
||||||
*/
|
*/
|
||||||
fun fetchChaptersFromSource() {
|
fun refreshChapters() {
|
||||||
hasRequested = true
|
presenterScope.launchUI {
|
||||||
isLoading = true
|
hasRequested = true
|
||||||
|
isLoading = true
|
||||||
presenterScope.launch(Dispatchers.IO) {
|
fetchChaptersFromSource(true)
|
||||||
val chapters = try {
|
|
||||||
source.getChapterList(manga.copy())
|
|
||||||
} catch (e: Exception) {
|
|
||||||
withContext(Dispatchers.Main) { view?.showError(trimException(e)) }
|
|
||||||
return@launch
|
|
||||||
}
|
|
||||||
isLoading = false
|
isLoading = false
|
||||||
try {
|
|
||||||
syncChaptersWithSource(chapters, manga, source)
|
|
||||||
|
|
||||||
getChapters()
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
view?.updateChapters(this@MangaDetailsPresenter.chapters)
|
|
||||||
}
|
|
||||||
getHistory()
|
|
||||||
} catch (e: java.lang.Exception) {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
view?.showError(trimException(e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,8 +570,7 @@ class MangaDetailsPresenter(
|
||||||
it.toProgressUpdate()
|
it.toProgressUpdate()
|
||||||
}
|
}
|
||||||
updateChapter.awaitAll(updates)
|
updateChapter.awaitAll(updates)
|
||||||
getChapters()
|
setCurrentChapters(getChapters())
|
||||||
withContext(Dispatchers.Main) { view?.updateChapters(chapters) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,8 +599,7 @@ class MangaDetailsPresenter(
|
||||||
if (read && deleteNow && preferences.removeAfterMarkedAsRead().get()) {
|
if (read && deleteNow && preferences.removeAfterMarkedAsRead().get()) {
|
||||||
deleteChapters(selectedChapters, false)
|
deleteChapters(selectedChapters, false)
|
||||||
}
|
}
|
||||||
getChapters()
|
setCurrentChapters(getChapters())
|
||||||
withContext(Dispatchers.Main) { view?.updateChapters(chapters) }
|
|
||||||
if (read && deleteNow) {
|
if (read && deleteNow) {
|
||||||
val latestReadChapter = selectedChapters.maxByOrNull { it.chapter_number.toInt() }?.chapter
|
val latestReadChapter = selectedChapters.maxByOrNull { it.chapter_number.toInt() }?.chapter
|
||||||
updateTrackChapterMarkedAsRead(preferences, latestReadChapter, manga.id) {
|
updateTrackChapterMarkedAsRead(preferences, latestReadChapter, manga.id) {
|
||||||
|
@ -741,8 +730,7 @@ class MangaDetailsPresenter(
|
||||||
|
|
||||||
private suspend fun asyncUpdateMangaAndChapters(justChapters: Boolean = false) {
|
private suspend fun asyncUpdateMangaAndChapters(justChapters: Boolean = false) {
|
||||||
if (!justChapters) updateManga.await(MangaUpdate(manga.id!!, chapterFlags = manga.chapter_flags))
|
if (!justChapters) updateManga.await(MangaUpdate(manga.id!!, chapterFlags = manga.chapter_flags))
|
||||||
getChapters()
|
setCurrentChapters(getChapters())
|
||||||
withUIContext { view?.updateChapters(chapters) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isScanlatorFiltered() = manga.filtered_scanlators?.isNotEmpty() == true
|
private fun isScanlatorFiltered() = manga.filtered_scanlators?.isNotEmpty() == true
|
||||||
|
@ -1158,9 +1146,9 @@ class MangaDetailsPresenter(
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun onQueueUpdate(queue: List<Download>) = withIOContext {
|
private suspend fun onQueueUpdate(queue: List<Download>) = withIOContext {
|
||||||
getChapters(queue)
|
setDownloadedChapters(chapters, queue)
|
||||||
withUIContext {
|
withUIContext {
|
||||||
view?.updateChapters(chapters)
|
view?.updateChapters()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,29 @@ interface Manga : SManga {
|
||||||
|
|
||||||
var cover_last_modified: Long
|
var cover_last_modified: Long
|
||||||
|
|
||||||
|
override fun copy(): Manga {
|
||||||
|
return (super.copy() as Manga).also {
|
||||||
|
it.id = this.id
|
||||||
|
it.source = this.source
|
||||||
|
it.favorite = this.favorite
|
||||||
|
it.last_update = this.last_update
|
||||||
|
it.date_added = this.date_added
|
||||||
|
it.viewer_flags = this.viewer_flags
|
||||||
|
it.chapter_flags = this.chapter_flags
|
||||||
|
it.hide_title = this.hide_title
|
||||||
|
it.filtered_scanlators = this.filtered_scanlators
|
||||||
|
|
||||||
|
it.ogTitle = this.ogTitle
|
||||||
|
it.ogAuthor = this.ogAuthor
|
||||||
|
it.ogArtist = this.ogArtist
|
||||||
|
it.ogDesc = this.ogDesc
|
||||||
|
it.ogGenre = this.ogGenre
|
||||||
|
it.ogStatus = this.ogStatus
|
||||||
|
|
||||||
|
it.cover_last_modified = this.cover_last_modified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated("Use ogTitle directly instead", ReplaceWith("ogTitle"))
|
@Deprecated("Use ogTitle directly instead", ReplaceWith("ogTitle"))
|
||||||
val originalTitle: String
|
val originalTitle: String
|
||||||
get() = ogTitle
|
get() = ogTitle
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue