feat(join by alias) : refactor navigation for create room flow

This commit is contained in:
ganfra 2025-02-20 20:59:22 +01:00
parent 21c6f9297d
commit 2bfa62922c
7 changed files with 72 additions and 48 deletions

View file

@ -357,8 +357,8 @@ class LoggedInFlowNode @AssistedInject constructor(
}
NavTarget.CreateRoom -> {
val callback = object : CreateRoomEntryPoint.Callback {
override fun onSuccess(roomId: RoomId) {
backstack.replace(NavTarget.Room(roomId.toRoomIdOrAlias()))
override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias) {
backstack.replace(NavTarget.Room(roomIdOrAlias))
}
}

View file

@ -11,7 +11,7 @@ import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import io.element.android.libraries.architecture.FeatureEntryPoint
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
interface CreateRoomEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder
@ -21,6 +21,6 @@ interface CreateRoomEntryPoint : FeatureEntryPoint {
}
interface Callback : Plugin {
fun onSuccess(roomId: RoomId)
fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias)
}
}

View file

@ -0,0 +1,35 @@
/*
* 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.features.createroom
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.push
import io.element.android.features.createroom.impl.CreateRoomFlowNode.NavTarget
import io.element.android.libraries.architecture.overlay.Overlay
import io.element.android.libraries.architecture.overlay.operation.hide
import io.element.android.libraries.architecture.overlay.operation.show
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
interface CreateRoomNavigator : Plugin {
fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias)
fun onCreateNewRoom()
}
class DefaultCreateRoomNavigator(
private val backstack: BackStack<NavTarget>,
private val openRoom: (RoomIdOrAlias) -> Unit,
) : CreateRoomNavigator {
override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias) = openRoom(roomIdOrAlias)
override fun onCreateNewRoom() {
backstack.push(NavTarget.NewRoom)
}
}

View file

@ -19,6 +19,7 @@ import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.createroom.CreateRoomNavigator
import io.element.android.features.createroom.impl.addpeople.AddPeopleNode
import io.element.android.features.createroom.impl.configureroom.ConfigureRoomNode
import io.element.android.features.createroom.impl.di.CreateRoomComponent
@ -46,6 +47,7 @@ class ConfigureRoomFlowNode @AssistedInject constructor(
private val component by lazy {
parent!!.bindings<CreateRoomComponent.ParentBindings>().createRoomComponentBuilder().build()
}
private val navigator = plugins<CreateRoomNavigator>().first()
override val daggerComponent: Any
get() = component
@ -58,6 +60,7 @@ class ConfigureRoomFlowNode @AssistedInject constructor(
data object ConfigureRoom : NavTarget
}
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) {
NavTarget.Root -> {
@ -69,8 +72,7 @@ class ConfigureRoomFlowNode @AssistedInject constructor(
createNode<AddPeopleNode>(buildContext = buildContext, plugins = listOf(callback))
}
NavTarget.ConfigureRoom -> {
val callbacks = plugins<ConfigureRoomNode.Callback>()
createNode<ConfigureRoomNode>(buildContext = buildContext, plugins = callbacks)
createNode<ConfigureRoomNode>(buildContext = buildContext, plugins = listOf(navigator))
}
}
}

View file

@ -9,24 +9,26 @@ package io.element.android.features.createroom.impl
import android.os.Parcelable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.navigation.transition.JumpToEndTransitionHandler
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.createroom.DefaultCreateRoomNavigator
import io.element.android.features.createroom.api.CreateRoomEntryPoint
import io.element.android.features.createroom.impl.configureroom.ConfigureRoomNode
import io.element.android.features.createroom.impl.root.CreateRoomRootNode
import io.element.android.libraries.architecture.BackstackView
import io.element.android.libraries.architecture.BaseFlowNode
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class)
@ -47,29 +49,23 @@ class CreateRoomFlowNode @AssistedInject constructor(
@Parcelize
data object NewRoom : NavTarget
}
private val navigator = DefaultCreateRoomNavigator(
backstack = backstack,
openRoom = { roomIdOrAlias ->
plugins<CreateRoomEntryPoint.Callback>().forEach { it.onOpenRoom(roomIdOrAlias) }
}
)
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) {
NavTarget.Root -> {
val callback = object : CreateRoomRootNode.Callback {
override fun onCreateNewRoom() {
backstack.push(NavTarget.NewRoom)
}
override fun onStartChatSuccess(roomId: RoomId) {
plugins<CreateRoomEntryPoint.Callback>().forEach { it.onSuccess(roomId) }
}
}
createNode<CreateRoomRootNode>(buildContext = buildContext, plugins = listOf(callback))
createNode<CreateRoomRootNode>(buildContext = buildContext, plugins = listOf(navigator))
}
NavTarget.NewRoom -> {
val callback = object : ConfigureRoomNode.Callback {
override fun onCreateRoomSuccess(roomId: RoomId) {
plugins<CreateRoomEntryPoint.Callback>().forEach { it.onSuccess(roomId) }
}
}
createNode<ConfigureRoomFlowNode>(buildContext = buildContext, plugins = listOf(callback))
createNode<ConfigureRoomFlowNode>(buildContext = buildContext, plugins = listOf(navigator))
}
}
}

View file

@ -18,8 +18,9 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.createroom.CreateRoomNavigator
import io.element.android.features.createroom.impl.di.CreateRoomScope
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
import io.element.android.services.analytics.api.AnalyticsService
@ContributesNode(CreateRoomScope::class)
@ -29,6 +30,9 @@ class ConfigureRoomNode @AssistedInject constructor(
private val presenter: ConfigureRoomPresenter,
private val analyticsService: AnalyticsService,
) : Node(buildContext, plugins = plugins) {
private val navigator = plugins<CreateRoomNavigator>().first()
init {
lifecycle.subscribe(
onResume = {
@ -37,14 +41,6 @@ class ConfigureRoomNode @AssistedInject constructor(
)
}
interface Callback : Plugin {
fun onCreateRoomSuccess(roomId: RoomId)
}
private fun onCreateRoomSuccess(roomId: RoomId) {
plugins<Callback>().forEach { it.onCreateRoomSuccess(roomId) }
}
@Composable
override fun View(modifier: Modifier) {
val state = presenter.present()
@ -52,7 +48,9 @@ class ConfigureRoomNode @AssistedInject constructor(
state = state,
modifier = modifier,
onBackClick = this::navigateUp,
onCreateRoomSuccess = this::onCreateRoomSuccess,
onCreateRoomSuccess = {
navigator.onOpenRoom(it.toRoomIdOrAlias())
},
)
}
}

View file

@ -20,9 +20,10 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.createroom.CreateRoomNavigator
import io.element.android.libraries.deeplink.usecase.InviteFriendsUseCase
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
import io.element.android.services.analytics.api.AnalyticsService
@ContributesNode(SessionScope::class)
@ -33,18 +34,8 @@ class CreateRoomRootNode @AssistedInject constructor(
private val analyticsService: AnalyticsService,
private val inviteFriendsUseCase: InviteFriendsUseCase,
) : Node(buildContext, plugins = plugins) {
interface Callback : Plugin {
fun onCreateNewRoom()
fun onStartChatSuccess(roomId: RoomId)
}
private fun onCreateNewRoom() {
plugins<Callback>().forEach { it.onCreateNewRoom() }
}
private fun onStartChatSuccess(roomId: RoomId) {
plugins<Callback>().forEach { it.onStartChatSuccess(roomId) }
}
private val navigator = plugins<CreateRoomNavigator>().first()
init {
lifecycle.subscribe(
@ -60,8 +51,10 @@ class CreateRoomRootNode @AssistedInject constructor(
state = state,
modifier = modifier,
onCloseClick = this::navigateUp,
onNewRoomClick = ::onCreateNewRoom,
onOpenDM = ::onStartChatSuccess,
onNewRoomClick = navigator::onCreateNewRoom,
onOpenDM = {
navigator.onOpenRoom(it.toRoomIdOrAlias())
},
onInviteFriendsClick = { invitePeople(activity) }
)
}