Resolve RoomId in RoomFlowNode.
This commit is contained in:
parent
09faa6d1c9
commit
235ef2a71b
9 changed files with 98 additions and 51 deletions
|
|
@ -43,17 +43,19 @@ import io.element.android.libraries.architecture.BaseFlowNode
|
|||
import io.element.android.libraries.architecture.NodeInputs
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
import io.element.android.libraries.architecture.inputs
|
||||
import io.element.android.libraries.designsystem.components.async.AsyncFailure
|
||||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.RoomAlias
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
|
||||
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
|
||||
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import timber.log.Timber
|
||||
import java.util.Optional
|
||||
|
|
@ -87,43 +89,72 @@ class RoomFlowNode @AssistedInject constructor(
|
|||
data object Loading : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object JoinRoom : NavTarget
|
||||
data class JoinRoom(val roomId: RoomId) : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data class RoomAliasError(val roomAlias: RoomAlias) : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data class JoinedRoom(val roomId: RoomId) : NavTarget
|
||||
}
|
||||
|
||||
private var roomMembershipJob: Job? = null
|
||||
|
||||
override fun onBuilt() {
|
||||
super.onBuilt()
|
||||
resolveRoomId()
|
||||
}
|
||||
|
||||
private fun resolveRoomId() {
|
||||
lifecycleScope.launch {
|
||||
when (val i = inputs.roomIdOrAlias) {
|
||||
is RoomIdOrAlias.Alias -> {
|
||||
client.resolveRoomAlias(i.roomAlias)
|
||||
.onFailure {
|
||||
Timber.e(it, "Failed to resolve room alias")
|
||||
backstack.newRoot(NavTarget.RoomAliasError(i.roomAlias))
|
||||
}
|
||||
.onSuccess {
|
||||
subscribeToRoomInfoFlow(it)
|
||||
}
|
||||
}
|
||||
is RoomIdOrAlias.Id -> {
|
||||
subscribeToRoomInfoFlow(i.roomId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun subscribeToRoomInfoFlow(roomId: RoomId) {
|
||||
client.getRoomInfoFlow(
|
||||
inputs.roomIdOrAlias
|
||||
roomId
|
||||
).onEach { roomInfo ->
|
||||
Timber.d("Room membership: ${roomInfo.map { it.currentUserMembership }}")
|
||||
val info = roomInfo.getOrNull()
|
||||
if (info?.currentUserMembership == CurrentUserMembership.JOINED) {
|
||||
backstack.newRoot(NavTarget.JoinedRoom(info.id))
|
||||
// When leaving the room from this session only, navigate up.
|
||||
roomMembershipJob?.cancel()
|
||||
roomMembershipJob = roomMembershipObserver.updates
|
||||
.filter { update -> update.roomId == info.id && !update.isUserInRoom }
|
||||
.onEach {
|
||||
navigateUp()
|
||||
}
|
||||
.launchIn(lifecycleScope)
|
||||
backstack.newRoot(NavTarget.JoinedRoom(roomId))
|
||||
} else {
|
||||
backstack.newRoot(NavTarget.JoinRoom)
|
||||
backstack.newRoot(NavTarget.JoinRoom(roomId))
|
||||
}
|
||||
}
|
||||
.launchIn(lifecycleScope)
|
||||
|
||||
// When leaving the room from this session only, navigate up.
|
||||
roomMembershipObserver.updates
|
||||
.filter { update -> update.roomId == roomId && !update.isUserInRoom }
|
||||
.onEach {
|
||||
navigateUp()
|
||||
}
|
||||
.launchIn(lifecycleScope)
|
||||
}
|
||||
|
||||
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
||||
return when (navTarget) {
|
||||
NavTarget.Loading -> loadingNode(buildContext)
|
||||
NavTarget.JoinRoom -> {
|
||||
val inputs = JoinRoomEntryPoint.Inputs(inputs.roomIdOrAlias, roomDescription = inputs.roomDescription)
|
||||
is NavTarget.JoinRoom -> {
|
||||
val inputs = JoinRoomEntryPoint.Inputs(
|
||||
roomId = navTarget.roomId,
|
||||
roomIdOrAlias = inputs.roomIdOrAlias,
|
||||
roomDescription = inputs.roomDescription,
|
||||
)
|
||||
joinRoomEntryPoint.createNode(this, buildContext, inputs)
|
||||
}
|
||||
is NavTarget.JoinedRoom -> {
|
||||
|
|
@ -131,6 +162,7 @@ class RoomFlowNode @AssistedInject constructor(
|
|||
val inputs = JoinedRoomFlowNode.Inputs(navTarget.roomId, initialElement = inputs.initialElement)
|
||||
createNode<JoinedRoomFlowNode>(buildContext, plugins = listOf(inputs) + roomFlowNodeCallback)
|
||||
}
|
||||
is NavTarget.RoomAliasError -> roomAliasErrorNode(buildContext, navTarget.roomAlias)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +172,15 @@ class RoomFlowNode @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun roomAliasErrorNode(buildContext: BuildContext, roomAlias: RoomAlias) = node(buildContext) {
|
||||
Box(modifier = it.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
AsyncFailure(
|
||||
throwable = Exception("Unable to resolve alias ${roomAlias.value}"),
|
||||
onRetry = { resolveRoomId() },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
BackstackView(transitionHandler = JumpToEndTransitionHandler())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue