diff --git a/components/AnimatedImage/library/src/commonMain/kotlin/org/jetbrains/compose/animatedimage/AnimatedImage.kt b/components/AnimatedImage/library/src/commonMain/kotlin/org/jetbrains/compose/animatedimage/AnimatedImage.kt index 920a0e2490..f09cdd3807 100644 --- a/components/AnimatedImage/library/src/commonMain/kotlin/org/jetbrains/compose/animatedimage/AnimatedImage.kt +++ b/components/AnimatedImage/library/src/commonMain/kotlin/org/jetbrains/compose/animatedimage/AnimatedImage.kt @@ -2,13 +2,32 @@ package org.jetbrains.compose.animatedimage import androidx.compose.ui.graphics.ImageBitmap +/** + * Represents an image formed by a sequence of frames with a specific duration each one. + */ expect class AnimatedImage +/** + * Loads an [AnimatedImage] from a given path. + * The image can be loaded from different sources depending on the platform (only desktop currently): + * Desktop: From the network if it's a valid URL, from the local storage otherwise. + */ expect suspend fun loadAnimatedImage(path: String): AnimatedImage +/** + * Loads an [AnimatedImage] from the resources. + */ expect suspend fun loadResourceAnimatedImage(path: String): AnimatedImage +/** + * Animates an [AnimatedImage] by returning an [ImageBitmap] for each frame of the image. + * The caller will be recomposed with each new frame that has been rendered. + */ expect fun AnimatedImage.animate(): ImageBitmap private val BlankBitmap = ImageBitmap(1, 1) + +/** + * Object used to represent a blank ImageBitmap with the minimum possible size. + */ val ImageBitmap.Companion.Blank get() = BlankBitmap \ 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 54084200a8..edeefd893c 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 @@ -7,42 +7,87 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue +/** + * Represents the load state of [T]. + */ sealed class LoadState { class Loading : LoadState() data class Success(val value: T) : LoadState() data class Error(val exception: Exception) : LoadState() } + +/** + * Load an item with type [T] asynchronously, and notify the caller about the load state. + * Whenever the load state changes (for example it succeeds or fails), the caller will be recomposed with the new state. + * The load will be cancelled when the [load] leaves the composition. + */ @Composable fun load(load: suspend () -> T): LoadState { return load(Unit, load) } +/** + * Load an item with type [T] asynchronously. Returns null while loading or if the load has failed. + * Whenever the result changes, the caller will be recomposed with the new value. + * The load will be cancelled when the [loadOrNull] leaves the composition. + */ @Composable fun loadOrNull(load: suspend () -> T): T? { return loadOrNull(Unit, load) } + +/** + * Load an item with type [T] asynchronously, and notify the caller about the load state. + * Whenever the load state changes (for example it succeeds or fails), the caller will be recomposed with the new state. + * The load will be cancelled and re-launched when [load] is recomposed with a different [key1]. + * The load will be cancelled when the [load] leaves the composition. + */ @Composable fun load(key1: Any?, load: suspend () -> T): LoadState { return load(key1, Unit, load) } +/** + * Load an item with type [T] asynchronously. Returns null while loading or if the load has failed. + * Whenever the result changes, the caller will be recomposed with the new value. + * The load will be cancelled and re-launched when [loadOrNull] is recomposed with a different [key1]. + * The load will be cancelled when the [loadOrNull] leaves the composition. + */ @Composable fun loadOrNull(key1: Any?, load: suspend () -> T): T? { return loadOrNull(key1, Unit, load) } +/** + * Load an item with type [T] asynchronously, and notify the caller about the load state. + * Whenever the load state changes (for example it succeeds or fails), the caller will be recomposed with the new state. + * The load will be cancelled and re-launched when [load] is recomposed with a different [key1] or [key2]. + * The load will be cancelled when the [load] leaves the composition. + */ @Composable fun load(key1: Any?, key2: Any?, load: suspend () -> T): LoadState { return load(key1, key2, Unit, load) } +/** + * Load an item with type [T] asynchronously. Returns null while loading or if the load has failed. + * Whenever the result changes, the caller will be recomposed with the new value. + * The load will be cancelled and re-launched when [loadOrNull] is recomposed with a different [key1] or [key2]. + * The load will be cancelled when the [loadOrNull] leaves the composition. + */ @Composable fun loadOrNull(key1: Any?, key2: Any?, load: suspend () -> T): T? { return loadOrNull(key1, key2, Unit, load) } +/** + * Load an item with type [T] asynchronously, and notify the caller about the load state. + * Whenever the load state changes (for example it succeeds or fails), the caller will be recomposed with the new state. + * The load will be cancelled and re-launched when [load] is recomposed with a different [key1], [key2] or [key3]. + * The load will be cancelled when the [load] leaves the composition. + */ @Composable fun load(key1: Any?, key2: Any?, key3: Any?, load: suspend () -> T): LoadState { var state: LoadState by remember(key1, key2, key3) { mutableStateOf(LoadState.Loading()) } @@ -56,6 +101,12 @@ fun load(key1: Any?, key2: Any?, key3: Any?, load: suspend () -> T): LoadSta return state } +/** + * Load an item with type [T] asynchronously. Returns null while loading or if the load has failed.. + * Whenever the result changes, the caller will be recomposed with the new value. + * The load will be cancelled and re-launched when [loadOrNull] is recomposed with a different [key1], [key2] or [key3]. + * The load will be cancelled when the [loadOrNull] leaves the composition. + */ @Composable fun loadOrNull(key1: Any?, key2: Any?, key3: Any?, load: suspend () -> T): T? { val state = load(key1, key2, key3, load)