mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
revert: Revert flow usage commits
Too much headache...
This commit is contained in:
parent
4a0f578211
commit
4ffb0ad8ee
3 changed files with 170 additions and 187 deletions
|
@ -182,37 +182,6 @@ var Manga.vibrantCoverColor: Int?
|
||||||
id?.let { MangaCoverMetadata.setVibrantColor(it, value) }
|
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 {
|
fun Manga.Companion.create(source: Long) = MangaImpl().apply {
|
||||||
this.source = source
|
this.source = source
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,7 @@ class MangaDetailsController :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val manga: Manga? get() = presenter.currentManga.value
|
private val manga: Manga? get() = if (presenter.isMangaLateInitInitialized()) presenter.manga else null
|
||||||
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.setAndGetChapters() } ?: return@runBlocking
|
val chapters = withTimeoutOrNull(1000) { presenter.getChaptersNow() } ?: return@runBlocking
|
||||||
binding.recycler.itemAnimator = null
|
binding.recycler.itemAnimator = null
|
||||||
tabletAdapter?.notifyItemChanged(0)
|
tabletAdapter?.notifyItemChanged(0)
|
||||||
adapter?.setChapters(chapters)
|
adapter?.setChapters(chapters)
|
||||||
|
@ -821,11 +821,15 @@ class MangaDetailsController :
|
||||||
updateMenuVisibility(activityBinding?.toolbar?.menu)
|
updateMenuVisibility(activityBinding?.toolbar?.menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateChapters() {
|
fun updateChapters(chapters: List<ChapterItem>) {
|
||||||
view ?: return
|
view ?: return
|
||||||
binding.swipeRefresh.isRefreshing = presenter.isLoading
|
binding.swipeRefresh.isRefreshing = presenter.isLoading
|
||||||
adapter?.setChapters(presenter.chapters)
|
if (presenter.chapters.isEmpty() && fromCatalogue && !presenter.hasRequested) {
|
||||||
|
launchUI { binding.swipeRefresh.isRefreshing = true }
|
||||||
|
presenter.fetchChaptersFromSource()
|
||||||
|
}
|
||||||
tabletAdapter?.notifyItemChanged(0)
|
tabletAdapter?.notifyItemChanged(0)
|
||||||
|
adapter?.setChapters(chapters)
|
||||||
addMangaHeader()
|
addMangaHeader()
|
||||||
colorToolbar(binding.recycler.canScrollVertically(-1))
|
colorToolbar(binding.recycler.canScrollVertically(-1))
|
||||||
updateMenuVisibility(activityBinding?.toolbar?.menu)
|
updateMenuVisibility(activityBinding?.toolbar?.menu)
|
||||||
|
|
|
@ -18,7 +18,6 @@ import eu.kanade.tachiyomi.data.database.models.History
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.database.models.bookmarkedFilter
|
import eu.kanade.tachiyomi.data.database.models.bookmarkedFilter
|
||||||
import eu.kanade.tachiyomi.data.database.models.chapterOrder
|
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.downloadedFilter
|
||||||
import eu.kanade.tachiyomi.data.database.models.prepareCoverUpdate
|
import eu.kanade.tachiyomi.data.database.models.prepareCoverUpdate
|
||||||
import eu.kanade.tachiyomi.data.database.models.readFilter
|
import eu.kanade.tachiyomi.data.database.models.readFilter
|
||||||
|
@ -35,7 +34,6 @@ 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
|
||||||
|
@ -78,15 +76,11 @@ 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
|
||||||
|
@ -133,15 +127,11 @@ class MangaDetailsPresenter(
|
||||||
|
|
||||||
private val networkPreferences: NetworkPreferences by injectLazy()
|
private val networkPreferences: NetworkPreferences by injectLazy()
|
||||||
|
|
||||||
private val currentMangaInternal = MutableStateFlow<Manga?>(null)
|
// private val currentMangaInternal: MutableStateFlow<Manga?> = MutableStateFlow(null)
|
||||||
val currentManga = currentMangaInternal.asStateFlow()
|
// val currentManga get() = currentMangaInternal.asStateFlow()
|
||||||
|
|
||||||
/**
|
lateinit var manga: Manga
|
||||||
* Unsafe, call only after currentManga is no longer null
|
fun isMangaLateInitInitialized() = ::manga.isInitialized
|
||||||
*/
|
|
||||||
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()
|
||||||
|
@ -161,12 +151,8 @@ class MangaDetailsPresenter(
|
||||||
|
|
||||||
var trackList: List<TrackItem> = emptyList()
|
var trackList: List<TrackItem> = emptyList()
|
||||||
|
|
||||||
private val currentChaptersInternal = MutableStateFlow<List<ChapterItem>>(emptyList())
|
var chapters: List<ChapterItem> = emptyList()
|
||||||
val currentChapters = currentChaptersInternal.asStateFlow()
|
private set
|
||||||
|
|
||||||
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
|
||||||
|
@ -174,7 +160,7 @@ class MangaDetailsPresenter(
|
||||||
var allHistory: List<History> = emptyList()
|
var allHistory: List<History> = emptyList()
|
||||||
private set
|
private set
|
||||||
|
|
||||||
val headerItem: MangaHeaderItem get() = MangaHeaderItem(mangaId, view?.fromCatalogue == true)
|
val headerItem: MangaHeaderItem by lazy { MangaHeaderItem(mangaId, view?.fromCatalogue == true)}
|
||||||
var tabletChapterHeaderItem: MangaHeaderItem? = null
|
var tabletChapterHeaderItem: MangaHeaderItem? = null
|
||||||
get() {
|
get() {
|
||||||
when (view?.isTablet) {
|
when (view?.isTablet) {
|
||||||
|
@ -200,15 +186,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() }
|
||||||
presenterScope.launchUI {
|
|
||||||
currentManga.collectLatest {
|
|
||||||
if (it == null) return@collectLatest
|
|
||||||
|
|
||||||
controller.updateHeader()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (currentManga.value == null) runBlocking { refreshMangaFromDb() }
|
|
||||||
syncData()
|
syncData()
|
||||||
|
|
||||||
presenterScope.launchUI {
|
presenterScope.launchUI {
|
||||||
|
@ -226,19 +204,6 @@ class MangaDetailsPresenter(
|
||||||
presenterScope.launchIO {
|
presenterScope.launchIO {
|
||||||
downloadManager.queueState.collectLatest(::onQueueUpdate)
|
downloadManager.queueState.collectLatest(::onQueueUpdate)
|
||||||
}
|
}
|
||||||
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 {
|
runBlocking {
|
||||||
tracks = getTrack.awaitAllByMangaId(mangaId)
|
tracks = getTrack.awaitAllByMangaId(mangaId)
|
||||||
|
@ -251,26 +216,25 @@ class MangaDetailsPresenter(
|
||||||
fun onCreateLate() {
|
fun onCreateLate() {
|
||||||
val controller = view ?: return
|
val controller = view ?: return
|
||||||
|
|
||||||
isLoading = true
|
|
||||||
controller.setRefresh(true) // FIXME: Use progress indicator instead
|
|
||||||
|
|
||||||
LibraryUpdateJob.updateFlow
|
LibraryUpdateJob.updateFlow
|
||||||
.filter { it == mangaId }
|
.filter { it == mangaId }
|
||||||
.onEach { onUpdateManga() }
|
.onEach { onUpdateManga() }
|
||||||
.launchIn(presenterScope)
|
.launchIn(presenterScope)
|
||||||
|
|
||||||
val updateMangaNeeded = currentManga.value?.initialized != true
|
if (manga.isLocal()) {
|
||||||
val updateChaptersNeeded = runBlocking { setAndGetChapters() }.isEmpty()
|
refreshAll()
|
||||||
|
} else if (!manga.initialized) {
|
||||||
|
isLoading = true
|
||||||
|
controller.setRefresh(true)
|
||||||
|
controller.updateHeader()
|
||||||
|
refreshAll()
|
||||||
|
} else {
|
||||||
|
runBlocking { getChapters() }
|
||||||
|
controller.updateChapters(this.chapters)
|
||||||
|
getHistory()
|
||||||
|
}
|
||||||
|
|
||||||
presenterScope.launch {
|
presenterScope.launch {
|
||||||
isLoading = true
|
|
||||||
val tasks = listOf(
|
|
||||||
async { if (updateMangaNeeded) fetchMangaFromSource() },
|
|
||||||
async { if (updateChaptersNeeded) fetchChaptersFromSource(false) },
|
|
||||||
)
|
|
||||||
tasks.awaitAll()
|
|
||||||
isLoading = false
|
|
||||||
|
|
||||||
setTrackItems()
|
setTrackItems()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,14 +243,16 @@ class MangaDetailsPresenter(
|
||||||
|
|
||||||
fun fetchChapters(andTracking: Boolean = true) {
|
fun fetchChapters(andTracking: Boolean = true) {
|
||||||
presenterScope.launch {
|
presenterScope.launch {
|
||||||
setCurrentChapters(getChapters())
|
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
|
||||||
|
@ -298,18 +264,20 @@ class MangaDetailsPresenter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use getChapter.subscribe() flow instead
|
suspend fun getChaptersNow(): List<ChapterItem> {
|
||||||
suspend fun setAndGetChapters(): List<ChapterItem> {
|
getChapters()
|
||||||
return currentChaptersInternal.updateAndGet { getChapters().applyChapterFilters() }
|
return chapters
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use getChapter.subscribe() flow instead
|
private suspend fun getChapters(queue: List<Download> = downloadManager.queueState.value) {
|
||||||
private fun setCurrentChapters(chapters: List<ChapterItem>) {
|
val chapters = getChapter.awaitAll(mangaId, isScanlatorFiltered()).map { it.toModel() }
|
||||||
currentChaptersInternal.update { chapters.applyChapterFilters() }
|
allChapters = if (!isScanlatorFiltered()) chapters else getChapter.awaitAll(mangaId, false).map { it.toModel() }
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun getChapters(): List<ChapterItem> {
|
// Find downloaded chapters
|
||||||
return getChapter.awaitAll(mangaId, isScanlatorFiltered()).map { it.toModel() }
|
setDownloadedChapters(chapters, queue)
|
||||||
|
allChapterScanlators = allChapters.mapNotNull { it.chapter.scanlator }.toSet()
|
||||||
|
|
||||||
|
this.chapters = applyChapterFilters(chapters)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getHistory() {
|
private fun getHistory() {
|
||||||
|
@ -323,17 +291,14 @@ class MangaDetailsPresenter(
|
||||||
*
|
*
|
||||||
* @param chapters the list of chapter from the database.
|
* @param chapters the list of chapter from the database.
|
||||||
*/
|
*/
|
||||||
private fun setDownloadedChapters(queue: List<Download>) {
|
private fun setDownloadedChapters(chapters: List<ChapterItem>, queue: List<Download>) {
|
||||||
currentChaptersInternal.update { chapters ->
|
for (chapter in chapters) {
|
||||||
for (chapter in chapters) {
|
if (downloadManager.isChapterDownloaded(chapter, manga)) {
|
||||||
if (downloadManager.isChapterDownloaded(chapter, manga)) {
|
chapter.status = Download.State.DOWNLOADED
|
||||||
chapter.status = Download.State.DOWNLOADED
|
} else if (queue.isNotEmpty()) {
|
||||||
} else if (queue.isNotEmpty()) {
|
chapter.status = queue.find { it.chapter.id == chapter.id }
|
||||||
chapter.status = queue.find { it.chapter.id == chapter.id }
|
?.status ?: Download.State.default
|
||||||
?.status ?: Download.State.default
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
chapters
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,12 +332,12 @@ class MangaDetailsPresenter(
|
||||||
* @param chapterList the list of chapters from the database
|
* @param chapterList the list of chapters from the database
|
||||||
* @return an observable of the list of chapters filtered and sorted.
|
* @return an observable of the list of chapters filtered and sorted.
|
||||||
*/
|
*/
|
||||||
private fun List<ChapterItem>.applyChapterFilters(): List<ChapterItem> {
|
private fun applyChapterFilters(chapterList: List<ChapterItem>): List<ChapterItem> {
|
||||||
if (isLockedFromSearch) {
|
if (isLockedFromSearch) {
|
||||||
return this
|
return chapterList
|
||||||
}
|
}
|
||||||
getScrollType(this)
|
getScrollType(chapterList)
|
||||||
return chapterSort.getChaptersSorted(this)
|
return chapterSort.getChaptersSorted(chapterList)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getChapterUrl(chapter: Chapter): String? {
|
fun getChapterUrl(chapter: Chapter): String? {
|
||||||
|
@ -429,7 +394,7 @@ class MangaDetailsPresenter(
|
||||||
download = null
|
download = null
|
||||||
}
|
}
|
||||||
|
|
||||||
view?.updateChapters()
|
view?.updateChapters(this.chapters)
|
||||||
|
|
||||||
downloadManager.deleteChapters(listOf(chapter), manga, source, true)
|
downloadManager.deleteChapters(listOf(chapter), manga, source, true)
|
||||||
}
|
}
|
||||||
|
@ -447,7 +412,7 @@ class MangaDetailsPresenter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update) view?.updateChapters()
|
if (update) view?.updateChapters(this.chapters)
|
||||||
|
|
||||||
if (isEverything) {
|
if (isEverything) {
|
||||||
downloadManager.deleteManga(manga, source)
|
downloadManager.deleteManga(manga, source)
|
||||||
|
@ -467,80 +432,125 @@ class MangaDetailsPresenter(
|
||||||
if (view?.isNotOnline() == true && !manga.isLocal()) return
|
if (view?.isNotOnline() == true && !manga.isLocal()) return
|
||||||
presenterScope.launch {
|
presenterScope.launch {
|
||||||
isLoading = true
|
isLoading = true
|
||||||
val tasks = listOf(
|
var mangaError: java.lang.Exception? = null
|
||||||
async { fetchMangaFromSource() },
|
var chapterError: java.lang.Exception? = null
|
||||||
async { fetchChaptersFromSource() },
|
val chapters = async(Dispatchers.IO) {
|
||||||
)
|
try {
|
||||||
tasks.awaitAll()
|
source.getChapterList(manga.copy())
|
||||||
isLoading = false
|
} catch (e: Exception) {
|
||||||
}
|
chapterError = e
|
||||||
}
|
emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val nManga = async(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
source.getMangaDetails(manga.copy())
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
mangaError = e
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun fetchMangaFromSource() {
|
val networkManga = nManga.await()
|
||||||
try {
|
if (networkManga != null) {
|
||||||
val manga = manga.copyDomain()
|
manga.prepareCoverUpdate(coverCache, networkManga, false)
|
||||||
val networkManga = source.getMangaDetails(manga.copy())
|
manga.copyFrom(networkManga)
|
||||||
|
manga.initialized = true
|
||||||
|
|
||||||
manga.prepareCoverUpdate(coverCache, networkManga, false)
|
updateManga.await(manga.toMangaUpdate())
|
||||||
manga.copyFrom(networkManga)
|
|
||||||
manga.initialized = true
|
|
||||||
|
|
||||||
updateManga.await(manga.toMangaUpdate())
|
launchIO {
|
||||||
|
val request =
|
||||||
|
ImageRequest.Builder(preferences.context).data(manga.cover())
|
||||||
|
.memoryCachePolicy(CachePolicy.DISABLED)
|
||||||
|
.diskCachePolicy(CachePolicy.WRITE_ONLY)
|
||||||
|
.build()
|
||||||
|
|
||||||
setCurrentManga(manga)
|
if (preferences.context.imageLoader.execute(request) is SuccessResult) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
presenterScope.launchNonCancellableIO {
|
view?.setPaletteColor()
|
||||||
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) {
|
|
||||||
withUIContext {
|
|
||||||
view?.setPaletteColor()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
val finChapters = chapters.await()
|
||||||
if (e is HttpException && e.code == 103) return
|
if (finChapters.isNotEmpty()) {
|
||||||
|
val newChapters = withIOContext { syncChaptersWithSource(finChapters, manga, source) }
|
||||||
withUIContext {
|
if (newChapters.first.isNotEmpty()) {
|
||||||
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(added.sortedBy { it.chapter_number }.map { it.toModel() })
|
downloadChapters(
|
||||||
}
|
newChapters.first.sortedBy { it.chapter_number }
|
||||||
withUIContext {
|
.map { it.toModel() },
|
||||||
view?.view?.context?.let { mangaShortcutManager.updateShortcuts(it) }
|
)
|
||||||
}
|
}
|
||||||
|
view?.view?.context?.let { mangaShortcutManager.updateShortcuts(it) }
|
||||||
}
|
}
|
||||||
if (removed.isNotEmpty() && manualFetch) {
|
if (newChapters.second.isNotEmpty()) {
|
||||||
val removedChaptersId = removed.map { it.id }
|
val removedChaptersId = newChapters.second.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()) {
|
||||||
withUIContext {
|
withContext(Dispatchers.Main) {
|
||||||
view?.showChaptersRemovedPopup(removedChapters)
|
view?.showChaptersRemovedPopup(
|
||||||
|
removedChapters,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setCurrentChapters(getChapters())
|
getChapters()
|
||||||
getHistory()
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
isLoading = false
|
||||||
withUIContext {
|
if (chapterError == null) {
|
||||||
view?.showError(trimException(e))
|
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)
|
||||||
|
}
|
||||||
|
getHistory()
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
view?.showError(trimException(e))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -569,7 +579,8 @@ class MangaDetailsPresenter(
|
||||||
it.toProgressUpdate()
|
it.toProgressUpdate()
|
||||||
}
|
}
|
||||||
updateChapter.awaitAll(updates)
|
updateChapter.awaitAll(updates)
|
||||||
setCurrentChapters(getChapters())
|
getChapters()
|
||||||
|
withContext(Dispatchers.Main) { view?.updateChapters(chapters) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,7 +609,8 @@ class MangaDetailsPresenter(
|
||||||
if (read && deleteNow && preferences.removeAfterMarkedAsRead().get()) {
|
if (read && deleteNow && preferences.removeAfterMarkedAsRead().get()) {
|
||||||
deleteChapters(selectedChapters, false)
|
deleteChapters(selectedChapters, false)
|
||||||
}
|
}
|
||||||
setCurrentChapters(getChapters())
|
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) {
|
||||||
|
@ -729,7 +741,8 @@ 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))
|
||||||
setCurrentChapters(getChapters())
|
getChapters()
|
||||||
|
withUIContext { view?.updateChapters(chapters) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isScanlatorFiltered() = manga.filtered_scanlators?.isNotEmpty() == true
|
private fun isScanlatorFiltered() = manga.filtered_scanlators?.isNotEmpty() == true
|
||||||
|
@ -798,7 +811,7 @@ class MangaDetailsPresenter(
|
||||||
withUIContext {
|
withUIContext {
|
||||||
view?.shareManga(uri.uri.toFile())
|
view?.shareManga(uri.uri.toFile())
|
||||||
}
|
}
|
||||||
} catch (_: Exception) {
|
} catch (_: java.lang.Exception) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1140,15 +1153,15 @@ class MangaDetailsPresenter(
|
||||||
|
|
||||||
override fun onStatusChange(download: Download) {
|
override fun onStatusChange(download: Download) {
|
||||||
super.onStatusChange(download)
|
super.onStatusChange(download)
|
||||||
currentChaptersInternal.update { chapters ->
|
chapters.find { it.id == download.chapter.id }?.status = download.status
|
||||||
chapters.find { it.id == download.chapter.id }?.status = download.status
|
|
||||||
chapters
|
|
||||||
}
|
|
||||||
onPageProgressUpdate(download)
|
onPageProgressUpdate(download)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun onQueueUpdate(queue: List<Download>) = withIOContext {
|
private suspend fun onQueueUpdate(queue: List<Download>) = withIOContext {
|
||||||
setDownloadedChapters(queue)
|
getChapters(queue)
|
||||||
|
withUIContext {
|
||||||
|
view?.updateChapters(chapters)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueueUpdate(download: Download) {
|
override fun onQueueUpdate(download: Download) {
|
||||||
|
@ -1160,10 +1173,7 @@ class MangaDetailsPresenter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPageProgressUpdate(download: Download) {
|
override fun onPageProgressUpdate(download: Download) {
|
||||||
currentChaptersInternal.update { chapters ->
|
chapters.find { it.id == download.chapter.id }?.download = download
|
||||||
chapters.find { it.id == download.chapter.id }?.download = download
|
|
||||||
chapters
|
|
||||||
}
|
|
||||||
view?.updateChapterDownload(download)
|
view?.updateChapterDownload(download)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue