Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support loading placeholders in compose previews #4982

Merged
merged 1 commit into from
Feb 24, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.compose.ui.graphics.DefaultAlpha
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.semantics.SemanticsPropertyKey
import androidx.compose.ui.semantics.SemanticsPropertyReceiver
import androidx.compose.ui.semantics.semantics
Expand All @@ -28,6 +29,7 @@ import com.bumptech.glide.integration.ktx.InternalGlideApi
import com.bumptech.glide.integration.ktx.ResolvableGlideSize
import com.bumptech.glide.integration.ktx.Size
import com.bumptech.glide.integration.ktx.Status
import com.google.accompanist.drawablepainter.rememberDrawablePainter

/** Mutates and returns the given [RequestBuilder] to apply relevant options. */
public typealias RequestBuilderTransform<T> = (RequestBuilder<T>) -> RequestBuilder<T>
Expand Down Expand Up @@ -111,6 +113,14 @@ public fun GlideImage(
val overrideSize: Size? = requestBuilder.overrideSize()
val (size, finalModifier) = rememberSizeAndModifier(overrideSize, modifier)

// TODO(judds): It seems like we should be able to use the production paths for
// resource / drawables as well as Composables. It's not totally clear what part of the prod code
// isn't supported.
if (LocalInspectionMode.current && loading?.isResourceOrDrawable() == true) {
PreviewResourceOrDrawable(loading, contentDescription, modifier)
return
}

SizedGlideImage(
requestBuilder = requestBuilder,
size = size,
Expand All @@ -125,6 +135,27 @@ public fun GlideImage(
)
}

@OptIn(ExperimentalGlideComposeApi::class)
@Composable
private fun PreviewResourceOrDrawable(
loading: Placeholder,
contentDescription: String?,
modifier: Modifier,
) {
val drawable =
when(loading) {
is Placeholder.OfDrawable -> loading.drawable
is Placeholder.OfResourceId -> LocalContext.current.getDrawable(loading.resourceId)
is Placeholder.OfComposable ->
throw IllegalArgumentException("Composables should go through the production codepath")
}
Image(
painter = rememberDrawablePainter(drawable),
modifier = modifier,
contentDescription = contentDescription,
)
}

/**
* Used to specify a [Drawable] to use in conjunction with [GlideImage]'s `loading` or `failure`
* parameters.
Expand Down Expand Up @@ -177,6 +208,13 @@ public sealed class Placeholder {
internal class OfResourceId(@DrawableRes internal val resourceId: Int) : Placeholder()
internal class OfComposable(internal val composable: @Composable () -> Unit) : Placeholder()

internal fun isResourceOrDrawable() =
when (this) {
is OfDrawable -> true
is OfResourceId -> true
is OfComposable -> false
}

internal fun maybeComposable(): (@Composable () -> Unit)? =
when (this) {
is OfComposable -> this.composable
Expand Down