feature (space) : add trailing action to SpaceRoomItemView
This commit is contained in:
parent
0931244713
commit
7050076beb
4 changed files with 116 additions and 29 deletions
|
|
@ -9,6 +9,7 @@ package io.element.android.features.space.impl
|
||||||
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
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.matrix.api.spaces.SpaceRoom
|
||||||
import io.element.android.libraries.previewutils.room.aSpaceRoom
|
import io.element.android.libraries.previewutils.room.aSpaceRoom
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
|
|
@ -17,24 +18,22 @@ import kotlinx.collections.immutable.toImmutableSet
|
||||||
open class SpaceStateProvider : PreviewParameterProvider<SpaceState> {
|
open class SpaceStateProvider : PreviewParameterProvider<SpaceState> {
|
||||||
override val values: Sequence<SpaceState>
|
override val values: Sequence<SpaceState>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
aSpaceState(),
|
|
||||||
aSpaceState(
|
aSpaceState(
|
||||||
parentSpace = aSpaceRoom(
|
|
||||||
name = null,
|
), aSpaceState(
|
||||||
numJoinedMembers = 5,
|
parentSpace = aSpaceRoom(
|
||||||
childrenCount = 10,
|
name = null,
|
||||||
worldReadable = true,
|
numJoinedMembers = 5,
|
||||||
),
|
childrenCount = 10,
|
||||||
hasMoreToLoad = true,
|
worldReadable = true,
|
||||||
),
|
),
|
||||||
aSpaceState(
|
hasMoreToLoad = true,
|
||||||
hasMoreToLoad = true,
|
), aSpaceState(
|
||||||
children = aListOfSpaceRooms(),
|
hasMoreToLoad = true,
|
||||||
),
|
children = aListOfSpaceRooms(),
|
||||||
aSpaceState(
|
), aSpaceState(
|
||||||
hasMoreToLoad = false,
|
hasMoreToLoad = false, children = aListOfSpaceRooms()
|
||||||
children = aListOfSpaceRooms()
|
)
|
||||||
)
|
|
||||||
// Add other states here
|
// Add other states here
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -56,13 +55,21 @@ fun aSpaceState(
|
||||||
seenSpaceInvites = seenSpaceInvites.toImmutableSet(),
|
seenSpaceInvites = seenSpaceInvites.toImmutableSet(),
|
||||||
hideInvitesAvatar = hideInvitesAvatar,
|
hideInvitesAvatar = hideInvitesAvatar,
|
||||||
hasMoreToLoad = hasMoreToLoad,
|
hasMoreToLoad = hasMoreToLoad,
|
||||||
eventSink = {}
|
eventSink = {})
|
||||||
)
|
|
||||||
|
|
||||||
private fun aListOfSpaceRooms(): List<SpaceRoom> {
|
private fun aListOfSpaceRooms(): List<SpaceRoom> {
|
||||||
return listOf(
|
return listOf(
|
||||||
aSpaceRoom(roomId = RoomId("!spaceId0:example.com")),
|
aSpaceRoom(
|
||||||
aSpaceRoom(roomId = RoomId("!spaceId1:example.com")),
|
roomId = RoomId("!spaceId0:example.com"),
|
||||||
aSpaceRoom(roomId = RoomId("!spaceId2:example.com")),
|
state = null,
|
||||||
|
),
|
||||||
|
aSpaceRoom(
|
||||||
|
roomId = RoomId("!spaceId1:example.com"),
|
||||||
|
state = CurrentUserMembership.JOINED,
|
||||||
|
),
|
||||||
|
aSpaceRoom(
|
||||||
|
roomId = RoomId("!spaceId2:example.com"),
|
||||||
|
state = CurrentUserMembership.INVITED,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ dependencies {
|
||||||
implementation(libs.coil.gif)
|
implementation(libs.coil.gif)
|
||||||
implementation(libs.coil.network.okhttp)
|
implementation(libs.coil.network.okhttp)
|
||||||
implementation(libs.jsoup)
|
implementation(libs.jsoup)
|
||||||
|
implementation(projects.libraries.previewutils)
|
||||||
|
|
||||||
testCommonDependencies(libs, true)
|
testCommonDependencies(libs, true)
|
||||||
testImplementation(projects.libraries.matrix.test)
|
testImplementation(projects.libraries.matrix.test)
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,10 @@ import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.ripple
|
import androidx.compose.material3.ripple
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.ReadOnlyComposable
|
import androidx.compose.runtime.ReadOnlyComposable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
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.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontStyle
|
import androidx.compose.ui.text.font.FontStyle
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.element.android.compound.theme.ElementTheme
|
import io.element.android.compound.theme.ElementTheme
|
||||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
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.AvatarSize
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarType
|
import io.element.android.libraries.designsystem.components.avatar.AvatarType
|
||||||
import io.element.android.libraries.designsystem.modifiers.onKeyboardContextMenuAction
|
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.Icon
|
||||||
import io.element.android.libraries.designsystem.theme.components.Text
|
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.designsystem.theme.unreadIndicator
|
||||||
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
|
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
|
||||||
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
||||||
|
|
@ -59,6 +66,7 @@ fun SpaceRoomItemView(
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
onLongClick: () -> Unit,
|
onLongClick: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
trailingAction: @Composable (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
SpaceRoomItemScaffold(
|
SpaceRoomItemScaffold(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
|
@ -67,16 +75,14 @@ fun SpaceRoomItemView(
|
||||||
hideAvatars = hideAvatars,
|
hideAvatars = hideAvatars,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
onLongClick = onLongClick,
|
onLongClick = onLongClick,
|
||||||
|
trailingAction = trailingAction,
|
||||||
) {
|
) {
|
||||||
NameAndIndicatorRow(
|
NameAndIndicatorRow(
|
||||||
isSpace = spaceRoom.isSpace,
|
isSpace = spaceRoom.isSpace, name = spaceRoom.name, showIndicator = showUnreadIndicator
|
||||||
name = spaceRoom.name,
|
|
||||||
showIndicator = showUnreadIndicator
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(1.dp))
|
Spacer(modifier = Modifier.height(1.dp))
|
||||||
SubtitleRow(
|
SubtitleRow(
|
||||||
visibilityIcon = spaceRoom.visibilityIcon(),
|
visibilityIcon = spaceRoom.visibilityIcon(), subtitle = spaceRoom.subtitle()
|
||||||
subtitle = spaceRoom.subtitle()
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(1.dp))
|
Spacer(modifier = Modifier.height(1.dp))
|
||||||
Text(
|
Text(
|
||||||
|
|
@ -166,7 +172,8 @@ private fun SpaceRoomItemScaffold(
|
||||||
onLongClick: () -> Unit,
|
onLongClick: () -> Unit,
|
||||||
hideAvatars: Boolean,
|
hideAvatars: Boolean,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
content: @Composable ColumnScope.() -> Unit
|
trailingAction: @Composable (() -> Unit)? = null,
|
||||||
|
content: @Composable ColumnScope.() -> Unit,
|
||||||
) {
|
) {
|
||||||
val clickModifier = Modifier
|
val clickModifier = Modifier
|
||||||
.combinedClickable(
|
.combinedClickable(
|
||||||
|
|
@ -174,8 +181,7 @@ private fun SpaceRoomItemScaffold(
|
||||||
onLongClick = onLongClick,
|
onLongClick = onLongClick,
|
||||||
onLongClickLabel = stringResource(CommonStrings.action_open_context_menu),
|
onLongClickLabel = stringResource(CommonStrings.action_open_context_menu),
|
||||||
indication = ripple(),
|
indication = ripple(),
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
interactionSource = remember { MutableInteractionSource() })
|
||||||
)
|
|
||||||
.onKeyboardContextMenuAction { onLongClick }
|
.onKeyboardContextMenuAction { onLongClick }
|
||||||
Row(
|
Row(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
|
@ -194,6 +200,10 @@ private fun SpaceRoomItemScaffold(
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
content = content,
|
content = content,
|
||||||
)
|
)
|
||||||
|
if (trailingAction != null) {
|
||||||
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
trailingAction()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,3 +243,16 @@ private fun SpaceRoom.visibilityIcon(): ImageVector? {
|
||||||
CompoundIcons.LockSolid()
|
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()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue