@@ -23,16 +23,21 @@ import androidx.compose.foundation.layout.Row
2323import androidx.compose.foundation.layout.size
2424import androidx.compose.foundation.shape.CircleShape
2525import androidx.compose.runtime.Composable
26+ import androidx.compose.runtime.SideEffect
2627import androidx.compose.ui.Alignment
2728import androidx.compose.ui.Modifier
2829import androidx.compose.ui.draw.clip
2930import androidx.compose.ui.layout.ContentScale
31+ import androidx.compose.ui.platform.LocalInspectionMode
3032import androidx.compose.ui.semantics.clearAndSetSemantics
3133import androidx.compose.ui.tooling.preview.Preview
3234import androidx.compose.ui.tooling.preview.PreviewParameter
3335import androidx.compose.ui.unit.dp
3436import androidx.compose.ui.unit.sp
3537import coil.compose.AsyncImage
38+ import coil.compose.AsyncImagePainter
39+ import coil.compose.SubcomposeAsyncImage
40+ import coil.compose.SubcomposeAsyncImageContent
3641import io.element.android.compound.theme.ElementTheme
3742import io.element.android.libraries.designsystem.colors.AvatarColorsProvider
3843import io.element.android.libraries.designsystem.preview.ElementThemedPreview
@@ -71,16 +76,34 @@ private fun ImageAvatar(
7176 modifier : Modifier = Modifier ,
7277 contentDescription : String? = null,
7378) {
74- AsyncImage (
75- model = avatarData,
76- onError = {
77- Timber .e(it.result.throwable, " Error loading avatar $it \n ${it.result} " )
78- },
79- contentDescription = contentDescription,
80- contentScale = ContentScale .Crop ,
81- placeholder = debugPlaceholderAvatar(),
82- modifier = modifier
83- )
79+ if (LocalInspectionMode .current) {
80+ // For compose previews, use debugPlaceholderAvatar()
81+ // instead of falling back to initials avatar on load failure
82+ AsyncImage (
83+ model = avatarData,
84+ contentDescription = contentDescription,
85+ placeholder = debugPlaceholderAvatar(),
86+ modifier = modifier
87+ )
88+ } else {
89+ SubcomposeAsyncImage (
90+ model = avatarData,
91+ contentDescription = contentDescription,
92+ contentScale = ContentScale .Crop ,
93+ modifier = modifier
94+ ) {
95+ when (val state = painter.state) {
96+ is AsyncImagePainter .State .Success -> SubcomposeAsyncImageContent ()
97+ is AsyncImagePainter .State .Error -> {
98+ SideEffect {
99+ Timber .e(state.result.throwable, " Error loading avatar $state \n ${state.result} " )
100+ }
101+ InitialsAvatar (avatarData = avatarData)
102+ }
103+ else -> InitialsAvatar (avatarData = avatarData)
104+ }
105+ }
106+ }
84107}
85108
86109@Composable
0 commit comments