mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-03 16:10:00 +00:00
Add SecureBackupSetupEntryPoint extension seam
Introduces a FeatureEntryPoint for the recovery-key setup screen so enterprise builds can vend a richer setup node. The FOSS default builds the standard auto-generated-key node; SecureBackupFlowNode now resolves the Setup and Change targets through this seam instead of creating SecureBackupSetupNode directly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+30
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2026 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.securebackup.api
|
||||||
|
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.bumble.appyx.core.node.Node
|
||||||
|
import io.element.android.libraries.architecture.FeatureEntryPoint
|
||||||
|
import io.element.android.libraries.architecture.NodeInputs
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for the recovery-key setup screen.
|
||||||
|
*
|
||||||
|
* The default (FOSS) implementation builds the standard auto-generated-key setup node. Enterprise
|
||||||
|
* builds replace this binding to vend a richer setup node (e.g. a homeserver-advertised custom
|
||||||
|
* recovery passphrase) while falling back to the standard node when no custom spec applies.
|
||||||
|
*/
|
||||||
|
interface SecureBackupSetupEntryPoint : FeatureEntryPoint {
|
||||||
|
data class Inputs(val isChangeRecoveryKeyUserStory: Boolean) : NodeInputs
|
||||||
|
|
||||||
|
fun createNode(
|
||||||
|
parentNode: Node,
|
||||||
|
buildContext: BuildContext,
|
||||||
|
inputs: Inputs,
|
||||||
|
): Node
|
||||||
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2026 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.securebackup.impl
|
||||||
|
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.bumble.appyx.core.node.Node
|
||||||
|
import dev.zacsweers.metro.AppScope
|
||||||
|
import dev.zacsweers.metro.ContributesBinding
|
||||||
|
import io.element.android.features.securebackup.api.SecureBackupSetupEntryPoint
|
||||||
|
import io.element.android.features.securebackup.impl.setup.SecureBackupSetupNode
|
||||||
|
import io.element.android.libraries.architecture.createNode
|
||||||
|
|
||||||
|
@ContributesBinding(AppScope::class)
|
||||||
|
class DefaultSecureBackupSetupEntryPoint : SecureBackupSetupEntryPoint {
|
||||||
|
override fun createNode(
|
||||||
|
parentNode: Node,
|
||||||
|
buildContext: BuildContext,
|
||||||
|
inputs: SecureBackupSetupEntryPoint.Inputs,
|
||||||
|
): Node {
|
||||||
|
return parentNode.createNode<SecureBackupSetupNode>(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = listOf(
|
||||||
|
SecureBackupSetupNode.Inputs(
|
||||||
|
isChangeRecoveryKeyUserStory = inputs.isChangeRecoveryKeyUserStory,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
-7
@@ -21,11 +21,11 @@ import dev.zacsweers.metro.Assisted
|
|||||||
import dev.zacsweers.metro.AssistedInject
|
import dev.zacsweers.metro.AssistedInject
|
||||||
import io.element.android.annotations.ContributesNode
|
import io.element.android.annotations.ContributesNode
|
||||||
import io.element.android.features.securebackup.api.SecureBackupEntryPoint
|
import io.element.android.features.securebackup.api.SecureBackupEntryPoint
|
||||||
|
import io.element.android.features.securebackup.api.SecureBackupSetupEntryPoint
|
||||||
import io.element.android.features.securebackup.impl.disable.SecureBackupDisableNode
|
import io.element.android.features.securebackup.impl.disable.SecureBackupDisableNode
|
||||||
import io.element.android.features.securebackup.impl.enter.SecureBackupEnterRecoveryKeyNode
|
import io.element.android.features.securebackup.impl.enter.SecureBackupEnterRecoveryKeyNode
|
||||||
import io.element.android.features.securebackup.impl.reset.ResetIdentityFlowNode
|
import io.element.android.features.securebackup.impl.reset.ResetIdentityFlowNode
|
||||||
import io.element.android.features.securebackup.impl.root.SecureBackupRootNode
|
import io.element.android.features.securebackup.impl.root.SecureBackupRootNode
|
||||||
import io.element.android.features.securebackup.impl.setup.SecureBackupSetupNode
|
|
||||||
import io.element.android.libraries.architecture.BackstackView
|
import io.element.android.libraries.architecture.BackstackView
|
||||||
import io.element.android.libraries.architecture.BaseFlowNode
|
import io.element.android.libraries.architecture.BaseFlowNode
|
||||||
import io.element.android.libraries.architecture.appyx.canPop
|
import io.element.android.libraries.architecture.appyx.canPop
|
||||||
@@ -39,6 +39,7 @@ import kotlinx.parcelize.Parcelize
|
|||||||
class SecureBackupFlowNode(
|
class SecureBackupFlowNode(
|
||||||
@Assisted buildContext: BuildContext,
|
@Assisted buildContext: BuildContext,
|
||||||
@Assisted plugins: List<Plugin>,
|
@Assisted plugins: List<Plugin>,
|
||||||
|
private val secureBackupSetupEntryPoint: SecureBackupSetupEntryPoint,
|
||||||
) : BaseFlowNode<SecureBackupFlowNode.NavTarget>(
|
) : BaseFlowNode<SecureBackupFlowNode.NavTarget>(
|
||||||
backstack = BackStack(
|
backstack = BackStack(
|
||||||
initialElement = when (plugins.filterIsInstance<SecureBackupEntryPoint.Params>().first().initialElement) {
|
initialElement = when (plugins.filterIsInstance<SecureBackupEntryPoint.Params>().first().initialElement) {
|
||||||
@@ -97,16 +98,18 @@ class SecureBackupFlowNode(
|
|||||||
createNode<SecureBackupRootNode>(buildContext, listOf(callback))
|
createNode<SecureBackupRootNode>(buildContext, listOf(callback))
|
||||||
}
|
}
|
||||||
NavTarget.Setup -> {
|
NavTarget.Setup -> {
|
||||||
val inputs = SecureBackupSetupNode.Inputs(
|
secureBackupSetupEntryPoint.createNode(
|
||||||
isChangeRecoveryKeyUserStory = false,
|
parentNode = this,
|
||||||
|
buildContext = buildContext,
|
||||||
|
inputs = SecureBackupSetupEntryPoint.Inputs(isChangeRecoveryKeyUserStory = false),
|
||||||
)
|
)
|
||||||
createNode<SecureBackupSetupNode>(buildContext, listOf(inputs))
|
|
||||||
}
|
}
|
||||||
NavTarget.Change -> {
|
NavTarget.Change -> {
|
||||||
val inputs = SecureBackupSetupNode.Inputs(
|
secureBackupSetupEntryPoint.createNode(
|
||||||
isChangeRecoveryKeyUserStory = true,
|
parentNode = this,
|
||||||
|
buildContext = buildContext,
|
||||||
|
inputs = SecureBackupSetupEntryPoint.Inputs(isChangeRecoveryKeyUserStory = true),
|
||||||
)
|
)
|
||||||
createNode<SecureBackupSetupNode>(buildContext, listOf(inputs))
|
|
||||||
}
|
}
|
||||||
NavTarget.Disable -> {
|
NavTarget.Disable -> {
|
||||||
createNode<SecureBackupDisableNode>(buildContext)
|
createNode<SecureBackupDisableNode>(buildContext)
|
||||||
|
|||||||
+1
@@ -32,6 +32,7 @@ class DefaultSecureBackupEntryPointTest {
|
|||||||
SecureBackupFlowNode(
|
SecureBackupFlowNode(
|
||||||
buildContext = buildContext,
|
buildContext = buildContext,
|
||||||
plugins = plugins,
|
plugins = plugins,
|
||||||
|
secureBackupSetupEntryPoint = DefaultSecureBackupSetupEntryPoint(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val callback = object : SecureBackupEntryPoint.Callback {
|
val callback = object : SecureBackupEntryPoint.Callback {
|
||||||
|
|||||||
Reference in New Issue
Block a user