Skip to content

Commit cb2b1dc

Browse files
committed
Replace flows in GlideSubcomposition with a listener on GlideNode
1 parent 60b567e commit cb2b1dc

File tree

2 files changed

+124
-150
lines changed

2 files changed

+124
-150
lines changed

integration/compose/src/main/java/com/bumptech/glide/integration/compose/GlideImage.kt

+52-93
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import androidx.annotation.DrawableRes
77
import androidx.compose.foundation.Image
88
import androidx.compose.foundation.layout.Box
99
import androidx.compose.runtime.Composable
10-
import androidx.compose.runtime.collectAsState
10+
import androidx.compose.runtime.MutableState
11+
import androidx.compose.runtime.mutableStateOf
1112
import androidx.compose.runtime.remember
1213
import androidx.compose.ui.Alignment
1314
import androidx.compose.ui.Modifier
@@ -20,21 +21,12 @@ import androidx.compose.ui.graphics.painter.ColorPainter
2021
import androidx.compose.ui.graphics.painter.Painter
2122
import androidx.compose.ui.layout.ContentScale
2223
import androidx.compose.ui.layout.Layout
23-
import androidx.compose.ui.layout.layout
2424
import androidx.compose.ui.platform.LocalContext
2525
import androidx.compose.ui.platform.LocalInspectionMode
2626
import com.bumptech.glide.Glide
2727
import com.bumptech.glide.RequestBuilder
2828
import com.bumptech.glide.RequestManager
29-
import com.bumptech.glide.integration.ktx.AsyncGlideSize
30-
import com.bumptech.glide.integration.ktx.ExperimentGlideFlows
31-
import com.bumptech.glide.integration.ktx.GlideFlowInstant
32-
import com.bumptech.glide.integration.ktx.ImmediateGlideSize
3329
import com.bumptech.glide.integration.ktx.InternalGlideApi
34-
import com.bumptech.glide.integration.ktx.ResolvableGlideSize
35-
import com.bumptech.glide.integration.ktx.Resource
36-
import com.bumptech.glide.integration.ktx.Status
37-
import com.bumptech.glide.integration.ktx.flowResolvable
3830
import com.bumptech.glide.load.DataSource
3931
import com.google.accompanist.drawablepainter.DrawablePainter
4032
import com.google.accompanist.drawablepainter.rememberDrawablePainter
@@ -90,7 +82,6 @@ public typealias RequestBuilderTransform<T> = (RequestBuilder<T>) -> RequestBuil
9082
// to RequestBuilder (though thumbnail() may make that a challenge).
9183
// TODO(judds): Consider how to deal with transitions.
9284
@ExperimentalGlideComposeApi
93-
@OptIn(InternalGlideApi::class)
9485
@Composable
9586
public fun GlideImage(
9687
model: Any?,
@@ -144,16 +135,16 @@ public fun GlideImage(
144135
}
145136
}
146137
} else {
147-
val size: ImmediateGlideSize? = requestBuilder.overrideSize()?.let { ImmediateGlideSize(it) }
148-
ModifierGlideImage(
149-
requestBuilder,
150-
size,
151-
contentDescription,
152-
modifier,
153-
alignment,
154-
contentScale,
155-
alpha,
156-
colorFilter,
138+
SimpleLayout(
139+
modifier
140+
.glideNode(
141+
requestBuilder,
142+
contentDescription,
143+
alignment,
144+
contentScale,
145+
alpha,
146+
colorFilter,
147+
)
157148
)
158149
}
159150
}
@@ -173,34 +164,14 @@ public interface GlideSubcompositionScope {
173164
public val painter: Painter
174165
}
175166

176-
@OptIn(ExperimentGlideFlows::class)
177167
@ExperimentalGlideComposeApi
178168
internal class GlideSubcompositionScopeImpl(
179-
private val value: GlideFlowInstant<Drawable>?,
169+
private val drawable: Drawable?,
170+
override val state: RequestState
180171
) : GlideSubcompositionScope {
181172

182173
override val painter: Painter
183-
get() = value?.drawable()?.toPainter() ?: ColorPainter(Color.Transparent)
184-
185-
override val state: RequestState
186-
get() = when (val current = value) {
187-
is com.bumptech.glide.integration.ktx.Placeholder -> {
188-
when (current.status) {
189-
Status.CLEARED -> RequestState.Loading
190-
Status.RUNNING -> RequestState.Loading
191-
Status.FAILED -> RequestState.Failure
192-
Status.SUCCEEDED -> throw IllegalStateException()
193-
}
194-
}
195-
196-
is Resource -> RequestState.Success(current.dataSource)
197-
null -> RequestState.Loading
198-
}
199-
200-
private fun GlideFlowInstant<Drawable>.drawable(): Drawable? = when (this) {
201-
is com.bumptech.glide.integration.ktx.Placeholder -> placeholder
202-
is Resource -> resource
203-
}
174+
get() = drawable?.toPainter() ?: ColorPainter(Color.Transparent)
204175

205176
private fun Drawable.toPainter(): Painter =
206177
when (this) {
@@ -210,19 +181,6 @@ internal class GlideSubcompositionScopeImpl(
210181
}
211182
}
212183

213-
@OptIn(InternalGlideApi::class)
214-
private fun Modifier.sizeObservingModifier(size: ResolvableGlideSize): Modifier =
215-
this.layout { measurable, constraints ->
216-
if (size is AsyncGlideSize) {
217-
val inferredSize = constraints.inferredGlideSize()
218-
if (inferredSize != null) {
219-
size.setSize(inferredSize)
220-
}
221-
}
222-
val placeable = measurable.measure(constraints)
223-
layout(placeable.width, placeable.height) { placeable.place(0, 0) }
224-
}
225-
226184
/**
227185
* The current state of a request associated with a Glide painter.
228186
*
@@ -295,7 +253,7 @@ public sealed class RequestState {
295253
* load never starting, or in an unreasonably large amount of memory being used. Loading overly
296254
* large images in memory can also impact scrolling performance.
297255
*/
298-
@OptIn(InternalGlideApi::class, ExperimentGlideFlows::class)
256+
@OptIn(InternalGlideApi::class)
299257
@ExperimentalGlideComposeApi
300258
@Composable
301259
public fun GlideSubcomposition(
@@ -310,27 +268,45 @@ public fun GlideSubcomposition(
310268
requestBuilderTransform(requestManager.load(model))
311269
}
312270

313-
val overrideSize = requestBuilder.overrideSize()
314-
val size = remember(overrideSize) {
315-
if (overrideSize != null) {
316-
ImmediateGlideSize(overrideSize)
317-
} else {
318-
AsyncGlideSize()
271+
val requestState: MutableState<RequestState> =
272+
remember(model, requestManager, requestBuilderTransform) {
273+
mutableStateOf(RequestState.Loading)
319274
}
275+
val drawable: MutableState<Drawable?> = remember(model, requestManager, requestBuilderTransform) {
276+
mutableStateOf(null)
320277
}
321278

322-
val result = remember(requestBuilder, size) {
323-
requestBuilder.flowResolvable(size)
324-
}.collectAsState(initial = null)
279+
val requestListener: StateTrackingListener =
280+
remember(model, requestManager, requestBuilderTransform) {
281+
StateTrackingListener(
282+
requestState,
283+
drawable
284+
)
285+
}
325286

326-
val scope = GlideSubcompositionScopeImpl(result.value)
287+
val scope = GlideSubcompositionScopeImpl(drawable.value, requestState.value)
327288

328-
if (overrideSize != null) {
289+
Box(
290+
modifier
291+
.glideNode(
292+
requestBuilder,
293+
draw = false,
294+
requestListener = requestListener,
295+
)
296+
) {
329297
scope.content()
330-
} else {
331-
Box(modifier = modifier.sizeObservingModifier(size)) {
332-
scope.content()
333-
}
298+
}
299+
}
300+
301+
@ExperimentalGlideComposeApi
302+
private class StateTrackingListener(
303+
val state: MutableState<RequestState>,
304+
val drawable: MutableState<Drawable?>
305+
) : RequestListener {
306+
307+
override fun onStateChanged(model: Any?, drawable: Drawable?, requestState: RequestState) {
308+
state.value = requestState
309+
this.drawable.value = drawable
334310
}
335311
}
336312

@@ -472,31 +448,14 @@ private fun RequestBuilder<Drawable>.contentScaleTransform(
472448
// TODO(judds): Think about how to handle the various fills
473449
}
474450

475-
@OptIn(InternalGlideApi::class, ExperimentalGlideComposeApi::class)
451+
476452
@Composable
477-
private fun ModifierGlideImage(
478-
requestBuilder: RequestBuilder<Drawable>,
479-
size: ImmediateGlideSize?,
480-
contentDescription: String?,
453+
private fun SimpleLayout(
481454
modifier: Modifier,
482-
alignment: Alignment,
483-
contentScale: ContentScale,
484-
alpha: Float,
485-
colorFilter: ColorFilter?
486455
) {
487456
Layout(
488-
{},
489457
modifier
490-
.glideNode(
491-
requestBuilder,
492-
size,
493-
contentDescription,
494-
alignment,
495-
contentScale,
496-
alpha,
497-
colorFilter,
498-
)
499-
) { _, constraints ->
458+
) { _, constraints ->
500459
layout(constraints.minWidth, constraints.minHeight) {}
501460
}
502461
}

0 commit comments

Comments
 (0)