feature (space) : add trailing action to SpaceRoomItemView

This commit is contained in:
ganfra
2025-09-24 16:52:56 +02:00
parent 0931244713
commit 7050076beb
4 changed files with 116 additions and 29 deletions

View File

@@ -9,6 +9,7 @@ package io.element.android.features.space.impl
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
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.spaces.SpaceRoom
import io.element.android.libraries.previewutils.room.aSpaceRoom
import kotlinx.collections.immutable.toImmutableList
@@ -17,24 +18,22 @@ import kotlinx.collections.immutable.toImmutableSet
open class SpaceStateProvider : PreviewParameterProvider<SpaceState> {
override val values: Sequence<SpaceState>
get() = sequenceOf(
aSpaceState(),
aSpaceState(
parentSpace = aSpaceRoom(
name = null,
numJoinedMembers = 5,
childrenCount = 10,
worldReadable = true,
),
hasMoreToLoad = true,
), aSpaceState(
parentSpace = aSpaceRoom(
name = null,
numJoinedMembers = 5,
childrenCount = 10,
worldReadable = true,
),
aSpaceState(
hasMoreToLoad = true,
children = aListOfSpaceRooms(),
),
aSpaceState(
hasMoreToLoad = false,
children = aListOfSpaceRooms()
)
hasMoreToLoad = true,
), aSpaceState(
hasMoreToLoad = true,
children = aListOfSpaceRooms(),
), aSpaceState(
hasMoreToLoad = false, children = aListOfSpaceRooms()
)
// Add other states here
)
}
@@ -56,13 +55,21 @@ fun aSpaceState(
seenSpaceInvites = seenSpaceInvites.toImmutableSet(),
hideInvitesAvatar = hideInvitesAvatar,
hasMoreToLoad = hasMoreToLoad,
eventSink = {}
)
eventSink = {})
private fun aListOfSpaceRooms(): List<SpaceRoom> {
return listOf(
aSpaceRoom(roomId = RoomId("!spaceId0:example.com")),
aSpaceRoom(roomId = RoomId("!spaceId1:example.com")),
aSpaceRoom(roomId = RoomId("!spaceId2:example.com")),
aSpaceRoom(
roomId = RoomId("!spaceId0:example.com"),
state = null,
),
aSpaceRoom(
roomId = RoomId("!spaceId1:example.com"),
state = CurrentUserMembership.JOINED,
),
aSpaceRoom(
roomId = RoomId("!spaceId2:example.com"),
state = CurrentUserMembership.INVITED,
),
)
}

View File

@@ -37,6 +37,7 @@ dependencies {
implementation(libs.coil.gif)
implementation(libs.coil.network.okhttp)
implementation(libs.jsoup)
implementation(projects.libraries.previewutils)
testCommonDependencies(libs, true)
testImplementation(projects.libraries.matrix.test)

View File

@@ -20,8 +20,10 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
@@ -31,6 +33,7 @@ import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle
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.compound.tokens.generated.CompoundIcons
@@ -41,8 +44,12 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.avatar.AvatarType
import io.element.android.libraries.designsystem.modifiers.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.ButtonSize
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.components.TextButton
import io.element.android.libraries.designsystem.theme.unreadIndicator
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.room.join.JoinRule
@@ -59,6 +66,7 @@ fun SpaceRoomItemView(
onClick: () -> Unit,
onLongClick: () -> Unit,
modifier: Modifier = Modifier,
trailingAction: @Composable (() -> Unit)? = null,
) {
SpaceRoomItemScaffold(
modifier = modifier,
@@ -67,16 +75,14 @@ fun SpaceRoomItemView(
hideAvatars = hideAvatars,
onClick = onClick,
onLongClick = onLongClick,
trailingAction = trailingAction,
) {
NameAndIndicatorRow(
isSpace = spaceRoom.isSpace,
name = spaceRoom.name,
showIndicator = showUnreadIndicator
isSpace = spaceRoom.isSpace, name = spaceRoom.name, showIndicator = showUnreadIndicator
)
Spacer(modifier = Modifier.height(1.dp))
SubtitleRow(
visibilityIcon = spaceRoom.visibilityIcon(),
subtitle = spaceRoom.subtitle()
visibilityIcon = spaceRoom.visibilityIcon(), subtitle = spaceRoom.subtitle()
)
Spacer(modifier = Modifier.height(1.dp))
Text(
@@ -166,7 +172,8 @@ private fun SpaceRoomItemScaffold(
onLongClick: () -> Unit,
hideAvatars: Boolean,
modifier: Modifier = Modifier,
content: @Composable ColumnScope.() -> Unit
trailingAction: @Composable (() -> Unit)? = null,
content: @Composable ColumnScope.() -> Unit,
) {
val clickModifier = Modifier
.combinedClickable(
@@ -174,8 +181,7 @@ private fun SpaceRoomItemScaffold(
onLongClick = onLongClick,
onLongClickLabel = stringResource(CommonStrings.action_open_context_menu),
indication = ripple(),
interactionSource = remember { MutableInteractionSource() }
)
interactionSource = remember { MutableInteractionSource() })
.onKeyboardContextMenuAction { onLongClick }
Row(
modifier = modifier
@@ -194,6 +200,10 @@ private fun SpaceRoomItemScaffold(
modifier = Modifier.weight(1f),
content = content,
)
if (trailingAction != null) {
Spacer(modifier = Modifier.width(16.dp))
trailingAction()
}
}
}
@@ -233,3 +243,16 @@ private fun SpaceRoom.visibilityIcon(): ImageVector? {
CompoundIcons.LockSolid()
}
}
@Composable
@PreviewsDayNight
internal fun SpaceRoomItemViewPreview(@PreviewParameter(SpaceRoomProvider::class) spaceRoom: SpaceRoom) = ElementPreview {
SpaceRoomItemView(
spaceRoom = spaceRoom,
showUnreadIndicator = spaceRoom.state == CurrentUserMembership.INVITED,
hideAvatars = false,
onClick = {},
onLongClick = {},
modifier = Modifier.fillMaxWidth()
)
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.ui.components
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
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.room.RoomType
import io.element.android.libraries.matrix.api.spaces.SpaceRoom
import io.element.android.libraries.previewutils.room.aSpaceRoom
class SpaceRoomProvider : PreviewParameterProvider<SpaceRoom> {
override val values: Sequence<SpaceRoom> = sequenceOf(
aSpaceRoom(
roomType = RoomType.Room,
name = "Room name",
topic = "Room topic that is quite long and might be truncated"
),
aSpaceRoom(
numJoinedMembers = 5,
childrenCount = 10,
worldReadable = true,
roomId = RoomId("!spaceId0:example.com"),
),
aSpaceRoom(
numJoinedMembers = 5,
childrenCount = 10,
worldReadable = true,
avatarUrl = "anUrl",
roomId = RoomId("!spaceId1:example.com"),
),
aSpaceRoom(
name = null,
numJoinedMembers = 5,
childrenCount = 10,
worldReadable = true,
avatarUrl = "anUrl",
roomId = RoomId("!spaceId2:example.com"),
state = CurrentUserMembership.INVITED,
),
aSpaceRoom(
name = null,
numJoinedMembers = 5,
childrenCount = 10,
worldReadable = true,
avatarUrl = "anUrl",
roomId = RoomId("!spaceId3:example.com"),
state = CurrentUserMembership.INVITED,
),
)
}