fix(deps): update coil to v3.2.0 (#4712)

* fix(deps): update coil to v3.2.0

* Fix compilation issue. Need to provide an image for preview.

https://coil-kt.github.io/coil/compose/#previews

* Improve preview for images.

* Update screenshots

* More cleanup

* Update screenshots

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Benoit Marty <benoit@matrix.org>
Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
renovate[bot] 2025-06-05 09:49:27 +02:00 committed by GitHub
parent 1ca2e9baf0
commit 03b801094b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
155 changed files with 362 additions and 399 deletions

View file

@ -59,13 +59,11 @@ import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFontFamilyResolver
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
@ -92,9 +90,10 @@ import com.airbnb.android.showkase.annotation.ShowkaseComposable
import com.vanniktech.blurhash.BlurHash
import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.libraries.designsystem.R
import io.element.android.libraries.designsystem.colors.AvatarColorsProvider
import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@ -103,6 +102,7 @@ import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.MediumTopAppBar
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.utils.CommonDrawables
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.Dispatchers
@ -465,7 +465,9 @@ internal fun BloomPreview() {
var topAppBarHeight by remember { mutableIntStateOf(-1) }
val topAppBarState = rememberTopAppBarState()
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(topAppBarState)
ElementPreview {
ElementPreview(
drawableFallbackForImages = CommonDrawables.sample_avatar,
) {
Scaffold(
modifier = Modifier
.fillMaxSize()
@ -489,14 +491,13 @@ internal fun BloomPreview() {
scrolledContainerColor = Color.Black.copy(alpha = 0.05f),
),
navigationIcon = {
Image(
modifier = Modifier
.padding(start = 8.dp)
.size(32.dp)
.clip(CircleShape),
painter = painterResource(id = R.drawable.sample_avatar),
contentScale = ContentScale.Crop,
contentDescription = null
Avatar(
avatarData = AvatarData(
id = "sample-avatar",
name = "sample",
url = "aURL",
size = AvatarSize.CurrentUserTopBar,
),
)
},
actions = {

View file

@ -21,7 +21,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.tooling.preview.Preview
@ -29,7 +28,6 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil3.compose.AsyncImage
import coil3.compose.AsyncImagePainter
import coil3.compose.SubcomposeAsyncImage
import coil3.compose.SubcomposeAsyncImageContent
@ -37,9 +35,9 @@ import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.designsystem.colors.AvatarColorsProvider
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.preview.debugPlaceholderAvatar
import io.element.android.libraries.designsystem.text.toSp
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.utils.CommonDrawables
import timber.log.Timber
@Composable
@ -79,41 +77,30 @@ private fun ImageAvatar(
modifier: Modifier = Modifier,
contentDescription: String? = null,
) {
if (LocalInspectionMode.current) {
// For compose previews, use debugPlaceholderAvatar()
// instead of falling back to initials avatar on load failure
AsyncImage(
model = avatarData,
contentDescription = contentDescription,
placeholder = debugPlaceholderAvatar(),
modifier = modifier
)
} else {
SubcomposeAsyncImage(
model = avatarData,
contentDescription = contentDescription,
contentScale = ContentScale.Crop,
modifier = modifier
) {
val collectedState by painter.state.collectAsState()
when (val state = collectedState) {
is AsyncImagePainter.State.Success -> SubcomposeAsyncImageContent()
is AsyncImagePainter.State.Error -> {
SideEffect {
Timber.e(state.result.throwable, "Error loading avatar $state\n${state.result}")
}
InitialsAvatar(
avatarData = avatarData,
forcedAvatarSize = forcedAvatarSize,
contentDescription = contentDescription,
)
SubcomposeAsyncImage(
model = avatarData,
contentDescription = contentDescription,
contentScale = ContentScale.Crop,
modifier = modifier
) {
val collectedState by painter.state.collectAsState()
when (val state = collectedState) {
is AsyncImagePainter.State.Success -> SubcomposeAsyncImageContent()
is AsyncImagePainter.State.Error -> {
SideEffect {
Timber.e(state.result.throwable, "Error loading avatar $state\n${state.result}")
}
else -> InitialsAvatar(
InitialsAvatar(
avatarData = avatarData,
forcedAvatarSize = forcedAvatarSize,
contentDescription = contentDescription,
)
}
else -> InitialsAvatar(
avatarData = avatarData,
forcedAvatarSize = forcedAvatarSize,
contentDescription = contentDescription,
)
}
}
}
@ -151,7 +138,9 @@ private fun InitialsAvatar(
@Preview(group = PreviewGroup.Avatars)
@Composable
internal fun AvatarPreview(@PreviewParameter(AvatarDataProvider::class) avatarData: AvatarData) =
ElementThemedPreview {
ElementThemedPreview(
drawableFallbackForImages = CommonDrawables.sample_avatar,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp)

View file

@ -7,14 +7,19 @@
package io.element.android.libraries.designsystem.preview
import androidx.annotation.DrawableRes
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalContext
import androidx.core.content.res.ResourcesCompat
import coil3.annotation.ExperimentalCoilApi
import coil3.asImage
import coil3.compose.AsyncImagePreviewHandler
import coil3.compose.LocalAsyncImagePreviewHandler
import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.designsystem.theme.components.Surface
import io.element.android.libraries.designsystem.utils.CommonDrawables
@OptIn(ExperimentalCoilApi::class)
@Composable
@ -22,9 +27,16 @@ import io.element.android.libraries.designsystem.theme.components.Surface
fun ElementPreview(
darkTheme: Boolean = isSystemInDarkTheme(),
showBackground: Boolean = true,
@DrawableRes
drawableFallbackForImages: Int = CommonDrawables.sample_background,
content: @Composable () -> Unit
) {
CompositionLocalProvider(LocalAsyncImagePreviewHandler provides AsyncImagePreviewHandler { null }) {
val context = LocalContext.current
CompositionLocalProvider(
LocalAsyncImagePreviewHandler provides AsyncImagePreviewHandler {
ResourcesCompat.getDrawable(context.resources, drawableFallbackForImages, null)!!.asImage()
}
) {
ElementTheme(darkTheme = darkTheme) {
if (showBackground) {
// If we have a proper contentColor applied we need a Surface instead of a Box

View file

@ -7,6 +7,7 @@
package io.element.android.libraries.designsystem.preview
import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -19,12 +20,15 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.utils.CommonDrawables
@Composable
@Suppress("ModifierMissing")
fun ElementThemedPreview(
showBackground: Boolean = true,
vertical: Boolean = true,
@DrawableRes
drawableFallbackForImages: Int = CommonDrawables.sample_background,
content: @Composable () -> Unit,
) {
Box(
@ -37,12 +41,14 @@ fun ElementThemedPreview(
ElementPreview(
darkTheme = false,
showBackground = showBackground,
drawableFallbackForImages = drawableFallbackForImages,
content = content,
)
Spacer(modifier = Modifier.height(4.dp))
ElementPreview(
darkTheme = true,
showBackground = showBackground,
drawableFallbackForImages = drawableFallbackForImages,
content = content
)
}
@ -51,12 +57,14 @@ fun ElementThemedPreview(
ElementPreview(
darkTheme = false,
showBackground = showBackground,
drawableFallbackForImages = drawableFallbackForImages,
content = content,
)
Spacer(modifier = Modifier.width(4.dp))
ElementPreview(
darkTheme = true,
showBackground = showBackground,
drawableFallbackForImages = drawableFallbackForImages,
content = content
)
}

View file

@ -1,39 +0,0 @@
/*
* Copyright 2023, 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.designsystem.preview
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.res.painterResource
import io.element.android.libraries.designsystem.R
/**
* I wanted to set up a FakeImageLoader as per https://github.com/coil-kt/coil/issues/1327
* but it does not render in preview. In the meantime, you can use this trick to have image.
*/
@Composable
fun debugPlaceholder(
@DrawableRes debugPreview: Int,
nonDebugPainter: Painter? = null,
) = if (LocalInspectionMode.current) {
painterResource(id = debugPreview)
} else {
nonDebugPainter
}
@Composable
fun debugPlaceholderBackground(nonDebugPainter: Painter? = null): Painter? {
return debugPlaceholder(debugPreview = R.drawable.sample_background, nonDebugPainter)
}
@Composable
fun debugPlaceholderAvatar(nonDebugPainter: Painter? = null): Painter? {
return debugPlaceholder(debugPreview = R.drawable.sample_avatar, nonDebugPainter)
}

View file

@ -38,6 +38,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.utils.CommonDrawables
import io.element.android.libraries.testtags.TestTags
import io.element.android.libraries.testtags.testTag
import io.element.android.libraries.ui.strings.CommonStrings
@ -107,7 +108,9 @@ fun EditableAvatarView(
@Composable
internal fun EditableAvatarViewPreview(
@PreviewParameter(EditableAvatarViewUriProvider::class) uri: Uri?
) = ElementPreview {
) = ElementPreview(
drawableFallbackForImages = CommonDrawables.sample_avatar,
) {
EditableAvatarView(
matrixId = "id",
displayName = "A room",

View file

@ -29,7 +29,6 @@ import coil3.request.ImageRequest
import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.preview.debugPlaceholderBackground
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.temporaryColorBgSpecial
@ -55,7 +54,7 @@ fun UnsavedAvatar(
AsyncImage(
modifier = commonModifier,
model = model,
placeholder = debugPlaceholderBackground(ColorPainter(MaterialTheme.colorScheme.surfaceVariant)),
placeholder = ColorPainter(MaterialTheme.colorScheme.surfaceVariant),
contentScale = ContentScale.Crop,
contentDescription = null,
)

View file

@ -7,7 +7,6 @@
package io.element.android.libraries.mediaviewer.impl.gallery.ui
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Box
@ -22,16 +21,13 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalInspectionMode
import coil3.compose.AsyncImage
import coil3.compose.AsyncImagePainter
import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.mediaviewer.impl.model.MediaItem
import io.element.android.libraries.mediaviewer.impl.model.aMediaItemImage
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ImageItemView(
image: MediaItem.Image,
@ -39,16 +35,10 @@ fun ImageItemView(
onLongClick: () -> Unit,
modifier: Modifier = Modifier,
) {
val bgColor = if (LocalInspectionMode.current) {
ElementTheme.colors.bgDecorative1
} else {
Color.Transparent
}
Box(
modifier = modifier
.aspectRatio(1f)
.combinedClickable(onClick = onClick, onLongClick = onLongClick)
.background(bgColor),
.combinedClickable(onClick = onClick, onLongClick = onLongClick),
) {
var isLoaded by remember { mutableStateOf(false) }
AsyncImage(

View file

@ -7,7 +7,6 @@
package io.element.android.libraries.mediaviewer.impl.gallery.ui
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Box
@ -27,7 +26,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
@ -40,7 +38,6 @@ import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.mediaviewer.impl.model.MediaItem
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun VideoItemView(
video: MediaItem.Video,
@ -48,16 +45,10 @@ fun VideoItemView(
onLongClick: () -> Unit,
modifier: Modifier = Modifier,
) {
val bgColor = if (LocalInspectionMode.current) {
ElementTheme.colors.bgDecorative2
} else {
Color.Transparent
}
Box(
modifier = modifier
.aspectRatio(1f)
.combinedClickable(onClick = onClick, onLongClick = onLongClick)
.background(bgColor),
.combinedClickable(onClick = onClick, onLongClick = onLongClick),
) {
var isLoaded by remember { mutableStateOf(false) }
AsyncImage(

View file

@ -37,6 +37,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onSizeChanged
@ -554,8 +555,11 @@ private fun ThumbnailView(
source = thumbnailSource,
kind = MediaRequestData.Kind.File(mediaInfo.filename, mediaInfo.mimeType)
)
val alpha = if (LocalInspectionMode.current) 0.1f else 1f
AsyncImage(
modifier = Modifier.fillMaxSize(),
modifier = Modifier
.fillMaxSize()
.alpha(alpha),
model = mediaRequestData,
contentScale = ContentScale.Fit,
contentDescription = null,