From a676d5fae147f05d16c6f49e4002a4366afeca35 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 23 Jun 2025 21:24:03 +0200 Subject: [PATCH 01/19] Extract UserAvatar to its own file. --- .../designsystem/components/avatar/Avatar.kt | 27 ------------- .../components/avatar/UserAvatar.kt | 39 +++++++++++++++++++ 2 files changed, 39 insertions(+), 27 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt 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 7358bd4ce3..508c945555 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 @@ -57,33 +57,6 @@ fun Avatar( } } -@Composable -private fun UserAvatar( - avatarData: AvatarData, - modifier: Modifier = Modifier, - contentDescription: String? = null, - forcedAvatarSize: Dp? = null, - hideImage: Boolean = false, -) { - if (avatarData.url.isNullOrBlank() || hideImage) { - InitialLetterAvatar( - avatarData = avatarData, - avatarType = AvatarType.User, - forcedAvatarSize = forcedAvatarSize, - modifier = modifier, - contentDescription = contentDescription, - ) - } else { - ImageAvatar( - avatarData = avatarData, - avatarType = AvatarType.User, - forcedAvatarSize = forcedAvatarSize, - modifier = modifier, - contentDescription = contentDescription, - ) - } -} - @Preview(group = PreviewGroup.Avatars) @Composable internal fun AvatarPreview(@PreviewParameter(AvatarDataProvider::class) avatarData: AvatarData) = diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt new file mode 100644 index 0000000000..54b0708078 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2025 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.components.avatar + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp + +@Composable +internal fun UserAvatar( + avatarData: AvatarData, + modifier: Modifier = Modifier, + contentDescription: String? = null, + forcedAvatarSize: Dp? = null, + hideImage: Boolean = false, +) { + if (avatarData.url.isNullOrBlank() || hideImage) { + InitialLetterAvatar( + avatarData = avatarData, + avatarType = AvatarType.User, + forcedAvatarSize = forcedAvatarSize, + modifier = modifier, + contentDescription = contentDescription, + ) + } else { + ImageAvatar( + avatarData = avatarData, + avatarType = AvatarType.User, + forcedAvatarSize = forcedAvatarSize, + modifier = modifier, + contentDescription = contentDescription, + ) + } +} From 0cc11ba6265d910b96a74161ab17833c04cf7101 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 23 Jun 2025 21:24:40 +0200 Subject: [PATCH 02/19] Cleanup code rework by IDE. --- .../libraries/designsystem/components/avatar/ImageAvatar.kt | 2 +- .../designsystem/components/avatar/InitialLetterAvatar.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/ImageAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/ImageAvatar.kt index 796ed6dfb4..f0161469e5 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/ImageAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/ImageAvatar.kt @@ -26,7 +26,7 @@ internal fun ImageAvatar( avatarData: AvatarData, avatarType: AvatarType, forcedAvatarSize: Dp?, - modifier: Modifier = Modifier.Companion, + modifier: Modifier = Modifier, contentDescription: String? = null, ) { val size = forcedAvatarSize ?: avatarData.size.dp diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialLetterAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialLetterAvatar.kt index 4c54d337ef..2534db52a1 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialLetterAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialLetterAvatar.kt @@ -18,7 +18,7 @@ internal fun InitialLetterAvatar( avatarType: AvatarType, forcedAvatarSize: Dp?, contentDescription: String?, - modifier: Modifier = Modifier.Companion, + modifier: Modifier = Modifier, ) { val avatarColors = AvatarColorsProvider.provide(avatarData.id) TextAvatar( From b36f68b8c401e6e5c077d69af4858ce6e5cd9317 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 23 Jun 2025 21:25:23 +0200 Subject: [PATCH 03/19] SpaceAvatar can be internal --- .../libraries/designsystem/components/avatar/SpaceAvatar.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt index 65906244e6..6f8ec2fda9 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt @@ -19,7 +19,7 @@ import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.utils.CommonDrawables @Composable -fun SpaceAvatar( +internal fun SpaceAvatar( avatarData: AvatarData, avatarType: AvatarType.Space, modifier: Modifier = Modifier, From 63d8d9b09e2a37b51f899cd6d3855b5f07d807fb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 23 Jun 2025 21:27:40 +0200 Subject: [PATCH 04/19] Remove default param for AvatarCluster.avatarType --- .../libraries/designsystem/components/avatar/AvatarCluster.kt | 3 ++- .../libraries/designsystem/components/avatar/RoomAvatar.kt | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt index 8406c951af..4827300394 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt @@ -33,8 +33,8 @@ private const val MAX_AVATAR_COUNT = 4 @Composable internal fun AvatarCluster( avatars: ImmutableList, + avatarType: AvatarType, modifier: Modifier = Modifier, - avatarType: AvatarType = AvatarType.User, hideAvatarImages: Boolean = false, contentDescription: String? = null, ) { @@ -119,6 +119,7 @@ internal fun AvatarClusterPreview() = ElementThemedPreview { for (ngOfAvatars in 1..5) { AvatarCluster( avatars = List(ngOfAvatars) { anAvatarData(it) }.toPersistentList(), + avatarType = AvatarType.User, ) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt index f01d71e41d..1b14a149d3 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt @@ -49,6 +49,8 @@ internal fun RoomAvatar( else -> { AvatarCluster( avatars = avatarType.heroes, + // Note: even for a room avatar, we use UserAvatarType here to display the avatar of heroes + avatarType = AvatarType.User, modifier = modifier, hideAvatarImages = hideAvatarImage, contentDescription = contentDescription From 52ad634504aa3efa967c56eca4054b75727051c4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 23 Jun 2025 21:36:53 +0200 Subject: [PATCH 05/19] Remove default param for Avatar.avatarType --- .../call/impl/ui/IncomingCallScreen.kt | 4 +- .../notifications/NotificationsOptInView.kt | 2 + .../knockrequests/impl/banner/AvatarRow.kt | 56 ++++++++++--------- .../impl/banner/KnockRequestsBannerView.kt | 7 ++- .../impl/list/KnockRequestsListView.kt | 6 +- .../impl/actionlist/ActionListView.kt | 8 ++- .../components/TimelineItemCallNotifyView.kt | 6 +- .../components/TimelineItemEventRow.kt | 2 + .../reactionsummary/ReactionSummaryView.kt | 6 +- .../receipt/TimelineItemReadReceiptView.kt | 28 +++++----- .../changeroles/ChangeRolesView.kt | 6 +- .../impl/components/RoomListTopBar.kt | 2 + .../impl/RoomMemberModerationView.kt | 2 + .../shared/UserProfileHeaderSection.kt | 2 + .../impl/ui/VerificationUserProfileContent.kt | 8 ++- .../atomic/molecules/ComposerAlertMolecule.kt | 6 +- .../designsystem/components/Bloom.kt | 2 + .../designsystem/components/avatar/Avatar.kt | 7 ++- .../components/avatar/DmAvatars.kt | 2 + .../components/avatar/UserAvatarPreview.kt | 5 +- .../CreateDmConfirmationBottomSheet.kt | 2 + .../matrix/ui/components/InviteSenderView.kt | 7 ++- .../matrix/ui/components/MatrixUserHeader.kt | 2 + .../matrix/ui/components/SelectedUser.kt | 6 +- .../matrix/ui/components/UnresolvedUserRow.kt | 6 +- .../libraries/matrix/ui/components/UserRow.kt | 6 +- .../impl/details/MediaDetailsBottomSheet.kt | 6 +- 27 files changed, 143 insertions(+), 59 deletions(-) diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallScreen.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallScreen.kt index 3a77fb4d81..954fa3568f 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallScreen.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallScreen.kt @@ -39,6 +39,7 @@ import io.element.android.libraries.designsystem.background.OnboardingBackground 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.components.avatar.AvatarType 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 @@ -74,7 +75,8 @@ internal fun IncomingCallScreen( name = notificationData.senderName, url = notificationData.avatarUrl, size = AvatarSize.IncomingCall, - ) + ), + avatarType = AvatarType.User, ) Spacer(modifier = Modifier.height(24.dp)) Text( diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt index 69bca0250b..444c311a63 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt @@ -38,6 +38,7 @@ import io.element.android.libraries.designsystem.components.PageTitle 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.components.avatar.AvatarType import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Button @@ -149,6 +150,7 @@ private fun NotificationRow( ) { Avatar( avatarData = AvatarData(id = avatarColorsId, name = avatarLetter, size = AvatarSize.NotificationsOptIn), + avatarType = AvatarType.User, ) Column(Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(12.dp)) { Box( diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/AvatarRow.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/AvatarRow.kt index 186a578945..bc0fbbdbeb 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/AvatarRow.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/AvatarRow.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.unit.dp 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.components.avatar.AvatarType import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.text.toPx @@ -43,6 +44,7 @@ import kotlinx.collections.immutable.toImmutableList @Composable fun AvatarRow( avatarDataList: ImmutableList, + avatarType: AvatarType, modifier: Modifier = Modifier, overlapRatio: Float = 0.5f, ) { @@ -58,35 +60,36 @@ fun AvatarRow( .forEachIndexed { index, avatarData -> Avatar( modifier = Modifier - .padding(start = avatarSize * (1 - overlapRatio) * (lastItemIndex - index)) - .graphicsLayer { - compositingStrategy = CompositingStrategy.Offscreen + .padding(start = avatarSize * (1 - overlapRatio) * (lastItemIndex - index)) + .graphicsLayer { + compositingStrategy = CompositingStrategy.Offscreen + } + .drawWithContent { + // Draw content and clear the pixels for the avatar on the left (right in RTL). + drawContent() + val xOffset = if (isRtl) { + size.width - avatarSizePx * (overlapRatio - 0.5f) + } else { + 0f + avatarSizePx * (overlapRatio - 0.5f) } - .drawWithContent { - // Draw content and clear the pixels for the avatar on the left (right in RTL). - drawContent() - val xOffset = if (isRtl) { - size.width - avatarSizePx * (overlapRatio - 0.5f) - } else { - 0f + avatarSizePx * (overlapRatio - 0.5f) - } - if (index < lastItemIndex) { - drawCircle( - color = Color.Black, - center = Offset( - x = xOffset, - y = size.height / 2, - ), - radius = avatarSizePx / 2, - blendMode = BlendMode.Clear, - ) - } + if (index < lastItemIndex) { + drawCircle( + color = Color.Black, + center = Offset( + x = xOffset, + y = size.height / 2, + ), + radius = avatarSizePx / 2, + blendMode = BlendMode.Clear, + ) } - .size(size = avatarSize) - // Keep internal padding, it has the advantage to not reduce the size of the Avatar image, - // which is already small in our use case. - .padding(2.dp), + } + .size(size = avatarSize) + // Keep internal padding, it has the advantage to not reduce the size of the Avatar image, + // which is already small in our use case. + .padding(2.dp), avatarData = avatarData, + avatarType = avatarType, ) } } @@ -122,6 +125,7 @@ private fun ContentToPreview(overlapRatio: Float) { size = AvatarSize.RoomListItem, ) }.toImmutableList(), + avatarType = AvatarType.User, overlapRatio = overlapRatio, ) } diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerView.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerView.kt index 09ac8bff59..334bb531ae 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerView.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerView.kt @@ -39,6 +39,7 @@ import io.element.android.libraries.designsystem.components.async.AsyncIndicator import io.element.android.libraries.designsystem.components.async.rememberAsyncIndicatorState import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Button @@ -195,7 +196,10 @@ private fun KnockRequestAvatarView( Box(modifier) { when (knockRequests.size) { 0 -> Unit - 1 -> Avatar(knockRequests.first().getAvatarData(AvatarSize.KnockRequestBanner)) + 1 -> Avatar( + avatarData = knockRequests.first().getAvatarData(AvatarSize.KnockRequestBanner), + avatarType = AvatarType.User, + ) else -> KnockRequestAvatarListView(knockRequests) } } @@ -214,6 +218,7 @@ private fun KnockRequestAvatarListView( .toImmutableList() AvatarRow( avatarDataList = avatars, + avatarType = AvatarType.User, modifier = modifier, ) } diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListView.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListView.kt index 3b90fe7e11..7e79203f31 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListView.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListView.kt @@ -56,6 +56,7 @@ import io.element.android.libraries.designsystem.components.ProgressDialog import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog import io.element.android.libraries.designsystem.preview.ElementPreview @@ -318,7 +319,10 @@ private fun KnockRequestItem( .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 12.dp) ) { - Avatar(knockRequest.getAvatarData(AvatarSize.KnockRequestItem)) + Avatar( + avatarData = knockRequest.getAvatarData(AvatarSize.KnockRequestItem), + avatarType = AvatarType.User, + ) Spacer(modifier = Modifier.width(16.dp)) Column { // Name and date diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt index a16f1efa19..aec3b8219e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt @@ -74,6 +74,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.utils.messagesummary.DefaultMessageSummaryFormatter import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -256,7 +257,12 @@ private fun MessageSummary( modifier: Modifier = Modifier, ) { val content: @Composable () -> Unit - val icon: @Composable () -> Unit = { Avatar(avatarData = event.senderAvatar.copy(size = AvatarSize.MessageActionSender)) } + val icon: @Composable () -> Unit = { + Avatar( + avatarData = event.senderAvatar.copy(size = AvatarSize.MessageActionSender), + avatarType = AvatarType.User, + ) + } val contentStyle = ElementTheme.typography.fontBodyMdRegular.copy(color = ElementTheme.colors.textSecondary) @Composable diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt index ed26d6558e..e4aee2febd 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt @@ -33,6 +33,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.roomcall.api.RoomCallState import io.element.android.features.roomcall.api.RoomCallStateProvider import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.text.toDp @@ -55,7 +56,10 @@ internal fun TimelineItemCallNotifyView( horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically, ) { - Avatar(avatarData = event.senderAvatar) + Avatar( + avatarData = event.senderAvatar, + avatarType = AvatarType.User, + ) Column(modifier = Modifier.weight(1f)) { Text( text = event.safeSenderName, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index 18d0658dd6..1b798de14f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -76,6 +76,7 @@ import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.components.EqualWidthColumn 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.AvatarType import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.swipe.SwipeableActionsState @@ -441,6 +442,7 @@ private fun MessageSenderInformation( .clip(CircleShape) .clickable(onClick = onClick), avatarData = senderAvatar, + avatarType = AvatarType.User, ) SenderName( modifier = Modifier diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryView.kt index c14d792252..081d93465f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryView.kt @@ -62,6 +62,7 @@ import io.element.android.features.messages.impl.timeline.model.AggregatedReacti 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.components.avatar.AvatarType import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.text.toDp @@ -249,7 +250,10 @@ private fun SenderRow( .semantics(mergeDescendants = true) {}, verticalAlignment = Alignment.CenterVertically ) { - Avatar(avatarData) + Avatar( + avatarData = avatarData, + avatarType = AvatarType.User, + ) Column( modifier = Modifier.padding(start = 12.dp), ) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt index 8493bad765..fd6e5cea53 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt @@ -37,6 +37,7 @@ import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.messages.impl.timeline.model.ReadReceiptData import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.avatar.getBestName import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -65,11 +66,11 @@ fun TimelineItemReadReceiptView( ReadReceiptsAvatars( receipts = state.receipts, modifier = Modifier - .clip(RoundedCornerShape(4.dp)) - .clickable { - onReadReceiptsClick() - } - .padding(2.dp) + .clip(RoundedCornerShape(4.dp)) + .clickable { + onReadReceiptsClick() + } + .padding(2.dp) ) } } @@ -112,9 +113,9 @@ private fun ReadReceiptsRow( ) { Row( modifier = modifier - .fillMaxWidth() - .height(AvatarSize.TimelineReadReceipt.dp + 8.dp) - .padding(horizontal = 18.dp), + .fillMaxWidth() + .height(AvatarSize.TimelineReadReceipt.dp + 8.dp) + .padding(horizontal = 18.dp), horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically, ) { @@ -154,15 +155,16 @@ private fun ReadReceiptsAvatars( .forEachIndexed { index, readReceiptData -> Box( modifier = Modifier - .padding(end = (12.dp + avatarStrokeSize * 2) * index) - .size(size = avatarSize + avatarStrokeSize * 2) - .clip(CircleShape) - .background(avatarStrokeColor) - .zIndex(index.toFloat()), + .padding(end = (12.dp + avatarStrokeSize * 2) * index) + .size(size = avatarSize + avatarStrokeSize * 2) + .clip(CircleShape) + .background(avatarStrokeColor) + .zIndex(index.toFloat()), contentAlignment = Alignment.Center, ) { Avatar( avatarData = readReceiptData.avatarData, + avatarType = AvatarType.User, ) } } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesView.kt index b1a7a7df21..2b1ee08f66 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesView.kt @@ -50,6 +50,7 @@ import io.element.android.libraries.designsystem.components.async.rememberAsyncI 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.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog @@ -341,7 +342,10 @@ private fun MemberRow( .padding(start = 16.dp, top = 4.dp, end = 16.dp, bottom = 4.dp), verticalAlignment = Alignment.CenterVertically ) { - Avatar(avatarData) + Avatar( + avatarData = avatarData, + avatarType = AvatarType.User, + ) Column( modifier = Modifier .padding(start = 12.dp) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt index 1f4c86f579..bee535d8cd 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt @@ -48,6 +48,7 @@ import io.element.android.libraries.designsystem.atomic.atoms.RedIndicatorAtom 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.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.avatarBloom import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -297,6 +298,7 @@ private fun NavigationIcon( Box { Avatar( avatarData = avatarData, + avatarType = AvatarType.User, contentDescription = stringResource(CommonStrings.common_settings), ) if (showAvatarIndicator) { diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationView.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationView.kt index c5a394338a..d4b7a7b69e 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationView.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationView.kt @@ -38,6 +38,7 @@ import io.element.android.libraries.designsystem.components.async.AsyncIndicator import io.element.android.libraries.designsystem.components.async.rememberAsyncIndicatorState import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog import io.element.android.libraries.designsystem.components.dialogs.TextFieldDialog import io.element.android.libraries.designsystem.components.list.ListItemContent @@ -223,6 +224,7 @@ private fun RoomMemberActionsBottomSheet( ) { Avatar( avatarData = user.getAvatarData(size = AvatarSize.RoomListManageUser), + avatarType = AvatarType.User, modifier = Modifier .padding(bottom = 28.dp) .align(Alignment.CenterHorizontally) diff --git a/features/userprofile/shared/src/main/kotlin/io/element/android/features/userprofile/shared/UserProfileHeaderSection.kt b/features/userprofile/shared/src/main/kotlin/io/element/android/features/userprofile/shared/UserProfileHeaderSection.kt index da88c0f508..2732e770f4 100644 --- a/features/userprofile/shared/src/main/kotlin/io/element/android/features/userprofile/shared/UserProfileHeaderSection.kt +++ b/features/userprofile/shared/src/main/kotlin/io/element/android/features/userprofile/shared/UserProfileHeaderSection.kt @@ -30,6 +30,7 @@ import io.element.android.libraries.designsystem.atomic.molecules.MatrixBadgeRow 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.components.avatar.AvatarType import io.element.android.libraries.designsystem.modifiers.niceClickable import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -61,6 +62,7 @@ fun UserProfileHeaderSection( ) { Avatar( avatarData = AvatarData(userId.value, userName, avatarUrl, AvatarSize.UserHeader), + avatarType = AvatarType.User, modifier = Modifier .clip(CircleShape) .clickable(enabled = avatarUrl != null) { openAvatarPreview(avatarUrl!!) } diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/ui/VerificationUserProfileContent.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/ui/VerificationUserProfileContent.kt index 4210e3559c..4f6cfcf456 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/ui/VerificationUserProfileContent.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/ui/VerificationUserProfileContent.kt @@ -25,6 +25,7 @@ import io.element.android.compound.theme.ElementTheme 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.components.avatar.AvatarType import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Text @@ -50,10 +51,11 @@ fun VerificationUserProfileContent( .padding(12.dp), verticalAlignment = Alignment.CenterVertically, ) { - Avatar(avatarData) - + Avatar( + avatarData = avatarData, + avatarType = AvatarType.User, + ) Spacer(modifier = Modifier.padding(12.dp)) - Column(verticalArrangement = Arrangement.spacedBy(2.dp)) { Text(text = displayName ?: userId.value, style = ElementTheme.typography.fontBodyLgMedium, color = ElementTheme.colors.textPrimary) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/ComposerAlertMolecule.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/ComposerAlertMolecule.kt index 0108779913..07e2454dbc 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/ComposerAlertMolecule.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/ComposerAlertMolecule.kt @@ -27,6 +27,7 @@ import io.element.android.compound.theme.ElementTheme 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.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.avatar.anAvatarData import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -72,7 +73,10 @@ fun ComposerAlertMolecule( horizontalArrangement = Arrangement.spacedBy(16.dp) ) { if (avatar != null) { - Avatar(avatarData = avatar) + Avatar( + avatarData = avatar, + avatarType = AvatarType.User, + ) } Text( text = content, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt index 764a208a82..fd4b380fdc 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt @@ -94,6 +94,7 @@ 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.components.avatar.AvatarType import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -498,6 +499,7 @@ internal fun BloomPreview() { url = "aURL", size = AvatarSize.CurrentUserTopBar, ), + avatarType = AvatarType.User, ) }, actions = { 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 508c945555..93e458bfcc 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 @@ -24,8 +24,8 @@ import io.element.android.libraries.designsystem.utils.CommonDrawables @Composable fun Avatar( avatarData: AvatarData, + avatarType: AvatarType, modifier: Modifier = Modifier, - avatarType: AvatarType = AvatarType.User, contentDescription: String? = null, // If not null, will be used instead of the size from avatarData forcedAvatarSize: Dp? = null, @@ -67,7 +67,10 @@ internal fun AvatarPreview(@PreviewParameter(AvatarDataProvider::class) avatarDa verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(16.dp) ) { - Avatar(avatarData) + Avatar( + avatarData = avatarData, + avatarType = AvatarType.User, + ) Text(text = avatarData.size.name + " " + avatarData.size.dp) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/DmAvatars.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/DmAvatars.kt index 7b4e6dee86..d0134fca78 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/DmAvatars.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/DmAvatars.kt @@ -55,6 +55,7 @@ fun DmAvatars( // Draw user avatar and cut top end corner Avatar( avatarData = userAvatarData, + avatarType = AvatarType.User, modifier = Modifier .align(Alignment.BottomStart) .graphicsLayer { @@ -85,6 +86,7 @@ fun DmAvatars( // Draw other user avatar Avatar( avatarData = otherUserAvatarData, + avatarType = AvatarType.User, modifier = Modifier .align(Alignment.TopEnd) .clip(CircleShape) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt index 8797c2750a..f3b55e53d2 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt @@ -33,7 +33,10 @@ internal fun UserAvatarColorsPreview() = ElementPreview { verticalAlignment = Alignment.CenterVertically, ) { // Note: it's OK, since the hash of "0" is 0, the hash of "1" is 1, etc. - Avatar(anAvatarData(id = "$it")) + Avatar( + avatarData = anAvatarData(id = "$it"), + avatarType = AvatarType.User, + ) Text(text = "Color index $it") } } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CreateDmConfirmationBottomSheet.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CreateDmConfirmationBottomSheet.kt index 75b8e5a5f3..b0a19924b3 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CreateDmConfirmationBottomSheet.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CreateDmConfirmationBottomSheet.kt @@ -25,6 +25,7 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Button @@ -62,6 +63,7 @@ fun CreateDmConfirmationBottomSheet( Spacer(modifier = Modifier.height(24.dp)) Avatar( avatarData = matrixUser.getAvatarData(AvatarSize.DmCreationConfirmation), + avatarType = AvatarType.User, ) Spacer(modifier = Modifier.height(16.dp)) Text( diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/InviteSenderView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/InviteSenderView.kt index 946c0d51e9..960bdb9098 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/InviteSenderView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/InviteSenderView.kt @@ -18,6 +18,7 @@ import io.element.android.compound.theme.ElementTheme 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.components.avatar.AvatarType import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Text @@ -35,7 +36,11 @@ fun InviteSenderView( modifier = modifier, ) { Box(modifier = Modifier.padding(vertical = 2.dp)) { - Avatar(avatarData = inviteSender.avatarData, hideImage = hideAvatarImage) + Avatar( + avatarData = inviteSender.avatarData, + avatarType = AvatarType.User, + hideImage = hideAvatarImage, + ) } Text( text = inviteSender.annotatedString(), diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeader.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeader.kt index 55833caf59..cb97c1e9f4 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeader.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeader.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Text @@ -65,6 +66,7 @@ private fun MatrixUserHeaderContent( modifier = Modifier .padding(vertical = 12.dp), avatarData = matrixUser.getAvatarData(size = AvatarSize.UserPreference), + avatarType = AvatarType.User, ) Spacer(modifier = Modifier.width(16.dp)) Column( diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUser.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUser.kt index ddb6134895..31cc724838 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUser.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUser.kt @@ -30,6 +30,7 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.AvatarType 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 @@ -54,7 +55,10 @@ fun SelectedUser( Column( horizontalAlignment = Alignment.CenterHorizontally, ) { - Avatar(matrixUser.getAvatarData(size = AvatarSize.SelectedUser)) + Avatar( + avatarData = matrixUser.getAvatarData(size = AvatarSize.SelectedUser), + avatarType = AvatarType.User, + ) Text( modifier = Modifier.clipToBounds(), text = matrixUser.getBestName(), diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnresolvedUserRow.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnresolvedUserRow.kt index 41f58fc67a..4c1c4d5f3c 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnresolvedUserRow.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnresolvedUserRow.kt @@ -27,6 +27,7 @@ import io.element.android.compound.tokens.generated.CompoundIcons 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.components.avatar.AvatarType import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Text @@ -46,7 +47,10 @@ fun UnresolvedUserRow( .padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 8.dp), verticalAlignment = Alignment.CenterVertically ) { - Avatar(avatarData) + Avatar( + avatarData = avatarData, + avatarType = AvatarType.User, + ) Column( modifier = Modifier .padding(start = 12.dp), diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UserRow.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UserRow.kt index 2f5874b664..2ee234bd43 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UserRow.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UserRow.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme 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.AvatarType import io.element.android.libraries.designsystem.theme.components.Text @Composable @@ -38,7 +39,10 @@ internal fun UserRow( .padding(start = 16.dp, top = 4.dp, end = 16.dp, bottom = 4.dp), verticalAlignment = Alignment.CenterVertically ) { - Avatar(avatarData) + Avatar( + avatarData = avatarData, + avatarType = AvatarType.User, + ) Column( modifier = Modifier .padding(start = 12.dp) diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/details/MediaDetailsBottomSheet.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/details/MediaDetailsBottomSheet.kt index 5d4b67a411..22c29c590b 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/details/MediaDetailsBottomSheet.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/details/MediaDetailsBottomSheet.kt @@ -29,6 +29,7 @@ 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.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -139,12 +140,13 @@ private fun SenderRow( ) { val id = mediaInfo.senderId?.value ?: "@Alice:domain" Avatar( - AvatarData( + avatarData = AvatarData( id = id, name = mediaInfo.senderName, url = mediaInfo.senderAvatar, size = AvatarSize.MediaSender, - ) + ), + avatarType = AvatarType.User, ) Column( modifier = Modifier From 9e65b7fa637fc4ae38e08c299e8cc9d9bf299406 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 23 Jun 2025 21:41:15 +0200 Subject: [PATCH 06/19] Extract subcomposable InitialOrImageAvatar --- .../components/avatar/InitialOrImageAvatar.kt | 39 +++++++++++++++++++ .../components/avatar/RoomAvatar.kt | 25 ++++-------- .../components/avatar/SpaceAvatar.kt | 10 +---- .../components/avatar/UserAvatar.kt | 25 ++++-------- 4 files changed, 57 insertions(+), 42 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt new file mode 100644 index 0000000000..e58a9f33c5 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2025 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.components.avatar + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp + +@Composable +internal fun InitialOrImageAvatar( + avatarData: AvatarData, + hideAvatarImage: Boolean, + forcedAvatarSize: Dp?, + avatarType: AvatarType, + modifier: Modifier, + contentDescription: String? +) { + when { + avatarData.url.isNullOrBlank() || hideAvatarImage -> InitialLetterAvatar( + avatarData = avatarData, + avatarType = avatarType, + forcedAvatarSize = forcedAvatarSize, + modifier = modifier, + contentDescription = contentDescription, + ) + else -> ImageAvatar( + avatarData = avatarData, + avatarType = avatarType, + forcedAvatarSize = forcedAvatarSize, + modifier = modifier, + contentDescription = contentDescription, + ) + } +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt index 1b14a149d3..3c3ec8b789 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt @@ -28,23 +28,14 @@ internal fun RoomAvatar( ) } avatarData.url != null || avatarType.heroes.isEmpty() -> { - if (avatarData.url.isNullOrBlank() || hideAvatarImage) { - InitialLetterAvatar( - avatarData = avatarData, - avatarType = avatarType, - modifier = modifier, - contentDescription = contentDescription, - forcedAvatarSize = null, - ) - } else { - ImageAvatar( - avatarData = avatarData, - avatarType = avatarType, - forcedAvatarSize = null, - modifier = modifier, - contentDescription = contentDescription, - ) - } + InitialOrImageAvatar( + avatarData = avatarData, + hideAvatarImage = hideAvatarImage, + avatarType = avatarType, + forcedAvatarSize = null, + modifier = modifier, + contentDescription = contentDescription, + ) } else -> { AvatarCluster( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt index 6f8ec2fda9..e70edb0e21 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt @@ -33,15 +33,9 @@ internal fun SpaceAvatar( modifier = modifier, contentDescription = contentDescription, ) - avatarData.url.isNullOrBlank() || hideAvatarImage -> InitialLetterAvatar( - avatarData = avatarData, - avatarType = avatarType, - modifier = modifier, - contentDescription = contentDescription, - forcedAvatarSize = null, - ) - else -> ImageAvatar( + else -> InitialOrImageAvatar( avatarData = avatarData, + hideAvatarImage = hideAvatarImage, avatarType = avatarType, forcedAvatarSize = null, modifier = modifier, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt index 54b0708078..699b92b3af 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt @@ -19,21 +19,12 @@ internal fun UserAvatar( forcedAvatarSize: Dp? = null, hideImage: Boolean = false, ) { - if (avatarData.url.isNullOrBlank() || hideImage) { - InitialLetterAvatar( - avatarData = avatarData, - avatarType = AvatarType.User, - forcedAvatarSize = forcedAvatarSize, - modifier = modifier, - contentDescription = contentDescription, - ) - } else { - ImageAvatar( - avatarData = avatarData, - avatarType = AvatarType.User, - forcedAvatarSize = forcedAvatarSize, - modifier = modifier, - contentDescription = contentDescription, - ) - } + InitialOrImageAvatar( + avatarData = avatarData, + hideAvatarImage = hideImage, + avatarType = AvatarType.User, + modifier = modifier, + contentDescription = contentDescription, + forcedAvatarSize = forcedAvatarSize, + ) } From 14bb7d3bd1885eb78d83131e686ca23be3974565 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 23 Jun 2025 21:51:56 +0200 Subject: [PATCH 07/19] Provide avatarShape: Shape instead of AvatarType to sub composable functions --- .../designsystem/components/avatar/ImageAvatar.kt | 11 ++++++----- .../components/avatar/InitialLetterAvatar.kt | 5 +++-- .../components/avatar/InitialOrImageAvatar.kt | 7 ++++--- .../designsystem/components/avatar/RoomAvatar.kt | 4 ++-- .../designsystem/components/avatar/SpaceAvatar.kt | 4 ++-- .../designsystem/components/avatar/TextAvatar.kt | 8 +++++--- .../components/avatar/TombstonedRoomAvatar.kt | 8 +++++--- .../designsystem/components/avatar/UserAvatar.kt | 2 +- 8 files changed, 28 insertions(+), 21 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/ImageAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/ImageAvatar.kt index f0161469e5..5d9f124127 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/ImageAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/ImageAvatar.kt @@ -14,6 +14,7 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.Dp import coil3.compose.AsyncImagePainter @@ -24,7 +25,7 @@ import timber.log.Timber @Composable internal fun ImageAvatar( avatarData: AvatarData, - avatarType: AvatarType, + avatarShape: Shape, forcedAvatarSize: Dp?, modifier: Modifier = Modifier, contentDescription: String? = null, @@ -35,8 +36,8 @@ internal fun ImageAvatar( contentDescription = contentDescription, contentScale = ContentScale.Companion.Crop, modifier = modifier - .size(size) - .clip(avatarType.avatarShape()) + .size(size) + .clip(avatarShape) ) { val collectedState by painter.state.collectAsState() when (val state = collectedState) { @@ -50,14 +51,14 @@ internal fun ImageAvatar( } InitialLetterAvatar( avatarData = avatarData, - avatarType = avatarType, + avatarShape = avatarShape, forcedAvatarSize = forcedAvatarSize, contentDescription = contentDescription, ) } else -> InitialLetterAvatar( avatarData = avatarData, - avatarType = avatarType, + avatarShape = avatarShape, forcedAvatarSize = forcedAvatarSize, contentDescription = contentDescription, ) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialLetterAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialLetterAvatar.kt index 2534db52a1..95add851de 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialLetterAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialLetterAvatar.kt @@ -9,13 +9,14 @@ package io.element.android.libraries.designsystem.components.avatar import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.Dp import io.element.android.libraries.designsystem.colors.AvatarColorsProvider @Composable internal fun InitialLetterAvatar( avatarData: AvatarData, - avatarType: AvatarType, + avatarShape: Shape, forcedAvatarSize: Dp?, contentDescription: String?, modifier: Modifier = Modifier, @@ -24,7 +25,7 @@ internal fun InitialLetterAvatar( TextAvatar( text = avatarData.initialLetter, size = forcedAvatarSize ?: avatarData.size.dp, - avatarType = avatarType, + avatarShape = avatarShape, colors = avatarColors, contentDescription = contentDescription, modifier = modifier diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt index e58a9f33c5..ce4282f950 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.designsystem.components.avatar import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.Dp @Composable @@ -16,21 +17,21 @@ internal fun InitialOrImageAvatar( avatarData: AvatarData, hideAvatarImage: Boolean, forcedAvatarSize: Dp?, - avatarType: AvatarType, + avatarShape: Shape, modifier: Modifier, contentDescription: String? ) { when { avatarData.url.isNullOrBlank() || hideAvatarImage -> InitialLetterAvatar( avatarData = avatarData, - avatarType = avatarType, + avatarShape = avatarShape, forcedAvatarSize = forcedAvatarSize, modifier = modifier, contentDescription = contentDescription, ) else -> ImageAvatar( avatarData = avatarData, - avatarType = avatarType, + avatarShape = avatarShape, forcedAvatarSize = forcedAvatarSize, modifier = modifier, contentDescription = contentDescription, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt index 3c3ec8b789..b194262c95 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt @@ -23,7 +23,7 @@ internal fun RoomAvatar( TombstonedRoomAvatar( size = avatarData.size, modifier = modifier, - avatarType = avatarType, + avatarShape = avatarType.avatarShape(), contentDescription = contentDescription ) } @@ -31,7 +31,7 @@ internal fun RoomAvatar( InitialOrImageAvatar( avatarData = avatarData, hideAvatarImage = hideAvatarImage, - avatarType = avatarType, + avatarShape = avatarType.avatarShape(), forcedAvatarSize = null, modifier = modifier, contentDescription = contentDescription, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt index e70edb0e21..45d0bf4cc9 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt @@ -29,14 +29,14 @@ internal fun SpaceAvatar( when { avatarType.isTombstoned -> TombstonedRoomAvatar( size = avatarData.size, - avatarType = avatarType, + avatarShape = avatarType.avatarShape(), modifier = modifier, contentDescription = contentDescription, ) else -> InitialOrImageAvatar( avatarData = avatarData, hideAvatarImage = hideAvatarImage, - avatarType = avatarType, + avatarShape = avatarType.avatarShape(), forcedAvatarSize = null, modifier = modifier, contentDescription = contentDescription, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt index 38200ef8c6..d2963a9a80 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt @@ -13,10 +13,12 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.semantics.clearAndSetSemantics import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.tooling.preview.Preview @@ -36,13 +38,13 @@ internal fun TextAvatar( size: Dp, colors: AvatarColors, contentDescription: String?, - avatarType: AvatarType, + avatarShape: Shape, modifier: Modifier = Modifier, ) { Box( modifier .size(size) - .clip(avatarType.avatarShape()) + .clip(avatarShape) .background(color = colors.background) ) { val fontSize = size.toSp() / 2 @@ -83,7 +85,7 @@ internal fun TextAvatarPreview() = ElementPreview { background = ElementTheme.colors.bgSubtlePrimary, foreground = ElementTheme.colors.iconPrimary, ), - avatarType = avatarType, + avatarShape = CircleShape, contentDescription = null, ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt index 2182c1b63e..7fcbb13ea1 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt @@ -7,8 +7,10 @@ package io.element.android.libraries.designsystem.components.avatar +import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.tooling.preview.Preview import io.element.android.compound.theme.AvatarColors import io.element.android.compound.theme.ElementTheme @@ -18,7 +20,7 @@ import io.element.android.libraries.designsystem.preview.PreviewGroup @Composable internal fun TombstonedRoomAvatar( size: AvatarSize, - avatarType: AvatarType, + avatarShape: Shape, modifier: Modifier = Modifier, contentDescription: String? = null, ) { @@ -30,7 +32,7 @@ internal fun TombstonedRoomAvatar( foreground = ElementTheme.colors.iconTertiary ), modifier = modifier, - avatarType = avatarType, + avatarShape = avatarShape, contentDescription = contentDescription, ) } @@ -40,7 +42,7 @@ internal fun TombstonedRoomAvatar( internal fun TombstonedRoomAvatarPreview() = ElementPreview { TombstonedRoomAvatar( size = AvatarSize.RoomListItem, - avatarType = AvatarType.Room(), + avatarShape = CircleShape, contentDescription = null, ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt index 699b92b3af..1abbadb119 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt @@ -22,7 +22,7 @@ internal fun UserAvatar( InitialOrImageAvatar( avatarData = avatarData, hideAvatarImage = hideImage, - avatarType = AvatarType.User, + avatarShape = AvatarType.User.avatarShape(), modifier = modifier, contentDescription = contentDescription, forcedAvatarSize = forcedAvatarSize, From abd92d05d4a5884fa2a1d98c10065f7523e4fcf2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 23 Jun 2025 21:56:20 +0200 Subject: [PATCH 08/19] Avoid potential infinite loop. --- .../designsystem/components/avatar/AvatarCluster.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt index 4827300394..d2dae9e25c 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt @@ -49,12 +49,13 @@ internal fun AvatarCluster( error("Unsupported number of avatars: 0") } 1 -> { - Avatar( + InitialOrImageAvatar( avatarData = limitedAvatars[0], - avatarType = avatarType, + hideAvatarImage = hideAvatarImages, + avatarShape = avatarType.avatarShape(), + forcedAvatarSize = null, modifier = modifier, contentDescription = contentDescription, - hideImage = hideAvatarImages ) } else -> { From 57ffa2615c944d924e619a0735accb4b5ebf4652 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 23 Jun 2025 22:00:25 +0200 Subject: [PATCH 09/19] Improve preview of AvatarCluster to show all types. --- .../designsystem/components/avatar/Avatar.kt | 2 + .../components/avatar/AvatarCluster.kt | 40 ++++++++++++++----- .../components/avatar/RoomAvatar.kt | 6 ++- .../components/avatar/SpaceAvatar.kt | 6 ++- .../components/avatar/TombstonedRoomAvatar.kt | 8 ++-- 5 files changed, 45 insertions(+), 17 deletions(-) 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 93e458bfcc..ceb6b64528 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 @@ -38,6 +38,7 @@ fun Avatar( avatarType = avatarType, modifier = modifier, hideAvatarImage = hideImage, + forcedAvatarSize = forcedAvatarSize, contentDescription = contentDescription, ) AvatarType.User -> UserAvatar( @@ -52,6 +53,7 @@ fun Avatar( avatarType = avatarType, modifier = modifier, hideAvatarImage = hideImage, + forcedAvatarSize = forcedAvatarSize, contentDescription = contentDescription, ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt index d2dae9e25c..8c1c650aa2 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.designsystem.components.avatar import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.size @@ -98,11 +99,20 @@ internal fun AvatarCluster( y = yOffset, ) ) { - Avatar( + InitialOrImageAvatar( avatarData = heroAvatar, + hideAvatarImage = hideAvatarImages, + avatarShape = avatarType.let { avatarType -> + if (avatarType is AvatarType.Space) { + // Reduce corner size for small Space avatars + avatarType.copy(cornerSize = avatarType.cornerSize / 2f) + } else { + avatarType + } + }.avatarShape(), forcedAvatarSize = heroAvatarSize, - avatarType = avatarType, - hideImage = hideAvatarImages, + modifier = Modifier, + contentDescription = contentDescription, ) } } @@ -114,14 +124,24 @@ internal fun AvatarCluster( @Preview(group = PreviewGroup.Avatars) @Composable internal fun AvatarClusterPreview() = ElementThemedPreview { - Row( - horizontalArrangement = Arrangement.spacedBy(8.dp) + Column( + verticalArrangement = Arrangement.spacedBy(8.dp), ) { - for (ngOfAvatars in 1..5) { - AvatarCluster( - avatars = List(ngOfAvatars) { anAvatarData(it) }.toPersistentList(), - avatarType = AvatarType.User, - ) + listOf( + AvatarType.User, + AvatarType.Room(), + AvatarType.Space(8.dp), + ).forEach { avatarType -> + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + for (ngOfAvatars in 1..5) { + AvatarCluster( + avatars = List(ngOfAvatars) { anAvatarData(it) }.toPersistentList(), + avatarType = avatarType, + ) + } + } } } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt index b194262c95..a27a4e166a 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.designsystem.components.avatar import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp @Composable internal fun RoomAvatar( @@ -16,12 +17,13 @@ internal fun RoomAvatar( avatarType: AvatarType.Room, modifier: Modifier = Modifier, hideAvatarImage: Boolean = false, + forcedAvatarSize: Dp? = null, contentDescription: String? = null, ) { when { avatarType.isTombstoned -> { TombstonedRoomAvatar( - size = avatarData.size, + size = forcedAvatarSize ?: avatarData.size.dp, modifier = modifier, avatarShape = avatarType.avatarShape(), contentDescription = contentDescription @@ -32,7 +34,7 @@ internal fun RoomAvatar( avatarData = avatarData, hideAvatarImage = hideAvatarImage, avatarShape = avatarType.avatarShape(), - forcedAvatarSize = null, + forcedAvatarSize = forcedAvatarSize, modifier = modifier, contentDescription = contentDescription, ) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt index 45d0bf4cc9..bae590c006 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt @@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup @@ -23,12 +24,13 @@ internal fun SpaceAvatar( avatarData: AvatarData, avatarType: AvatarType.Space, modifier: Modifier = Modifier, + forcedAvatarSize: Dp? = null, hideAvatarImage: Boolean = false, contentDescription: String? = null, ) { when { avatarType.isTombstoned -> TombstonedRoomAvatar( - size = avatarData.size, + size = forcedAvatarSize ?: avatarData.size.dp, avatarShape = avatarType.avatarShape(), modifier = modifier, contentDescription = contentDescription, @@ -37,7 +39,7 @@ internal fun SpaceAvatar( avatarData = avatarData, hideAvatarImage = hideAvatarImage, avatarShape = avatarType.avatarShape(), - forcedAvatarSize = null, + forcedAvatarSize = forcedAvatarSize, modifier = modifier, contentDescription = contentDescription, ) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt index 7fcbb13ea1..4610f22514 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt @@ -12,6 +12,8 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp import io.element.android.compound.theme.AvatarColors import io.element.android.compound.theme.ElementTheme import io.element.android.libraries.designsystem.preview.ElementPreview @@ -19,14 +21,14 @@ import io.element.android.libraries.designsystem.preview.PreviewGroup @Composable internal fun TombstonedRoomAvatar( - size: AvatarSize, + size: Dp, avatarShape: Shape, modifier: Modifier = Modifier, contentDescription: String? = null, ) { TextAvatar( text = "!", - size = size.dp, + size = size, colors = AvatarColors( background = ElementTheme.colors.bgSubtlePrimary, foreground = ElementTheme.colors.iconTertiary @@ -41,7 +43,7 @@ internal fun TombstonedRoomAvatar( @Composable internal fun TombstonedRoomAvatarPreview() = ElementPreview { TombstonedRoomAvatar( - size = AvatarSize.RoomListItem, + size = 52.dp, avatarShape = CircleShape, contentDescription = null, ) From e5b7e653727b2f2c08aae9b93cb91ef8bc2aed7f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Jun 2025 09:06:08 +0200 Subject: [PATCH 10/19] Update screenshot --- ...esignsystem.components.avatar_AvatarCluster_Avatars_en.png | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_AvatarCluster_Avatars_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_AvatarCluster_Avatars_en.png index 72b14d9cc3..337db7278a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_AvatarCluster_Avatars_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_AvatarCluster_Avatars_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c6afcae51ee69dcdb9dbf60c8f72e55b9b07e4feb72dfba0a40ffeebed6ab681 -size 25730 +oid sha256:e1f8da07dfd80edeb381f78397114526d732ab1660ba95bd253690112c348cb4 +size 57397 From 69ceceab41c06f9746544771b327e72e3fd33cb4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Jun 2025 09:06:29 +0200 Subject: [PATCH 11/19] Fix regression on preview. --- .../libraries/designsystem/components/avatar/TextAvatar.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt index d2963a9a80..2869d0d6b5 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt @@ -85,7 +85,7 @@ internal fun TextAvatarPreview() = ElementPreview { background = ElementTheme.colors.bgSubtlePrimary, foreground = ElementTheme.colors.iconPrimary, ), - avatarShape = CircleShape, + avatarShape = avatarType.avatarShape(), contentDescription = null, ) } From 8281a9d8ce088f32ff8f95ab918e5b1253cd9ebb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Jun 2025 09:06:39 +0200 Subject: [PATCH 12/19] Quality --- .../android/features/knockrequests/impl/banner/AvatarRow.kt | 1 + .../designsystem/components/avatar/InitialOrImageAvatar.kt | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/AvatarRow.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/AvatarRow.kt index bc0fbbdbeb..992098dc91 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/AvatarRow.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/AvatarRow.kt @@ -37,6 +37,7 @@ import kotlinx.collections.immutable.toImmutableList * Draw a row of avatars (they must all have the same size), from start to end. * @param avatarDataList the avatars to render. Note: they will all be rendered, the caller may * want to limit the list size + * @param avatarType the type of avatars to render * @param modifier Jetpack Compose modifier * @param overlapRatio the overlap ration. When 0f, avatars will render without overlap, when 1f * only the first avatar will be visible diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt index ce4282f950..7c583d3ddf 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt @@ -18,8 +18,8 @@ internal fun InitialOrImageAvatar( hideAvatarImage: Boolean, forcedAvatarSize: Dp?, avatarShape: Shape, - modifier: Modifier, - contentDescription: String? + contentDescription: String?, + modifier: Modifier = Modifier, ) { when { avatarData.url.isNullOrBlank() || hideAvatarImage -> InitialLetterAvatar( From 6161e20f6cda2f10d5cac931ee29c3bdfeeca495 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Jun 2025 09:08:15 +0200 Subject: [PATCH 13/19] Replace `values()` by `entries` --- .../designsystem/components/avatar/AvatarDataProvider.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarDataProvider.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarDataProvider.kt index ea9e749baf..3c209df2cf 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarDataProvider.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarDataProvider.kt @@ -11,7 +11,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider open class AvatarDataProvider : PreviewParameterProvider { override val values: Sequence - get() = AvatarSize.values() + get() = AvatarSize.entries .asSequence() .map { sequenceOf( From 6cbed45acfaf9ebbf23b1f56aa6c7960b6de4065 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Jun 2025 09:12:12 +0200 Subject: [PATCH 14/19] Move internal elements to `internal` package. --- .../libraries/designsystem/components/avatar/Avatar.kt | 3 +++ .../components/avatar/{ => internal}/AvatarCluster.kt | 6 +++++- .../components/avatar/{ => internal}/ImageAvatar.kt | 3 ++- .../components/avatar/{ => internal}/InitialLetterAvatar.kt | 3 ++- .../avatar/{ => internal}/InitialOrImageAvatar.kt | 3 ++- .../components/avatar/{ => internal}/RoomAvatar.kt | 5 ++++- .../components/avatar/{ => internal}/SpaceAvatar.kt | 6 +++++- .../components/avatar/{ => internal}/TextAvatar.kt | 5 +++-- .../avatar/{ => internal}/TombstonedRoomAvatar.kt | 2 +- .../components/avatar/{ => internal}/UserAvatar.kt | 5 ++++- .../components/avatar/{ => internal}/UserAvatarPreview.kt | 5 ++++- 11 files changed, 35 insertions(+), 11 deletions(-) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/{ => internal}/AvatarCluster.kt (94%) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/{ => internal}/ImageAvatar.kt (96%) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/{ => internal}/InitialLetterAvatar.kt (91%) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/{ => internal}/InitialOrImageAvatar.kt (93%) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/{ => internal}/RoomAvatar.kt (87%) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/{ => internal}/SpaceAvatar.kt (87%) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/{ => internal}/TextAvatar.kt (94%) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/{ => internal}/TombstonedRoomAvatar.kt (99%) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/{ => internal}/UserAvatar.kt (77%) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/{ => internal}/UserAvatarPreview.kt (86%) 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 ceb6b64528..db7ef62483 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 @@ -16,6 +16,9 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.components.avatar.internal.RoomAvatar +import io.element.android.libraries.designsystem.components.avatar.internal.SpaceAvatar +import io.element.android.libraries.designsystem.components.avatar.internal.UserAvatar import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.theme.components.Text diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/AvatarCluster.kt similarity index 94% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/AvatarCluster.kt index 8c1c650aa2..940917ecfd 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/AvatarCluster.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.designsystem.components.avatar +package io.element.android.libraries.designsystem.components.avatar.internal import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -20,6 +20,10 @@ import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarType +import io.element.android.libraries.designsystem.components.avatar.anAvatarData +import io.element.android.libraries.designsystem.components.avatar.avatarShape import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import kotlinx.collections.immutable.ImmutableList diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/ImageAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt similarity index 96% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/ImageAvatar.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt index 5d9f124127..db30a94830 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/ImageAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.designsystem.components.avatar +package io.element.android.libraries.designsystem.components.avatar.internal import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable @@ -20,6 +20,7 @@ import androidx.compose.ui.unit.Dp import coil3.compose.AsyncImagePainter import coil3.compose.SubcomposeAsyncImage import coil3.compose.SubcomposeAsyncImageContent +import io.element.android.libraries.designsystem.components.avatar.AvatarData import timber.log.Timber @Composable diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialLetterAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/InitialLetterAvatar.kt similarity index 91% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialLetterAvatar.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/InitialLetterAvatar.kt index 95add851de..6503917b23 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialLetterAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/InitialLetterAvatar.kt @@ -5,13 +5,14 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.designsystem.components.avatar +package io.element.android.libraries.designsystem.components.avatar.internal import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.Dp import io.element.android.libraries.designsystem.colors.AvatarColorsProvider +import io.element.android.libraries.designsystem.components.avatar.AvatarData @Composable internal fun InitialLetterAvatar( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/InitialOrImageAvatar.kt similarity index 93% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/InitialOrImageAvatar.kt index 7c583d3ddf..3111048d3b 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/InitialOrImageAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/InitialOrImageAvatar.kt @@ -5,12 +5,13 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.designsystem.components.avatar +package io.element.android.libraries.designsystem.components.avatar.internal import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.Dp +import io.element.android.libraries.designsystem.components.avatar.AvatarData @Composable internal fun InitialOrImageAvatar( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/RoomAvatar.kt similarity index 87% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/RoomAvatar.kt index a27a4e166a..9fd2ff8cca 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/RoomAvatar.kt @@ -5,11 +5,14 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.designsystem.components.avatar +package io.element.android.libraries.designsystem.components.avatar.internal import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.Dp +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarType +import io.element.android.libraries.designsystem.components.avatar.avatarShape @Composable internal fun RoomAvatar( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/SpaceAvatar.kt similarity index 87% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/SpaceAvatar.kt index bae590c006..8f5635105d 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/SpaceAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/SpaceAvatar.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.designsystem.components.avatar +package io.element.android.libraries.designsystem.components.avatar.internal import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row @@ -15,6 +15,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarType +import io.element.android.libraries.designsystem.components.avatar.anAvatarData +import io.element.android.libraries.designsystem.components.avatar.avatarShape import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.utils.CommonDrawables diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/TextAvatar.kt similarity index 94% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/TextAvatar.kt index 2869d0d6b5..c5ce75ad5a 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/TextAvatar.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.designsystem.components.avatar +package io.element.android.libraries.designsystem.components.avatar.internal import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement @@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -27,6 +26,8 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import io.element.android.compound.theme.AvatarColors import io.element.android.compound.theme.ElementTheme +import io.element.android.libraries.designsystem.components.avatar.AvatarType +import io.element.android.libraries.designsystem.components.avatar.avatarShape import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.text.toSp diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/TombstonedRoomAvatar.kt similarity index 99% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/TombstonedRoomAvatar.kt index 4610f22514..b712ff9fb1 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/TombstonedRoomAvatar.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.designsystem.components.avatar +package io.element.android.libraries.designsystem.components.avatar.internal import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/UserAvatar.kt similarity index 77% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/UserAvatar.kt index 1abbadb119..ad0275593d 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/UserAvatar.kt @@ -5,11 +5,14 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.designsystem.components.avatar +package io.element.android.libraries.designsystem.components.avatar.internal import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.Dp +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarType +import io.element.android.libraries.designsystem.components.avatar.avatarShape @Composable internal fun UserAvatar( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/UserAvatarPreview.kt similarity index 86% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/UserAvatarPreview.kt index f3b55e53d2..d4a629a052 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/UserAvatarPreview.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.designsystem.components.avatar +package io.element.android.libraries.designsystem.components.avatar.internal import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -16,6 +16,9 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import io.element.android.compound.theme.avatarColors +import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.components.avatar.AvatarType +import io.element.android.libraries.designsystem.components.avatar.anAvatarData import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Text From cadca03a7e7f2e6f30e5983ecb781e8c8ad95661 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Jun 2025 09:18:28 +0200 Subject: [PATCH 15/19] Add preview with an image. --- .../user/editprofile/EditUserProfileStateProvider.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt index 298fd8cb17..0e4c1b4f2d 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt @@ -7,7 +7,9 @@ package io.element.android.features.preferences.impl.user.editprofile +import android.net.Uri import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.core.net.toUri import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.permissions.api.aPermissionsState @@ -17,14 +19,17 @@ open class EditUserProfileStateProvider : PreviewParameterProvider get() = sequenceOf( aEditUserProfileState(), + aEditUserProfileState(userAvatarUrl = "example://uri".toUri()), // Add other states here ) } -fun aEditUserProfileState() = EditUserProfileState( +fun aEditUserProfileState( + userAvatarUrl: Uri? = null, +) = EditUserProfileState( userId = UserId("@john.doe:matrix.org"), displayName = "John Doe", - userAvatarUrl = null, + userAvatarUrl = userAvatarUrl, avatarActions = persistentListOf(), saveAction = AsyncAction.Uninitialized, saveButtonEnabled = true, From 045ca6fbb21756890cd26b5d8ae049b28df7dbb7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Jun 2025 09:49:21 +0200 Subject: [PATCH 16/19] Ensure AvatarSize is correctly used in UnsavedAvatar, instead of hard coded size. --- .../impl/configureroom/ConfigureRoomView.kt | 2 ++ .../matrix/ui/components/EditableAvatarView.kt | 12 +++++++----- .../matrix/ui/components/UnsavedAvatar.kt | 14 ++++++++------ 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt index afc6ef0bde..f68f434707 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt @@ -40,6 +40,7 @@ import io.element.android.libraries.designsystem.atomic.atoms.RoundedIconAtom import io.element.android.libraries.designsystem.atomic.atoms.RoundedIconAtomSize import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults +import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.list.ListItemContent @@ -220,6 +221,7 @@ private fun RoomNameWithAvatar( ) { UnsavedAvatar( avatarUri = avatarUri, + avatarSize = AvatarSize.EditRoomDetails, avatarType = AvatarType.Room(), modifier = Modifier.clickable(onClick = onAvatarClick), ) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt index 8412c18826..3b8b6831ca 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt @@ -13,7 +13,6 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape @@ -61,7 +60,6 @@ fun EditableAvatarView( val a11yAvatar = stringResource(CommonStrings.a11y_avatar) Box( modifier = Modifier - .size(avatarSize.dp) .clickable( interactionSource = remember { MutableInteractionSource() }, onClick = onAvatarClick, @@ -75,16 +73,20 @@ fun EditableAvatarView( when (avatarUrl?.scheme) { null, "mxc" -> { Avatar( - avatarData = AvatarData(matrixId, displayName, avatarUrl?.toString(), size = avatarSize), + avatarData = AvatarData( + id = matrixId, + name = displayName, + url = avatarUrl?.toString(), + size = avatarSize, + ), avatarType = avatarType, - modifier = Modifier.fillMaxSize(), ) } else -> { UnsavedAvatar( avatarUri = avatarUrl, + avatarSize = avatarSize, avatarType = avatarType, - modifier = Modifier.fillMaxSize(), ) } } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt index 5a9ee72c75..db26ecb8da 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt @@ -28,6 +28,7 @@ import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import coil3.request.ImageRequest import io.element.android.compound.theme.ElementTheme +import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.avatar.avatarShape import io.element.android.libraries.designsystem.preview.ElementPreview @@ -43,11 +44,12 @@ import io.element.android.libraries.designsystem.theme.temporaryColorBgSpecial @Composable fun UnsavedAvatar( avatarUri: Uri?, + avatarSize: AvatarSize, avatarType: AvatarType, modifier: Modifier = Modifier, ) { val commonModifier = modifier - .size(70.dp) + .size(avatarSize.dp) .clip(avatarType.avatarShape()) if (avatarUri != null) { @@ -69,7 +71,7 @@ fun UnsavedAvatar( contentDescription = null, modifier = Modifier .align(Alignment.Center) - .size(40.dp), + .size(avatarSize.dp * 4 / 7), tint = ElementTheme.colors.iconSecondary, ) } @@ -83,9 +85,9 @@ internal fun UnsavedAvatarPreview() = ElementPreview { modifier = Modifier.padding(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), ) { - UnsavedAvatar(null, AvatarType.User) - UnsavedAvatar(Uri.EMPTY, AvatarType.User) - UnsavedAvatar(null, AvatarType.Space(8.dp)) - UnsavedAvatar(Uri.EMPTY, AvatarType.Space(8.dp)) + UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.User) + UnsavedAvatar(Uri.EMPTY, AvatarSize.EditRoomDetails, AvatarType.User) + UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.Space(8.dp)) + UnsavedAvatar(Uri.EMPTY, AvatarSize.EditRoomDetails, AvatarType.Space(8.dp)) } } From 0f4939b689ff0ab13fea5a1845436731c82523cf Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 24 Jun 2025 08:10:17 +0000 Subject: [PATCH 17/19] Update screenshots --- ...nces.impl.user.editprofile_EditUserProfileView_Day_1_en.png | 3 +++ ...es.impl.user.editprofile_EditUserProfileView_Night_1_en.png | 3 +++ ...em.components.avatar.internal_AvatarCluster_Avatars_en.png} | 0 ...stem.components.avatar.internal_SpaceAvatar_Avatars_en.png} | 0 ...ystem.components.avatar.internal_TextAvatar_Avatars_en.png} | 0 ...onents.avatar.internal_TombstonedRoomAvatar_Avatars_en.png} | 0 ...m.components.avatar.internal_UserAvatarColors_Day_0_en.png} | 0 ...components.avatar.internal_UserAvatarColors_Night_0_en.png} | 0 8 files changed, 6 insertions(+) create mode 100644 tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png rename tests/uitests/src/test/snapshots/images/{libraries.designsystem.components.avatar_AvatarCluster_Avatars_en.png => libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{libraries.designsystem.components.avatar_SpaceAvatar_Avatars_en.png => libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{libraries.designsystem.components.avatar_TextAvatar_Avatars_en.png => libraries.designsystem.components.avatar.internal_TextAvatar_Avatars_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{libraries.designsystem.components.avatar_TombstonedRoomAvatar_Avatars_en.png => libraries.designsystem.components.avatar.internal_TombstonedRoomAvatar_Avatars_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{libraries.designsystem.components.avatar_UserAvatarColors_Day_0_en.png => libraries.designsystem.components.avatar.internal_UserAvatarColors_Day_0_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{libraries.designsystem.components.avatar_UserAvatarColors_Night_0_en.png => libraries.designsystem.components.avatar.internal_UserAvatarColors_Night_0_en.png} (100%) diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png new file mode 100644 index 0000000000..cd12b08a00 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69fdae3edcd02635868f209a2c1ff21ce807ffb4c6d44dcf89fb0f54e1b9c1f3 +size 68396 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png new file mode 100644 index 0000000000..5d291def2f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6da7fb8d713d5d8255593f2007edf068870dbd05225fe2c0562d197a1739b876 +size 67313 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_AvatarCluster_Avatars_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_AvatarCluster_Avatars_en.png rename to tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_SpaceAvatar_Avatars_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_SpaceAvatar_Avatars_en.png rename to tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_TextAvatar_Avatars_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_TextAvatar_Avatars_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_TextAvatar_Avatars_en.png rename to tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_TextAvatar_Avatars_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_TombstonedRoomAvatar_Avatars_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_TombstonedRoomAvatar_Avatars_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_TombstonedRoomAvatar_Avatars_en.png rename to tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_TombstonedRoomAvatar_Avatars_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_UserAvatarColors_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_UserAvatarColors_Day_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_UserAvatarColors_Day_0_en.png rename to tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_UserAvatarColors_Day_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_UserAvatarColors_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_UserAvatarColors_Night_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_UserAvatarColors_Night_0_en.png rename to tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_UserAvatarColors_Night_0_en.png From b8f22fc3eb8b83a824a261495876cb8271a7c434 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Jun 2025 11:00:53 +0200 Subject: [PATCH 18/19] Space avatar rounded corner has radius of 25% of the width. --- .../components/avatar/AvatarShape.kt | 18 ++++++++++++++---- .../components/avatar/AvatarType.kt | 2 -- .../avatar/internal/AvatarCluster.kt | 13 +++---------- .../components/avatar/internal/SpaceAvatar.kt | 10 +++++----- .../components/avatar/internal/TextAvatar.kt | 4 ++-- .../matrix/ui/components/UnsavedAvatar.kt | 6 +++--- 6 files changed, 27 insertions(+), 26 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarShape.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarShape.kt index 8f80286abf..c4c2c77766 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarShape.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarShape.kt @@ -11,12 +11,22 @@ import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.unit.Dp @Composable -fun AvatarType.avatarShape(): Shape { +fun AvatarType.User.avatarShape() = CircleShape + +@Composable +fun AvatarType.Room.avatarShape() = CircleShape + +@Composable +fun AvatarType.Space.avatarShape(avatarSize: Dp) = RoundedCornerShape(avatarSize * 0.25f) + +@Composable +fun AvatarType.avatarShape(avatarSize: Dp): Shape { return when (this) { - is AvatarType.Space -> RoundedCornerShape(cornerSize) - is AvatarType.Room, - AvatarType.User -> CircleShape + is AvatarType.Space -> avatarShape(avatarSize) + is AvatarType.Room -> avatarShape() + is AvatarType.User -> avatarShape() } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarType.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarType.kt index 720a0b0e6a..6d99574a55 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarType.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarType.kt @@ -8,7 +8,6 @@ package io.element.android.libraries.designsystem.components.avatar import androidx.compose.runtime.Immutable -import androidx.compose.ui.unit.Dp import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -22,7 +21,6 @@ sealed interface AvatarType { ) : AvatarType data class Space( - val cornerSize: Dp, val isTombstoned: Boolean = false, ) : AvatarType } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/AvatarCluster.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/AvatarCluster.kt index 940917ecfd..c100988053 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/AvatarCluster.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/AvatarCluster.kt @@ -57,7 +57,7 @@ internal fun AvatarCluster( InitialOrImageAvatar( avatarData = limitedAvatars[0], hideAvatarImage = hideAvatarImages, - avatarShape = avatarType.avatarShape(), + avatarShape = avatarType.avatarShape(limitedAvatars[0].size.dp), forcedAvatarSize = null, modifier = modifier, contentDescription = contentDescription, @@ -106,14 +106,7 @@ internal fun AvatarCluster( InitialOrImageAvatar( avatarData = heroAvatar, hideAvatarImage = hideAvatarImages, - avatarShape = avatarType.let { avatarType -> - if (avatarType is AvatarType.Space) { - // Reduce corner size for small Space avatars - avatarType.copy(cornerSize = avatarType.cornerSize / 2f) - } else { - avatarType - } - }.avatarShape(), + avatarShape = avatarType.avatarShape(heroAvatarSize), forcedAvatarSize = heroAvatarSize, modifier = Modifier, contentDescription = contentDescription, @@ -134,7 +127,7 @@ internal fun AvatarClusterPreview() = ElementThemedPreview { listOf( AvatarType.User, AvatarType.Room(), - AvatarType.Space(8.dp), + AvatarType.Space(), ).forEach { avatarType -> Row( horizontalArrangement = Arrangement.spacedBy(8.dp) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/SpaceAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/SpaceAvatar.kt index 8f5635105d..b8880744c9 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/SpaceAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/SpaceAvatar.kt @@ -32,17 +32,18 @@ internal fun SpaceAvatar( hideAvatarImage: Boolean = false, contentDescription: String? = null, ) { + val size = forcedAvatarSize ?: avatarData.size.dp when { avatarType.isTombstoned -> TombstonedRoomAvatar( - size = forcedAvatarSize ?: avatarData.size.dp, - avatarShape = avatarType.avatarShape(), + size = size, + avatarShape = avatarType.avatarShape(size), modifier = modifier, contentDescription = contentDescription, ) else -> InitialOrImageAvatar( avatarData = avatarData, hideAvatarImage = hideAvatarImage, - avatarShape = avatarType.avatarShape(), + avatarShape = avatarType.avatarShape(size), forcedAvatarSize = forcedAvatarSize, modifier = modifier, contentDescription = contentDescription, @@ -62,12 +63,11 @@ internal fun SpaceAvatarPreview() = ) { SpaceAvatar( avatarData = anAvatarData(), - avatarType = AvatarType.Space(cornerSize = 16.dp), + avatarType = AvatarType.Space(), ) SpaceAvatar( avatarData = anAvatarData(), avatarType = AvatarType.Space( - cornerSize = 16.dp, isTombstoned = true, ), ) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/TextAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/TextAvatar.kt index c5ce75ad5a..f44319fece 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/TextAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/TextAvatar.kt @@ -77,7 +77,7 @@ internal fun TextAvatarPreview() = ElementPreview { listOf( AvatarType.User, AvatarType.Room(), - AvatarType.Space(8.dp), + AvatarType.Space(), ).forEach { avatarType -> TextAvatar( text = "AB", @@ -86,7 +86,7 @@ internal fun TextAvatarPreview() = ElementPreview { background = ElementTheme.colors.bgSubtlePrimary, foreground = ElementTheme.colors.iconPrimary, ), - avatarShape = avatarType.avatarShape(), + avatarShape = avatarType.avatarShape(40.dp), contentDescription = null, ) } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt index db26ecb8da..1e041a69fe 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt @@ -50,7 +50,7 @@ fun UnsavedAvatar( ) { val commonModifier = modifier .size(avatarSize.dp) - .clip(avatarType.avatarShape()) + .clip(avatarType.avatarShape(avatarSize.dp)) if (avatarUri != null) { val context = LocalContext.current @@ -87,7 +87,7 @@ internal fun UnsavedAvatarPreview() = ElementPreview { ) { UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.User) UnsavedAvatar(Uri.EMPTY, AvatarSize.EditRoomDetails, AvatarType.User) - UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.Space(8.dp)) - UnsavedAvatar(Uri.EMPTY, AvatarSize.EditRoomDetails, AvatarType.Space(8.dp)) + UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.Space()) + UnsavedAvatar(Uri.EMPTY, AvatarSize.EditRoomDetails, AvatarType.Space()) } } From f92b64660515d3325a34ba3cd06f12e4821c5286 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 24 Jun 2025 09:13:33 +0000 Subject: [PATCH 19/19] Update screenshots --- ...em.components.avatar.internal_AvatarCluster_Avatars_en.png | 4 ++-- ...stem.components.avatar.internal_SpaceAvatar_Avatars_en.png | 4 ++-- ...ystem.components.avatar.internal_TextAvatar_Avatars_en.png | 4 ++-- .../libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png | 4 ++-- ...ibraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en.png index 337db7278a..53b5d638de 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e1f8da07dfd80edeb381f78397114526d732ab1660ba95bd253690112c348cb4 -size 57397 +oid sha256:3c7a7b64a83f68670c0c38eac2782ad5121fe18638c6a21f3b868d0cb4820c7c +size 59391 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en.png index 1cd1400485..30ccebfb08 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d61143149a23cbb1549ee11b1ad00fd4eee16d173407bc847bde91c39cd1b5bc -size 9178 +oid sha256:57545d6b9690b892859f7bf2d2aa92d3fdc1a3ae7b4849e39cf6df10bb0dbbb4 +size 8719 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_TextAvatar_Avatars_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_TextAvatar_Avatars_en.png index faa0713a56..48fa2bbb5a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_TextAvatar_Avatars_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar.internal_TextAvatar_Avatars_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0b632082558328aa485712b8684016a84a9d1eaba7f96cd92b47d364e6c9169f -size 7981 +oid sha256:def7dc550efea75745153ad0cf71c7d92905205549965ba1f192ee3612cec9c4 +size 8041 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png index 38e8527fe3..31eecc07a5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e20e9a7264a6784fbaf6525e73a07318abd27bcf025541b880fd27ac0cca4ba4 -size 69466 +oid sha256:82c54bb785e7c2c301109f25b59e527193e1c786fdfda1252b82702c685cfd7d +size 68516 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png index 05dae22db7..2811748c8f 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:991318dc36c1e6b86a753241638c36adafb896f852f4d5d0e15dd251fa025311 -size 68974 +oid sha256:ca5be5bfe66000d7730a9405ffb2992644f638fb58b28ac3f647c0c242ed8c4d +size 68007