Browse Source

Media: improve BlurHashAsyncImage

feature/jme/open-room-member-details-when-clicking-on-user-data
ganfra 1 year ago
parent
commit
48389ccd26
  1. 42
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/blurhash/BlurHashAsyncImage.kt

42
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/blurhash/BlurHashAsyncImage.kt

@ -16,17 +16,24 @@
package io.element.android.features.messages.impl.timeline.components.blurhash package io.element.android.features.messages.impl.timeline.components.blurhash
import android.graphics.Bitmap import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import coil.compose.SubcomposeAsyncImage import coil.compose.AsyncImage
import com.vanniktech.blurhash.BlurHash import com.vanniktech.blurhash.BlurHash
@Composable @Composable
@ -37,20 +44,30 @@ fun BlurHashAsyncImage(
contentScale: ContentScale = ContentScale.Fit, contentScale: ContentScale = ContentScale.Fit,
contentDescription: String? = null, contentDescription: String? = null,
) { ) {
SubcomposeAsyncImage( var isLoading by rememberSaveable(model) { mutableStateOf(true) }
model = model, Box(
modifier = modifier, modifier = modifier,
contentAlignment = Alignment.Center,
) {
AsyncImage(
model = model,
contentScale = contentScale, contentScale = contentScale,
contentDescription = contentDescription, contentDescription = contentDescription,
loading = { onSuccess = { isLoading = false }
)
AnimatedVisibility(
visible = isLoading,
enter = fadeIn(),
exit = fadeOut(),
) {
BlurHashImage( BlurHashImage(
blurHash = blurHash, blurHash = blurHash,
contentDescription = contentDescription,
contentScale = ContentScale.FillBounds, contentScale = ContentScale.FillBounds,
contentDescription = "Loading placeholder"
)
},
) )
} }
}
}
@Composable @Composable
fun BlurHashImage( fun BlurHashImage(
@ -60,12 +77,13 @@ fun BlurHashImage(
contentScale: ContentScale = ContentScale.Fit, contentScale: ContentScale = ContentScale.Fit,
) { ) {
if (blurHash == null) return if (blurHash == null) return
val bitmapState = remember { val bitmapState = remember(blurHash) {
mutableStateOf<Bitmap?>(null) mutableStateOf(
// Build a small blurhash image so that it's fast
BlurHash.decode(blurHash, 10, 10)
)
} }
DisposableEffect(blurHash) { DisposableEffect(blurHash) {
// Build a small blurhash image so that it's fast
bitmapState.value = BlurHash.decode(blurHash, 10, 10)
onDispose { onDispose {
bitmapState.value?.recycle() bitmapState.value?.recycle()
} }

Loading…
Cancel
Save