CoroutinePresenter changes

This commit is contained in:
Jobobby04 2021-01-06 00:54:11 -05:00
parent 142aa0f02a
commit 68c12d79ee
4 changed files with 43 additions and 24 deletions

View File

@ -136,7 +136,7 @@ class MergedSource : SuspendHttpSource() {
val ifDownloadNewChapters = downloadChapters && manga.shouldDownloadNewChapters(db, preferences) val ifDownloadNewChapters = downloadChapters && manga.shouldDownloadNewChapters(db, preferences)
return mangaReferences.filter { it.mangaSourceId != MERGED_SOURCE_ID }.map { return mangaReferences.filter { it.mangaSourceId != MERGED_SOURCE_ID }.map {
load(db, sourceManager, it) it.load(db, sourceManager)
}.mapNotNull { loadedManga -> }.mapNotNull { loadedManga ->
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
if (loadedManga.manga != null && loadedManga.reference.getChapterUpdates) { if (loadedManga.manga != null && loadedManga.reference.getChapterUpdates) {
@ -165,23 +165,23 @@ class MergedSource : SuspendHttpSource() {
} }
} }
suspend fun load(db: DatabaseHelper, sourceManager: SourceManager, reference: MergedMangaReference): LoadedMangaSource { suspend fun MergedMangaReference.load(db: DatabaseHelper, sourceManager: SourceManager): LoadedMangaSource {
var manga = db.getManga(reference.mangaUrl, reference.mangaSourceId).await() var manga = db.getManga(mangaUrl, mangaSourceId).await()
val source = sourceManager.getOrStub(manga?.source ?: reference.mangaSourceId) val source = sourceManager.getOrStub(manga?.source ?: mangaSourceId)
if (manga == null) { if (manga == null) {
manga = Manga.create(reference.mangaSourceId).apply { manga = Manga.create(mangaSourceId).apply {
url = reference.mangaUrl url = mangaUrl
} }
manga.copyFrom(source.getMangaDetails(manga.toMangaInfo()).toSManga()) manga.copyFrom(source.getMangaDetails(manga.toMangaInfo()).toSManga())
try { try {
manga.id = db.insertManga(manga).await().insertedId() manga.id = db.insertManga(manga).await().insertedId()
reference.mangaId = manga.id mangaId = manga.id
db.insertNewMergedMangaId(reference).await() db.insertNewMergedMangaId(this).await()
} catch (e: Exception) { } catch (e: Exception) {
XLog.tag("MergedSource").enableStackTrace(e.stackTrace.contentToString(), 5) XLog.tag("MergedSource").enableStackTrace(e.stackTrace.contentToString(), 5)
} }
} }
return LoadedMangaSource(source, manga, reference) return LoadedMangaSource(source, manga, this)
} }
data class LoadedMangaSource(val source: Source, val manga: Manga?, val reference: MergedMangaReference) data class LoadedMangaSource(val source: Source, val manga: Manga?, val reference: MergedMangaReference)

View File

@ -1,41 +1,60 @@
package exh.ui.base package exh.ui.base
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import nucleus.presenter.Presenter import nucleus.presenter.Presenter
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
@Suppress("DEPRECATION") @Suppress("DEPRECATION", "unused")
open class CoroutinePresenter<V> : Presenter<V>() { open class CoroutinePresenter<V>(
val scope = CoroutineScope(Job() + Dispatchers.Main) scope: CoroutineScope = CoroutineScope(Job() + Dispatchers.Main)
) : Presenter<V>(),
CoroutineScope by scope
{
@Suppress("DeprecatedCallableAddReplaceWith") @Suppress("DeprecatedCallableAddReplaceWith")
@Deprecated("Use launchInView") @Deprecated("Use launchInView, Flow.inView, Flow.mapView")
override fun getView(): V? { override fun getView(): V? {
return super.getView() return super.getView()
} }
fun launchInView(block: (CoroutineScope, V) -> Unit) = scope.launch(Dispatchers.Main) { fun launchInView(block: (CoroutineScope, V) -> Unit) = launch(Dispatchers.Main) {
view?.let { block.invoke(this, it) } view?.let { block.invoke(this, it) }
} }
fun <F> Flow<F>.onEachView(block: (V, F) -> Unit) = onEach { inline fun <F> Flow<F>.inView(crossinline block: (V, F) -> Unit) = onEach {
view?.let { view -> block(view, it) } withContext(Dispatchers.Main) {
view?.let { view -> block(view, it) }
}
} }
fun <F, P> Flow<F>.mapView(block: (V, F) -> P): Flow<P> = mapNotNull { inline fun <F, P> Flow<F>.mapView(crossinline block: (V, F) -> P): Flow<P> {
view?.let { view -> block(view, it) } return mapNotNull {
withContext(Dispatchers.Main) {
view?.let { view -> block(view, it) }
}
}
} }
fun Flow<*>.launchUnderContext(context: CoroutineContext = EmptyCoroutineContext) =
launch(this + context) { this@launchInHere.collect() }
fun Flow<*>.launch() = launchIn(this)
@CallSuper @CallSuper
override fun destroy() { override fun destroy() {
super.destroy() super.destroy()
scope.cancel() cancel()
} }
} }

View File

@ -41,13 +41,13 @@ class MetadataViewPresenter(
meta.value = it.raise(mainSource.metaClass) meta.value = it.raise(mainSource.metaClass)
} }
} }
.launchIn(scope + Dispatchers.IO) .launchUnderContext(Dispatchers.IO)
meta meta
.onEachView { view, metadata -> .inView { view, metadata ->
view.onNextMangaInfo(metadata) view.onNextMangaInfo(metadata)
} }
.launchIn(scope) .launch()
} }
private fun getMangaMetaObservable(): Flow<FlatMetadata?> { private fun getMangaMetaObservable(): Flow<FlatMetadata?> {

View File

@ -21,7 +21,7 @@ class SmartSearchPresenter(private val source: CatalogueSource, private val conf
override fun onCreate(savedState: Bundle?) { override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState) super.onCreate(savedState)
scope.launch(Dispatchers.IO) { launch(Dispatchers.IO) {
val result = try { val result = try {
val resultManga = smartSearchEngine.smartSearch(source, config.origTitle) val resultManga = smartSearchEngine.smartSearch(source, config.origTitle)
if (resultManga != null) { if (resultManga != null) {