Room directory : implement simple join room
This commit is contained in:
parent
83b6875394
commit
0700384ef0
10 changed files with 89 additions and 19 deletions
|
|
@ -32,7 +32,7 @@ interface RoomDirectoryEntryPoint : FeatureEntryPoint {
|
|||
}
|
||||
|
||||
interface Callback : Plugin {
|
||||
fun onJoinRoom(roomId: RoomId)
|
||||
fun onOpenRoom(roomId: RoomId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,11 @@
|
|||
|
||||
package io.element.android.features.roomdirectory.impl.root
|
||||
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
|
||||
sealed interface RoomDirectoryEvents {
|
||||
data class JoinRoom(val roomId: RoomId) : RoomDirectoryEvents
|
||||
data class Search(val query: String) : RoomDirectoryEvents
|
||||
data object LoadMore : RoomDirectoryEvents
|
||||
data object JoinRoomDismissError : RoomDirectoryEvents
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ class RoomDirectoryNode @AssistedInject constructor(
|
|||
private val presenter: RoomDirectoryPresenter,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
|
||||
private fun onJoinRoom(roomId: RoomId) {
|
||||
private fun onRoomJoined(roomId: RoomId) {
|
||||
plugins<RoomDirectoryEntryPoint.Callback>().forEach {
|
||||
it.onJoinRoom(roomId)
|
||||
it.onOpenRoom(roomId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ class RoomDirectoryNode @AssistedInject constructor(
|
|||
val state = presenter.present()
|
||||
RoomDirectoryView(
|
||||
state = state,
|
||||
onJoinRoom = ::onJoinRoom,
|
||||
onRoomJoined = ::onRoomJoined,
|
||||
onBackPressed = ::navigateUp,
|
||||
modifier = modifier
|
||||
)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package io.element.android.features.roomdirectory.impl.root
|
|||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
|
|
@ -27,13 +28,17 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import io.element.android.features.roomdirectory.impl.root.model.toUiModel
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.architecture.runUpdatingState
|
||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryList
|
||||
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -41,6 +46,7 @@ import javax.inject.Inject
|
|||
|
||||
class RoomDirectoryPresenter @Inject constructor(
|
||||
private val dispatchers: CoroutineDispatchers,
|
||||
private val matrixClient: MatrixClient,
|
||||
roomDirectoryService: RoomDirectoryService,
|
||||
) : Presenter<RoomDirectoryState> {
|
||||
|
||||
|
|
@ -56,6 +62,9 @@ class RoomDirectoryPresenter @Inject constructor(
|
|||
val hasMoreToLoad by produceState(initialValue = true, allRooms) {
|
||||
value = roomDirectoryList.hasMoreToLoad()
|
||||
}
|
||||
val joinRoomAction: MutableState<AsyncAction<RoomId>> = remember {
|
||||
mutableStateOf(AsyncAction.Uninitialized)
|
||||
}
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
LaunchedEffect(searchQuery) {
|
||||
roomDirectoryList.filter(searchQuery, 20)
|
||||
|
|
@ -70,6 +79,12 @@ class RoomDirectoryPresenter @Inject constructor(
|
|||
is RoomDirectoryEvents.Search -> {
|
||||
searchQuery = event.query
|
||||
}
|
||||
is RoomDirectoryEvents.JoinRoom -> {
|
||||
coroutineScope.joinRoom(joinRoomAction, event.roomId)
|
||||
}
|
||||
RoomDirectoryEvents.JoinRoomDismissError -> {
|
||||
joinRoomAction.value = AsyncAction.Uninitialized
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -77,10 +92,17 @@ class RoomDirectoryPresenter @Inject constructor(
|
|||
query = searchQuery,
|
||||
roomDescriptions = allRooms,
|
||||
displayLoadMoreIndicator = hasMoreToLoad,
|
||||
joinRoomAction = joinRoomAction.value,
|
||||
eventSink = ::handleEvents
|
||||
)
|
||||
}
|
||||
|
||||
private fun CoroutineScope.joinRoom(state: MutableState<AsyncAction<RoomId>>, roomId: RoomId) = launch {
|
||||
state.runUpdatingState {
|
||||
matrixClient.joinRoom(roomId)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RoomDirectoryList.collectItemsAsState() = remember {
|
||||
items.map { list ->
|
||||
|
|
|
|||
|
|
@ -17,12 +17,15 @@
|
|||
package io.element.android.features.roomdirectory.impl.root
|
||||
|
||||
import io.element.android.features.roomdirectory.impl.root.model.RoomDescriptionUiModel
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
data class RoomDirectoryState(
|
||||
val query: String,
|
||||
val roomDescriptions: ImmutableList<RoomDescriptionUiModel>,
|
||||
val displayLoadMoreIndicator: Boolean,
|
||||
val joinRoomAction: AsyncAction<RoomId>,
|
||||
val eventSink: (RoomDirectoryEvents) -> Unit
|
||||
) {
|
||||
val displayEmptyState = roomDescriptions.isEmpty() && !displayLoadMoreIndicator
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ package io.element.android.features.roomdirectory.impl.root
|
|||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.features.roomdirectory.impl.root.model.RoomDescriptionUiModel
|
||||
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.designsystem.theme.components.SearchBarResultState
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -63,13 +63,13 @@ open class RoomDirectorySearchStateProvider : PreviewParameterProvider<RoomDirec
|
|||
|
||||
fun aRoomDirectoryState(
|
||||
query: String = "",
|
||||
isSearchActive: Boolean = false,
|
||||
displayLoadMoreIndicator: Boolean = false,
|
||||
roomDescriptions: ImmutableList<RoomDescriptionUiModel> = persistentListOf(),
|
||||
searchResults: SearchBarResultState<ImmutableList<RoomDescriptionUiModel>> = SearchBarResultState.Initial(),
|
||||
joinRoomAction: AsyncAction<RoomId> = AsyncAction.Uninitialized,
|
||||
) = RoomDirectoryState(
|
||||
query = query,
|
||||
roomDescriptions = roomDescriptions,
|
||||
displayLoadMoreIndicator = displayLoadMoreIndicator,
|
||||
joinRoomAction = joinRoomAction,
|
||||
eventSink = {},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,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.features.roomdirectory.impl.root.model.RoomDescriptionUiModel
|
||||
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.button.BackButton
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
|
|
@ -66,10 +67,15 @@ import kotlinx.collections.immutable.ImmutableList
|
|||
@Composable
|
||||
fun RoomDirectoryView(
|
||||
state: RoomDirectoryState,
|
||||
onRoomJoined: (RoomId) -> Unit,
|
||||
onBackPressed: () -> Unit,
|
||||
onJoinRoom: (RoomId) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
||||
fun joinRoom(roomId: RoomId) {
|
||||
state.eventSink(RoomDirectoryEvents.JoinRoom(roomId))
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
topBar = {
|
||||
|
|
@ -78,13 +84,19 @@ fun RoomDirectoryView(
|
|||
content = { padding ->
|
||||
RoomDirectoryContent(
|
||||
state = state,
|
||||
onResultClicked = onJoinRoom,
|
||||
onResultClicked = ::joinRoom,
|
||||
modifier = Modifier
|
||||
.padding(padding)
|
||||
.consumeWindowInsets(padding)
|
||||
)
|
||||
}
|
||||
)
|
||||
AsyncActionView(
|
||||
async = state.joinRoomAction,
|
||||
onSuccess = onRoomJoined,
|
||||
onErrorDismiss = {
|
||||
state.eventSink(RoomDirectoryEvents.JoinRoomDismissError)
|
||||
})
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
|
|
@ -295,7 +307,7 @@ private fun RoomDirectoryRoomRow(
|
|||
fun RoomDirectorySearchViewLightPreview(@PreviewParameter(RoomDirectorySearchStateProvider::class) state: RoomDirectoryState) = ElementPreview {
|
||||
RoomDirectoryView(
|
||||
state = state,
|
||||
onJoinRoom = {},
|
||||
onRoomJoined = {},
|
||||
onBackPressed = {},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue