Browse Source

[Architecture] introduce BackstackNode

misc/jme/add-logging-to-state-machine
ganfra 2 years ago
parent
commit
91863e2529
  1. 33
      app/src/main/kotlin/io/element/android/x/node/LoggedInFlowNode.kt
  2. 31
      app/src/main/kotlin/io/element/android/x/node/NotLoggedInFlowNode.kt
  3. 26
      app/src/main/kotlin/io/element/android/x/node/RoomFlowNode.kt
  4. 44
      app/src/main/kotlin/io/element/android/x/node/RootFlowNode.kt
  5. 2
      features/login/build.gradle.kts
  6. 25
      features/login/src/main/kotlin/io/element/android/features/login/impl/LoginFlowNode.kt
  7. 2
      features/logout/build.gradle.kts
  8. 2
      features/messages/build.gradle.kts
  9. 2
      features/onboarding/build.gradle.kts
  10. 2
      features/preferences/build.gradle.kts
  11. 26
      features/preferences/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt
  12. 2
      features/rageshake/build.gradle.kts
  13. 2
      features/roomlist/build.gradle.kts
  14. 2
      features/template/build.gradle.kts
  15. 38
      libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/BackstackNode.kt

33
app/src/main/kotlin/io/element/android/x/node/LoggedInFlowNode.kt

@ -27,7 +27,6 @@ import com.bumble.appyx.core.composable.Children
import com.bumble.appyx.core.lifecycle.subscribe import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.node.node import com.bumble.appyx.core.node.node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.core.plugin.plugins
@ -38,6 +37,7 @@ import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.preferences.api.PreferencesEntryPoint import io.element.android.features.preferences.api.PreferencesEntryPoint
import io.element.android.features.roomlist.api.RoomListEntryPoint import io.element.android.features.roomlist.api.RoomListEntryPoint
import io.element.android.libraries.architecture.BackstackNode
import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler
import io.element.android.libraries.architecture.bindings import io.element.android.libraries.architecture.bindings
@ -54,35 +54,20 @@ import io.element.android.x.di.SessionComponent
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ContributesNode(AppScope::class) @ContributesNode(AppScope::class)
class LoggedInFlowNode( class LoggedInFlowNode @AssistedInject constructor(
buildContext: BuildContext, @Assisted buildContext: BuildContext,
plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val backstack: BackStack<NavTarget>,
private val roomListEntryPoint: RoomListEntryPoint, private val roomListEntryPoint: RoomListEntryPoint,
private val preferencesEntryPoint: PreferencesEntryPoint, private val preferencesEntryPoint: PreferencesEntryPoint,
) : ParentNode<LoggedInFlowNode.NavTarget>( ) : BackstackNode<LoggedInFlowNode.NavTarget>(
navModel = backstack, backstack = BackStack(
initialElement = NavTarget.RoomList,
savedStateMap = buildContext.savedStateMap,
),
buildContext = buildContext, buildContext = buildContext,
plugins = plugins plugins = plugins
), DaggerComponentOwner { ), DaggerComponentOwner {
@AssistedInject
constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
roomListEntryPoint: RoomListEntryPoint,
preferencesEntryPoint: PreferencesEntryPoint,
) : this(
buildContext = buildContext,
plugins = plugins,
roomListEntryPoint = roomListEntryPoint,
preferencesEntryPoint = preferencesEntryPoint,
backstack = BackStack(
initialElement = NavTarget.RoomList,
savedStateMap = buildContext.savedStateMap,
)
)
interface Callback : Plugin { interface Callback : Plugin {
fun onOpenBugReport() fun onOpenBugReport()
} }

31
app/src/main/kotlin/io/element/android/x/node/NotLoggedInFlowNode.kt

@ -23,7 +23,6 @@ import com.bumble.appyx.core.composable.Children
import com.bumble.appyx.core.lifecycle.subscribe import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.push import com.bumble.appyx.navmodel.backstack.operation.push
@ -32,38 +31,26 @@ import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.login.api.LoginEntryPoint import io.element.android.features.login.api.LoginEntryPoint
import io.element.android.features.onboarding.api.OnBoardingEntryPoint import io.element.android.features.onboarding.api.OnBoardingEntryPoint
import io.element.android.libraries.architecture.BackstackNode
import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler
import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.AppScope
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import timber.log.Timber import timber.log.Timber
@ContributesNode(AppScope::class) @ContributesNode(AppScope::class)
class NotLoggedInFlowNode private constructor( class NotLoggedInFlowNode @AssistedInject constructor(
buildContext: BuildContext, @Assisted buildContext: BuildContext,
plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val onBoardingEntryPoint: OnBoardingEntryPoint, private val onBoardingEntryPoint: OnBoardingEntryPoint,
private val loginEntryPoint: LoginEntryPoint, private val loginEntryPoint: LoginEntryPoint,
private val backstack: BackStack<NavTarget>, ) : BackstackNode<NotLoggedInFlowNode.NavTarget>(
) : ParentNode<NotLoggedInFlowNode.NavTarget>( backstack = BackStack(
navModel = backstack, initialElement = NavTarget.OnBoarding,
savedStateMap = buildContext.savedStateMap
),
buildContext = buildContext, buildContext = buildContext,
plugins = plugins, plugins = plugins,
) { ) {
@AssistedInject
constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
onBoardingEntryPoint: OnBoardingEntryPoint,
loginEntryPoint: LoginEntryPoint,
)
: this(
buildContext = buildContext,
plugins = plugins,
onBoardingEntryPoint = onBoardingEntryPoint,
loginEntryPoint = loginEntryPoint,
backstack = BackStack(initialElement = NavTarget.OnBoarding, savedStateMap = buildContext.savedStateMap),
)
init { init {
lifecycle.subscribe( lifecycle.subscribe(
onCreate = { Timber.v("OnCreate") }, onCreate = { Timber.v("OnCreate") },

26
app/src/main/kotlin/io/element/android/x/node/RoomFlowNode.kt

@ -23,13 +23,13 @@ import com.bumble.appyx.core.composable.Children
import com.bumble.appyx.core.lifecycle.subscribe import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.messages.MessagesNode import io.element.android.features.messages.MessagesNode
import io.element.android.libraries.architecture.BackstackNode
import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.bindings import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
@ -42,12 +42,14 @@ import kotlinx.parcelize.Parcelize
import timber.log.Timber import timber.log.Timber
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class RoomFlowNode private constructor( class RoomFlowNode @AssistedInject constructor(
buildContext: BuildContext, @Assisted buildContext: BuildContext,
plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val backstack: BackStack<NavTarget>, ) : BackstackNode<RoomFlowNode.NavTarget>(
) : ParentNode<RoomFlowNode.NavTarget>( backstack = BackStack(
navModel = backstack, initialElement = NavTarget.Messages,
savedStateMap = buildContext.savedStateMap,
),
buildContext = buildContext, buildContext = buildContext,
plugins = plugins, plugins = plugins,
), DaggerComponentOwner { ), DaggerComponentOwner {
@ -56,16 +58,6 @@ class RoomFlowNode private constructor(
val room: MatrixRoom, val room: MatrixRoom,
) : NodeInputs ) : NodeInputs
@AssistedInject
constructor(@Assisted buildContext: BuildContext, @Assisted plugins: List<Plugin>) : this(
buildContext = buildContext,
plugins = plugins,
backstack = BackStack(
initialElement = NavTarget.Messages,
savedStateMap = buildContext.savedStateMap,
),
)
private val inputs: Inputs by nodeInputs() private val inputs: Inputs by nodeInputs()
override val daggerComponent: Any by lazy { override val daggerComponent: Any by lazy {

44
app/src/main/kotlin/io/element/android/x/node/RootFlowNode.kt

@ -27,7 +27,6 @@ import androidx.lifecycle.lifecycleScope
import com.bumble.appyx.core.composable.Children import com.bumble.appyx.core.composable.Children
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.node.node import com.bumble.appyx.core.node.node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
@ -38,6 +37,8 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.rageshake.bugreport.BugReportEntryPoint import io.element.android.features.rageshake.bugreport.BugReportEntryPoint
import io.element.android.features.rageshake.bugreport.BugReportNode
import io.element.android.libraries.architecture.BackstackNode
import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.architecture.nodeInputsProvider import io.element.android.libraries.architecture.nodeInputsProvider
@ -57,46 +58,25 @@ import kotlinx.parcelize.Parcelize
import timber.log.Timber import timber.log.Timber
@ContributesNode(AppScope::class) @ContributesNode(AppScope::class)
class RootFlowNode private constructor( class RootFlowNode @AssistedInject constructor(
private val buildContext: BuildContext, @Assisted buildContext: BuildContext,
private val backstack: BackStack<NavTarget> = BackStack( @Assisted plugins: List<Plugin>,
initialElement = NavTarget.SplashScreen, @ApplicationContext context: Context,
savedStateMap = buildContext.savedStateMap,
),
private val appComponentOwner: DaggerComponentOwner,
private val authenticationService: MatrixAuthenticationService, private val authenticationService: MatrixAuthenticationService,
private val matrixClientsHolder: MatrixClientsHolder, private val matrixClientsHolder: MatrixClientsHolder,
private val presenter: RootPresenter, private val presenter: RootPresenter,
private val bugReportEntryPoint: BugReportEntryPoint, private val bugReportEntryPoint: BugReportEntryPoint,
) : ) :
ParentNode<RootFlowNode.NavTarget>( BackstackNode<RootFlowNode.NavTarget>(
navModel = backstack,
buildContext = buildContext
),
DaggerComponentOwner by appComponentOwner {
@AssistedInject
constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
@ApplicationContext context: Context,
authenticationService: MatrixAuthenticationService,
matrixClientsHolder: MatrixClientsHolder,
presenter: RootPresenter,
bugReportEntryPoint: BugReportEntryPoint,
) : this(
buildContext = buildContext,
backstack = BackStack( backstack = BackStack(
initialElement = NavTarget.SplashScreen, initialElement = NavTarget.SplashScreen,
savedStateMap = buildContext.savedStateMap, savedStateMap = buildContext.savedStateMap,
), ),
appComponentOwner = context.applicationContext as DaggerComponentOwner, buildContext = buildContext,
authenticationService = authenticationService, plugins = plugins
matrixClientsHolder = matrixClientsHolder, ),
presenter = presenter,
bugReportEntryPoint = bugReportEntryPoint, DaggerComponentOwner by (context as DaggerComponentOwner) {
)
override fun onBuilt() { override fun onBuilt() {
super.onBuilt() super.onBuilt()

2
features/login/build.gradle.kts

@ -18,8 +18,8 @@
@Suppress("DSL_SCOPE_VIOLATION") @Suppress("DSL_SCOPE_VIOLATION")
plugins { plugins {
id("io.element.android-compose-library") id("io.element.android-compose-library")
alias(libs.plugins.ksp)
alias(libs.plugins.anvil) alias(libs.plugins.anvil)
alias(libs.plugins.ksp)
id("kotlin-parcelize") id("kotlin-parcelize")
} }

25
features/login/src/main/kotlin/io/element/android/features/login/impl/LoginFlowNode.kt

@ -31,32 +31,25 @@ import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.login.impl.changeserver.ChangeServerNode import io.element.android.features.login.impl.changeserver.ChangeServerNode
import io.element.android.features.login.impl.root.LoginRootNode import io.element.android.features.login.impl.root.LoginRootNode
import io.element.android.libraries.architecture.BackstackNode
import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.AppScope
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ContributesNode(AppScope::class) @ContributesNode(AppScope::class)
class LoginFlowNode( class LoginFlowNode @AssistedInject constructor(
buildContext: BuildContext, @Assisted buildContext: BuildContext,
plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val backstack: BackStack<NavTarget>, ) : BackstackNode<LoginFlowNode.NavTarget>(
) : ParentNode<LoginFlowNode.NavTarget>( backstack = BackStack(
navModel = backstack, initialElement = NavTarget.Root,
savedStateMap = buildContext.savedStateMap,
),
buildContext = buildContext, buildContext = buildContext,
plugins = plugins, plugins = plugins,
) { ) {
@AssistedInject
constructor(@Assisted buildContext: BuildContext, @Assisted plugins: List<Plugin>) : this(
buildContext = buildContext,
plugins = plugins,
backstack = BackStack(
initialElement = NavTarget.Root,
savedStateMap = buildContext.savedStateMap,
),
)
sealed interface NavTarget : Parcelable { sealed interface NavTarget : Parcelable {
@Parcelize @Parcelize
object Root : NavTarget object Root : NavTarget

2
features/logout/build.gradle.kts

@ -18,8 +18,8 @@
@Suppress("DSL_SCOPE_VIOLATION") @Suppress("DSL_SCOPE_VIOLATION")
plugins { plugins {
id("io.element.android-compose-library") id("io.element.android-compose-library")
alias(libs.plugins.ksp)
alias(libs.plugins.anvil) alias(libs.plugins.anvil)
alias(libs.plugins.ksp)
} }
android { android {

2
features/messages/build.gradle.kts

@ -18,8 +18,8 @@
@Suppress("DSL_SCOPE_VIOLATION") @Suppress("DSL_SCOPE_VIOLATION")
plugins { plugins {
id("io.element.android-compose-library") id("io.element.android-compose-library")
alias(libs.plugins.ksp)
alias(libs.plugins.anvil) alias(libs.plugins.anvil)
alias(libs.plugins.ksp)
} }
android { android {

2
features/onboarding/build.gradle.kts

@ -18,8 +18,8 @@
@Suppress("DSL_SCOPE_VIOLATION") @Suppress("DSL_SCOPE_VIOLATION")
plugins { plugins {
id("io.element.android-compose-library") id("io.element.android-compose-library")
alias(libs.plugins.ksp)
alias(libs.plugins.anvil) alias(libs.plugins.anvil)
alias(libs.plugins.ksp)
} }
android { android {

2
features/preferences/build.gradle.kts

@ -18,8 +18,8 @@
@Suppress("DSL_SCOPE_VIOLATION") @Suppress("DSL_SCOPE_VIOLATION")
plugins { plugins {
id("io.element.android-compose-library") id("io.element.android-compose-library")
alias(libs.plugins.ksp)
alias(libs.plugins.anvil) alias(libs.plugins.anvil)
alias(libs.plugins.ksp)
id("kotlin-parcelize") id("kotlin-parcelize")
} }

26
features/preferences/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt

@ -22,7 +22,6 @@ import androidx.compose.ui.Modifier
import com.bumble.appyx.core.composable.Children import com.bumble.appyx.core.composable.Children
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.core.plugin.plugins
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
@ -31,32 +30,25 @@ import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.preferences.api.PreferencesEntryPoint import io.element.android.features.preferences.api.PreferencesEntryPoint
import io.element.android.features.preferences.impl.root.PreferencesRootNode import io.element.android.features.preferences.impl.root.PreferencesRootNode
import io.element.android.libraries.architecture.BackstackNode
import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class PreferencesFlowNode( class PreferencesFlowNode @AssistedInject constructor(
buildContext: BuildContext, @Assisted buildContext: BuildContext,
plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val backstack: BackStack<NavTarget>, ) : BackstackNode<PreferencesFlowNode.NavTarget>(
) : ParentNode<PreferencesFlowNode.NavTarget>( backstack = BackStack(
navModel = backstack, initialElement = NavTarget.Root,
savedStateMap = buildContext.savedStateMap,
),
buildContext = buildContext, buildContext = buildContext,
plugins = plugins plugins = plugins
) { ) {
@AssistedInject
constructor(@Assisted buildContext: BuildContext, @Assisted plugins: List<Plugin>) : this(
buildContext = buildContext,
plugins = plugins,
backstack = BackStack(
initialElement = NavTarget.Root,
savedStateMap = buildContext.savedStateMap,
)
)
sealed interface NavTarget : Parcelable { sealed interface NavTarget : Parcelable {
@Parcelize @Parcelize
object Root : NavTarget object Root : NavTarget

2
features/rageshake/build.gradle.kts

@ -18,8 +18,8 @@
@Suppress("DSL_SCOPE_VIOLATION") @Suppress("DSL_SCOPE_VIOLATION")
plugins { plugins {
id("io.element.android-compose-library") id("io.element.android-compose-library")
alias(libs.plugins.ksp)
alias(libs.plugins.anvil) alias(libs.plugins.anvil)
alias(libs.plugins.ksp)
id("kotlin-parcelize") id("kotlin-parcelize")
} }

2
features/roomlist/build.gradle.kts

@ -18,8 +18,8 @@
@Suppress("DSL_SCOPE_VIOLATION") @Suppress("DSL_SCOPE_VIOLATION")
plugins { plugins {
id("io.element.android-compose-library") id("io.element.android-compose-library")
alias(libs.plugins.ksp)
alias(libs.plugins.anvil) alias(libs.plugins.anvil)
alias(libs.plugins.ksp)
} }
android { android {

2
features/template/build.gradle.kts

@ -18,8 +18,8 @@
@Suppress("DSL_SCOPE_VIOLATION") @Suppress("DSL_SCOPE_VIOLATION")
plugins { plugins {
id("io.element.android-compose-library") id("io.element.android-compose-library")
alias(libs.plugins.ksp)
alias(libs.plugins.anvil) alias(libs.plugins.anvil)
alias(libs.plugins.ksp)
} }
android { android {

38
libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/BackstackNode.kt

@ -0,0 +1,38 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.architecture
import androidx.compose.runtime.Stable
import com.bumble.appyx.Appyx
import com.bumble.appyx.core.children.ChildEntry
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.navmodel.backstack.BackStack
@Stable
abstract class BackstackNode<NavTarget : Any>(
val backstack: BackStack<NavTarget>,
buildContext: BuildContext,
childKeepMode: ChildEntry.KeepMode = Appyx.defaultChildKeepMode,
plugins: List<Plugin>
) : ParentNode<NavTarget>(
navModel = backstack,
buildContext = buildContext,
plugins = plugins,
childKeepMode = childKeepMode,
)
Loading…
Cancel
Save