Sync with tachiyomi, support load progress
This commit is contained in:
1 parent
60438ae1ed
commit
f06167ba4b
5 files changed
+67
-38
No files matched your search
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -39,19 +39,18 @@ class PagerPageHolder(
|
||||
/**
|
||||
* Loading progress bar to indicate the current progress.
|
||||
*/
|
||||
private val progressIndicator: ReaderProgressIndicator =
|
||||
ReaderProgressIndicator(readerThemedContext).apply {
|
||||
updateLayoutParams<LayoutParams> {
|
||||
gravity = Gravity.CENTER
|
||||
}
|
||||
private val progressIndicator: ReaderProgressIndicator = ReaderProgressIndicator(readerThemedContext).apply {
|
||||
updateLayoutParams<LayoutParams> {
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+35
-12
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user