From f06167ba4bfd069959811ade670ec331f6f97db8 Mon Sep 17 00:00:00 2001 From: tarsin Date: Tue, 20 Dec 2022 19:03:57 +0800 Subject: [PATCH] Sync with tachiyomi, support load progress --- .../eu/kanade/tachiyomi/source/model/Page.kt | 10 +++- .../tachiyomi/ui/reader/loader/PageLoader.kt | 2 +- .../reader/viewer/ReaderProgressIndicator.kt | 5 +- .../ui/reader/viewer/pager/PagerPageHolder.kt | 41 ++++++++-------- .../viewer/webtoon/WebtoonPageHolder.kt | 47 ++++++++++++++----- 5 files changed, 67 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt b/app/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt index 586067597..c1e695893 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.source.model import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow open class Page(val index: Int) { @@ -9,7 +10,14 @@ open class Page(val index: Int) { var status = MutableStateFlow(State.QUEUE) - var progress = MutableStateFlow(0f) + private val _progressFlow = MutableStateFlow(0) + + val progressFlow = _progressFlow.asStateFlow() + var progress: Int + get() = _progressFlow.value + set(value) { + _progressFlow.value = value + } enum class State { QUEUE, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/PageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/PageLoader.kt index f5ccdd848..7d7ec4e21 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/PageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/PageLoader.kt @@ -48,7 +48,7 @@ abstract class PageLoader { fun notifyPagePercent(index: Int, percent: Float) { mPages[index].status.compareAndSet(Page.State.QUEUE, Page.State.DOWNLOAD_IMAGE) - mPages[index].progress.value = percent + mPages[index].progress = (percent * 100).toInt() } fun notifyPageSucceed(index: Int, image: Image) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderProgressIndicator.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderProgressIndicator.kt index e565ee878..75f710686 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderProgressIndicator.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderProgressIndicator.kt @@ -11,10 +11,9 @@ import androidx.annotation.IntRange import com.google.android.material.progressindicator.CircularProgressIndicator /** - * A wrapper for [CircularProgressIndicator] that always rotates while being determinate. + * A wrapper for [CircularProgressIndicator] that always rotates. * - * By always rotating we give the feedback to the user that the application isn't 'stuck', - * and by making it determinate the user also approximately knows how much the operation will take. + * By always rotating we give the feedback to the user that the application isn't 'stuck'. */ class ReaderProgressIndicator @JvmOverloads constructor( context: Context, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index daf505e6f..b01253533 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -39,19 +39,18 @@ class PagerPageHolder( /** * Loading progress bar to indicate the current progress. */ - private val progressIndicator: ReaderProgressIndicator = - ReaderProgressIndicator(readerThemedContext).apply { - updateLayoutParams { - gravity = Gravity.CENTER - } + private val progressIndicator: ReaderProgressIndicator = ReaderProgressIndicator(readerThemedContext).apply { + updateLayoutParams { + gravity = Gravity.CENTER } + } /** * Error layout to show when the image fails to load. */ private var errorLayout: ReaderErrorBinding? = null - private var scope = CoroutineScope(Dispatchers.IO) + private val scope = CoroutineScope(Dispatchers.IO) /** * Subscription for status changes of the page. @@ -59,17 +58,12 @@ class PagerPageHolder( private var statusJob: Job? = null /** - * Subscription for progress changes of the page. + * Job for progress changes of the page. */ private var progressJob: Job? = null init { addView(progressIndicator) - progressJob = scope.launch(Dispatchers.Main) { - page.progress.collect { - progressIndicator.setProgress(it.toInt()) - } - } statusJob = scope.launch(Dispatchers.Main) { page.status.collectLatest { processStatus(it) @@ -83,10 +77,17 @@ class PagerPageHolder( @SuppressLint("ClickableViewAccessibility") override fun onDetachedFromWindow() { super.onDetachedFromWindow() - unsubscribeProgress() + cancelProgressJob() unsubscribeStatus() } + private fun launchProgressJob() { + progressJob?.cancel() + progressJob = scope.launch(Dispatchers.Main) { + page.progressFlow.collectLatest { value -> progressIndicator.setProgress(value) } + } + } + /** * Called when the status of the page changes. * @@ -97,17 +98,16 @@ class PagerPageHolder( Page.State.QUEUE -> setQueued() Page.State.LOAD_PAGE -> setLoading() Page.State.DOWNLOAD_IMAGE -> { + launchProgressJob() setDownloading() } - Page.State.READY -> { page.image?.mObtainedDrawable?.let { setImage(it) } - unsubscribeProgress() + cancelProgressJob() } - Page.State.ERROR -> { setError() - unsubscribeProgress() + cancelProgressJob() } } } @@ -117,13 +117,12 @@ class PagerPageHolder( */ private fun unsubscribeStatus() { statusJob?.cancel() + statusJob = null } - /** - * Unsubscribes from the progress subscription. - */ - private fun unsubscribeProgress() { + private fun cancelProgressJob() { progressJob?.cancel() + progressJob = null } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt index 728df02de..0ebf78071 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt @@ -63,14 +63,21 @@ class WebtoonPageHolder( */ private var page: ReaderPage? = null - private var progressJob: Job? = null + private val scope = CoroutineScope(Dispatchers.IO) + /** + * Subscription for status changes of the page. + */ private var statusJob: Job? = null - private var scope = CoroutineScope(Dispatchers.IO) + /** + * Job for progress changes of the page. + */ + private var progressJob: Job? = null init { refreshLayoutParams() + frame.onImageLoaded = { onImageDecoded() } frame.onImageLoadError = { onImageDecodeError() } frame.onScaleChanged = { viewer.activity.hideMenu() } @@ -81,11 +88,6 @@ class WebtoonPageHolder( */ fun bind(page: ReaderPage) { this.page = page - progressJob = scope.launch(Dispatchers.Main) { - page.progress.collect { - progressIndicator.setProgress(it.toInt()) - } - } statusJob = scope.launch(Dispatchers.Main) { page.status.collectLatest { processStatus(it) @@ -111,13 +113,27 @@ class WebtoonPageHolder( */ override fun recycle() { statusJob?.cancel() - progressJob?.cancel() + cancelProgressJob() + removeErrorLayout() frame.recycle() page?.image?.recycle() progressIndicator.setProgress(0, animated = false) } + /** + * Observes the progress of the page and updates view. + */ + private fun launchProgressJob() { + cancelProgressJob() + + val page = page ?: return + + progressJob = scope.launch(Dispatchers.Main) { + page.progressFlow.collectLatest { value -> progressIndicator.setProgress(value) } + } + } + /** * Called when the status of the page changes. * @@ -128,21 +144,28 @@ class WebtoonPageHolder( Page.State.QUEUE -> setQueued() Page.State.LOAD_PAGE -> setLoading() Page.State.DOWNLOAD_IMAGE -> { + launchProgressJob() setDownloading() } - Page.State.READY -> { page?.image?.mObtainedDrawable?.let { setImage(it) } - progressJob?.cancel() + cancelProgressJob() } - Page.State.ERROR -> { setError() - progressJob?.cancel() + cancelProgressJob() } } } + /** + * Unsubscribes from the progress subscription. + */ + private fun cancelProgressJob() { + progressJob?.cancel() + progressJob = null + } + /** * Called when the page is queued. */