Fix hiding page loading indicator (close #1357)
This commit is contained in:
@@ -1,28 +0,0 @@
|
||||
package org.koitharu.kotatsu.core.util
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewTreeObserver
|
||||
|
||||
/**
|
||||
* ProgressIndicator become INVISIBLE instead of GONE by hide() call.
|
||||
* It`s final so we need this workaround
|
||||
*/
|
||||
class GoneOnInvisibleListener(
|
||||
private val view: View,
|
||||
) : ViewTreeObserver.OnGlobalLayoutListener {
|
||||
|
||||
override fun onGlobalLayout() {
|
||||
if (view.visibility == View.INVISIBLE) {
|
||||
view.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
fun attach() {
|
||||
view.viewTreeObserver.addOnGlobalLayoutListener(this)
|
||||
onGlobalLayout()
|
||||
}
|
||||
|
||||
fun detach() {
|
||||
view.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import androidx.appcompat.widget.ActionMenuView
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.descendants
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@@ -155,9 +154,9 @@ fun TabLayout.setTabsEnabled(enabled: Boolean) {
|
||||
|
||||
fun BaseProgressIndicator<*>.showOrHide(value: Boolean) {
|
||||
if (value) {
|
||||
if (!isVisible) show()
|
||||
show()
|
||||
} else {
|
||||
if (isVisible) hide()
|
||||
hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package org.koitharu.kotatsu.reader.ui.pager
|
||||
|
||||
import android.content.ComponentCallbacks2
|
||||
import android.content.ComponentCallbacks2.TRIM_MEMORY_COMPLETE
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.view.View
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.core.view.isGone
|
||||
@@ -21,7 +24,6 @@ import org.koitharu.kotatsu.core.util.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.core.util.ext.isLowRamDevice
|
||||
import org.koitharu.kotatsu.core.util.ext.isSerializable
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.showOrHide
|
||||
import org.koitharu.kotatsu.databinding.LayoutPageInfoBinding
|
||||
import org.koitharu.kotatsu.parsers.util.ifZero
|
||||
import org.koitharu.kotatsu.reader.domain.PageLoader
|
||||
@@ -37,7 +39,7 @@ abstract class BasePageHolder<B : ViewBinding>(
|
||||
networkState: NetworkState,
|
||||
exceptionResolver: ExceptionResolver,
|
||||
lifecycleOwner: LifecycleOwner,
|
||||
) : LifecycleAwareViewHolder(binding.root, lifecycleOwner), DefaultOnImageEventListener {
|
||||
) : LifecycleAwareViewHolder(binding.root, lifecycleOwner), DefaultOnImageEventListener, ComponentCallbacks2 {
|
||||
|
||||
protected val viewModel = PageViewModel(
|
||||
loader = loader,
|
||||
@@ -82,9 +84,12 @@ abstract class BasePageHolder<B : ViewBinding>(
|
||||
@CallSuper
|
||||
protected open fun onConfigChanged(settings: ReaderSettings) {
|
||||
settings.applyBackground(itemView)
|
||||
if (viewModel.state.value is PageState.Shown) {
|
||||
if (settings.applyBitmapConfig(ssiv)) {
|
||||
reloadImage()
|
||||
} else if (viewModel.state.value is PageState.Shown) {
|
||||
onReady()
|
||||
}
|
||||
ssiv.applyDownSampling(isResumed())
|
||||
}
|
||||
|
||||
fun reloadImage() {
|
||||
@@ -103,7 +108,7 @@ abstract class BasePageHolder<B : ViewBinding>(
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
context.registerComponentCallbacks(viewModel)
|
||||
context.registerComponentCallbacks(this)
|
||||
viewModel.state.observe(this, ::onStateChanged)
|
||||
viewModel.settingsProducer.observe(this, ::onConfigChanged)
|
||||
}
|
||||
@@ -122,7 +127,7 @@ abstract class BasePageHolder<B : ViewBinding>(
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
context.unregisterComponentCallbacks(viewModel)
|
||||
context.unregisterComponentCallbacks(this)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
@@ -136,9 +141,18 @@ abstract class BasePageHolder<B : ViewBinding>(
|
||||
ssiv.recycle()
|
||||
}
|
||||
|
||||
override fun onTrimMemory(level: Int) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) = Unit
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
final override fun onLowMemory() = onTrimMemory(TRIM_MEMORY_COMPLETE)
|
||||
|
||||
protected open fun onStateChanged(state: PageState) {
|
||||
bindingInfo.layoutError.isVisible = state is PageState.Error
|
||||
bindingInfo.progressBar.showOrHide(!state.isFinalState())
|
||||
bindingInfo.progressBar.isGone = state.isFinalState()
|
||||
bindingInfo.textViewStatus.isGone = state.isFinalState()
|
||||
val progress = (state as? PageState.Loading)?.progress ?: -1
|
||||
if (progress in 0..100) {
|
||||
|
||||
@@ -30,17 +30,12 @@ open class PageHolder(
|
||||
networkState = networkState,
|
||||
exceptionResolver = exceptionResolver,
|
||||
lifecycleOwner = owner,
|
||||
),
|
||||
ZoomControl.ZoomControlListener {
|
||||
), ZoomControl.ZoomControlListener {
|
||||
|
||||
override val ssiv = binding.ssiv
|
||||
|
||||
override fun onConfigChanged(settings: ReaderSettings) {
|
||||
super.onConfigChanged(settings)
|
||||
if (settings.applyBitmapConfig(binding.ssiv)) {
|
||||
reloadImage()
|
||||
}
|
||||
binding.ssiv.applyDownSampling(isResumed())
|
||||
binding.textViewNumber.isVisible = settings.isPagesNumbersEnabled
|
||||
}
|
||||
|
||||
@@ -50,11 +45,6 @@ open class PageHolder(
|
||||
binding.textViewNumber.text = (data.index + 1).toString()
|
||||
}
|
||||
|
||||
override fun onRecycled() {
|
||||
super.onRecycled()
|
||||
binding.ssiv.recycle()
|
||||
}
|
||||
|
||||
override fun onReady() {
|
||||
binding.ssiv.maxScale = 2f * maxOf(
|
||||
binding.ssiv.width / binding.ssiv.sWidth.toFloat(),
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.koitharu.kotatsu.reader.ui.pager.vm
|
||||
|
||||
import android.content.ComponentCallbacks2
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Rect
|
||||
import android.net.Uri
|
||||
import androidx.annotation.WorkerThread
|
||||
@@ -20,6 +18,7 @@ import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.plus
|
||||
import kotlinx.coroutines.withContext
|
||||
import okio.IOException
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
||||
import org.koitharu.kotatsu.core.os.NetworkState
|
||||
@@ -35,7 +34,7 @@ class PageViewModel(
|
||||
private val networkState: NetworkState,
|
||||
private val exceptionResolver: ExceptionResolver,
|
||||
private val isWebtoon: Boolean,
|
||||
) : DefaultOnImageEventListener, ComponentCallbacks2 {
|
||||
) : DefaultOnImageEventListener {
|
||||
|
||||
private val scope = loader.loaderScope + Dispatchers.Main.immediate
|
||||
private var job: Job? = null
|
||||
@@ -43,12 +42,6 @@ class PageViewModel(
|
||||
|
||||
val state = MutableStateFlow<PageState>(PageState.Empty)
|
||||
|
||||
init {
|
||||
scope.launch(Dispatchers.Main) { // the same as post() -- wait until child fields init
|
||||
// callback.onConfigChanged()
|
||||
}
|
||||
}
|
||||
|
||||
fun isLoading() = job?.isActive == true
|
||||
|
||||
fun onBind(page: MangaPage) {
|
||||
@@ -64,13 +57,14 @@ class PageViewModel(
|
||||
job = scope.launch {
|
||||
prevJob?.cancelAndJoin()
|
||||
val e = (state.value as? PageState.Error)?.error
|
||||
if (e != null && ExceptionResolver.Companion.canResolve(e)) {
|
||||
if (!isFromUser) {
|
||||
return@launch
|
||||
if (e != null && ExceptionResolver.canResolve(e)) {
|
||||
if (isFromUser) {
|
||||
exceptionResolver.resolve(e)
|
||||
}
|
||||
exceptionResolver.resolve(e)
|
||||
}
|
||||
doLoad(page, force = true)
|
||||
withContext(Dispatchers.Default) {
|
||||
doLoad(page, force = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,8 +80,12 @@ class PageViewModel(
|
||||
}
|
||||
|
||||
override fun onImageLoaded() {
|
||||
state.update {
|
||||
if (it is PageState.Loaded) PageState.Shown(it.source, it.isConverted) else it
|
||||
state.update { currentState ->
|
||||
if (currentState is PageState.Loaded) {
|
||||
PageState.Shown(currentState.source, currentState.isConverted)
|
||||
} else {
|
||||
currentState
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,18 +107,9 @@ class PageViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) = Unit
|
||||
|
||||
@Suppress("OVERRIDE_DEPRECATION")
|
||||
override fun onLowMemory() = Unit
|
||||
|
||||
override fun onTrimMemory(level: Int) {
|
||||
// callback.onTrimMemory()
|
||||
}
|
||||
|
||||
private fun tryConvert(uri: Uri, e: Exception) {
|
||||
val prevJob = job
|
||||
job = scope.launch {
|
||||
job = scope.launch(Dispatchers.Default) {
|
||||
prevJob?.join()
|
||||
state.value = PageState.Converting()
|
||||
try {
|
||||
@@ -143,7 +132,7 @@ class PageViewModel(
|
||||
|
||||
@WorkerThread
|
||||
private suspend fun doLoad(data: MangaPage, force: Boolean) = coroutineScope {
|
||||
state.value = PageState.Loading(null/* TODO */, -1)
|
||||
state.value = PageState.Loading(null, -1)
|
||||
val previewJob = launch {
|
||||
val preview = loader.loadPreview(data) ?: return@launch
|
||||
state.update {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package org.koitharu.kotatsu.reader.ui.pager.webtoon
|
||||
|
||||
import android.view.View
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
||||
import org.koitharu.kotatsu.core.os.NetworkState
|
||||
import org.koitharu.kotatsu.core.util.GoneOnInvisibleListener
|
||||
import org.koitharu.kotatsu.databinding.ItemPageWebtoonBinding
|
||||
import org.koitharu.kotatsu.reader.domain.PageLoader
|
||||
import org.koitharu.kotatsu.reader.ui.config.ReaderSettings
|
||||
@@ -28,29 +28,9 @@ class WebtoonHolder(
|
||||
override val ssiv = binding.ssiv
|
||||
|
||||
private var scrollToRestore = 0
|
||||
private val goneOnInvisibleListener = GoneOnInvisibleListener(bindingInfo.progressBar)
|
||||
|
||||
override fun onConfigChanged(settings: ReaderSettings) {
|
||||
super.onConfigChanged(settings)
|
||||
if (settings.applyBitmapConfig(binding.ssiv)) {
|
||||
reloadImage()
|
||||
}
|
||||
binding.ssiv.applyDownSampling(isResumed())
|
||||
}
|
||||
|
||||
override fun onRecycled() {
|
||||
super.onRecycled()
|
||||
binding.ssiv.recycle()
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
goneOnInvisibleListener.attach()
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
goneOnInvisibleListener.detach()
|
||||
init {
|
||||
bindingInfo.progressBar.setVisibilityAfterHide(View.GONE)
|
||||
}
|
||||
|
||||
override fun onReady() {
|
||||
|
||||
Reference in New Issue
Block a user