space: start branching space settings flow

This commit is contained in:
ganfra
2025-11-28 15:54:05 +01:00
parent 9a081c496f
commit b78761e89a
4 changed files with 127 additions and 21 deletions

View File

@@ -40,6 +40,8 @@ dependencies {
implementation(projects.libraries.featureflag.api)
implementation(projects.features.invite.api)
implementation(projects.libraries.previewutils)
implementation(projects.features.securityandprivacy.api)
implementation(projects.features.rolesandpermissions.api)
api(projects.features.space.api)
testCommonDependencies(libs, true)

View File

@@ -28,7 +28,7 @@ import io.element.android.features.space.api.SpaceEntryPoint
import io.element.android.features.space.impl.di.SpaceFlowGraph
import io.element.android.features.space.impl.leave.LeaveSpaceNode
import io.element.android.features.space.impl.root.SpaceNode
import io.element.android.features.space.impl.settings.SpaceSettingsNode
import io.element.android.features.space.impl.settings.SpaceSettingsFlowNode
import io.element.android.libraries.architecture.BackstackView
import io.element.android.libraries.architecture.BaseFlowNode
import io.element.android.libraries.architecture.callback
@@ -115,32 +115,20 @@ class SpaceFlowNode(
createNode<SpaceNode>(buildContext, listOf(callback))
}
NavTarget.Settings -> {
val callback = object : SpaceSettingsNode.Callback {
override fun closeSettings() {
backstack.pop()
}
override fun navigateToSpaceInfo() {
// TODO
}
val callback = object : SpaceSettingsFlowNode.Callback {
override fun navigateToSpaceMembers() {
callback.navigateToRoomMemberList()
}
override fun navigateToRolesAndPermissions() {
// TODO
}
override fun navigateToSecurityAndPrivacy() {
// TODO
}
override fun startLeaveSpaceFlow() {
backstack.push(NavTarget.Leave)
}
override fun closeSettings() {
backstack.pop()
}
}
createNode<SpaceSettingsNode>(buildContext, listOf(callback))
createNode<SpaceSettingsFlowNode>(buildContext, listOf(callback))
}
}
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright (c) 2025 Element Creations 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.space.impl.settings
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 dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedInject
import io.element.android.annotations.ContributesNode
import io.element.android.features.rolesandpermissions.api.RolesAndPermissionsEntryPoint
import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint
import io.element.android.features.space.impl.di.SpaceFlowScope
import io.element.android.libraries.architecture.BackstackView
import io.element.android.libraries.architecture.BaseFlowNode
import io.element.android.libraries.architecture.callback
import io.element.android.libraries.architecture.createNode
import kotlinx.parcelize.Parcelize
@ContributesNode(SpaceFlowScope::class)
@AssistedInject
class SpaceSettingsFlowNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val securityAndPrivacyEntryPoint: SecurityAndPrivacyEntryPoint,
private val rolesAndPermissionsEntryPoint: RolesAndPermissionsEntryPoint,
) : BaseFlowNode<SpaceSettingsFlowNode.NavTarget>(
backstack = BackStack(
initialElement = NavTarget.Root,
savedStateMap = buildContext.savedStateMap,
),
buildContext = buildContext,
plugins = plugins,
) {
interface Callback : Plugin {
fun navigateToSpaceMembers()
fun startLeaveSpaceFlow()
fun closeSettings()
}
sealed interface NavTarget : Parcelable {
@Parcelize
data object Root : NavTarget
@Parcelize
data object SecurityAndPrivacy : NavTarget
@Parcelize
data object RolesAndPermissions : NavTarget
}
private val callback: Callback = callback()
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) {
is NavTarget.Root -> {
val callback = object : SpaceSettingsNode.Callback {
override fun closeSettings() {
callback.closeSettings()
}
override fun navigateToEditDetails() {
// TODO
}
override fun navigateToSpaceMembers() {
callback.navigateToSpaceMembers()
}
override fun navigateToRolesAndPermissions() {
backstack.push(NavTarget.RolesAndPermissions)
}
override fun navigateToSecurityAndPrivacy() {
backstack.push(NavTarget.SecurityAndPrivacy)
}
override fun startLeaveSpaceFlow() {
callback.startLeaveSpaceFlow()
}
}
createNode<SpaceSettingsNode>(
buildContext = buildContext,
plugins = listOf(callback),
)
}
is NavTarget.SecurityAndPrivacy -> {
securityAndPrivacyEntryPoint.createNode(
parentNode = this,
buildContext = buildContext,
)
}
is NavTarget.RolesAndPermissions -> {
rolesAndPermissionsEntryPoint.createNode(
parentNode = this,
buildContext = buildContext,
)
}
}
}
@Composable
override fun View(modifier: Modifier) {
BackstackView(modifier)
}
}

View File

@@ -32,7 +32,7 @@ class SpaceSettingsNode(
interface Callback : Plugin {
fun closeSettings()
fun navigateToSpaceInfo()
fun navigateToEditDetails()
fun navigateToSpaceMembers()
fun navigateToRolesAndPermissions()
fun navigateToSecurityAndPrivacy()
@@ -48,7 +48,7 @@ class SpaceSettingsNode(
SpaceSettingsView(
state = state,
modifier = modifier,
onSpaceInfoClick = callback::navigateToSpaceInfo,
onSpaceInfoClick = callback::navigateToEditDetails,
onBackClick = callback::closeSettings,
onMembersClick = callback::navigateToSpaceMembers,
onRolesAndPermissionsClick = callback::navigateToRolesAndPermissions,