From e689eaf73a077327c0f110655add8d3fdb13b9a5 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 23 Oct 2025 16:01:47 +0200 Subject: [PATCH] design(space): let divider be full width # Conflicts: # features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt --- .../home/impl/spaces/HomeSpacesView.kt | 33 ++++--- .../features/space/impl/root/SpaceView.kt | 61 +++++++------ .../matrix/ui/components/SpaceRoomItemView.kt | 88 +++++++++---------- 3 files changed, 92 insertions(+), 90 deletions(-) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt index bc1f474956..12ef091b3a 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt @@ -10,6 +10,7 @@ package io.element.android.features.home.impl.spaces import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.PreviewParameter @@ -57,20 +58,24 @@ fun HomeSpacesView( item { HorizontalDivider() } - state.spaceRooms.forEach { spaceRoom -> - item(spaceRoom.roomId) { - val isInvitation = spaceRoom.state == CurrentUserMembership.INVITED - SpaceRoomItemView( - spaceRoom = spaceRoom, - showUnreadIndicator = isInvitation && spaceRoom.roomId !in state.seenSpaceInvites, - hideAvatars = isInvitation && state.hideInvitesAvatar, - onClick = { - onSpaceClick(spaceRoom.roomId) - }, - onLongClick = { - // TODO - }, - ) + itemsIndexed( + items = state.spaceRooms, + key = { _, spaceRoom -> spaceRoom.roomId } + ) { index, spaceRoom -> + val isInvitation = spaceRoom.state == CurrentUserMembership.INVITED + SpaceRoomItemView( + spaceRoom = spaceRoom, + showUnreadIndicator = isInvitation && spaceRoom.roomId !in state.seenSpaceInvites, + hideAvatars = isInvitation && state.hideInvitesAvatar, + onClick = { + onSpaceClick(spaceRoom.roomId) + }, + onLongClick = { + // TODO + }, + ) + if (index != state.spaceRooms.lastIndex) { + HorizontalDivider() } } } diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt index cd722ac6f3..cbcae289e0 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -182,32 +183,36 @@ private fun SpaceViewContent( HorizontalDivider() } } - state.children.forEach { spaceRoom -> - item { - val isInvitation = spaceRoom.state == CurrentUserMembership.INVITED - val isCurrentlyJoining = state.isJoining(spaceRoom.roomId) - SpaceRoomItemView( - spaceRoom = spaceRoom, - showUnreadIndicator = isInvitation && spaceRoom.roomId !in state.seenSpaceInvites, - hideAvatars = isInvitation && state.hideInvitesAvatar, - onClick = { - onRoomClick(spaceRoom) + itemsIndexed( + items = state.children, + key = { _, spaceRoom -> spaceRoom.roomId } + ) { index, spaceRoom -> + val isInvitation = spaceRoom.state == CurrentUserMembership.INVITED + val isCurrentlyJoining = state.isJoining(spaceRoom.roomId) + SpaceRoomItemView( + spaceRoom = spaceRoom, + showUnreadIndicator = isInvitation && spaceRoom.roomId !in state.seenSpaceInvites, + hideAvatars = isInvitation && state.hideInvitesAvatar, + onClick = { + onRoomClick(spaceRoom) + }, + onLongClick = { + // TODO + }, + trailingAction = spaceRoom.trailingAction(isCurrentlyJoining = isCurrentlyJoining) { + state.eventSink(SpaceEvents.Join(spaceRoom)) + }, + bottomAction = spaceRoom.inviteButtons( + onAcceptClick = { + state.eventSink(SpaceEvents.AcceptInvite(spaceRoom)) }, - onLongClick = { - // TODO - }, - trailingAction = spaceRoom.trailingAction(isCurrentlyJoining = isCurrentlyJoining) { - state.eventSink(SpaceEvents.Join(spaceRoom)) - }, - bottomAction = spaceRoom.inviteButtons( - onAcceptClick = { - state.eventSink(SpaceEvents.AcceptInvite(spaceRoom)) - }, - onDeclineClick = { - state.eventSink(SpaceEvents.DeclineInvite(spaceRoom)) - } - ) + onDeclineClick = { + state.eventSink(SpaceEvents.DeclineInvite(spaceRoom)) + } ) + ) + if (index != state.children.lastIndex) { + HorizontalDivider() } } if (state.hasMoreToLoad) { @@ -328,10 +333,10 @@ private fun SpaceAvatarAndNameRow( ) Text( modifier = Modifier - .padding(horizontal = 8.dp) - .semantics { - heading() - }, + .padding(horizontal = 8.dp) + .semantics { + heading() + }, text = name ?: stringResource(CommonStrings.common_no_space_name), style = ElementTheme.typography.fontBodyLgMedium, fontStyle = FontStyle.Italic.takeIf { name == null }, diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceRoomItemView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceRoomItemView.kt index 90ed843483..1bede0784b 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceRoomItemView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceRoomItemView.kt @@ -43,7 +43,6 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.modifiers.onKeyboardContextMenuAction import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.designsystem.theme.components.HorizontalDivider import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.unreadIndicator @@ -81,56 +80,50 @@ fun SpaceRoomItemView( interactionSource = remember { MutableInteractionSource() } ) .onKeyboardContextMenuAction { onLongClick } - Box(modifier = modifier.then(clickModifier)) { - Column( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), + Column( + modifier = modifier + .then(clickModifier) + .padding(horizontal = 16.dp, vertical = 12.dp), + ) { + SpaceRoomItemScaffold( + avatarData = spaceRoom.getAvatarData(AvatarSize.SpaceListItem), + isSpace = spaceRoom.isSpace, + hideAvatars = hideAvatars, + heroes = spaceRoom.heroes + .map { hero -> hero.getAvatarData(AvatarSize.SpaceListItem) } + .toImmutableList(), + trailingAction = trailingAction, ) { - SpaceRoomItemScaffold( - avatarData = spaceRoom.getAvatarData(AvatarSize.SpaceListItem), - isSpace = spaceRoom.isSpace, - hideAvatars = hideAvatars, - heroes = spaceRoom.heroes - .map { hero -> hero.getAvatarData(AvatarSize.SpaceListItem) } - .toImmutableList(), - trailingAction = trailingAction, - ) { - NameAndIndicatorRow( - name = spaceRoom.displayName, - showIndicator = showUnreadIndicator + NameAndIndicatorRow( + name = spaceRoom.displayName, + showIndicator = showUnreadIndicator + ) + Spacer(modifier = Modifier.height(1.dp)) + SubtitleRow( + visibilityIcon = spaceRoom.visibilityIcon(), + subtitle = spaceRoom.subtitle() + ) + Spacer(modifier = Modifier.height(1.dp)) + val info = spaceRoom.info() + if (info.isNotBlank()) { + Text( + modifier = Modifier.weight(1f), + style = ElementTheme.typography.fontBodyMdRegular, + text = info, + color = ElementTheme.colors.textSecondary, + maxLines = 1, + overflow = TextOverflow.Ellipsis ) - Spacer(modifier = Modifier.height(1.dp)) - SubtitleRow( - visibilityIcon = spaceRoom.visibilityIcon(), - subtitle = spaceRoom.subtitle() - ) - Spacer(modifier = Modifier.height(1.dp)) - val info = spaceRoom.info() - if (info.isNotBlank()) { - Text( - modifier = Modifier.weight(1f), - style = ElementTheme.typography.fontBodyMdRegular, - text = info, - color = ElementTheme.colors.textSecondary, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } - if (bottomAction != null) { - Spacer(modifier = Modifier.height(12.dp)) - // Match the padding of the text content (avatar + spacer) - Box(modifier = Modifier.padding(start = AvatarSize.SpaceListItem.dp + 16.dp)) { - bottomAction() - } - Spacer(modifier = Modifier.height(4.dp)) } } - HorizontalDivider( - modifier = Modifier - // Match the padding of the text content (padding + avatar + spacer) - .padding(start = AvatarSize.SpaceListItem.dp + 16.dp + 16.dp) - .align(Alignment.BottomCenter) - ) + if (bottomAction != null) { + Spacer(modifier = Modifier.height(12.dp)) + // Match the padding of the text content (avatar + spacer) + Box(modifier = Modifier.padding(start = AvatarSize.SpaceListItem.dp + 16.dp)) { + bottomAction() + } + Spacer(modifier = Modifier.height(4.dp)) + } } } @@ -264,7 +257,6 @@ internal fun SpaceRoomItemViewPreview(@PreviewParameter(SpaceRoomProvider::class hideAvatars = false, onClick = {}, onLongClick = {}, - modifier = Modifier.fillMaxWidth().padding(8.dp), bottomAction = if (spaceRoom.state == CurrentUserMembership.INVITED) { { InviteButtonsRowMolecule({}, {}) } } else {