Room navigation : make it working with RoomDirectory

This commit is contained in:
ganfra 2024-04-10 15:14:59 +02:00
parent 9604acb75a
commit db9a402ce5
20 changed files with 226 additions and 163 deletions

View file

@ -25,6 +25,7 @@ import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.features.roomdirectory.api.RoomDirectoryEntryPoint
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.core.RoomId
@ -35,9 +36,16 @@ class RoomDirectoryNode @AssistedInject constructor(
@Assisted plugins: List<Plugin>,
private val presenter: RoomDirectoryPresenter,
) : Node(buildContext, plugins = plugins) {
private fun onResultClicked(roomDescription: RoomDescription) {
plugins<RoomDirectoryEntryPoint.Callback>().forEach {
it.onResultClicked(roomDescription)
}
}
private fun onRoomJoined(roomId: RoomId) {
plugins<RoomDirectoryEntryPoint.Callback>().forEach {
it.onOpenRoom(roomId)
it.onRoomJoined(roomId)
}
}
@ -47,6 +55,7 @@ class RoomDirectoryNode @AssistedInject constructor(
RoomDirectoryView(
state = state,
onRoomJoined = ::onRoomJoined,
onResultClicked = ::onResultClicked,
onBackPressed = ::navigateUp,
modifier = modifier
)

View file

@ -19,8 +19,6 @@ package io.element.android.features.roomdirectory.impl.root
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.matrix.api.core.RoomId
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@ -71,25 +69,17 @@ fun aRoomDescriptionList(): ImmutableList<RoomDescription> {
roomId = RoomId("!exa:matrix.org"),
name = "Element X Android",
description = "Element X is a secure, private and decentralized messenger.",
avatarData = AvatarData(
id = "!exa:matrix.org",
name = "Element X Android",
url = null,
size = AvatarSize.RoomDirectoryItem
),
avatarUrl = null,
canBeJoined = true,
numberOfMembers = 2765,
),
RoomDescription(
roomId = RoomId("!exi:matrix.org"),
name = "Element X iOS",
description = "Element X is a secure, private and decentralized messenger.",
avatarData = AvatarData(
id = "!exi:matrix.org",
name = "Element X iOS",
url = null,
size = AvatarSize.RoomDirectoryItem
),
avatarUrl = null,
canBeJoined = false,
numberOfMembers = 356,
)
)
}

View file

@ -51,6 +51,7 @@ import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.features.roomdirectory.impl.R
import io.element.android.libraries.designsystem.components.async.AsyncActionView
import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@ -70,12 +71,13 @@ import kotlinx.collections.immutable.ImmutableList
@Composable
fun RoomDirectoryView(
state: RoomDirectoryState,
onResultClicked: (RoomDescription) -> Unit,
onRoomJoined: (RoomId) -> Unit,
onBackPressed: () -> Unit,
modifier: Modifier = Modifier,
) {
fun joinRoom(roomId: RoomId) {
state.eventSink(RoomDirectoryEvents.JoinRoom(roomId))
fun joinRoom(roomDescription: RoomDescription) {
state.eventSink(RoomDirectoryEvents.JoinRoom(roomDescription.roomId))
}
Scaffold(
@ -86,10 +88,11 @@ fun RoomDirectoryView(
content = { padding ->
RoomDirectoryContent(
state = state,
onResultClicked = ::joinRoom,
onResultClicked = onResultClicked,
onJoinClicked = ::joinRoom,
modifier = Modifier
.padding(padding)
.consumeWindowInsets(padding)
.padding(padding)
.consumeWindowInsets(padding)
)
}
)
@ -128,7 +131,8 @@ private fun RoomDirectoryTopBar(
@Composable
private fun RoomDirectoryContent(
state: RoomDirectoryState,
onResultClicked: (RoomId) -> Unit,
onResultClicked: (RoomDescription) -> Unit,
onJoinClicked: (RoomDescription) -> Unit,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
@ -143,6 +147,7 @@ private fun RoomDirectoryContent(
displayLoadMoreIndicator = state.displayLoadMoreIndicator,
displayEmptyState = state.displayEmptyState,
onResultClicked = onResultClicked,
onJoinClicked = onJoinClicked,
onReachedLoadMore = { state.eventSink(RoomDirectoryEvents.LoadMore) },
)
}
@ -153,7 +158,8 @@ private fun RoomDirectoryRoomList(
roomDescriptions: ImmutableList<RoomDescription>,
displayLoadMoreIndicator: Boolean,
displayEmptyState: Boolean,
onResultClicked: (RoomId) -> Unit,
onResultClicked: (RoomDescription) -> Unit,
onJoinClicked: (RoomDescription) -> Unit,
onReachedLoadMore: () -> Unit,
modifier: Modifier = Modifier,
) {
@ -161,7 +167,12 @@ private fun RoomDirectoryRoomList(
items(roomDescriptions) { roomDescription ->
RoomDirectoryRoomRow(
roomDescription = roomDescription,
onClick = onResultClicked,
onClick = {
onResultClicked(roomDescription)
},
onJoinClick = {
onJoinClicked(roomDescription)
},
)
}
if (displayEmptyState) {
@ -188,10 +199,10 @@ private fun RoomDirectoryRoomList(
@Composable
private fun LoadMoreIndicator(modifier: Modifier = Modifier) {
Box(
modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(24.dp),
modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(24.dp),
contentAlignment = Alignment.Center,
) {
CircularProgressIndicator(
@ -256,30 +267,29 @@ private fun SearchTextField(
@Composable
private fun RoomDirectoryRoomRow(
roomDescription: RoomDescription,
onClick: (RoomId) -> Unit,
onClick: () -> Unit,
onJoinClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier
.fillMaxWidth()
.clickable(enabled = roomDescription.canBeJoined) {
onClick(roomDescription.roomId)
}
.padding(
top = 12.dp,
bottom = 12.dp,
start = 16.dp,
)
.height(IntrinsicSize.Min),
.fillMaxWidth()
.clickable(enabled = roomDescription.canBeJoined, onClick = onClick)
.padding(
top = 12.dp,
bottom = 12.dp,
start = 16.dp,
)
.height(IntrinsicSize.Min),
) {
Avatar(
avatarData = roomDescription.avatarData,
avatarData = roomDescription.avatarData(AvatarSize.RoomDirectoryItem),
modifier = Modifier.align(Alignment.CenterVertically)
)
Column(
modifier = Modifier
.weight(1f)
.padding(start = 16.dp)
.weight(1f)
.padding(start = 16.dp)
) {
Text(
text = roomDescription.name,
@ -301,8 +311,9 @@ private fun RoomDirectoryRoomRow(
text = stringResource(id = CommonStrings.action_join),
color = ElementTheme.colors.textSuccessPrimary,
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(start = 4.dp, end = 12.dp)
.align(Alignment.CenterVertically)
.clickable(onClick = onJoinClick)
.padding(start = 4.dp, end = 12.dp)
)
} else {
Spacer(modifier = Modifier.width(24.dp))
@ -315,6 +326,7 @@ private fun RoomDirectoryRoomRow(
internal fun RoomDirectoryViewPreview(@PreviewParameter(RoomDirectoryStateProvider::class) state: RoomDirectoryState) = ElementPreview {
RoomDirectoryView(
state = state,
onResultClicked = {},
onRoomJoined = {},
onBackPressed = {},
)

View file

@ -42,12 +42,8 @@ fun MatrixRoomDescription.toFeatureModel(): RoomDescription {
roomId = roomId,
name = name(),
description = description(),
avatarData = AvatarData(
id = roomId.value,
name = name,
url = avatarUrl,
size = AvatarSize.RoomDirectoryItem,
),
avatarUrl = avatarUrl,
numberOfMembers = numberOfMembers,
canBeJoined = joinRule == MatrixRoomDescription.JoinRule.PUBLIC,
)
}

View file

@ -105,7 +105,7 @@ private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomD
setContent {
RoomDirectoryView(
state = state,
onRoomJoined = onRoomJoined,
onRoomClicked = onRoomJoined,
onBackPressed = onBackPressed,
)
}