From 4ff361bd62196bb210d71770768cb743a3825528 Mon Sep 17 00:00:00 2001 From: Igor Demin Date: Fri, 29 Apr 2022 17:46:48 +0400 Subject: [PATCH] Components. AnimatedImage. Fix 'load' function. (#2043) Passed to 'load' lambda can change every recomposition (it depends on variables which are captured inside it) --- .../compose/animatedimage/demo/Main.kt | 27 ++++++------- .../jetbrains/compose/resources/LoadState.kt | 38 +++++++++++++++++-- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/components/AnimatedImage/demo/src/jvmMain/kotlin/org/jetbrains/compose/animatedimage/demo/Main.kt b/components/AnimatedImage/demo/src/jvmMain/kotlin/org/jetbrains/compose/animatedimage/demo/Main.kt index a4b1b93c8b..34d18c9308 100644 --- a/components/AnimatedImage/demo/src/jvmMain/kotlin/org/jetbrains/compose/animatedimage/demo/Main.kt +++ b/components/AnimatedImage/demo/src/jvmMain/kotlin/org/jetbrains/compose/animatedimage/demo/Main.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.size import androidx.compose.material.CircularProgressIndicator import androidx.compose.material.Text +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.unit.dp @@ -16,16 +17,14 @@ import org.jetbrains.compose.resources.LoadState import org.jetbrains.compose.resources.load import org.jetbrains.compose.resources.loadOrNull -fun main() = singleWindowApplication { - val url = - "https://raw.githubusercontent.com/JetBrains/skija/ccf303ebcf926e5ef000fc42d1a6b5b7f1e0b2b5/examples/scenes/images/codecs/animated.gif" - - // Load an image async - val animatedImage = - load { loadAnimatedImage(url) } // use "load { loadResourceAnimatedImage(url) }" for resources +private val url = + "https://raw.githubusercontent.com/JetBrains/skija/ccf303ebcf926e5ef000fc42d1a6b5b7f1e0b2b5/examples/scenes/images/codecs/animated.gif" +fun main() = singleWindowApplication { Column { - when (animatedImage) { + // Load an image async + // use "load { loadResourceAnimatedImage(url) }" for resources + when (val animatedImage = load { loadAnimatedImage(url) }) { is LoadState.Success -> Image( bitmap = animatedImage.value.animate(), contentDescription = null, @@ -34,12 +33,10 @@ fun main() = singleWindowApplication { is LoadState.Error -> Text("Error!") } - Column { - Image( - loadOrNull { loadAnimatedImage(url) }?.animate() ?: ImageBitmap.Blank, - contentDescription = null, - Modifier.size(100.dp) - ) - } + Image( + loadOrNull { loadAnimatedImage(url) }?.animate() ?: ImageBitmap.Blank, + contentDescription = null, + Modifier.size(100.dp) + ) } } \ No newline at end of file diff --git a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/LoadState.kt b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/LoadState.kt index 616f92d13c..54084200a8 100644 --- a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/LoadState.kt +++ b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/LoadState.kt @@ -15,8 +15,38 @@ sealed class LoadState { @Composable fun load(load: suspend () -> T): LoadState { - var state: LoadState by remember(load) { mutableStateOf(LoadState.Loading()) } - LaunchedEffect(load) { + return load(Unit, load) +} + +@Composable +fun loadOrNull(load: suspend () -> T): T? { + return loadOrNull(Unit, load) +} + +@Composable +fun load(key1: Any?, load: suspend () -> T): LoadState { + return load(key1, Unit, load) +} + +@Composable +fun loadOrNull(key1: Any?, load: suspend () -> T): T? { + return loadOrNull(key1, Unit, load) +} + +@Composable +fun load(key1: Any?, key2: Any?, load: suspend () -> T): LoadState { + return load(key1, key2, Unit, load) +} + +@Composable +fun loadOrNull(key1: Any?, key2: Any?, load: suspend () -> T): T? { + return loadOrNull(key1, key2, Unit, load) +} + +@Composable +fun load(key1: Any?, key2: Any?, key3: Any?, load: suspend () -> T): LoadState { + var state: LoadState by remember(key1, key2, key3) { mutableStateOf(LoadState.Loading()) } + LaunchedEffect(key1, key2, key3) { state = try { LoadState.Success(load()) } catch (e: Exception) { @@ -27,7 +57,7 @@ fun load(load: suspend () -> T): LoadState { } @Composable -fun loadOrNull(load: suspend () -> T): T? { - val state = load(load) +fun loadOrNull(key1: Any?, key2: Any?, key3: Any?, load: suspend () -> T): T? { + val state = load(key1, key2, key3, load) return (state as? LoadState.Success)?.value } \ No newline at end of file