Use 1.x API to fetch manga details in browse view

(cherry picked from commit 7310ec4fe4cd0771afb9e62f8e3ccc7eb720efd1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
This commit is contained in:
arkon 2020-10-31 10:00:02 -04:00 committed by Jobobby04
parent 98dade1b4d
commit c2ccbe5aff

View File

@ -8,12 +8,14 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaCategory import eu.kanade.tachiyomi.data.database.models.MangaCategory
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.browse.source.filter.AutoComplete import eu.kanade.tachiyomi.ui.browse.source.filter.AutoComplete
import eu.kanade.tachiyomi.ui.browse.source.filter.AutoCompleteSectionItem import eu.kanade.tachiyomi.ui.browse.source.filter.AutoCompleteSectionItem
@ -31,9 +33,15 @@ import eu.kanade.tachiyomi.ui.browse.source.filter.TextSectionItem
import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateItem import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateItem
import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateSectionItem import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateSectionItem
import eu.kanade.tachiyomi.util.chapter.ChapterSettingsHelper import eu.kanade.tachiyomi.util.chapter.ChapterSettingsHelper
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.removeCovers import eu.kanade.tachiyomi.util.removeCovers
import exh.savedsearches.EXHSavedSearch import exh.savedsearches.EXHSavedSearch
import exh.savedsearches.JsonSavedSearch import exh.savedsearches.JsonSavedSearch
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.isActive
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
@ -44,7 +52,6 @@ import rx.Observable
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import rx.subjects.PublishSubject
import timber.log.Timber import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -100,9 +107,9 @@ open class BrowseSourcePresenter(
private lateinit var pager: Pager private lateinit var pager: Pager
/** /**
* Subject that initializes a list of manga. * Flow of manga list to initialize.
*/ */
private val mangaDetailSubject = PublishSubject.create<List<Manga>>() private val mangaDetailsFlow = MutableStateFlow<List<Manga>>(emptyList())
/** /**
* Subscription for the pager. * Subscription for the pager.
@ -121,9 +128,9 @@ open class BrowseSourcePresenter(
// SY <-- // SY <--
/** /**
* Subscription to initialize manga details. * Job to initialize manga details.
*/ */
private var initializerSubscription: Subscription? = null private var initializerJob: Job? = null
override fun onCreate(savedState: Bundle?) { override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState) super.onCreate(savedState)
@ -162,7 +169,7 @@ open class BrowseSourcePresenter(
this.query = query this.query = query
this.appliedFilters = filters this.appliedFilters = filters
subscribeToMangaInitializer() initializeManga()
// Create a new pager. // Create a new pager.
pager = createPager(query, filters) pager = createPager(query, filters)
@ -222,24 +229,22 @@ open class BrowseSourcePresenter(
/** /**
* Subscribes to the initializer of manga details and updates the view if needed. * Subscribes to the initializer of manga details and updates the view if needed.
*/ */
private fun subscribeToMangaInitializer() { private fun initializeManga() {
initializerSubscription?.let { remove(it) } initializerJob?.cancel()
initializerSubscription = mangaDetailSubject.observeOn(Schedulers.io()) initializerJob = launchIO {
.flatMap { Observable.from(it) } mangaDetailsFlow
.filter { it.thumbnail_url == null && !it.initialized } .onEach { mangas ->
.concatMap { getMangaDetailsObservable(it) } if (!isActive) return@onEach
.onBackpressureBuffer()
.observeOn(AndroidSchedulers.mainThread()) try {
.subscribe( mangas.filter { it.thumbnail_url == null && !it.initialized }
{ manga -> .map { getMangaDetails(it) }
@Suppress("DEPRECATION") .forEach { launchUI { view?.onMangaInitialized(it) } }
view?.onMangaInitialized(manga) } catch (error: Exception) {
}, launchUI { Timber.e(error) }
{ error -> }
Timber.e(error)
} }
) }
.apply { add(this) }
} }
/** /**
@ -267,24 +272,27 @@ open class BrowseSourcePresenter(
* @param mangas the list of manga to initialize. * @param mangas the list of manga to initialize.
*/ */
fun initializeMangas(mangas: List<Manga>) { fun initializeMangas(mangas: List<Manga>) {
mangaDetailSubject.onNext(mangas) launchIO { mangaDetailsFlow.emit(mangas) }
} }
/** /**
* Returns an observable of manga that initializes the given manga. * Returns the initialized manga.
* *
* @param manga the manga to initialize. * @param manga the manga to initialize.
* @return an observable of the manga to initialize * @return the initialized manga
*/ */
private fun getMangaDetailsObservable(manga: Manga): Observable<Manga> { private suspend fun getMangaDetails(manga: Manga): Manga {
return source.fetchMangaDetails(manga) return try {
.flatMap { networkManga -> source.getMangaDetails(manga.toMangaInfo())
manga.copyFrom(networkManga) .let { networkManga ->
manga.initialized = true manga.copyFrom(networkManga.toSManga())
db.insertManga(manga).executeAsBlocking() manga.initialized = true
Observable.just(manga) db.insertManga(manga).executeAsBlocking()
} manga
.onErrorResumeNext { Observable.just(manga) } }
} catch (e: Exception) {
manga
}
} }
/** /**
@ -312,7 +320,7 @@ open class BrowseSourcePresenter(
* Refreshes the active display mode. * Refreshes the active display mode.
*/ */
fun refreshDisplayMode() { fun refreshDisplayMode() {
subscribeToMangaInitializer() initializeManga()
} }
/** /**