feature(space): make sure to handle topic properly
This commit is contained in:
parent
dbc0c42e31
commit
9d05eb8e6f
7 changed files with 102 additions and 3 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,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
|
||||
|
|
@ -112,6 +114,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(
|
||||
|
|
@ -122,6 +126,7 @@ class SpacePresenter(
|
|||
hasMoreToLoad = hasMoreToLoad,
|
||||
joinActions = joinActions.toPersistentMap(),
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,17 @@ open class SpaceStateProvider : PreviewParameterProvider<SpaceState> {
|
|||
hasMoreToLoad = false,
|
||||
children = aListOfSpaceRooms(),
|
||||
joiningRooms = setOf(RoomId("!spaceId0:example.com")),
|
||||
)
|
||||
),
|
||||
aSpaceState(
|
||||
hasMoreToLoad = false,
|
||||
topicViewerState = TopicViewerState.Shown(
|
||||
topic = "Description of the space goes right here. Lorem ipsum dolor sit amet consectetur. " +
|
||||
"Leo viverra morbi habitant in. Sem amet enim habitant nibh augue mauris. " +
|
||||
"Interdum mauris ultrices tincidunt proin morbi erat aenean risus nibh. " +
|
||||
"Diam amet sit fermentum vulputate faucibus."
|
||||
),
|
||||
children = aListOfSpaceRooms(),
|
||||
),
|
||||
// Add other states here
|
||||
)
|
||||
}
|
||||
|
|
@ -70,6 +80,7 @@ fun aSpaceState(
|
|||
hideInvitesAvatar: Boolean = false,
|
||||
hasMoreToLoad: Boolean = false,
|
||||
acceptDeclineInviteState: AcceptDeclineInviteState = anAcceptDeclineInviteState(),
|
||||
topicViewerState: TopicViewerState = TopicViewerState.Hidden,
|
||||
eventSink: (SpaceEvents) -> Unit = { },
|
||||
) = SpaceState(
|
||||
currentSpace = parentSpace,
|
||||
|
|
@ -79,6 +90,7 @@ fun aSpaceState(
|
|||
hasMoreToLoad = hasMoreToLoad,
|
||||
joinActions = joinActions.toImmutableMap(),
|
||||
acceptDeclineInviteState = acceptDeclineInviteState,
|
||||
topicViewerState = topicViewerState,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,13 +7,18 @@
|
|||
|
||||
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.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
|
|
@ -33,6 +38,7 @@ 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.async.AsyncIndicator
|
||||
import io.element.android.libraries.designsystem.components.async.AsyncIndicatorHost
|
||||
import io.element.android.libraries.designsystem.components.async.rememberAsyncIndicatorState
|
||||
|
|
@ -48,6 +54,7 @@ import io.element.android.libraries.designsystem.theme.components.DropdownMenu
|
|||
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.IconButton
|
||||
import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet
|
||||
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||
|
|
@ -61,6 +68,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 +95,10 @@ fun SpaceView(
|
|||
) {
|
||||
SpaceViewContent(
|
||||
state = state,
|
||||
onRoomClick = onRoomClick
|
||||
onRoomClick = onRoomClick,
|
||||
onTopicClick = { topic ->
|
||||
state.eventSink(SpaceEvents.ShowTopicViewer(topic))
|
||||
}
|
||||
)
|
||||
JoinRoomFailureEffect(
|
||||
hasAnyFailure = state.hasAnyFailure,
|
||||
|
|
@ -97,6 +108,14 @@ fun SpaceView(
|
|||
}
|
||||
},
|
||||
)
|
||||
if (state.topicViewerState is TopicViewerState.Shown) {
|
||||
TopicViewerBottomSheet(
|
||||
topicViewerState = state.topicViewerState,
|
||||
onDismiss = {
|
||||
state.eventSink(SpaceEvents.HideTopicViewer)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -120,10 +139,44 @@ private fun JoinRoomFailureEffect(
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun TopicViewerBottomSheet(
|
||||
topicViewerState: TopicViewerState.Shown,
|
||||
onDismiss: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = onDismiss,
|
||||
modifier = modifier,
|
||||
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
) {
|
||||
Text(
|
||||
stringResource(CommonStrings.common_description),
|
||||
style = ElementTheme.typography.fontBodyLgMedium,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
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 +187,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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue