Merge pull request #5493 from element-hq/feature/fga/space_description
feature(space): make sure to handle topic properly
This commit is contained in:
@@ -15,4 +15,7 @@ sealed interface SpaceEvents {
|
||||
data object ClearFailures : SpaceEvents
|
||||
data class AcceptInvite(val spaceRoom: SpaceRoom) : SpaceEvents
|
||||
data class DeclineInvite(val spaceRoom: SpaceRoom) : SpaceEvents
|
||||
|
||||
data class ShowTopicViewer(val topic: String) : SpaceEvents
|
||||
data object HideTopicViewer : SpaceEvents
|
||||
}
|
||||
|
||||
@@ -81,6 +81,8 @@ class SpacePresenter(
|
||||
val currentSpace by spaceRoomList.currentSpaceFlow.collectAsState()
|
||||
val (joinActions, setJoinActions) = remember { mutableStateOf(emptyMap<RoomId, AsyncAction<Unit>>()) }
|
||||
|
||||
var topicViewerState: TopicViewerState by remember { mutableStateOf(TopicViewerState.Hidden) }
|
||||
|
||||
LaunchedEffect(children) {
|
||||
// Remove joined children from the join actions
|
||||
val joinedChildren = children
|
||||
@@ -113,6 +115,8 @@ class SpacePresenter(
|
||||
AcceptDeclineInviteEvents.DeclineInvite(invite = event.spaceRoom.toInviteData(), shouldConfirm = true, blockUser = false)
|
||||
)
|
||||
}
|
||||
SpaceEvents.HideTopicViewer -> topicViewerState = TopicViewerState.Hidden
|
||||
is SpaceEvents.ShowTopicViewer -> topicViewerState = TopicViewerState.Shown(event.topic)
|
||||
}
|
||||
}
|
||||
return SpaceState(
|
||||
@@ -123,6 +127,7 @@ class SpacePresenter(
|
||||
hasMoreToLoad = hasMoreToLoad,
|
||||
joinActions = joinActions.toImmutableMap(),
|
||||
acceptDeclineInviteState = acceptDeclineInviteState,
|
||||
topicViewerState = topicViewerState,
|
||||
eventSink = ::handleEvents,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package io.element.android.features.space.impl.root
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
@@ -23,6 +24,7 @@ data class SpaceState(
|
||||
val hasMoreToLoad: Boolean,
|
||||
val joinActions: ImmutableMap<RoomId, AsyncAction<Unit>>,
|
||||
val acceptDeclineInviteState: AcceptDeclineInviteState,
|
||||
val topicViewerState: TopicViewerState,
|
||||
val eventSink: (SpaceEvents) -> Unit
|
||||
) {
|
||||
fun isJoining(spaceId: RoomId): Boolean = joinActions[spaceId] == AsyncAction.Loading
|
||||
@@ -30,3 +32,9 @@ data class SpaceState(
|
||||
it is AsyncAction.Failure
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
sealed interface TopicViewerState {
|
||||
data object Hidden : TopicViewerState
|
||||
data class Shown(val topic: String) : TopicViewerState
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
package io.element.android.features.space.impl.root
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
|
||||
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
|
||||
import io.element.android.features.invite.api.acceptdecline.anAcceptDeclineInviteState
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
@@ -25,51 +26,32 @@ open class SpaceStateProvider : PreviewParameterProvider<SpaceState> {
|
||||
override val values: Sequence<SpaceState>
|
||||
get() = sequenceOf(
|
||||
aSpaceState(),
|
||||
aSpaceState(parentSpace = aParentSpace(joinRule = JoinRule.Public)),
|
||||
aSpaceState(parentSpace = aParentSpace(joinRule = JoinRule.Restricted(persistentListOf()))),
|
||||
aSpaceState(children = aListOfSpaceRooms()),
|
||||
aSpaceState(
|
||||
parentSpace = aSpaceRoom(
|
||||
joinRule = JoinRule.Public
|
||||
)
|
||||
),
|
||||
aSpaceState(
|
||||
parentSpace = aSpaceRoom(
|
||||
joinRule = JoinRule.Restricted(persistentListOf())
|
||||
)
|
||||
),
|
||||
aSpaceState(
|
||||
parentSpace = aSpaceRoom(
|
||||
numJoinedMembers = 5,
|
||||
childrenCount = 10,
|
||||
worldReadable = true,
|
||||
),
|
||||
hasMoreToLoad = true,
|
||||
),
|
||||
aSpaceState(
|
||||
hasMoreToLoad = true,
|
||||
children = aListOfSpaceRooms(),
|
||||
),
|
||||
aSpaceState(
|
||||
hasMoreToLoad = false,
|
||||
parentSpace = aParentSpace(),
|
||||
children = aListOfSpaceRooms(),
|
||||
joiningRooms = setOf(RoomId("!spaceId0:example.com")),
|
||||
)
|
||||
hasMoreToLoad = false
|
||||
),
|
||||
aSpaceState(
|
||||
topicViewerState = TopicViewerState.Shown(topic = "Space description goes here." + LoremIpsum(20).values.first()),
|
||||
),
|
||||
// Add other states here
|
||||
)
|
||||
}
|
||||
|
||||
fun aSpaceState(
|
||||
parentSpace: SpaceRoom? = aSpaceRoom(
|
||||
numJoinedMembers = 5,
|
||||
childrenCount = 10,
|
||||
worldReadable = true,
|
||||
roomId = RoomId("!spaceId0:example.com"),
|
||||
),
|
||||
parentSpace: SpaceRoom? = aParentSpace(),
|
||||
children: List<SpaceRoom> = emptyList(),
|
||||
seenSpaceInvites: Set<RoomId> = emptySet(),
|
||||
joiningRooms: Set<RoomId> = emptySet(),
|
||||
joinActions: Map<RoomId, AsyncAction<Unit>> = joiningRooms.associateWith { AsyncAction.Loading },
|
||||
hideInvitesAvatar: Boolean = false,
|
||||
hasMoreToLoad: Boolean = false,
|
||||
hasMoreToLoad: Boolean = true,
|
||||
acceptDeclineInviteState: AcceptDeclineInviteState = anAcceptDeclineInviteState(),
|
||||
topicViewerState: TopicViewerState = TopicViewerState.Hidden,
|
||||
eventSink: (SpaceEvents) -> Unit = { },
|
||||
) = SpaceState(
|
||||
currentSpace = parentSpace,
|
||||
@@ -79,9 +61,23 @@ fun aSpaceState(
|
||||
hasMoreToLoad = hasMoreToLoad,
|
||||
joinActions = joinActions.toImmutableMap(),
|
||||
acceptDeclineInviteState = acceptDeclineInviteState,
|
||||
topicViewerState = topicViewerState,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
||||
private fun aParentSpace(
|
||||
joinRule: JoinRule? = null,
|
||||
): SpaceRoom {
|
||||
return aSpaceRoom(
|
||||
numJoinedMembers = 5,
|
||||
childrenCount = 10,
|
||||
worldReadable = true,
|
||||
joinRule = joinRule,
|
||||
roomId = RoomId("!spaceId0:example.com"),
|
||||
topic = "Space description goes here. " + LoremIpsum(20).values.first(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun aListOfSpaceRooms(): List<SpaceRoom> {
|
||||
return listOf(
|
||||
aSpaceRoom(
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package io.element.android.features.space.impl.root
|
||||
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@@ -33,6 +34,8 @@ import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.libraries.designsystem.atomic.molecules.InviteButtonsRowMolecule
|
||||
import io.element.android.libraries.designsystem.components.ClickableLinkText
|
||||
import io.element.android.libraries.designsystem.components.SimpleModalBottomSheet
|
||||
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
|
||||
@@ -61,6 +64,7 @@ import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun SpaceView(
|
||||
state: SpaceState,
|
||||
@@ -87,7 +91,10 @@ fun SpaceView(
|
||||
) {
|
||||
SpaceViewContent(
|
||||
state = state,
|
||||
onRoomClick = onRoomClick
|
||||
onRoomClick = onRoomClick,
|
||||
onTopicClick = { topic ->
|
||||
state.eventSink(SpaceEvents.ShowTopicViewer(topic))
|
||||
}
|
||||
)
|
||||
JoinRoomFailureEffect(
|
||||
hasAnyFailure = state.hasAnyFailure,
|
||||
@@ -97,6 +104,14 @@ fun SpaceView(
|
||||
}
|
||||
},
|
||||
)
|
||||
if (state.topicViewerState is TopicViewerState.Shown) {
|
||||
TopicViewerBottomSheet(
|
||||
topicViewerState = state.topicViewerState,
|
||||
onDismiss = {
|
||||
state.eventSink(SpaceEvents.HideTopicViewer)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -120,10 +135,31 @@ private fun JoinRoomFailureEffect(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TopicViewerBottomSheet(
|
||||
topicViewerState: TopicViewerState.Shown,
|
||||
onDismiss: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
SimpleModalBottomSheet(
|
||||
title = stringResource(CommonStrings.common_description),
|
||||
onDismiss = onDismiss,
|
||||
modifier = modifier
|
||||
) {
|
||||
ClickableLinkText(
|
||||
text = topicViewerState.topic,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SpaceViewContent(
|
||||
state: SpaceState,
|
||||
onRoomClick: (spaceRoom: SpaceRoom) -> Unit,
|
||||
onTopicClick: (String) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
LazyColumn(modifier.fillMaxSize()) {
|
||||
@@ -134,9 +170,11 @@ private fun SpaceViewContent(
|
||||
avatarData = currentSpace.getAvatarData(AvatarSize.SpaceHeader),
|
||||
name = currentSpace.displayName,
|
||||
topic = currentSpace.topic,
|
||||
topicMaxLines = 2,
|
||||
visibility = currentSpace.visibility,
|
||||
heroes = currentSpace.heroes.toImmutableList(),
|
||||
numberOfMembers = currentSpace.numJoinedMembers,
|
||||
onTopicClick = onTopicClick
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ class SpacePresenterTest {
|
||||
assertThat(state.hasMoreToLoad).isTrue()
|
||||
assertThat(state.joinActions).isEmpty()
|
||||
assertThat(state.acceptDeclineInviteState).isEqualTo(anAcceptDeclineInviteState())
|
||||
assertThat(state.topicViewerState).isEqualTo(TopicViewerState.Hidden)
|
||||
advanceUntilIdle()
|
||||
paginateResult.assertions().isCalledOnce()
|
||||
}
|
||||
@@ -236,6 +237,24 @@ class SpacePresenterTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - topic viewer state`() = runTest {
|
||||
val paginateResult = lambdaRecorder<Result<Unit>> {
|
||||
Result.success(Unit)
|
||||
}
|
||||
val spaceRoomList = FakeSpaceRoomList(paginateResult = paginateResult)
|
||||
val presenter = createSpacePresenter(spaceRoomList = spaceRoomList)
|
||||
presenter.test {
|
||||
val state = awaitItem()
|
||||
assertThat(state.topicViewerState).isEqualTo(TopicViewerState.Hidden)
|
||||
advanceUntilIdle()
|
||||
state.eventSink(SpaceEvents.ShowTopicViewer("topic"))
|
||||
assertThat(awaitItem().topicViewerState).isEqualTo(TopicViewerState.Shown("topic"))
|
||||
state.eventSink(SpaceEvents.HideTopicViewer)
|
||||
assertThat(awaitItem().topicViewerState).isEqualTo(TopicViewerState.Hidden)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - accept invite is transmitted to acceptDeclineInviteState`() {
|
||||
`invite action is transmitted to acceptDeclineInviteState`(
|
||||
|
||||
@@ -18,6 +18,7 @@ import io.element.android.libraries.matrix.api.room.CurrentUserMembership
|
||||
import io.element.android.libraries.matrix.api.spaces.SpaceRoom
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_NAME
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_TOPIC
|
||||
import io.element.android.libraries.previewutils.room.aSpaceRoom
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
@@ -31,6 +32,7 @@ import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SpaceViewTest {
|
||||
@@ -42,6 +44,7 @@ class SpaceViewTest {
|
||||
ensureCalledOnce {
|
||||
rule.setSpaceView(
|
||||
aSpaceState(
|
||||
hasMoreToLoad = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onBackClick = it,
|
||||
@@ -58,6 +61,7 @@ class SpaceViewTest {
|
||||
rule.setSpaceView(
|
||||
aSpaceState(
|
||||
children = listOf(aSpaceRoom),
|
||||
hasMoreToLoad = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onRoomClick = it,
|
||||
@@ -73,6 +77,7 @@ class SpaceViewTest {
|
||||
rule.setSpaceView(
|
||||
aSpaceState(
|
||||
children = listOf(aSpaceRoom),
|
||||
hasMoreToLoad = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
@@ -80,12 +85,14 @@ class SpaceViewTest {
|
||||
eventsRecorder.assertSingle(SpaceEvents.Join(aSpaceRoom))
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on accept invite emits the expected Event`() {
|
||||
val aSpaceRoom = aSpaceRoom(roomId = A_ROOM_ID, state = CurrentUserMembership.INVITED)
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>()
|
||||
rule.setSpaceView(
|
||||
aSpaceState(
|
||||
hasMoreToLoad = false,
|
||||
children = listOf(aSpaceRoom),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
@@ -94,12 +101,14 @@ class SpaceViewTest {
|
||||
eventsRecorder.assertSingle(SpaceEvents.AcceptInvite(aSpaceRoom))
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on decline invite emits the expected Event`() {
|
||||
val aSpaceRoom = aSpaceRoom(roomId = A_ROOM_ID, state = CurrentUserMembership.INVITED)
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>()
|
||||
rule.setSpaceView(
|
||||
aSpaceState(
|
||||
hasMoreToLoad = false,
|
||||
children = listOf(aSpaceRoom),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
@@ -107,6 +116,21 @@ class SpaceViewTest {
|
||||
rule.clickOn(CommonStrings.action_decline)
|
||||
eventsRecorder.assertSingle(SpaceEvents.DeclineInvite(aSpaceRoom))
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on topic emits the expected Event`() {
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>()
|
||||
rule.setSpaceView(
|
||||
aSpaceState(
|
||||
parentSpace = aSpaceRoom(topic = A_ROOM_TOPIC),
|
||||
hasMoreToLoad = false,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
rule.onNodeWithText(A_ROOM_TOPIC).performClick()
|
||||
eventsRecorder.assertSingle(SpaceEvents.ShowTopicViewer(A_ROOM_TOPIC))
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setSpaceView(
|
||||
|
||||
@@ -20,6 +20,7 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
@@ -51,6 +52,7 @@ fun ClickableLinkText(
|
||||
onClick: () -> Unit = {},
|
||||
onLongClick: () -> Unit = {},
|
||||
style: TextStyle = LocalTextStyle.current,
|
||||
color: Color = Color.Unspecified,
|
||||
inlineContent: ImmutableMap<String, InlineTextContent> = persistentMapOf(),
|
||||
) {
|
||||
ClickableLinkText(
|
||||
@@ -62,6 +64,7 @@ fun ClickableLinkText(
|
||||
onClick = onClick,
|
||||
onLongClick = onLongClick,
|
||||
style = style,
|
||||
color = color,
|
||||
inlineContent = inlineContent,
|
||||
)
|
||||
}
|
||||
@@ -76,6 +79,7 @@ fun ClickableLinkText(
|
||||
onClick: () -> Unit = {},
|
||||
onLongClick: () -> Unit = {},
|
||||
style: TextStyle = LocalTextStyle.current,
|
||||
color: Color = Color.Unspecified,
|
||||
inlineContent: ImmutableMap<String, InlineTextContent> = persistentMapOf(),
|
||||
) {
|
||||
@Suppress("NAME_SHADOWING")
|
||||
@@ -126,6 +130,7 @@ fun ClickableLinkText(
|
||||
text = annotatedString,
|
||||
modifier = modifier.then(pressIndicator),
|
||||
style = style,
|
||||
color = color,
|
||||
onTextLayout = {
|
||||
layoutResult.value = it
|
||||
},
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.components
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun SimpleModalBottomSheet(
|
||||
title: String,
|
||||
onDismiss: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable ColumnScope.() -> Unit,
|
||||
) {
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = onDismiss,
|
||||
modifier = modifier,
|
||||
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
) {
|
||||
Text(
|
||||
title,
|
||||
style = ElementTheme.typography.fontBodyLgMedium,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
content()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun SimpleModalBottomSheetPreview() = ElementPreview {
|
||||
SimpleModalBottomSheet(title = "A title", onDismiss = {}) {
|
||||
Text(
|
||||
text = LoremIpsum(20).values.first(),
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package io.element.android.libraries.matrix.ui.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -43,6 +44,7 @@ fun SpaceHeaderView(
|
||||
numberOfMembers: Int,
|
||||
modifier: Modifier = Modifier,
|
||||
topicMaxLines: Int = Int.MAX_VALUE,
|
||||
onTopicClick: ((String) -> Unit)? = null,
|
||||
) {
|
||||
RoomPreviewOrganism(
|
||||
modifier = modifier.padding(24.dp),
|
||||
@@ -68,7 +70,16 @@ fun SpaceHeaderView(
|
||||
description = if (topic.isNullOrBlank()) {
|
||||
null
|
||||
} else {
|
||||
{ RoomPreviewDescriptionAtom(description = topic, maxLines = topicMaxLines) }
|
||||
{
|
||||
RoomPreviewDescriptionAtom(
|
||||
description = topic,
|
||||
maxLines = topicMaxLines,
|
||||
modifier = Modifier.clickable(
|
||||
enabled = onTopicClick != null,
|
||||
onClick = { onTopicClick?.invoke(topic) }
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
memberCount = {
|
||||
SpaceMembersView(
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user