refactor (start chat) : create invite people module and start branching them

This commit is contained in:
ganfra 2025-08-08 17:20:32 +02:00 committed by Benoit Marty
parent 41cf1afce3
commit b4a8b17391
21 changed files with 717 additions and 32 deletions

View file

@ -8,25 +8,32 @@
package io.element.android.features.createroom.impl
import android.os.Parcelable
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
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.impl.addpeople.AddPeopleNode
import io.element.android.features.createroom.impl.configureroom.ConfigureRoomNode
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.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import kotlinx.coroutines.runBlocking
import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class)
class CreateRoomFlowNode @AssistedInject constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val client: MatrixClient,
) : BaseFlowNode<CreateRoomFlowNode.NavTarget>(
backstack = BackStack(
initialElement = NavTarget.ConfigureRoom,
@ -35,13 +42,30 @@ class CreateRoomFlowNode @AssistedInject constructor(
buildContext = buildContext,
plugins = plugins
) {
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) {
NavTarget.ConfigureRoom -> createNode<ConfigureRoomNode>(buildContext)
is NavTarget.AddPeople -> createNode<AddPeopleNode>(buildContext)
NavTarget.ConfigureRoom -> {
val callback = object : ConfigureRoomNode.Callback {
override fun onCreateRoomSuccess(roomId: RoomId) {
backstack.push(NavTarget.AddPeople(roomId))
}
}
createNode<ConfigureRoomNode>(buildContext, plugins = listOf(callback))
}
is NavTarget.AddPeople -> {
val joinedRoom = runBlocking { client.getJoinedRoom(navTarget.roomId) } ?: error("Room not found")
val inputs = AddPeopleNode.Inputs(joinedRoom)
createNode<AddPeopleNode>(buildContext, plugins = listOf(inputs))
}
}
}
@Composable
override fun View(modifier: Modifier) {
BackstackView()
}
sealed interface NavTarget : Parcelable {
@Parcelize
data object ConfigureRoom : NavTarget

View file

@ -9,10 +9,13 @@ package io.element.android.features.createroom.impl
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.features.createroom.api.CreateRoomEntryPoint
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.SessionScope
import javax.inject.Inject
@ContributesBinding(SessionScope::class)
class DefaultCreateRoomEntryPoint @Inject constructor(): CreateRoomEntryPoint {
override fun createNode(parentNode: Node, buildContext: BuildContext): Node {
return parentNode.createNode<CreateRoomFlowNode>(buildContext)

View file

@ -7,11 +7,40 @@
package io.element.android.features.createroom.impl.addpeople
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.squareup.anvil.annotations.ContributesBinding
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.invitepeople.api.InvitePeoplePresenter
import io.element.android.features.invitepeople.api.InvitePeopleRenderer
import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.room.JoinedRoom
class AddPeopleNode(
buildContext: BuildContext,
plugins: List<Plugin>,
) : Node(buildContext, plugins = plugins)
@ContributesNode(SessionScope::class)
class AddPeopleNode @AssistedInject constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val invitePeoplePresenterFactory: InvitePeoplePresenter.Factory,
private val invitePeopleRenderer: InvitePeopleRenderer,
) : Node(buildContext, plugins = plugins) {
data class Inputs(
val joinedRoom: JoinedRoom
): NodeInputs
private val joinedRoom = inputs<Inputs>().joinedRoom
private val invitePeoplePresenter = invitePeoplePresenterFactory.create(joinedRoom)
@Composable
override fun View(modifier: Modifier) {
val state = invitePeoplePresenter.present()
invitePeopleRenderer.Render(state, Modifier)
}
}

View file

@ -13,11 +13,14 @@ import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
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.libraries.architecture.inputs
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.services.analytics.api.AnalyticsService
@ContributesNode(SessionScope::class)
@ -28,6 +31,10 @@ class ConfigureRoomNode @AssistedInject constructor(
private val analyticsService: AnalyticsService,
) : Node(buildContext, plugins = plugins) {
interface Callback: Plugin {
fun onCreateRoomSuccess(roomId: RoomId)
}
init {
lifecycle.subscribe(
onResume = {
@ -36,6 +43,10 @@ class ConfigureRoomNode @AssistedInject constructor(
)
}
private fun onCreateRoomSuccess(roomId: RoomId){
plugins<Callback>().forEach { it.onCreateRoomSuccess(roomId) }
}
@Composable
override fun View(modifier: Modifier) {
val state = presenter.present()
@ -43,9 +54,7 @@ class ConfigureRoomNode @AssistedInject constructor(
state = state,
modifier = modifier,
onBackClick = this::navigateUp,
onCreateRoomSuccess = {
},
onCreateRoomSuccess = ::onCreateRoomSuccess,
)
}
}