diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index 065c81e407..cc3d571735 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -86,12 +86,14 @@ import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType +import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.matrix.ui.room.canCall import io.element.android.libraries.matrix.ui.room.canRedactOtherAsState import io.element.android.libraries.matrix.ui.room.canRedactOwnAsState import io.element.android.libraries.matrix.ui.room.canSendMessageAsState import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -151,6 +153,9 @@ class MessagesPresenter @AssistedInject constructor( val roomAvatar: AsyncData by remember { derivedStateOf { roomInfo?.avatarData()?.let { AsyncData.Success(it) } ?: AsyncData.Uninitialized } } + val heroes by remember { + derivedStateOf { roomInfo?.heroes().orEmpty().toPersistentList() } + } var hasDismissedInviteDialog by rememberSaveable { mutableStateOf(false) @@ -217,6 +222,7 @@ class MessagesPresenter @AssistedInject constructor( roomId = room.roomId, roomName = roomName, roomAvatar = roomAvatar, + heroes = heroes, userHasPermissionToSendMessage = userHasPermissionToSendMessage, userHasPermissionToRedactOwn = userHasPermissionToRedactOwn, userHasPermissionToRedactOther = userHasPermissionToRedactOther, @@ -250,6 +256,12 @@ class MessagesPresenter @AssistedInject constructor( ) } + private fun MatrixRoomInfo.heroes(): List { + return heroes.map { user -> + user.getAvatarData(size = AvatarSize.TimelineRoom) + } + } + private fun CoroutineScope.handleTimelineAction( action: TimelineItemAction, targetEvent: TimelineItem.Event, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt index 752aa94a9f..e8657d70bd 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt @@ -29,12 +29,14 @@ import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage import io.element.android.libraries.matrix.api.core.RoomId +import kotlinx.collections.immutable.ImmutableList @Immutable data class MessagesState( val roomId: RoomId, val roomName: AsyncData, val roomAvatar: AsyncData, + val heroes: ImmutableList, val userHasPermissionToSendMessage: Boolean, val userHasPermissionToRedactOwn: Boolean, val userHasPermissionToRedactOther: Boolean, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt index 526edfb1e7..1396d3e17c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt @@ -99,8 +99,8 @@ fun aMessagesState( userHasPermissionToSendReaction: Boolean = true, composerState: MessageComposerState = aMessageComposerState( textEditorState = TextEditorState.Rich(aRichTextEditorState(initialText = "Hello", initialFocus = true)), - isFullScreen = false, - mode = MessageComposerMode.Normal, + isFullScreen = false, + mode = MessageComposerMode.Normal, ), voiceMessageComposerState: VoiceMessageComposerState = aVoiceMessageComposerState(), timelineState: TimelineState = aTimelineState( @@ -121,6 +121,7 @@ fun aMessagesState( roomId = RoomId("!id:domain"), roomName = roomName, roomAvatar = roomAvatar, + heroes = persistentListOf(), userHasPermissionToSendMessage = userHasPermissionToSendMessage, userHasPermissionToRedactOwn = userHasPermissionToRedactOwn, userHasPermissionToRedactOther = userHasPermissionToRedactOther, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index b8997865ce..2da1d64642 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -83,9 +83,9 @@ import io.element.android.libraries.androidutils.ui.hideKeyboard import io.element.android.libraries.designsystem.atomic.molecules.IconTitlePlaceholdersRowMolecule import io.element.android.libraries.designsystem.components.ProgressDialog import io.element.android.libraries.designsystem.components.ProgressDialogType -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.CompositeAvatar 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 @@ -187,6 +187,7 @@ fun MessagesView( MessagesViewTopBar( roomName = state.roomName.dataOrNull(), roomAvatar = state.roomAvatar.dataOrNull(), + heroes = state.heroes, callState = state.callState, onBackClick = { // Since the textfield is now based on an Android view, this is no longer done automatically. @@ -442,6 +443,7 @@ private fun MessagesViewComposerBottomSheetContents( private fun MessagesViewTopBar( roomName: String?, roomAvatar: AvatarData?, + heroes: ImmutableList, callState: RoomCallState, onRoomDetailsClick: () -> Unit, onJoinCallClick: () -> Unit, @@ -457,6 +459,7 @@ private fun MessagesViewTopBar( RoomAvatarAndNameRow( roomName = roomName, roomAvatar = roomAvatar, + heroes = heroes, modifier = titleModifier ) } else { @@ -500,13 +503,17 @@ private fun CallMenuItem( private fun RoomAvatarAndNameRow( roomName: String, roomAvatar: AvatarData, + heroes: ImmutableList, modifier: Modifier = Modifier ) { Row( modifier = modifier, verticalAlignment = Alignment.CenterVertically ) { - Avatar(roomAvatar) + CompositeAvatar( + avatarData = roomAvatar, + heroes = heroes, + ) Spacer(modifier = Modifier.width(8.dp)) Text( text = roomName, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/mentions/MentionSuggestionsPickerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/mentions/MentionSuggestionsPickerView.kt index 9af2407657..48c626680e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/mentions/MentionSuggestionsPickerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/mentions/MentionSuggestionsPickerView.kt @@ -93,14 +93,14 @@ private fun RoomMemberSuggestionItemView( modifier: Modifier = Modifier, ) { Row(modifier = modifier.clickable { onSelectSuggestion(memberSuggestion) }, horizontalArrangement = Arrangement.spacedBy(16.dp)) { - val avatarSize = AvatarSize.TimelineRoom val avatarData = when (memberSuggestion) { - is ResolvedMentionSuggestion.AtRoom -> roomAvatar?.copy(size = avatarSize) ?: AvatarData(roomId, roomName, null, avatarSize) + is ResolvedMentionSuggestion.AtRoom -> roomAvatar?.copy(size = AvatarSize.Suggestion) + ?: AvatarData(roomId, roomName, null, AvatarSize.Suggestion) is ResolvedMentionSuggestion.Member -> AvatarData( - memberSuggestion.roomMember.userId.value, - memberSuggestion.roomMember.displayName, - memberSuggestion.roomMember.avatarUrl, - avatarSize, + id = memberSuggestion.roomMember.userId.value, + name = memberSuggestion.roomMember.displayName, + url = memberSuggestion.roomMember.avatarUrl, + size = AvatarSize.Suggestion, ) } val title = when (memberSuggestion) { diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt index f13aa90c4d..c69970bd3f 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt @@ -25,9 +25,8 @@ import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.tooling.preview.PreviewParameter import io.element.android.features.preferences.impl.R 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.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.CompositeAvatar import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory import io.element.android.libraries.designsystem.components.preferences.PreferencePage @@ -37,7 +36,9 @@ import io.element.android.libraries.designsystem.theme.components.ListItem import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.collections.immutable.toPersistentList /** * A view that allows a user to edit the default notification setting for rooms. This can be set separately @@ -96,12 +97,6 @@ fun EditDefaultNotificationSettingView( RoomNotificationMode.MUTE -> stringResource(id = CommonStrings.common_mute) null -> "" } - val avatarData = AvatarData( - id = summary.identifier(), - name = summary.details.name, - url = summary.details.avatarUrl, - size = AvatarSize.CustomRoomNotificationSetting, - ) ListItem( headlineContent = { val roomName = summary.details.name @@ -114,7 +109,12 @@ fun EditDefaultNotificationSettingView( Text(text = subtitle) }, leadingContent = ListItemContent.Custom { - Avatar(avatarData = avatarData) + CompositeAvatar( + avatarData = summary.details.getAvatarData(size = AvatarSize.CustomRoomNotificationSetting), + heroes = summary.details.heroes.map { user -> + user.getAvatarData(size = AvatarSize.CustomRoomNotificationSetting) + }.toPersistentList() + ) }, onClick = { openRoomNotificationSettings(summary.details.roomId) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt index 167c301a35..d191ef2eee 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt @@ -109,7 +109,7 @@ fun EditUserProfileView( matrixId = state.userId.value, displayName = state.displayName, avatarUrl = state.userAvatarUrl, - avatarSize = AvatarSize.RoomHeader, + avatarSize = AvatarSize.EditProfileDetails, onAvatarClick = { onAvatarClick() }, modifier = Modifier.align(Alignment.CenterHorizontally), ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt index 966dade2c3..3d07ea3e63 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt @@ -49,6 +49,7 @@ import io.element.android.libraries.matrix.ui.room.getDirectRoomMember import io.element.android.libraries.matrix.ui.room.isOwnUserAdmin import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analyticsproviders.api.trackers.captureInteraction +import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -151,6 +152,7 @@ class RoomDetailsPresenter @Inject constructor( isFavorite = isFavorite, displayRolesAndPermissionsSettings = !room.isDm && isUserAdmin, isPublic = isPublic, + heroes = roomInfo?.heroes.orEmpty().toPersistentList(), eventSink = ::handleEvents, ) } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt index aee1694e93..787aa79741 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt @@ -23,6 +23,8 @@ import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomNotificationSettings +import io.element.android.libraries.matrix.api.user.MatrixUser +import kotlinx.collections.immutable.ImmutableList data class RoomDetailsState( val roomId: RoomId, @@ -43,6 +45,7 @@ data class RoomDetailsState( val isFavorite: Boolean, val displayRolesAndPermissionsSettings: Boolean, val isPublic: Boolean, + val heroes: ImmutableList, val eventSink: (RoomDetailsEvent) -> Unit ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt index f970b80d82..6c3e9bdac0 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt @@ -28,6 +28,9 @@ import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembershipState import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationSettings +import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.ui.components.aMatrixUserList +import kotlinx.collections.immutable.toPersistentList open class RoomDetailsStateProvider : PreviewParameterProvider { override val values: Sequence @@ -48,6 +51,7 @@ open class RoomDetailsStateProvider : PreviewParameterProvider ), aRoomDetailsState(canCall = false, canInvite = false), aRoomDetailsState(isPublic = false), + aRoomDetailsState(heroes = aMatrixUserList()), // Add other state here ) } @@ -99,6 +103,7 @@ fun aRoomDetailsState( isFavorite: Boolean = false, displayAdminSettings: Boolean = false, isPublic: Boolean = true, + heroes: List = emptyList(), eventSink: (RoomDetailsEvent) -> Unit = {}, ) = RoomDetailsState( roomId = roomId, @@ -119,6 +124,7 @@ fun aRoomDetailsState( isFavorite = isFavorite, displayRolesAndPermissionsSettings = displayAdminSettings, isPublic = isPublic, + heroes = heroes.toPersistentList(), eventSink = eventSink ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index 078e1f6def..56838c534a 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -26,7 +26,6 @@ import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons @@ -54,9 +53,9 @@ import io.element.android.features.userprofile.shared.blockuser.BlockUserDialogs import io.element.android.features.userprofile.shared.blockuser.BlockUserSection import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage import io.element.android.libraries.designsystem.components.ClickableLinkText -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.CompositeAvatar import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.button.MainActionButton import io.element.android.libraries.designsystem.components.list.ListItemContent @@ -81,9 +80,13 @@ import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.getBestName +import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toPersistentList @Composable fun RoomDetailsView( @@ -127,6 +130,7 @@ fun RoomDetailsView( roomAlias = state.roomAlias, isEncrypted = state.isEncrypted, isPublic = state.isPublic, + heroes = state.heroes, openAvatarPreview = { avatarUrl -> openAvatarPreview(state.roomName, avatarUrl) }, @@ -324,6 +328,7 @@ private fun RoomHeaderSection( roomAlias: RoomAlias?, isEncrypted: Boolean, isPublic: Boolean, + heroes: ImmutableList, openAvatarPreview: (url: String) -> Unit, ) { Column( @@ -332,10 +337,12 @@ private fun RoomHeaderSection( .padding(horizontal = 16.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { - Avatar( + CompositeAvatar( avatarData = AvatarData(roomId.value, roomName, avatarUrl, AvatarSize.RoomHeader), + heroes = heroes.map { user -> + user.getAvatarData(size = AvatarSize.RoomHeader) + }.toPersistentList(), modifier = Modifier - .size(70.dp) .clickable(enabled = avatarUrl != null) { openAvatarPreview(avatarUrl!!) } .testTag(TestTags.roomDetailAvatar) ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index 488286ce00..b12ecf4ec8 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -67,7 +67,7 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.api.room.RoomMember -import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.api.room.toMatrixUser import io.element.android.libraries.matrix.ui.components.MatrixUserRow import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList @@ -276,11 +276,7 @@ private fun RoomMemberListItem( } MatrixUserRow( modifier = modifier.clickable(onClick = onClick), - matrixUser = MatrixUser( - userId = roomMember.userId, - displayName = roomMember.displayName, - avatarUrl = roomMember.avatarUrl, - ), + matrixUser = roomMember.toMatrixUser(), avatarSize = AvatarSize.UserListItem, trailingContent = roleText?.let { @Composable { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationView.kt index 03c602fdd4..a96e4ef46f 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationView.kt @@ -45,7 +45,6 @@ import io.element.android.libraries.designsystem.components.async.AsyncIndicator import io.element.android.libraries.designsystem.components.async.AsyncIndicatorHost 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.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog import io.element.android.libraries.designsystem.components.list.ListItemContent @@ -59,6 +58,7 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.getBestName +import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.launch @@ -217,12 +217,7 @@ private fun RoomMemberActionsBottomSheet( modifier = Modifier.padding(vertical = 16.dp) ) { Avatar( - avatarData = AvatarData( - id = roomMember.userId.value, - name = roomMember.displayName, - url = roomMember.avatarUrl, - size = AvatarSize.RoomListManageUser, - ), + avatarData = roomMember.getAvatarData(size = AvatarSize.RoomListManageUser), modifier = Modifier .padding(bottom = 28.dp) .align(Alignment.CenterHorizontally) 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 f5b1873717..d89ad29b78 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 @@ -81,6 +81,7 @@ import io.element.android.libraries.matrix.api.room.getBestName import io.element.android.libraries.matrix.api.room.toMatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.ui.components.SelectedUsersRowList +import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList @@ -327,7 +328,7 @@ private fun ListMemberItem( } MemberRow( modifier = Modifier.clickable(enabled = canToggle, onClick = { onToggleSelection(roomMember) }), - avatarData = AvatarData(roomMember.userId.value, roomMember.displayName, roomMember.avatarUrl, AvatarSize.UserListItem), + avatarData = roomMember.getAvatarData(size = AvatarSize.UserListItem), name = roomMember.getBestName(), userId = roomMember.userId.value.takeIf { roomMember.displayName?.isNotBlank() == true }, isPending = roomMember.membership == RoomMembershipState.INVITE, diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsViewTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsViewTest.kt index 62dbac449c..dc1c1735cb 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsViewTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsViewTest.kt @@ -126,6 +126,7 @@ class RoomDetailsViewTest { } } + @Config(qualifiers = "h1024dp") @Test fun `click on add topic emit expected event`() { ensureCalledOnceWithParam(RoomDetailsAction.AddTopic) { callback -> diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt index d90faef985..f7602faa16 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt @@ -53,7 +53,7 @@ import io.element.android.features.roomlist.impl.model.RoomListRoomSummaryProvid import io.element.android.features.roomlist.impl.model.RoomSummaryDisplayType import io.element.android.libraries.core.extensions.orEmpty import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom -import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.components.avatar.CompositeAvatar 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 @@ -158,7 +158,10 @@ private fun RoomSummaryScaffoldRow( .padding(horizontal = 16.dp, vertical = 11.dp) .height(IntrinsicSize.Min), ) { - Avatar(room.avatarData) + CompositeAvatar( + avatarData = room.avatarData, + heroes = room.heroes, + ) Spacer(modifier = Modifier.width(16.dp)) Column( modifier = Modifier.fillMaxWidth(), diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt index 80232563ed..18ba73bdc1 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt @@ -26,7 +26,11 @@ import io.element.android.libraries.eventformatter.api.RoomLastMessageFormatter import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.roomlist.RoomSummary +import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails +import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.matrix.ui.model.toInviteSender +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList import javax.inject.Inject class RoomListRoomSummaryFactory @Inject constructor( @@ -54,43 +58,45 @@ class RoomListRoomSummaryFactory @Inject constructor( inviteSender = null, isDm = false, canonicalAlias = null, + heroes = persistentListOf(), ) } } fun create(roomSummary: RoomSummary.Filled): RoomListRoomSummary { - val roomIdentifier = roomSummary.identifier() - val avatarData = AvatarData( - id = roomIdentifier, - name = roomSummary.details.name, - url = roomSummary.details.avatarUrl, - size = AvatarSize.RoomListItem, - ) + return create(roomSummary.details) + } + + private fun create(details: RoomSummaryDetails): RoomListRoomSummary { + val avatarData = details.getAvatarData(size = AvatarSize.RoomListItem) return RoomListRoomSummary( - id = roomIdentifier, - roomId = RoomId(roomIdentifier), - name = roomSummary.details.name, - numberOfUnreadMessages = roomSummary.details.numUnreadMessages, - numberOfUnreadMentions = roomSummary.details.numUnreadMentions, - numberOfUnreadNotifications = roomSummary.details.numUnreadNotifications, - isMarkedUnread = roomSummary.details.isMarkedUnread, - timestamp = lastMessageTimestampFormatter.format(roomSummary.details.lastMessageTimestamp), - lastMessage = roomSummary.details.lastMessage?.let { message -> - roomLastMessageFormatter.format(message.event, roomSummary.details.isDirect) + id = details.roomId.value, + roomId = details.roomId, + name = details.name, + numberOfUnreadMessages = details.numUnreadMessages, + numberOfUnreadMentions = details.numUnreadMentions, + numberOfUnreadNotifications = details.numUnreadNotifications, + isMarkedUnread = details.isMarkedUnread, + timestamp = lastMessageTimestampFormatter.format(details.lastMessageTimestamp), + lastMessage = details.lastMessage?.let { message -> + roomLastMessageFormatter.format(message.event, details.isDirect) }.orEmpty(), avatarData = avatarData, - userDefinedNotificationMode = roomSummary.details.userDefinedNotificationMode, - hasRoomCall = roomSummary.details.hasRoomCall, - isDirect = roomSummary.details.isDirect, - isFavorite = roomSummary.details.isFavorite, - inviteSender = roomSummary.details.inviter?.toInviteSender(), - isDm = roomSummary.details.isDm, - canonicalAlias = roomSummary.details.canonicalAlias, - displayType = if (roomSummary.details.currentUserMembership == CurrentUserMembership.INVITED) { + userDefinedNotificationMode = details.userDefinedNotificationMode, + hasRoomCall = details.hasRoomCall, + isDirect = details.isDirect, + isFavorite = details.isFavorite, + inviteSender = details.inviter?.toInviteSender(), + isDm = details.isDm, + canonicalAlias = details.canonicalAlias, + displayType = if (details.currentUserMembership == CurrentUserMembership.INVITED) { RoomSummaryDisplayType.INVITE } else { RoomSummaryDisplayType.ROOM - } + }, + heroes = details.heroes.map { user -> + user.getAvatarData(size = AvatarSize.RoomListItem) + }.toImmutableList(), ) } } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummary.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummary.kt index 9afa6cd749..5e0bd5c65a 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummary.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummary.kt @@ -22,6 +22,7 @@ import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.ui.model.InviteSender +import kotlinx.collections.immutable.ImmutableList @Immutable data class RoomListRoomSummary( @@ -43,6 +44,7 @@ data class RoomListRoomSummary( val isDm: Boolean, val isFavorite: Boolean, val inviteSender: InviteSender?, + val heroes: ImmutableList, ) { val isHighlighted = userDefinedNotificationMode != RoomNotificationMode.MUTE && (numberOfUnreadNotifications > 0 || numberOfUnreadMentions > 0) || diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt index a39d50eac0..473c60049a 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt @@ -24,6 +24,7 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.ui.model.InviteSender +import kotlinx.collections.immutable.toImmutableList open class RoomListRoomSummaryProvider : PreviewParameterProvider { override val values: Sequence @@ -142,6 +143,7 @@ internal fun aRoomListRoomSummary( inviteSender: InviteSender? = null, displayType: RoomSummaryDisplayType = RoomSummaryDisplayType.ROOM, canonicalAlias: RoomAlias? = null, + heroes: List = emptyList(), ) = RoomListRoomSummary( id = id, roomId = RoomId(id), @@ -161,4 +163,5 @@ internal fun aRoomListRoomSummary( inviteSender = inviteSender, displayType = displayType, canonicalAlias = canonicalAlias, + heroes = heroes.toImmutableList(), ) diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryTest.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryTest.kt index 6ad7c07960..bf24dfd6dd 100644 --- a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryTest.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryTest.kt @@ -23,6 +23,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_NAME +import kotlinx.collections.immutable.toPersistentList import org.junit.Test class RoomListRoomSummaryTest { @@ -91,6 +92,7 @@ internal fun createRoomListRoomSummary( userDefinedNotificationMode: RoomNotificationMode? = null, isFavorite: Boolean = false, displayType: RoomSummaryDisplayType = RoomSummaryDisplayType.ROOM, + heroes: List = emptyList(), ) = RoomListRoomSummary( id = A_ROOM_ID.value, roomId = A_ROOM_ID, @@ -110,4 +112,5 @@ internal fun createRoomListRoomSummary( canonicalAlias = null, inviteSender = null, isDm = false, + heroes = heroes.toPersistentList(), ) 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 173716aee3..4e8183977f 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 @@ -32,6 +32,7 @@ import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.semantics.clearAndSetSemantics 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 androidx.compose.ui.unit.sp import coil.compose.AsyncImage @@ -52,18 +53,22 @@ fun Avatar( avatarData: AvatarData, modifier: Modifier = Modifier, contentDescription: String? = null, + // If not null, will be used instead of the size from avatarData + forcedAvatarSize: Dp? = null, ) { val commonModifier = modifier - .size(avatarData.size.dp) + .size(forcedAvatarSize ?: avatarData.size.dp) .clip(CircleShape) if (avatarData.url.isNullOrBlank()) { InitialsAvatar( avatarData = avatarData, + forcedAvatarSize = forcedAvatarSize, modifier = commonModifier, ) } else { ImageAvatar( avatarData = avatarData, + forcedAvatarSize = forcedAvatarSize, modifier = commonModifier, contentDescription = contentDescription, ) @@ -73,6 +78,7 @@ fun Avatar( @Composable private fun ImageAvatar( avatarData: AvatarData, + forcedAvatarSize: Dp?, modifier: Modifier = Modifier, contentDescription: String? = null, ) { @@ -98,9 +104,15 @@ private fun ImageAvatar( SideEffect { Timber.e(state.result.throwable, "Error loading avatar $state\n${state.result}") } - InitialsAvatar(avatarData = avatarData) + InitialsAvatar( + avatarData = avatarData, + forcedAvatarSize = forcedAvatarSize, + ) } - else -> InitialsAvatar(avatarData = avatarData) + else -> InitialsAvatar( + avatarData = avatarData, + forcedAvatarSize = forcedAvatarSize, + ) } } } @@ -109,13 +121,14 @@ private fun ImageAvatar( @Composable private fun InitialsAvatar( avatarData: AvatarData, + forcedAvatarSize: Dp?, modifier: Modifier = Modifier, ) { val avatarColors = AvatarColorsProvider.provide(avatarData.id, ElementTheme.isLightTheme) Box( modifier.background(color = avatarColors.background) ) { - val fontSize = avatarData.size.dp.toSp() / 2 + val fontSize = (forcedAvatarSize ?: avatarData.size.dp).toSp() / 2 val originalFont = ElementTheme.typography.fontHeadingMdBold val ratio = fontSize.value / originalFont.fontSize.value val lineHeight = originalFont.lineHeight * ratio diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt index 54791f8505..e56c580abb 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt @@ -55,4 +55,8 @@ enum class AvatarSize(val dp: Dp) { CustomRoomNotificationSetting(36.dp), RoomDirectoryItem(36.dp), + + EditProfileDetails(96.dp), + + Suggestion(32.dp), } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/CompositeAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/CompositeAvatar.kt new file mode 100644 index 0000000000..6ae505e048 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/CompositeAvatar.kt @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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.Row +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +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.preview.ElementThemedPreview +import io.element.android.libraries.designsystem.preview.PreviewGroup +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toPersistentList +import java.util.Collections +import kotlin.math.PI +import kotlin.math.cos +import kotlin.math.sin + +@Composable +fun CompositeAvatar( + avatarData: AvatarData, + heroes: ImmutableList, + modifier: Modifier = Modifier, + contentDescription: String? = null, +) { + if (avatarData.url != null || heroes.isEmpty()) { + Avatar(avatarData, modifier, contentDescription) + } else { + val limitedHeroes = heroes.take(4) + val numberOfHeroes = limitedHeroes.size + if (numberOfHeroes == 4) { + // Swap 2 and 3 so that the 4th hero is at the bottom right + Collections.swap(limitedHeroes, 2, 3) + } + when (numberOfHeroes) { + 0 -> { + error("Unsupported number of heroes: 0") + } + 1 -> { + Avatar(heroes[0], modifier, contentDescription) + } + else -> { + val angle = 2 * Math.PI / numberOfHeroes + val offsetRadius = when (numberOfHeroes) { + 2 -> avatarData.size.dp.value / 4.2 + 3 -> avatarData.size.dp.value / 4.0 + 4 -> avatarData.size.dp.value / 3.1 + else -> error("Unsupported number of heroes: $numberOfHeroes") + } + val heroAvatarSize = when (numberOfHeroes) { + 2 -> avatarData.size.dp / 2.2f + 3 -> avatarData.size.dp / 2.4f + 4 -> avatarData.size.dp / 2.2f + else -> error("Unsupported number of heroes: $numberOfHeroes") + } + val angleOffset = when (numberOfHeroes) { + 2 -> PI + 3 -> 7 * PI / 6 + 4 -> 13 * PI / 4 + else -> error("Unsupported number of heroes: $numberOfHeroes") + } + Box( + modifier = modifier + .size(avatarData.size.dp) + .semantics { + this.contentDescription = contentDescription.orEmpty() + }, + contentAlignment = Alignment.Center, + ) { + limitedHeroes.forEachIndexed { index, heroAvatar -> + val xOffset = (offsetRadius * cos(angle * index.toDouble() + angleOffset)).dp + val yOffset = (offsetRadius * sin(angle * index.toDouble() + angleOffset)).dp + Box( + modifier = Modifier + .size(heroAvatarSize) + .offset( + x = xOffset, + y = yOffset, + ) + ) { + Avatar( + heroAvatar, + forcedAvatarSize = heroAvatarSize, + ) + } + } + } + } + } + } +} + +@Preview(group = PreviewGroup.Avatars) +@Composable +internal fun CompositeAvatarPreview() = ElementThemedPreview { + val mainAvatar = anAvatarData( + id = "Zac", + name = "Zac", + size = AvatarSize.RoomListItem, + ) + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + repeat(6) { nbOfHeroes -> + CompositeAvatar( + avatarData = mainAvatar, + heroes = List(nbOfHeroes) { aHeroAvatarData(it) }.toPersistentList(), + ) + } + } +} + +private fun aHeroAvatarData(i: Int) = anAvatarData( + id = ('A' + i).toString(), + name = ('A' + i).toString() +) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt index 4fae22ad57..70da8e7364 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt @@ -20,6 +20,7 @@ import androidx.compose.runtime.Immutable import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableMap @@ -49,5 +50,6 @@ data class MatrixRoomInfo( val notificationCount: Long, val userDefinedNotificationMode: RoomNotificationMode?, val hasRoomCall: Boolean, - val activeRoomCallParticipants: ImmutableList + val activeRoomCallParticipants: ImmutableList, + val heroes: ImmutableList, ) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt index 425da8d3ca..1e38b00b61 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt @@ -22,6 +22,7 @@ import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.message.RoomMessage +import io.element.android.libraries.matrix.api.user.MatrixUser sealed interface RoomSummary { data class Empty(val identifier: String) : RoomSummary @@ -52,6 +53,7 @@ data class RoomSummaryDetails( val isDm: Boolean, val isFavorite: Boolean, val currentUserMembership: CurrentUserMembership, + val heroes: List, ) { val lastMessageTimestamp = lastMessage?.originServerTs } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt index d01a7d1740..6a87b02a2b 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt @@ -22,10 +22,12 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.MatrixRoomInfo import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toPersistentMap +import org.matrix.rustcomponents.sdk.RoomHero import org.matrix.rustcomponents.sdk.Membership as RustMembership import org.matrix.rustcomponents.sdk.RoomInfo as RustRoomInfo import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode @@ -55,7 +57,8 @@ class MatrixRoomInfoMapper { notificationCount = it.notificationCount.toLong(), userDefinedNotificationMode = it.userDefinedNotificationMode?.map(), hasRoomCall = it.hasRoomCall, - activeRoomCallParticipants = it.activeRoomCallParticipants.toImmutableList() + activeRoomCallParticipants = it.activeRoomCallParticipants.toImmutableList(), + heroes = it.elementHeroes().toImmutableList() ) } } @@ -72,6 +75,15 @@ fun RustRoomNotificationMode.map(): RoomNotificationMode = when (this) { RustRoomNotificationMode.MUTE -> RoomNotificationMode.MUTE } +/** + * Map a RoomHero to a MatrixUser. There is not need to create a RoomHero type on the application side. + */ +fun RoomHero.map(): MatrixUser = MatrixUser( + userId = UserId(userId), + displayName = displayName, + avatarUrl = avatarUrl +) + fun mapPowerLevels(powerLevels: Map): ImmutableMap { return powerLevels.mapKeys { (key, _) -> UserId(key) }.toPersistentMap() } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoExt.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoExt.kt new file mode 100644 index 0000000000..bd6cc7eda4 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoExt.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.matrix.impl.room + +import io.element.android.libraries.matrix.api.user.MatrixUser +import org.matrix.rustcomponents.sdk.RoomInfo + +/** + * Extract the heroes from the room info. + * For now we only use heroes for direct rooms with 2 members. + * Also we keep the heroes only if there is one single hero. + */ +fun RoomInfo.elementHeroes(): List { + return heroes + .takeIf { isDirect && activeMembersCount.toLong() == 2L } + ?.takeIf { it.size == 1 } + ?.map { it.map() } + .orEmpty() +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt index 3ccc071316..f45c843694 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt @@ -20,6 +20,7 @@ import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails import io.element.android.libraries.matrix.impl.notificationsettings.RoomNotificationSettingsMapper +import io.element.android.libraries.matrix.impl.room.elementHeroes import io.element.android.libraries.matrix.impl.room.map import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper import io.element.android.libraries.matrix.impl.room.message.RoomMessageFactory @@ -49,6 +50,7 @@ class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFacto isDm = roomInfo.isDirect && roomInfo.activeMembersCount.toLong() == 2L, isFavorite = roomInfo.isFavourite, currentUserMembership = roomInfo.membership.map(), + heroes = roomInfo.elementHeroes(), ) } } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt index 5583f6b11e..558d7abb60 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt @@ -45,6 +45,7 @@ import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerL import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.Timeline +import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings import io.element.android.libraries.matrix.test.AN_AVATAR_URL @@ -754,7 +755,8 @@ fun aRoomInfo( userDefinedNotificationMode: RoomNotificationMode? = null, hasRoomCall: Boolean = false, userPowerLevels: ImmutableMap = persistentMapOf(), - activeRoomCallParticipants: List = emptyList() + activeRoomCallParticipants: List = emptyList(), + heroes: List = emptyList(), ) = MatrixRoomInfo( id = id, name = name, @@ -779,6 +781,7 @@ fun aRoomInfo( hasRoomCall = hasRoomCall, userPowerLevels = userPowerLevels, activeRoomCallParticipants = activeRoomCallParticipants.toImmutableList(), + heroes = heroes.toImmutableList(), ) fun defaultRoomPowerLevels() = MatrixRoomPowerLevels( diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt index d9fdffa62a..611a68aad6 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt @@ -27,6 +27,7 @@ import io.element.android.libraries.matrix.api.room.message.RoomMessage import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem +import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_NAME @@ -78,6 +79,7 @@ fun aRoomSummaryDetails( isDm: Boolean = false, isFavorite: Boolean = false, currentUserMembership: CurrentUserMembership = CurrentUserMembership.JOINED, + heroes: List = emptyList(), ) = RoomSummaryDetails( roomId = roomId, name = name, @@ -95,6 +97,7 @@ fun aRoomSummaryDetails( isDm = isDm, isFavorite = isFavorite, currentUserMembership = currentUserMembership, + heroes = heroes, ) fun aRoomMessage( diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/RoomSummaryDetailsProvider.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/RoomSummaryDetailsProvider.kt index a433f49395..275848f3fc 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/RoomSummaryDetailsProvider.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/RoomSummaryDetailsProvider.kt @@ -24,6 +24,7 @@ import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.message.RoomMessage import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails +import io.element.android.libraries.matrix.api.user.MatrixUser open class RoomSummaryDetailsProvider : PreviewParameterProvider { override val values: Sequence @@ -50,6 +51,7 @@ fun aRoomSummaryDetails( isMarkedUnread: Boolean = false, isFavorite: Boolean = false, currentUserMembership: CurrentUserMembership = CurrentUserMembership.JOINED, + heroes: List = emptyList(), ) = RoomSummaryDetails( roomId = roomId, name = name, @@ -67,4 +69,5 @@ fun aRoomSummaryDetails( isMarkedUnread = isMarkedUnread, isFavorite = isFavorite, currentUserMembership = currentUserMembership, + heroes = heroes, ) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt index 7f8f9f2f56..f34b071379 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt @@ -36,16 +36,17 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp 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.CompositeAvatar import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Surface import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails +import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.collections.immutable.toImmutableList @Composable fun SelectedRoom( @@ -60,7 +61,12 @@ fun SelectedRoom( Column( horizontalAlignment = Alignment.CenterHorizontally, ) { - Avatar(AvatarData(roomSummary.roomId.value, roomSummary.name, roomSummary.avatarUrl, AvatarSize.SelectedRoom)) + CompositeAvatar( + avatarData = roomSummary.getAvatarData(size = AvatarSize.SelectedRoom), + heroes = roomSummary.heroes.map { user -> + user.getAvatarData(size = AvatarSize.SelectedRoom) + }.toImmutableList() + ) Text( // If name is null, we do not have space to render "No room name", so just use `#` here. text = roomSummary.name ?: "#", diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/InviteSender.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/InviteSender.kt index 410fb7edbd..dcc8e6e327 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/InviteSender.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/InviteSender.kt @@ -60,10 +60,5 @@ data class InviteSender( fun RoomMember.toInviteSender() = InviteSender( userId = userId, displayName = displayName ?: "", - avatarData = AvatarData( - id = userId.value, - name = displayName, - url = avatarUrl, - size = AvatarSize.InviteSender, - ), + avatarData = getAvatarData(size = AvatarSize.InviteSender), ) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomMemberExtension.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomMemberExtension.kt new file mode 100644 index 0000000000..95ec1cc230 --- /dev/null +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomMemberExtension.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.matrix.ui.model + +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.matrix.api.room.RoomMember + +fun RoomMember.getAvatarData(size: AvatarSize) = AvatarData( + id = userId.value, + name = displayName, + url = avatarUrl, + size = size, +) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomSummaryExtension.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomSummaryExtension.kt new file mode 100644 index 0000000000..dd86d375f3 --- /dev/null +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomSummaryExtension.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.matrix.ui.model + +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails + +fun RoomSummaryDetails.getAvatarData(size: AvatarSize) = AvatarData( + id = roomId.value, + name = name, + url = avatarUrl, + size = size, +) diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt index fa8525bdc1..7ade4f759d 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt @@ -41,9 +41,8 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.PreviewParameter 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.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.CompositeAvatar import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -59,9 +58,11 @@ import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails import io.element.android.libraries.matrix.ui.components.SelectedRoom +import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.roomselect.api.RoomSelectMode import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toPersistentList @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -221,13 +222,11 @@ private fun RoomSummaryView( .heightIn(56.dp), verticalAlignment = Alignment.CenterVertically ) { - Avatar( - avatarData = AvatarData( - id = summary.roomId.value, - name = summary.name, - url = summary.avatarUrl, - size = AvatarSize.RoomSelectRoomListItem, - ), + CompositeAvatar( + avatarData = summary.getAvatarData(size = AvatarSize.RoomSelectRoomListItem), + heroes = summary.heroes.map { user -> + user.getAvatarData(size = AvatarSize.RoomSelectRoomListItem) + }.toPersistentList() ) Column( modifier = Modifier diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_0,NEXUS_5,1.0,en].png index d2f9ab5db9..8a8a532ba2 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a4744d8211b2afaa0e45d018e618296be417db72976a7fe248044e69dc419747 -size 46405 +oid sha256:b66bfca625a2c5abbb99eb63840c99d941331f74da6741203f382ee49fec29fa +size 45772 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_1,NEXUS_5,1.0,en].png index 1866e67ab6..773c3fe950 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b070a8b1d40d9b944a35f1ca9d034dac4d8f75fcd2ce29ca90a6c0d02eefe567 -size 34637 +oid sha256:5e1320dbc665a15434e9ea46bc8f085cb0a1dfe1a328d41139401ebd8ef23f84 +size 34975 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_10,NEXUS_5,1.0,en].png index 1273e8ea35..99307b9b97 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_10,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_10,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d6975f45047b144416e394c61d50b2c67296e075ab87521b2bd19190e688b2db -size 44684 +oid sha256:24d1b09fbf025b954711e4bd8392d32675568154bbd06ce8c69f4a8deb91a958 +size 43695 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_11,NEXUS_5,1.0,en].png index 4bfc4b76c6..f11e3460cb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_11,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_11,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:06ecef645a1770f028a0be5b519d9fa058896599764b679d431302530dfe5bfd -size 43593 +oid sha256:05d47c7317111c9e7ac34f66705a8344114501c35d05d630f2146e128300077d +size 42587 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_12,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..2218fcc35e --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_12,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5491a9525166428c8b1ce94aaf3ef56aa5415cab19f8bcd99be128c265925e9 +size 45669 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_2,NEXUS_5,1.0,en].png index 2eabc0dccf..028a806260 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d89dc9226478c87a95f381474dc952372506c59f5797b1ebc06a73f79cda7d4 -size 36723 +oid sha256:42590cba46dc5f9e0d4e9504d1ea854c5f5f3fdf3acaddca2604988164153beb +size 37065 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_3,NEXUS_5,1.0,en].png index 91047eaa4c..5e5446c198 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fee91322d75a86cf574c0bae99fc7534a7a41f0aa9925554c2cecdd1f67616a2 -size 35594 +oid sha256:30e9d873c187481341222a986741061eb84162127d7e0d086d3c957d9ef2d2d8 +size 35945 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_4,NEXUS_5,1.0,en].png index 91424489cd..d9e920eb75 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb91e113a89b29e43529fee0140b04c9d45aa6dee95b636e8b02cb697f8eaec3 -size 42854 +oid sha256:189e30f39a33924a6da727d4caa4ce117df66cc9dd1857c4909649cf8db51fdb +size 43191 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_7,NEXUS_5,1.0,en].png index 6c046aa84e..e70f6778f8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dcb14bafbaeb398a7351528b9756888190cb3614b64ced30604525d33042d0b7 -size 45983 +oid sha256:a0f12af0b98d2d145d5443554a0657cd0699fe27f86447873630a189cbce615a +size 45008 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_8,NEXUS_5,1.0,en].png index 8273c91f0a..f4023197f4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27f9fd42938231cbedef25c60c0bf5c38445ed4ae3c43076a3d0d1de781c1571 -size 44882 +oid sha256:db2babbe88dd81723ecf8f1c83fa73042efb590d04f1b12aaabf102f7f576dd9 +size 43883 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_9,NEXUS_5,1.0,en].png index 162cd9c264..866944d635 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_9,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetailsDark_null_RoomDetailsDark--1_3_null_9,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d851ccac1aea76e629d3b8ef381595e734e8d02789ebea3a28b5f40dfb07040f -size 44838 +oid sha256:53056291448931a702d761557712626259f04a3969f128553a7bc7a172d74d5b +size 43840 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_0,NEXUS_5,1.0,en].png index 2ef84f644e..0c89045531 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7a077772fbbcd2e5096e9fa5907705e5bb3d04692c597510f825102ce31afb6a -size 47451 +oid sha256:d69018133b9a3ebf36e7819031df2c8b8bc19f1e7632cfeabc02ca6bcf76ffce +size 46744 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_1,NEXUS_5,1.0,en].png index 2467e58bcd..0e629da29e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e60750a386993ee7e14a2f1e9afcbfb898d6212f9f043d67431017991b53a3c4 -size 35470 +oid sha256:374166110a04cee8f63d1d330601976970e5abcd92947cfb284e61613cf47f51 +size 35727 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_10,NEXUS_5,1.0,en].png index bc1dc06a99..0d9c8a73b7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_10,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_10,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7d805eed0dbdf07599c836af16e904ec5a6ebe4adb0b9ebfa5200f2065630cfa -size 45596 +oid sha256:04a0838ac192efeacb821d23ed8b3ce8305b8e8084beb0e5a0fbc56cfa1ce964 +size 44435 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_11,NEXUS_5,1.0,en].png index 1635ac1d06..343de082ef 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_11,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_11,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c04bd5c13058d696364295110fc4b323b424766bda0ba42c13b2ed772e8f6520 -size 44474 +oid sha256:6d760e5015257bd8d608749c1926c6177e4d0ef70d5d5f32764e970f4c80cb43 +size 43331 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_12,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..3ba823f05b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_12,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63d2319dc4617d805f0b652983e4bb7b6e4aa7c2e9c6ec37398fce2e2413a79d +size 46441 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_2,NEXUS_5,1.0,en].png index 7cc2a1b656..e8e3831962 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb96628c10622b9f39b9723b4c3a7b1a7e38a643753a42159af63e8f00a2f51c -size 37610 +oid sha256:8c3dec8246e5605c61a9132cea048c5afaad35751246ffd81160c33782c26c93 +size 37861 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_3,NEXUS_5,1.0,en].png index 7a1641860a..3f3136ce6c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f84aea29dfb13dbe42c6e466b3afd7258742bf2c0411039ab93e554803945333 -size 36229 +oid sha256:c8491d21c160851bbe3a0362edae05e46cf9cb072ca4bf41ad569a3a6c57097c +size 36458 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_4,NEXUS_5,1.0,en].png index f09ef9182f..00cc501d4b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e7e580cd945db94a37cfaa162ab709ade3a830f20a42bb98a28fd7650114a90 -size 43740 +oid sha256:f7f08cac8eecb3ae6067f756411d0ec5607d3207832cfe69858ef1189f18ee45 +size 43996 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_7,NEXUS_5,1.0,en].png index b3e71b54a2..7a9d976302 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:14b22efc30f883ca6812f9e87bf8eaecc3d37479fa5421026fcaf7b01a11e952 -size 46986 +oid sha256:ea0cfd0f222862a8becdd4b4a7f2e47a4a7d83ecb1ff761889c46631d7d43e97 +size 45861 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_8,NEXUS_5,1.0,en].png index 0af429e838..9a0cf77937 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:45a3856e5d802c02302318caf584b4356122c3412bea177944ec8edab0c809c0 -size 45846 +oid sha256:cd7aa71f1d24d4cacafb4aaea8802d1493e317604d5ea35f0d9fac1a304d7f19 +size 44718 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_9,NEXUS_5,1.0,en].png index 1dc805428d..a2ec270d02 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_9,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_RoomDetails_null_RoomDetails--0_2_null_9,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd29438c4d913cd920e2f19e85f9098d6a486a401fcd8e14a9f7a323dd5c334c -size 45773 +oid sha256:234e65b2caa1f23f9e4d0e01c142d22df0d407851e554a7db3e0b09c57acf47a +size 44626 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_66,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_66,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..3697470264 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_66,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6be06e6a243feb8096a2f121e5cadbd5d82351807b537c938e0e7cbfdf52739 +size 21115 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_67,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_67,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..7ad7b48d2a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_67,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94607803d470f7f5772cbf421b3e56a845556773b3545cae5b42314a1804a02a +size 18858 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_68,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_68,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..fc23c2c5ad --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_68,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f3a7f0a4944f35fd726d5090eab08140b57332e6f7d8eb475fc6bf9ef37bcdf +size 26033 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_69,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_69,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..2202019ea4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_69,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61d634e424c3858902d03a50a128ecbba4c62766ebba97cd04f6eb147f41f71d +size 15042 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_70,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_70,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..594f49999b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_70,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4fea2725865c6277387d8f9d4f1bc980548b671f2946c89dbb9f4cad34be80d7 +size 14267 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_71,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_71,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..b294ff8e75 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_Avatar_null_Avatars_Avatar_0_null_71,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e88e6991bca9f0c99c28b6126b10135d0ba8de1faa7bc6174e6f66bc11b2ce03 +size 16794 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_CompositeAvatar_null_Avatars_CompositeAvatar_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_CompositeAvatar_null_Avatars_CompositeAvatar_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..c48605599a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_CompositeAvatar_null_Avatars_CompositeAvatar_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa80768048c3247ede26c831a9d16a2f9c27774b5d9b75e70cb31e0f26b4d411 +size 27620