Skip to content

Commit

Permalink
Update AsyncImage after upstream changes
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisbanes committed Jul 9, 2023
1 parent 72ec215 commit b5de3bb
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ internal object IosImageLoaderFactory : ImageLoaderFactory {
override fun create(
block: ImageLoaderConfigBuilder.() -> Unit,
): ImageLoader = ImageLoader {
// commonConfig()

components {
setupDefaultComponents(imageScope)
setupDefaultComponents()
}
interceptor {
memoryCacheConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal object DesktopImageLoaderFactory : ImageLoaderFactory {
block: ImageLoaderConfigBuilder.() -> Unit,
): ImageLoader = ImageLoader {
components {
setupDefaultComponents(imageScope)
setupDefaultComponents()
}
interceptor {
memoryCacheConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import com.seiko.imageloader.ImageLoader
import com.seiko.imageloader.ImageRequestState
import com.seiko.imageloader.LocalImageLoader
import com.seiko.imageloader.asImageBitmap
import com.seiko.imageloader.model.ImageAction
import com.seiko.imageloader.model.ImageRequest
import com.seiko.imageloader.model.ImageRequestBuilder
import com.seiko.imageloader.model.ImageResult
Expand All @@ -47,17 +47,16 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.withContext

@OptIn(ExperimentalCoroutinesApi::class)
@Composable
fun AsyncImage(
model: Any?,
contentDescription: String?,
modifier: Modifier = Modifier,
onState: ((ImageRequestState) -> Unit)? = null,
onEvent: ((ImageAction) -> Unit)? = null,
requestBuilder: (ImageRequestBuilder.() -> ImageRequestBuilder)? = null,
imageLoader: ImageLoader = LocalImageLoader.current,
alignment: Alignment = Alignment.Center,
Expand All @@ -67,41 +66,27 @@ fun AsyncImage(
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
) {
val sizeResolver = ConstraintsSizeResolver()
var requestState: ImageRequestState by remember { mutableStateOf(ImageRequestState.Loading()) }
val lastRequestBuilder by rememberUpdatedState(requestBuilder)

val request by produceState<ImageRequest?>(null, model, contentScale) {
val request by produceState(ImageRequest(Unit), model, contentScale) {
value = ImageRequest {
data(model)
size(sizeResolver)
requestBuilder?.invoke(this)

options {
if (scale == Scale.AUTO) {
scale = contentScale.toScale()
}
}
eventListener { event ->
requestState = ImageRequestState.Loading(event)
}
lastRequestBuilder?.invoke(this)
}
}

var result by remember { mutableStateOf<ImageResult?>(null) }
LaunchedEffect(imageLoader) {
snapshotFlow { request }
.filterNotNull()
.mapLatest {
withContext(imageLoader.config.imageScope.coroutineContext) {
imageLoader.execute(it)
.flatMapLatest { imageLoader.async(it) }
.collect { action ->
onEvent?.invoke(action)
if (action is ImageResult) {
result = action
}
}
.collect { result = it }
}

val lastOnState by rememberUpdatedState(onState)
LaunchedEffect(Unit) {
snapshotFlow { requestState }
.collect { lastOnState?.invoke(it) }
}

Crossfade(
Expand Down Expand Up @@ -145,7 +130,7 @@ private fun ResultImage(
)
}

is ImageResult.Image -> result.image.toPainter(filterQuality)
is ImageResult.Image -> result.image.toPainter()
is ImageResult.Painter -> result.painter
else -> EmptyPainter
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ import app.tivi.overlays.showInDialog
import app.tivi.screens.AccountScreen
import app.tivi.screens.EpisodeTrackScreen
import app.tivi.screens.UpNextScreen
import com.seiko.imageloader.ImageRequestState
import com.seiko.imageloader.model.ImageResult
import com.slack.circuit.overlay.LocalOverlayHost
import com.slack.circuit.runtime.CircuitContext
import com.slack.circuit.runtime.Screen
Expand Down Expand Up @@ -388,8 +388,8 @@ private fun UpNextItem(

AsyncImage(
model = model,
onState = { state ->
if (state is ImageRequestState.Failure && model is EpisodeImageModel) {
onEvent = { state ->
if (state is ImageResult.Error && model is EpisodeImageModel) {
// If the episode backdrop request failed, fallback to the show backdrop
model = show.asImageModel(ImageType.BACKDROP)
}
Expand Down

0 comments on commit b5de3bb

Please sign in to comment.