mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
refactor(manga): Slowly using flow attempt 2
This commit is contained in:
parent
f8d74a6b2f
commit
f81be429df
3 changed files with 183 additions and 169 deletions
|
@ -182,6 +182,37 @@ var Manga.vibrantCoverColor: Int?
|
|||
id?.let { MangaCoverMetadata.setVibrantColor(it, value) }
|
||||
}
|
||||
|
||||
fun Manga.copyDomain(): Manga = MangaImpl().also { other ->
|
||||
other.url = this.url
|
||||
other.title = this.title
|
||||
other.artist = this.artist
|
||||
other.author = this.author
|
||||
other.description = this.description
|
||||
other.genre = this.genre
|
||||
other.status = this.status
|
||||
other.thumbnail_url = this.thumbnail_url
|
||||
other.initialized = this.initialized
|
||||
|
||||
other.id = this.id
|
||||
other.source = this.source
|
||||
other.favorite = this.favorite
|
||||
other.last_update = this.last_update
|
||||
other.date_added = this.date_added
|
||||
other.viewer_flags = this.viewer_flags
|
||||
other.chapter_flags = this.chapter_flags
|
||||
other.hide_title = this.hide_title
|
||||
other.filtered_scanlators = this.filtered_scanlators
|
||||
|
||||
other.ogTitle = this.ogTitle
|
||||
other.ogAuthor = this.ogAuthor
|
||||
other.ogArtist = this.ogArtist
|
||||
other.ogDesc = this.ogDesc
|
||||
other.ogGenre = this.ogGenre
|
||||
other.ogStatus = this.ogStatus
|
||||
|
||||
other.cover_last_modified = this.cover_last_modified
|
||||
}
|
||||
|
||||
fun Manga.Companion.create(source: Long) = MangaImpl().apply {
|
||||
this.source = source
|
||||
}
|
||||
|
|
|
@ -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
|
||||
override val presenter: MangaDetailsPresenter
|
||||
private var coverColor: Int? = null
|
||||
|
@ -674,7 +674,7 @@ class MangaDetailsController :
|
|||
returningFromReader = false
|
||||
runBlocking {
|
||||
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
|
||||
tabletAdapter?.notifyItemChanged(0)
|
||||
adapter?.setChapters(chapters)
|
||||
|
@ -821,15 +821,11 @@ class MangaDetailsController :
|
|||
updateMenuVisibility(activityBinding?.toolbar?.menu)
|
||||
}
|
||||
|
||||
fun updateChapters(chapters: List<ChapterItem>) {
|
||||
fun updateChapters() {
|
||||
view ?: return
|
||||
binding.swipeRefresh.isRefreshing = presenter.isLoading
|
||||
if (presenter.chapters.isEmpty() && fromCatalogue && !presenter.hasRequested) {
|
||||
launchUI { binding.swipeRefresh.isRefreshing = true }
|
||||
presenter.fetchChaptersFromSource()
|
||||
}
|
||||
adapter?.setChapters(presenter.chapters)
|
||||
tabletAdapter?.notifyItemChanged(0)
|
||||
adapter?.setChapters(chapters)
|
||||
addMangaHeader()
|
||||
colorToolbar(binding.recycler.canScrollVertically(-1))
|
||||
updateMenuVisibility(activityBinding?.toolbar?.menu)
|
||||
|
|
|
@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.data.database.models.History
|
|||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.database.models.bookmarkedFilter
|
||||
import eu.kanade.tachiyomi.data.database.models.chapterOrder
|
||||
import eu.kanade.tachiyomi.data.database.models.copyDomain
|
||||
import eu.kanade.tachiyomi.data.database.models.downloadedFilter
|
||||
import eu.kanade.tachiyomi.data.database.models.prepareCoverUpdate
|
||||
import eu.kanade.tachiyomi.data.database.models.readFilter
|
||||
|
@ -34,6 +35,7 @@ import eu.kanade.tachiyomi.data.track.EnhancedTrackService
|
|||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.data.track.TrackService
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
import eu.kanade.tachiyomi.network.HttpException
|
||||
import eu.kanade.tachiyomi.network.NetworkPreferences
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
|
@ -76,11 +78,15 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.flow.updateAndGet
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
|
@ -127,11 +133,15 @@ class MangaDetailsPresenter(
|
|||
|
||||
private val networkPreferences: NetworkPreferences by injectLazy()
|
||||
|
||||
// private val currentMangaInternal: MutableStateFlow<Manga?> = MutableStateFlow(null)
|
||||
// val currentManga get() = currentMangaInternal.asStateFlow()
|
||||
private val currentMangaInternal = MutableStateFlow<Manga?>(null)
|
||||
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 mangaShortcutManager: MangaShortcutManager by injectLazy()
|
||||
|
@ -151,8 +161,12 @@ class MangaDetailsPresenter(
|
|||
|
||||
var trackList: List<TrackItem> = emptyList()
|
||||
|
||||
var chapters: List<ChapterItem> = emptyList()
|
||||
private set
|
||||
private val currentChaptersInternal = MutableStateFlow<List<ChapterItem>>(emptyList())
|
||||
val currentChapters = currentChaptersInternal.asStateFlow()
|
||||
|
||||
var chapters: List<ChapterItem>
|
||||
get() = currentChapters.value
|
||||
private set(value) { currentChaptersInternal.value = value }
|
||||
|
||||
var allChapters: List<ChapterItem> = emptyList()
|
||||
private set
|
||||
|
@ -186,7 +200,7 @@ class MangaDetailsPresenter(
|
|||
val controller = view ?: return
|
||||
|
||||
isLockedFromSearch = controller.shouldLockIfNeeded && SecureActivityDelegate.shouldBeLocked()
|
||||
if (!::manga.isInitialized) runBlocking { refreshMangaFromDb() }
|
||||
if (currentManga.value == null) runBlocking { refreshMangaFromDb() }
|
||||
syncData()
|
||||
|
||||
presenterScope.launchUI {
|
||||
|
@ -204,6 +218,26 @@ class MangaDetailsPresenter(
|
|||
presenterScope.launchIO {
|
||||
downloadManager.queueState.collectLatest(::onQueueUpdate)
|
||||
}
|
||||
presenterScope.launchUI {
|
||||
currentManga.collectLatest {
|
||||
if (it == null) return@collectLatest
|
||||
|
||||
controller.updateHeader()
|
||||
}
|
||||
}
|
||||
presenterScope.launchIO {
|
||||
currentChapters.collectLatest { chapters ->
|
||||
allChapters = if (!isScanlatorFiltered()) chapters else getChapter.awaitAll(mangaId, false).map { it.toModel() }
|
||||
|
||||
allChapterScanlators = allChapters.mapNotNull { it.chapter.scanlator }.toSet()
|
||||
|
||||
getHistory()
|
||||
|
||||
withUIContext {
|
||||
controller.updateChapters()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runBlocking {
|
||||
tracks = getTrack.awaitAllByMangaId(mangaId)
|
||||
|
@ -216,25 +250,24 @@ class MangaDetailsPresenter(
|
|||
fun onCreateLate() {
|
||||
val controller = view ?: return
|
||||
|
||||
isLoading = true
|
||||
controller.setRefresh(true) // FIXME: Use progress indicator instead
|
||||
|
||||
LibraryUpdateJob.updateFlow
|
||||
.filter { it == mangaId }
|
||||
.onEach { onUpdateManga() }
|
||||
.launchIn(presenterScope)
|
||||
|
||||
if (manga.isLocal()) {
|
||||
refreshAll()
|
||||
} else if (!manga.initialized) {
|
||||
isLoading = true
|
||||
controller.setRefresh(true)
|
||||
controller.updateHeader()
|
||||
refreshAll()
|
||||
} else {
|
||||
runBlocking { getChapters() }
|
||||
controller.updateChapters(this.chapters)
|
||||
getHistory()
|
||||
}
|
||||
val updateMangaNeeded = !manga.initialized
|
||||
val updateChaptersNeeded = runBlocking { setAndGetChapters() }.isEmpty()
|
||||
|
||||
presenterScope.launch {
|
||||
val tasks = listOf(
|
||||
async { if (updateMangaNeeded) fetchMangaFromSource() },
|
||||
async { if (updateChaptersNeeded) fetchChaptersFromSource(false) },
|
||||
)
|
||||
tasks.awaitAll()
|
||||
|
||||
setTrackItems()
|
||||
}
|
||||
|
||||
|
@ -243,16 +276,14 @@ class MangaDetailsPresenter(
|
|||
|
||||
fun fetchChapters(andTracking: Boolean = true) {
|
||||
presenterScope.launch {
|
||||
getChapters()
|
||||
setCurrentChapters(getChapters())
|
||||
if (andTracking) fetchTracks()
|
||||
withContext(Dispatchers.Main) { view?.updateChapters(chapters) }
|
||||
getHistory()
|
||||
}
|
||||
}
|
||||
|
||||
fun setCurrentManga(manga: Manga?) {
|
||||
// currentMangaInternal.update { manga }
|
||||
this.manga = manga!!
|
||||
currentMangaInternal.update { manga }
|
||||
}
|
||||
|
||||
// TODO: Use flow to "sync" data instead
|
||||
|
@ -264,20 +295,18 @@ class MangaDetailsPresenter(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun getChaptersNow(): List<ChapterItem> {
|
||||
getChapters()
|
||||
return chapters
|
||||
// TODO: Use getChapter.subscribe() flow instead
|
||||
suspend fun setAndGetChapters(): List<ChapterItem> {
|
||||
return currentChaptersInternal.updateAndGet { getChapters().applyChapterFilters() }
|
||||
}
|
||||
|
||||
private suspend fun getChapters(queue: List<Download> = downloadManager.queueState.value) {
|
||||
val chapters = getChapter.awaitAll(mangaId, isScanlatorFiltered()).map { it.toModel() }
|
||||
allChapters = if (!isScanlatorFiltered()) chapters else getChapter.awaitAll(mangaId, false).map { it.toModel() }
|
||||
// TODO: Use getChapter.subscribe() flow instead
|
||||
private fun setCurrentChapters(chapters: List<ChapterItem>) {
|
||||
currentChaptersInternal.update { chapters.applyChapterFilters() }
|
||||
}
|
||||
|
||||
// Find downloaded chapters
|
||||
setDownloadedChapters(chapters, queue)
|
||||
allChapterScanlators = allChapters.mapNotNull { it.chapter.scanlator }.toSet()
|
||||
|
||||
this.chapters = applyChapterFilters(chapters)
|
||||
private suspend fun getChapters(): List<ChapterItem> {
|
||||
return getChapter.awaitAll(mangaId, isScanlatorFiltered()).map { it.toModel() }
|
||||
}
|
||||
|
||||
private fun getHistory() {
|
||||
|
@ -291,14 +320,17 @@ class MangaDetailsPresenter(
|
|||
*
|
||||
* @param chapters the list of chapter from the database.
|
||||
*/
|
||||
private fun setDownloadedChapters(chapters: List<ChapterItem>, queue: List<Download>) {
|
||||
for (chapter in chapters) {
|
||||
if (downloadManager.isChapterDownloaded(chapter, manga)) {
|
||||
chapter.status = Download.State.DOWNLOADED
|
||||
} else if (queue.isNotEmpty()) {
|
||||
chapter.status = queue.find { it.chapter.id == chapter.id }
|
||||
?.status ?: Download.State.default
|
||||
private fun setDownloadedChapters(queue: List<Download>) {
|
||||
currentChaptersInternal.update { chapters ->
|
||||
for (chapter in chapters) {
|
||||
if (downloadManager.isChapterDownloaded(chapter, manga)) {
|
||||
chapter.status = Download.State.DOWNLOADED
|
||||
} else if (queue.isNotEmpty()) {
|
||||
chapter.status = queue.find { it.chapter.id == chapter.id }
|
||||
?.status ?: Download.State.default
|
||||
}
|
||||
}
|
||||
chapters
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,12 +364,12 @@ class MangaDetailsPresenter(
|
|||
* @param chapterList the list of chapters from the database
|
||||
* @return an observable of the list of chapters filtered and sorted.
|
||||
*/
|
||||
private fun applyChapterFilters(chapterList: List<ChapterItem>): List<ChapterItem> {
|
||||
private fun List<ChapterItem>.applyChapterFilters(): List<ChapterItem> {
|
||||
if (isLockedFromSearch) {
|
||||
return chapterList
|
||||
return this
|
||||
}
|
||||
getScrollType(chapterList)
|
||||
return chapterSort.getChaptersSorted(chapterList)
|
||||
getScrollType(this)
|
||||
return chapterSort.getChaptersSorted(this)
|
||||
}
|
||||
|
||||
fun getChapterUrl(chapter: Chapter): String? {
|
||||
|
@ -394,7 +426,7 @@ class MangaDetailsPresenter(
|
|||
download = null
|
||||
}
|
||||
|
||||
view?.updateChapters(this.chapters)
|
||||
view?.updateChapters()
|
||||
|
||||
downloadManager.deleteChapters(listOf(chapter), manga, source, true)
|
||||
}
|
||||
|
@ -412,7 +444,7 @@ class MangaDetailsPresenter(
|
|||
}
|
||||
}
|
||||
|
||||
if (update) view?.updateChapters(this.chapters)
|
||||
if (update) view?.updateChapters()
|
||||
|
||||
if (isEverything) {
|
||||
downloadManager.deleteManga(manga, source)
|
||||
|
@ -432,125 +464,80 @@ class MangaDetailsPresenter(
|
|||
if (view?.isNotOnline() == true && !manga.isLocal()) return
|
||||
presenterScope.launch {
|
||||
isLoading = true
|
||||
var mangaError: java.lang.Exception? = null
|
||||
var chapterError: java.lang.Exception? = null
|
||||
val chapters = async(Dispatchers.IO) {
|
||||
try {
|
||||
source.getChapterList(manga.copy())
|
||||
} catch (e: Exception) {
|
||||
chapterError = e
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
val nManga = async(Dispatchers.IO) {
|
||||
try {
|
||||
source.getMangaDetails(manga.copy())
|
||||
} catch (e: java.lang.Exception) {
|
||||
mangaError = e
|
||||
null
|
||||
}
|
||||
}
|
||||
val tasks = listOf(
|
||||
async { fetchMangaFromSource() },
|
||||
async { fetchChaptersFromSource() },
|
||||
)
|
||||
tasks.awaitAll()
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
val networkManga = nManga.await()
|
||||
if (networkManga != null) {
|
||||
manga.prepareCoverUpdate(coverCache, networkManga, false)
|
||||
manga.copyFrom(networkManga)
|
||||
manga.initialized = true
|
||||
private suspend fun fetchMangaFromSource() {
|
||||
try {
|
||||
val manga = manga.copyDomain()
|
||||
val networkManga = source.getMangaDetails(manga.copy())
|
||||
|
||||
updateManga.await(manga.toMangaUpdate())
|
||||
manga.prepareCoverUpdate(coverCache, networkManga, false)
|
||||
manga.copyFrom(networkManga)
|
||||
manga.initialized = true
|
||||
|
||||
launchIO {
|
||||
val request =
|
||||
ImageRequest.Builder(preferences.context).data(manga.cover())
|
||||
.memoryCachePolicy(CachePolicy.DISABLED)
|
||||
.diskCachePolicy(CachePolicy.WRITE_ONLY)
|
||||
.build()
|
||||
updateManga.await(manga.toMangaUpdate())
|
||||
|
||||
if (preferences.context.imageLoader.execute(request) is SuccessResult) {
|
||||
withContext(Dispatchers.Main) {
|
||||
view?.setPaletteColor()
|
||||
}
|
||||
setCurrentManga(manga)
|
||||
|
||||
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()
|
||||
if (finChapters.isNotEmpty()) {
|
||||
val newChapters = withIOContext { syncChaptersWithSource(finChapters, manga, source) }
|
||||
if (newChapters.first.isNotEmpty()) {
|
||||
} catch (e: Exception) {
|
||||
if (e is HttpException && e.code == 103) return
|
||||
|
||||
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)) {
|
||||
downloadChapters(
|
||||
newChapters.first.sortedBy { it.chapter_number }
|
||||
.map { it.toModel() },
|
||||
)
|
||||
downloadChapters(added.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()) {
|
||||
val removedChaptersId = newChapters.second.map { it.id }
|
||||
if (removed.isNotEmpty() && manualFetch) {
|
||||
val removedChaptersId = removed.map { it.id }
|
||||
val removedChapters = this@MangaDetailsPresenter.chapters.filter {
|
||||
it.id in removedChaptersId && it.isDownloaded
|
||||
}
|
||||
if (removedChapters.isNotEmpty()) {
|
||||
withContext(Dispatchers.Main) {
|
||||
view?.showChaptersRemovedPopup(
|
||||
removedChapters,
|
||||
)
|
||||
withUIContext {
|
||||
view?.showChaptersRemovedPopup(removedChapters)
|
||||
}
|
||||
}
|
||||
}
|
||||
getChapters()
|
||||
}
|
||||
isLoading = false
|
||||
if (chapterError == null) {
|
||||
withContext(Dispatchers.Main) {
|
||||
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.
|
||||
*/
|
||||
fun fetchChaptersFromSource() {
|
||||
hasRequested = true
|
||||
isLoading = true
|
||||
|
||||
presenterScope.launch(Dispatchers.IO) {
|
||||
val chapters = try {
|
||||
source.getChapterList(manga.copy())
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) { view?.showError(trimException(e)) }
|
||||
return@launch
|
||||
}
|
||||
isLoading = false
|
||||
try {
|
||||
syncChaptersWithSource(chapters, manga, source)
|
||||
|
||||
getChapters()
|
||||
withContext(Dispatchers.Main) {
|
||||
view?.updateChapters(this@MangaDetailsPresenter.chapters)
|
||||
}
|
||||
setCurrentChapters(getChapters())
|
||||
getHistory()
|
||||
} catch (e: java.lang.Exception) {
|
||||
withContext(Dispatchers.Main) {
|
||||
view?.showError(trimException(e))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
withUIContext {
|
||||
view?.showError(trimException(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -579,8 +566,7 @@ class MangaDetailsPresenter(
|
|||
it.toProgressUpdate()
|
||||
}
|
||||
updateChapter.awaitAll(updates)
|
||||
getChapters()
|
||||
withContext(Dispatchers.Main) { view?.updateChapters(chapters) }
|
||||
setCurrentChapters(getChapters())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -609,8 +595,7 @@ class MangaDetailsPresenter(
|
|||
if (read && deleteNow && preferences.removeAfterMarkedAsRead().get()) {
|
||||
deleteChapters(selectedChapters, false)
|
||||
}
|
||||
getChapters()
|
||||
withContext(Dispatchers.Main) { view?.updateChapters(chapters) }
|
||||
setCurrentChapters(getChapters())
|
||||
if (read && deleteNow) {
|
||||
val latestReadChapter = selectedChapters.maxByOrNull { it.chapter_number.toInt() }?.chapter
|
||||
updateTrackChapterMarkedAsRead(preferences, latestReadChapter, manga.id) {
|
||||
|
@ -741,8 +726,7 @@ class MangaDetailsPresenter(
|
|||
|
||||
private suspend fun asyncUpdateMangaAndChapters(justChapters: Boolean = false) {
|
||||
if (!justChapters) updateManga.await(MangaUpdate(manga.id!!, chapterFlags = manga.chapter_flags))
|
||||
getChapters()
|
||||
withUIContext { view?.updateChapters(chapters) }
|
||||
setCurrentChapters(getChapters())
|
||||
}
|
||||
|
||||
private fun isScanlatorFiltered() = manga.filtered_scanlators?.isNotEmpty() == true
|
||||
|
@ -811,7 +795,7 @@ class MangaDetailsPresenter(
|
|||
withUIContext {
|
||||
view?.shareManga(uri.uri.toFile())
|
||||
}
|
||||
} catch (_: java.lang.Exception) {
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1153,15 +1137,15 @@ class MangaDetailsPresenter(
|
|||
|
||||
override fun onStatusChange(download: Download) {
|
||||
super.onStatusChange(download)
|
||||
chapters.find { it.id == download.chapter.id }?.status = download.status
|
||||
currentChaptersInternal.update { chapters ->
|
||||
chapters.find { it.id == download.chapter.id }?.status = download.status
|
||||
chapters
|
||||
}
|
||||
onPageProgressUpdate(download)
|
||||
}
|
||||
|
||||
private suspend fun onQueueUpdate(queue: List<Download>) = withIOContext {
|
||||
getChapters(queue)
|
||||
withUIContext {
|
||||
view?.updateChapters(chapters)
|
||||
}
|
||||
setDownloadedChapters(queue)
|
||||
}
|
||||
|
||||
override fun onQueueUpdate(download: Download) {
|
||||
|
@ -1173,7 +1157,10 @@ class MangaDetailsPresenter(
|
|||
}
|
||||
|
||||
override fun onPageProgressUpdate(download: Download) {
|
||||
chapters.find { it.id == download.chapter.id }?.download = download
|
||||
currentChaptersInternal.update { chapters ->
|
||||
chapters.find { it.id == download.chapter.id }?.download = download
|
||||
chapters
|
||||
}
|
||||
view?.updateChapterDownload(download)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue