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

This commit is contained in:
arkon 2020-10-31 10:00:02 -04:00
parent b1ce3693ed
commit 7310ec4fe4

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.CheckboxItem import eu.kanade.tachiyomi.ui.browse.source.filter.CheckboxItem
import eu.kanade.tachiyomi.ui.browse.source.filter.CheckboxSectionItem import eu.kanade.tachiyomi.ui.browse.source.filter.CheckboxSectionItem
@ -29,12 +31,17 @@ 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 kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.isActive
import rx.Observable 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
@ -85,9 +92,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.
@ -100,9 +107,9 @@ open class BrowseSourcePresenter(
private var pageSubscription: Subscription? = null private var pageSubscription: Subscription? = null
/** /**
* 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)
@ -133,7 +140,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)
@ -189,24 +196,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) }
} }
/** /**
@ -234,24 +239,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
}
} }
/** /**
@ -279,7 +287,7 @@ open class BrowseSourcePresenter(
* Refreshes the active display mode. * Refreshes the active display mode.
*/ */
fun refreshDisplayMode() { fun refreshDisplayMode() {
subscribeToMangaInitializer() initializeManga()
} }
/** /**