Use 1.x API to fetch manga details in browse view
This commit is contained in:
parent
b1ce3693ed
commit
7310ec4fe4
1 changed files with 44 additions and 36 deletions
|
@ -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.Manga
|
||||
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.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
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.browse.source.filter.CheckboxItem
|
||||
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.TriStateSectionItem
|
||||
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 kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.isActive
|
||||
import rx.Observable
|
||||
import rx.Subscription
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import rx.schedulers.Schedulers
|
||||
import rx.subjects.PublishSubject
|
||||
import timber.log.Timber
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
@ -85,9 +92,9 @@ open class BrowseSourcePresenter(
|
|||
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.
|
||||
|
@ -100,9 +107,9 @@ open class BrowseSourcePresenter(
|
|||
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?) {
|
||||
super.onCreate(savedState)
|
||||
|
@ -133,7 +140,7 @@ open class BrowseSourcePresenter(
|
|||
this.query = query
|
||||
this.appliedFilters = filters
|
||||
|
||||
subscribeToMangaInitializer()
|
||||
initializeManga()
|
||||
|
||||
// Create a new pager.
|
||||
pager = createPager(query, filters)
|
||||
|
@ -189,24 +196,22 @@ open class BrowseSourcePresenter(
|
|||
/**
|
||||
* Subscribes to the initializer of manga details and updates the view if needed.
|
||||
*/
|
||||
private fun subscribeToMangaInitializer() {
|
||||
initializerSubscription?.let { remove(it) }
|
||||
initializerSubscription = mangaDetailSubject.observeOn(Schedulers.io())
|
||||
.flatMap { Observable.from(it) }
|
||||
.filter { it.thumbnail_url == null && !it.initialized }
|
||||
.concatMap { getMangaDetailsObservable(it) }
|
||||
.onBackpressureBuffer()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{ manga ->
|
||||
@Suppress("DEPRECATION")
|
||||
view?.onMangaInitialized(manga)
|
||||
},
|
||||
{ error ->
|
||||
Timber.e(error)
|
||||
private fun initializeManga() {
|
||||
initializerJob?.cancel()
|
||||
initializerJob = launchIO {
|
||||
mangaDetailsFlow
|
||||
.onEach { mangas ->
|
||||
if (!isActive) return@onEach
|
||||
|
||||
try {
|
||||
mangas.filter { it.thumbnail_url == null && !it.initialized }
|
||||
.map { getMangaDetails(it) }
|
||||
.forEach { launchUI { view?.onMangaInitialized(it) } }
|
||||
} catch (error: Exception) {
|
||||
launchUI { Timber.e(error) }
|
||||
}
|
||||
}
|
||||
)
|
||||
.apply { add(this) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -234,24 +239,27 @@ open class BrowseSourcePresenter(
|
|||
* @param mangas the list of manga to initialize.
|
||||
*/
|
||||
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.
|
||||
* @return an observable of the manga to initialize
|
||||
* @return the initialized manga
|
||||
*/
|
||||
private fun getMangaDetailsObservable(manga: Manga): Observable<Manga> {
|
||||
return source.fetchMangaDetails(manga)
|
||||
.flatMap { networkManga ->
|
||||
manga.copyFrom(networkManga)
|
||||
manga.initialized = true
|
||||
db.insertManga(manga).executeAsBlocking()
|
||||
Observable.just(manga)
|
||||
}
|
||||
.onErrorResumeNext { Observable.just(manga) }
|
||||
private suspend fun getMangaDetails(manga: Manga): Manga {
|
||||
return try {
|
||||
source.getMangaDetails(manga.toMangaInfo())
|
||||
.let { networkManga ->
|
||||
manga.copyFrom(networkManga.toSManga())
|
||||
manga.initialized = true
|
||||
db.insertManga(manga).executeAsBlocking()
|
||||
manga
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
manga
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -279,7 +287,7 @@ open class BrowseSourcePresenter(
|
|||
* Refreshes the active display mode.
|
||||
*/
|
||||
fun refreshDisplayMode() {
|
||||
subscribeToMangaInitializer()
|
||||
initializeManga()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Reference in a new issue