Rewrite Batch Add into kotlin flow

This commit is contained in:
Jobobby04 2022-01-01 15:59:30 -05:00
parent 08f6a7fbd6
commit 21b620ee86
2 changed files with 77 additions and 75 deletions

View File

@ -9,15 +9,17 @@ import dev.chrisbanes.insetter.applyInsetter
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.EhFragmentBatchAddBinding import eu.kanade.tachiyomi.databinding.EhFragmentBatchAddBinding
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.util.lang.combineLatest import kotlinx.coroutines.channels.BufferOverflow
import eu.kanade.tachiyomi.util.lang.plusAssign import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import reactivecircus.flowbinding.android.view.clicks import reactivecircus.flowbinding.android.view.clicks
import rx.android.schedulers.AndroidSchedulers
import rx.subscriptions.CompositeSubscription
/** /**
* Batch add screen * Batch add screen
@ -40,7 +42,7 @@ class BatchAddController : NucleusController<EhFragmentBatchAddBinding, BatchAdd
binding.progressDismissBtn.clicks() binding.progressDismissBtn.clicks()
.onEach { .onEach {
presenter.currentlyAddingRelay.call(BatchAddPresenter.STATE_PROGRESS_TO_INPUT) presenter.currentlyAddingFlow.value = BatchAddPresenter.STATE_PROGRESS_TO_INPUT
} }
.launchIn(viewScope) .launchIn(viewScope)
@ -50,53 +52,53 @@ class BatchAddController : NucleusController<EhFragmentBatchAddBinding, BatchAdd
} }
} }
val progressSubscriptions = CompositeSubscription() presenter.currentlyAddingFlow
.buffer(capacity = 0, onBufferOverflow = BufferOverflow.SUSPEND)
.mapLatest { event ->
when (event) {
BatchAddPresenter.STATE_INPUT_TO_PROGRESS -> coroutineScope {
showProgress(binding)
presenter.progressFlow
.buffer(capacity = Channel.RENDEZVOUS)
.combine(presenter.progressTotalFlow) { progress, total ->
// Show hide dismiss button
binding.progressDismissBtn.isVisible = progress == total
formatProgress(progress, total)
}
.onEach {
binding.progressText.text = it
}
.launchIn(this)
presenter.currentlyAddingRelay presenter.progressTotalFlow
.onBackpressureBuffer() .buffer(capacity = Channel.RENDEZVOUS)
.observeOn(AndroidSchedulers.mainThread()) .onEach {
.subscribeUntilDestroy { binding.progressBar.max = it
progressSubscriptions.clear() }
if (it == BatchAddPresenter.STATE_INPUT_TO_PROGRESS) { .launchIn(this)
showProgress(binding)
progressSubscriptions += presenter.progressRelay
.onBackpressureBuffer()
.observeOn(AndroidSchedulers.mainThread())
.combineLatest(presenter.progressTotalRelay) { progress, total ->
// Show hide dismiss button
binding.progressDismissBtn.isVisible = progress == total
formatProgress(progress, total)
}.subscribeUntilDestroy {
binding.progressText.text = it
}
progressSubscriptions += presenter.progressTotalRelay presenter.progressFlow
.onBackpressureBuffer() .buffer(capacity = Channel.RENDEZVOUS)
.observeOn(AndroidSchedulers.mainThread()) .onEach {
.subscribeUntilDestroy { binding.progressBar.progress = it
binding.progressBar.max = it }
} .launchIn(this)
progressSubscriptions += presenter.progressRelay presenter.eventFlow
.onBackpressureBuffer() ?.buffer(capacity = Channel.RENDEZVOUS)
.observeOn(AndroidSchedulers.mainThread()) ?.onEach {
.subscribeUntilDestroy { binding.progressLog.append("$it\n")
binding.progressBar.progress = it }
} ?.launchIn(this)
Unit
presenter.eventRelay }
?.onBackpressureBuffer() BatchAddPresenter.STATE_PROGRESS_TO_INPUT -> {
?.observeOn(AndroidSchedulers.mainThread()) hideProgress(binding)
?.subscribeUntilDestroy { presenter.currentlyAddingFlow.value = BatchAddPresenter.STATE_IDLE
binding.progressLog.append("$it\n") }
}?.let {
progressSubscriptions += it
}
} else if (it == BatchAddPresenter.STATE_PROGRESS_TO_INPUT) {
hideProgress(binding)
presenter.currentlyAddingRelay.call(BatchAddPresenter.STATE_IDLE)
} }
} }
.launchIn(viewScope)
} }
private val EhFragmentBatchAddBinding.progressViews private val EhFragmentBatchAddBinding.progressViews
@ -150,7 +152,7 @@ class BatchAddController : NucleusController<EhFragmentBatchAddBinding, BatchAdd
return return
} }
presenter.addGalleries(activity!!, galleries) presenter.addGalleries(applicationContext!!, galleries)
} }
private fun noGalleriesSpecified() { private fun noGalleriesSpecified() {

View File

@ -1,8 +1,6 @@
package exh.ui.batchadd package exh.ui.batchadd
import android.content.Context import android.content.Context
import com.jakewharton.rxrelay.BehaviorRelay
import com.jakewharton.rxrelay.ReplayRelay
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
@ -10,50 +8,52 @@ import eu.kanade.tachiyomi.util.lang.withIOContext
import exh.GalleryAddEvent import exh.GalleryAddEvent
import exh.GalleryAdder import exh.GalleryAdder
import exh.log.xLogE import exh.log.xLogE
import exh.util.trimOrNull import exh.util.dropEmpty
import exh.util.trimAll
import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ensureActive import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.injectLazy
import uy.kohesive.injekt.api.get
class BatchAddPresenter : BasePresenter<BatchAddController>() { class BatchAddPresenter : BasePresenter<BatchAddController>() {
private val preferences: PreferencesHelper by injectLazy()
private val galleryAdder by lazy { GalleryAdder() } private val galleryAdder by lazy { GalleryAdder() }
val progressTotalRelay = BehaviorRelay.create(0)!! val progressTotalFlow = MutableStateFlow(0)
val progressRelay = BehaviorRelay.create(0)!! val progressFlow = MutableStateFlow(0)
var eventRelay: ReplayRelay<String>? = null var eventFlow: MutableSharedFlow<String>? = null
val currentlyAddingRelay = BehaviorRelay.create(STATE_IDLE)!! val currentlyAddingFlow = MutableStateFlow(STATE_IDLE)
fun addGalleries(context: Context, galleries: String) { fun addGalleries(context: Context, galleries: String) {
eventRelay = ReplayRelay.create() eventFlow = MutableSharedFlow(1)
val regex = val regex =
"""[0-9]*?\.[a-z0-9]*?:""".toRegex() """[0-9]*?\.[a-z0-9]*?:""".toRegex()
val testedGalleries: String
testedGalleries = if (regex.containsMatchIn(galleries)) { val testedGalleries = if (regex.containsMatchIn(galleries)) {
val url = if (preferences.enableExhentai().get()) {
"https://exhentai.org/g/"
} else {
"https://e-hentai.org/g/"
}
regex.findAll(galleries).map { galleryKeys -> regex.findAll(galleries).map { galleryKeys ->
val linkParts = galleryKeys.value.split(".") val linkParts = galleryKeys.value.split(".")
val link = "${if (Injekt.get<PreferencesHelper>().enableExhentai().get()) { url + linkParts[0] + "/" + linkParts[1].replace(":", "")
"https://exhentai.org/g/"
} else {
"https://e-hentai.org/g/"
}}${linkParts[0]}/${linkParts[1].replace(":", "")}"
link
}.joinToString(separator = "\n") }.joinToString(separator = "\n")
} else { } else {
galleries galleries
} }
val splitGalleries = testedGalleries.split("\n").mapNotNull { val splitGalleries = testedGalleries.split("\n")
it.trimOrNull() .trimAll()
} .dropEmpty()
progressRelay.call(0) progressFlow.value = 0
progressTotalRelay.call(splitGalleries.size) progressTotalFlow.value = splitGalleries.size
currentlyAddingRelay.call(STATE_INPUT_TO_PROGRESS) currentlyAddingFlow.value = STATE_INPUT_TO_PROGRESS
val handler = CoroutineExceptionHandler { _, throwable -> val handler = CoroutineExceptionHandler { _, throwable ->
xLogE("Batch add error", throwable) xLogE("Batch add error", throwable)
@ -71,8 +71,8 @@ class BatchAddPresenter : BasePresenter<BatchAddController>() {
} else { } else {
failed.add(s) failed.add(s)
} }
progressRelay.call(i + 1) progressFlow.value = i + 1
eventRelay?.call( eventFlow?.emit(
( (
when (result) { when (result) {
is GalleryAddEvent.Success -> context.getString(R.string.batch_add_ok) is GalleryAddEvent.Success -> context.getString(R.string.batch_add_ok)
@ -84,7 +84,7 @@ class BatchAddPresenter : BasePresenter<BatchAddController>() {
// Show report // Show report
val summary = context.getString(R.string.batch_add_summary, succeeded.size, failed.size) val summary = context.getString(R.string.batch_add_summary, succeeded.size, failed.size)
eventRelay?.call(summary) eventFlow?.emit(summary)
} }
} }