mirror of
https://git.mihon.tech/mihonapp/mihon
synced 2024-11-26 07:06:03 +03:00
Replace RxJava in DownloadQueueScreenModel (#8872)
This commit is contained in:
parent
46774771ec
commit
2245658363
2 changed files with 32 additions and 35 deletions
|
@ -18,9 +18,8 @@ data class Download(
|
||||||
var pages: List<Page>? = null,
|
var pages: List<Page>? = null,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@Volatile
|
val totalProgress: Int
|
||||||
@Transient
|
get() = pages?.sumOf(Page::progress) ?: 0
|
||||||
var totalProgress: Int = 0
|
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
@Transient
|
@Transient
|
||||||
|
|
|
@ -11,19 +11,21 @@ import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.databinding.DownloadListBinding
|
import eu.kanade.tachiyomi.databinding.DownloadListBinding
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import kotlinx.coroutines.flow.debounce
|
||||||
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import rx.Observable
|
|
||||||
import rx.Subscription
|
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
class DownloadQueueScreenModel(
|
class DownloadQueueScreenModel(
|
||||||
private val downloadManager: DownloadManager = Injekt.get(),
|
private val downloadManager: DownloadManager = Injekt.get(),
|
||||||
|
@ -40,9 +42,9 @@ class DownloadQueueScreenModel(
|
||||||
var adapter: DownloadAdapter? = null
|
var adapter: DownloadAdapter? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of subscriptions for active downloads.
|
* Map of jobs for active downloads.
|
||||||
*/
|
*/
|
||||||
val progressSubscriptions by lazy { mutableMapOf<Download, Subscription>() }
|
private val progressJobs = mutableMapOf<Download, Job>()
|
||||||
|
|
||||||
val listener = object : DownloadAdapter.DownloadItemListener {
|
val listener = object : DownloadAdapter.DownloadItemListener {
|
||||||
/**
|
/**
|
||||||
|
@ -130,10 +132,10 @@ class DownloadQueueScreenModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDispose() {
|
override fun onDispose() {
|
||||||
for (subscription in progressSubscriptions.values) {
|
for (job in progressJobs.values) {
|
||||||
subscription.unsubscribe()
|
job.cancel()
|
||||||
}
|
}
|
||||||
progressSubscriptions.clear()
|
progressJobs.clear()
|
||||||
adapter = null
|
adapter = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,16 +182,16 @@ class DownloadQueueScreenModel(
|
||||||
fun onStatusChange(download: Download) {
|
fun onStatusChange(download: Download) {
|
||||||
when (download.status) {
|
when (download.status) {
|
||||||
Download.State.DOWNLOADING -> {
|
Download.State.DOWNLOADING -> {
|
||||||
observeProgress(download)
|
launchProgressJob(download)
|
||||||
// Initial update of the downloaded pages
|
// Initial update of the downloaded pages
|
||||||
onUpdateDownloadedPages(download)
|
onUpdateDownloadedPages(download)
|
||||||
}
|
}
|
||||||
Download.State.DOWNLOADED -> {
|
Download.State.DOWNLOADED -> {
|
||||||
unsubscribeProgress(download)
|
cancelProgressJob(download)
|
||||||
onUpdateProgress(download)
|
onUpdateProgress(download)
|
||||||
onUpdateDownloadedPages(download)
|
onUpdateDownloadedPages(download)
|
||||||
}
|
}
|
||||||
Download.State.ERROR -> unsubscribeProgress(download)
|
Download.State.ERROR -> cancelProgressJob(download)
|
||||||
else -> {
|
else -> {
|
||||||
/* unused */
|
/* unused */
|
||||||
}
|
}
|
||||||
|
@ -201,29 +203,25 @@ class DownloadQueueScreenModel(
|
||||||
*
|
*
|
||||||
* @param download the download to observe its progress.
|
* @param download the download to observe its progress.
|
||||||
*/
|
*/
|
||||||
private fun observeProgress(download: Download) {
|
private fun launchProgressJob(download: Download) {
|
||||||
val subscription = Observable.interval(50, TimeUnit.MILLISECONDS)
|
val job = coroutineScope.launch {
|
||||||
// Get the sum of percentages for all the pages.
|
while (download.pages == null) {
|
||||||
.flatMap {
|
delay(50)
|
||||||
Observable.from(download.pages)
|
|
||||||
.map(Page::progress)
|
|
||||||
.reduce { x, y -> x + y }
|
|
||||||
}
|
}
|
||||||
// Keep only the latest emission to avoid backpressure.
|
|
||||||
.onBackpressureLatest()
|
val progressFlows = download.pages!!.map(Page::progressFlow)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
combine(progressFlows, Array<Int>::sum)
|
||||||
.subscribe { progress ->
|
.distinctUntilChanged()
|
||||||
// Update the view only if the progress has changed.
|
.debounce(50)
|
||||||
if (download.totalProgress != progress) {
|
.collectLatest {
|
||||||
download.totalProgress = progress
|
|
||||||
onUpdateProgress(download)
|
onUpdateProgress(download)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid leaking subscriptions
|
// Avoid leaking jobs
|
||||||
progressSubscriptions.remove(download)?.unsubscribe()
|
progressJobs.remove(download)?.cancel()
|
||||||
|
|
||||||
progressSubscriptions[download] = subscription
|
progressJobs[download] = job
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -231,8 +229,8 @@ class DownloadQueueScreenModel(
|
||||||
*
|
*
|
||||||
* @param download the download to unsubscribe.
|
* @param download the download to unsubscribe.
|
||||||
*/
|
*/
|
||||||
private fun unsubscribeProgress(download: Download) {
|
private fun cancelProgressJob(download: Download) {
|
||||||
progressSubscriptions.remove(download)?.unsubscribe()
|
progressJobs.remove(download)?.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue