Fixes
This commit is contained in:
@@ -1,13 +1,12 @@
|
||||
package org.koitharu.kotatsu.core.ui.image
|
||||
|
||||
import android.view.View
|
||||
import android.view.View.OnLayoutChangeListener
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewTreeObserver
|
||||
import android.view.ViewTreeObserver.OnPreDrawListener
|
||||
import android.widget.ImageView
|
||||
import coil3.size.Dimension
|
||||
import coil3.size.Size
|
||||
import coil3.size.ViewSizeResolver
|
||||
import kotlinx.coroutines.CancellableContinuation
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.math.roundToInt
|
||||
@@ -20,31 +19,67 @@ class CoverSizeResolver(
|
||||
) : ViewSizeResolver<ImageView> {
|
||||
|
||||
override suspend fun size(): Size {
|
||||
// Fast path: the view is already measured.
|
||||
getSize()?.let { return it }
|
||||
return suspendCancellableCoroutine { cont ->
|
||||
val layoutListener = LayoutListener(cont)
|
||||
view.addOnLayoutChangeListener(layoutListener)
|
||||
cont.invokeOnCancellation {
|
||||
view.removeOnLayoutChangeListener(layoutListener)
|
||||
|
||||
// Slow path: wait for the view to be measured.
|
||||
return suspendCancellableCoroutine { continuation ->
|
||||
val viewTreeObserver = view.viewTreeObserver
|
||||
|
||||
val preDrawListener = object : OnPreDrawListener {
|
||||
private var isResumed = false
|
||||
|
||||
override fun onPreDraw(): Boolean {
|
||||
val size = getSize()
|
||||
if (size != null) {
|
||||
viewTreeObserver.removePreDrawListenerSafe(this)
|
||||
|
||||
if (!isResumed) {
|
||||
isResumed = true
|
||||
continuation.resume(size)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
viewTreeObserver.addOnPreDrawListener(preDrawListener)
|
||||
|
||||
continuation.invokeOnCancellation {
|
||||
viewTreeObserver.removePreDrawListenerSafe(preDrawListener)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSize(): Size? {
|
||||
val lp = view.layoutParams
|
||||
var width = getDimension(lp.width, view.width, view.paddingLeft + view.paddingRight)
|
||||
var height = getDimension(lp.height, view.height, view.paddingTop + view.paddingBottom)
|
||||
if (width == null && height == null) {
|
||||
return null
|
||||
}
|
||||
if (height == null && width != null) {
|
||||
height = Dimension((width.px * ASPECT_RATIO_HEIGHT / ASPECT_RATIO_WIDTH).roundToInt())
|
||||
} else if (width == null && height != null) {
|
||||
width = Dimension((height.px * ASPECT_RATIO_WIDTH / ASPECT_RATIO_HEIGHT).roundToInt())
|
||||
var width = getWidth()
|
||||
var height = getHeight()
|
||||
when {
|
||||
width == null && height == null -> {
|
||||
return null
|
||||
}
|
||||
height == null && width != null -> {
|
||||
height = Dimension((width.px * ASPECT_RATIO_HEIGHT / ASPECT_RATIO_WIDTH).roundToInt())
|
||||
}
|
||||
width == null && height != null -> {
|
||||
width = Dimension((height.px * ASPECT_RATIO_WIDTH / ASPECT_RATIO_HEIGHT).roundToInt())
|
||||
}
|
||||
}
|
||||
return Size(checkNotNull(width), checkNotNull(height))
|
||||
}
|
||||
|
||||
private fun getWidth() = getDimension(
|
||||
paramSize = view.layoutParams?.width ?: -1,
|
||||
viewSize = view.width,
|
||||
paddingSize = if (subtractPadding) view.paddingLeft + view.paddingRight else 0
|
||||
)
|
||||
|
||||
private fun getHeight() = getDimension(
|
||||
paramSize = view.layoutParams?.height ?: -1,
|
||||
viewSize = view.height,
|
||||
paddingSize = if (subtractPadding) view.paddingTop + view.paddingBottom else 0
|
||||
)
|
||||
|
||||
private fun getDimension(paramSize: Int, viewSize: Int, paddingSize: Int): Dimension.Pixels? {
|
||||
if (paramSize == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
return null
|
||||
@@ -60,24 +95,11 @@ class CoverSizeResolver(
|
||||
return null
|
||||
}
|
||||
|
||||
private inner class LayoutListener(
|
||||
private val continuation: CancellableContinuation<Size>,
|
||||
) : OnLayoutChangeListener {
|
||||
|
||||
override fun onLayoutChange(
|
||||
v: View,
|
||||
left: Int,
|
||||
top: Int,
|
||||
right: Int,
|
||||
bottom: Int,
|
||||
oldLeft: Int,
|
||||
oldTop: Int,
|
||||
oldRight: Int,
|
||||
oldBottom: Int,
|
||||
) {
|
||||
val size = getSize() ?: return
|
||||
v.removeOnLayoutChangeListener(this)
|
||||
continuation.resume(size)
|
||||
private fun ViewTreeObserver.removePreDrawListenerSafe(victim: OnPreDrawListener) {
|
||||
if (isAlive) {
|
||||
removeOnPreDrawListener(victim)
|
||||
} else {
|
||||
view.viewTreeObserver.removeOnPreDrawListener(victim)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,7 +446,7 @@ class DetailsActivity :
|
||||
val manga = details.toManga()
|
||||
with(viewBinding) {
|
||||
textViewTitle.text = manga.title
|
||||
textViewSubtitle.textAndVisible = manga.altTitle
|
||||
textViewSubtitle.textAndVisible = manga.altTitles.joinToString("\n")
|
||||
textViewNsfw.isVisible = manga.isNsfw
|
||||
textViewDescription.text = details.description.ifNullOrEmpty { getString(R.string.no_description) }
|
||||
}
|
||||
@@ -561,6 +561,7 @@ class DetailsActivity :
|
||||
}
|
||||
|
||||
private fun loadCover(imageUrl: String?) {
|
||||
viewBinding.imageViewCover.isEnabled = !imageUrl.isNullOrEmpty()
|
||||
val lastResult = CoilUtils.result(viewBinding.imageViewCover)
|
||||
if (lastResult is SuccessResult && lastResult.request.data == imageUrl) {
|
||||
return
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.koitharu.kotatsu.settings.userdata.storage
|
||||
|
||||
import coil3.ImageLoader
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -35,6 +36,7 @@ class StorageManageSettingsViewModel @Inject constructor(
|
||||
private val cookieJar: MutableCookieJar,
|
||||
private val deleteReadChaptersUseCase: DeleteReadChaptersUseCase,
|
||||
private val mangaDataRepositoryProvider: Provider<MangaDataRepository>,
|
||||
private val coil: ImageLoader,
|
||||
) : BaseViewModel() {
|
||||
|
||||
val onActionDone = MutableEventFlow<ReversibleAction>()
|
||||
@@ -78,6 +80,9 @@ class StorageManageSettingsViewModel @Inject constructor(
|
||||
storageManager.clearCache(cache)
|
||||
checkNotNull(cacheSizes[cache]).value = storageManager.computeCacheSize(cache)
|
||||
loadStorageUsage()
|
||||
if (cache == CacheDir.THUMBS || cache == CacheDir.FAVICONS) {
|
||||
coil.memoryCache?.clear()
|
||||
}
|
||||
} finally {
|
||||
loadingKeys.update { it - key }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user