diff --git a/FEATURES.md b/FEATURES.md index 74c88b51ee..6fffdd76d3 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -8,6 +8,7 @@ Note that following list of changes compared to Element X is likely incomplete, - Schildi theme with more neutral colors and some design tweaks † - Schildi layout tweaks † - Faster screen transitions † +- Show avatar placeholders instead of blank space for avatars that failed to load - App icon & branding ⸸ diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt index 3aa0516041..42a30599df 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt @@ -23,6 +23,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -35,6 +36,9 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.schildi.theme.ScTheme import coil.compose.AsyncImage +import coil.compose.AsyncImagePainter +import coil.compose.SubcomposeAsyncImage +import coil.compose.SubcomposeAsyncImageContent import io.element.android.compound.theme.ElementTheme import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.preview.ElementThemedPreview @@ -74,16 +78,26 @@ private fun ImageAvatar( modifier: Modifier = Modifier, contentDescription: String? = null, ) { - AsyncImage( + SubcomposeAsyncImage( model = avatarData, - onError = { + /*onError = { Timber.e(it.result.throwable, "Error loading avatar $it\n${it.result}") - }, + },*/ contentDescription = contentDescription, contentScale = ContentScale.Crop, - placeholder = debugPlaceholderAvatar(), + //placeholder = debugPlaceholderAvatar(), modifier = modifier - ) + ) { + val state = painter.state + if (state is AsyncImagePainter.State.Success) { + SubcomposeAsyncImageContent() + } else if (state is AsyncImagePainter.State.Error) { + SideEffect { + Timber.e(state.result.throwable, "Error loading avatar $state\n${state.result}") + } + InitialsAvatar(avatarData = avatarData) + } + } } @Composable