fix(ios): gif causing glithces in liquid glass bar

This commit is contained in:
tapframe 2026-05-09 00:28:06 +05:30
parent 7290158c53
commit d342959493
3 changed files with 42 additions and 4 deletions

View file

@ -70,6 +70,7 @@ import org.jetbrains.compose.resources.stringResource
@Composable
fun HomeScreen(
modifier: Modifier = Modifier,
animateCollectionGifs: Boolean = true,
onCatalogClick: ((HomeCatalogSection) -> Unit)? = null,
onPosterClick: ((MetaPreview) -> Unit)? = null,
onPosterLongClick: ((MetaPreview) -> Unit)? = null,
@ -560,6 +561,7 @@ fun HomeScreen(
collection = collection,
modifier = Modifier.padding(bottom = 12.dp),
sectionPadding = homeSectionPadding,
animateGifs = animateCollectionGifs,
onFolderClick = onFolderClick,
)
}

View file

@ -37,6 +37,7 @@ fun HomeCollectionRowSection(
collection: Collection,
modifier: Modifier = Modifier,
sectionPadding: Dp? = null,
animateGifs: Boolean = true,
onFolderClick: ((collectionId: String, folderId: String) -> Unit)? = null,
) {
if (collection.folders.isEmpty()) return
@ -46,6 +47,7 @@ fun HomeCollectionRowSection(
collection = collection,
modifier = modifier.fillMaxWidth(),
sectionPadding = sectionPadding,
animateGifs = animateGifs,
onFolderClick = onFolderClick,
)
} else {
@ -54,6 +56,7 @@ fun HomeCollectionRowSection(
collection = collection,
modifier = Modifier.fillMaxWidth(),
sectionPadding = homeSectionHorizontalPaddingForWidth(maxWidth.value),
animateGifs = animateGifs,
onFolderClick = onFolderClick,
)
}
@ -65,6 +68,7 @@ private fun HomeCollectionRowSectionContent(
collection: Collection,
modifier: Modifier,
sectionPadding: Dp,
animateGifs: Boolean,
onFolderClick: ((collectionId: String, folderId: String) -> Unit)?,
) {
NuvioShelfSection(
@ -77,6 +81,7 @@ private fun HomeCollectionRowSectionContent(
) { folder ->
CollectionFolderCard(
folder = folder,
animateGifs = animateGifs,
onClick = onFolderClick?.let { { it(collection.id, folder.id) } },
)
}
@ -86,6 +91,7 @@ private fun HomeCollectionRowSectionContent(
private fun CollectionFolderCard(
folder: CollectionFolder,
modifier: Modifier = Modifier,
animateGifs: Boolean = true,
onClick: (() -> Unit)? = null,
) {
val posterCardStyle = rememberPosterCardStyleUiState()
@ -138,7 +144,7 @@ private fun CollectionFolderCard(
contentDescription = folder.title,
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Crop,
animateIfPossible = isAnimatedCollectionFolderImage(folder, imageUrl),
animateIfPossible = animateGifs && isAnimatedCollectionFolderImage(folder, imageUrl),
)
}
!folder.coverEmoji.isNullOrBlank() -> {

View file

@ -2,6 +2,7 @@ package com.nuvio.app.features.home.components
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@ -51,6 +52,16 @@ private data class ExpandedGifFrames(
val tickCentiseconds: Int,
)
private class GifImageViewHolder {
var imageView: UIImageView? = null
fun clear() {
imageView?.stopAnimating()
imageView?.image = null
imageView = null
}
}
@OptIn(ExperimentalForeignApi::class)
@Composable
internal actual fun CollectionCardRemoteImage(
@ -76,6 +87,13 @@ internal actual fun CollectionCardRemoteImage(
gifImage = loadGifImage(imageUrl)
}
val imageViewHolder = remember(imageUrl) { GifImageViewHolder() }
DisposableEffect(imageUrl) {
onDispose {
imageViewHolder.clear()
}
}
UIKitView(
modifier = modifier,
factory = {
@ -83,19 +101,31 @@ internal actual fun CollectionCardRemoteImage(
contentMode = UIViewContentMode.UIViewContentModeScaleAspectFill
clipsToBounds = true
userInteractionEnabled = false
image = gifImage
tag = imageUrl.hashCode().toLong()
imageViewHolder.imageView = this
updateGifImage(gifImage)
}
},
update = { imageView ->
imageViewHolder.imageView = imageView
if (imageView.tag != imageUrl.hashCode().toLong()) {
imageView.tag = imageUrl.hashCode().toLong()
}
imageView.image = gifImage
imageView.updateGifImage(gifImage)
},
)
}
private fun UIImageView.updateGifImage(image: UIImage?) {
if (this.image != image) {
stopAnimating()
this.image = image
}
if (image != null) {
startAnimating()
}
}
private fun cachedGifImage(imageUrl: String): UIImage? {
val image = gifImageCache[imageUrl] ?: return null
gifImageCacheOrder.remove(imageUrl)
@ -311,4 +341,4 @@ private fun ByteArray.readUnsignedShort(startIndex: Int): Int {
return this[startIndex].unsignedInt() or (this[startIndex + 1].unsignedInt() shl 8)
}
private fun Byte.unsignedInt(): Int = toInt() and 0xFF
private fun Byte.unsignedInt(): Int = toInt() and 0xFF