diff --git a/gradle.properties b/gradle.properties index 71acd565..dbae1d27 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ kotlin.mpp.enableGranularSourceSetsMetadata=true # Maven GROUP=cafe.adriel.voyager -VERSION_NAME=1.0.0-rc01 +VERSION_NAME=1.0.0-rc02 POM_DESCRIPTION=A pragmatic navigation library for Jetpack Compose POM_INCEPTION_YEAR=2021 diff --git a/samples/android/src/main/java/cafe/adriel/voyager/sample/tabNavigation/tabs/TabContent.kt b/samples/android/src/main/java/cafe/adriel/voyager/sample/tabNavigation/tabs/TabContent.kt index 5216fedc..418b2596 100644 --- a/samples/android/src/main/java/cafe/adriel/voyager/sample/tabNavigation/tabs/TabContent.kt +++ b/samples/android/src/main/java/cafe/adriel/voyager/sample/tabNavigation/tabs/TabContent.kt @@ -15,7 +15,6 @@ import androidx.compose.ui.unit.dp import cafe.adriel.voyager.core.lifecycle.LifecycleEffect import cafe.adriel.voyager.core.model.rememberScreenModel import cafe.adriel.voyager.navigator.Navigator -import cafe.adriel.voyager.navigator.NavigatorDisposeBehavior import cafe.adriel.voyager.navigator.tab.LocalTabNavigator import cafe.adriel.voyager.navigator.tab.Tab import cafe.adriel.voyager.sample.androidViewModel.AndroidListViewModel @@ -34,10 +33,7 @@ fun Tab.TabContent() { onDisposed = { Log.d("Navigator", "Dispose tab $tabTitle") }, ) - Navigator( - screen = BasicNavigationScreen(index = 0), - disposeBehavior = NavigatorDisposeBehavior(autoDisposeNavigator = false), - ) { navigator -> + Navigator(BasicNavigationScreen(index = 0)) { navigator -> SlideTransition(navigator) { screen -> val screenModel = rememberScreenModel { ListScreenModel() } val viewModel = getViewModel() diff --git a/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/Navigator.kt b/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/Navigator.kt index 871ca050..f24be165 100644 --- a/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/Navigator.kt +++ b/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/Navigator.kt @@ -66,11 +66,11 @@ public fun Navigator( CompositionLocalProvider( LocalNavigatorStateHolder providesDefault rememberSaveableStateHolder() ) { - val navigator = rememberNavigator(screens, LocalNavigator.current) + val navigator = rememberNavigator(screens, disposeBehavior, LocalNavigator.current) val lifecycleOwner = rememberScreenLifecycleOwner(navigator.lastItem) val hooks = lifecycleOwner.getHooks() - if (disposeBehavior.autoDisposeNavigator) { + if (navigator.parent?.disposeBehavior?.disposeNestedNavigators != false) { NavigatorDisposableEffect(navigator) } @@ -78,7 +78,7 @@ public fun Navigator( LocalNavigator provides navigator, *hooks.providers.toTypedArray() ) { - if (disposeBehavior.autoDisposeSteps) { + if (disposeBehavior.disposeSteps) { StepDisposableEffect(navigator) } @@ -91,6 +91,7 @@ public fun Navigator( public class Navigator internal constructor( screens: List, + public val disposeBehavior: NavigatorDisposeBehavior, public val stateHolder: SaveableStateHolder, public val parent: Navigator? = null ) : Stack by screens.toMutableStateStack(minSize = 1) { @@ -124,6 +125,6 @@ public class Navigator internal constructor( } public data class NavigatorDisposeBehavior( - val autoDisposeNavigator: Boolean = true, - val autoDisposeSteps: Boolean = true, + val disposeNestedNavigators: Boolean = true, + val disposeSteps: Boolean = true, ) diff --git a/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/internal/NavigatorDisposable.kt b/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/internal/NavigatorDisposable.kt index 032a65c8..d9b84bc2 100644 --- a/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/internal/NavigatorDisposable.kt +++ b/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/internal/NavigatorDisposable.kt @@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import cafe.adriel.voyager.core.lifecycle.ScreenLifecycleStore import cafe.adriel.voyager.core.model.ScreenModelStore +import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.stack.StackEvent import cafe.adriel.voyager.navigator.Navigator @@ -17,9 +18,7 @@ internal fun NavigatorDisposableEffect( DisposableEffect(navigator) { onDispose { for (screen in navigator.items) { - ScreenModelStore.remove(screen) - ScreenLifecycleStore.remove(screen) - navigator.stateHolder.removeState(screen.key) + navigator.dispose(screen) } navigator.clearEvent() } @@ -35,11 +34,17 @@ internal fun StepDisposableEffect( DisposableEffect(currentScreen.key) { onDispose { if (navigator.lastEvent in disposableEvents) { - ScreenModelStore.remove(currentScreen) - ScreenLifecycleStore.remove(currentScreen) - navigator.stateHolder.removeState(currentScreen.key) + navigator.dispose(currentScreen) navigator.clearEvent() } } } } + +private fun Navigator.dispose( + screen: Screen +) { + ScreenModelStore.remove(screen) + ScreenLifecycleStore.remove(screen) + stateHolder.removeState(screen.key) +} diff --git a/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/internal/NavigatorSaver.kt b/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/internal/NavigatorSaver.kt index 54c5aba8..27040256 100644 --- a/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/internal/NavigatorSaver.kt +++ b/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/internal/NavigatorSaver.kt @@ -9,6 +9,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.staticCompositionLocalOf import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.Navigator +import cafe.adriel.voyager.navigator.NavigatorDisposeBehavior internal val LocalNavigatorStateHolder: ProvidableCompositionLocal = staticCompositionLocalOf { error("LocalNavigatorStateHolder not initialized") } @@ -16,20 +17,22 @@ internal val LocalNavigatorStateHolder: ProvidableCompositionLocal, + disposeBehavior: NavigatorDisposeBehavior, parent: Navigator? ): Navigator { val stateHolder = LocalNavigatorStateHolder.current - return rememberSaveable(saver = navigatorSaver(stateHolder, parent)) { - Navigator(screens, stateHolder, parent) + return rememberSaveable(saver = navigatorSaver(stateHolder, disposeBehavior, parent)) { + Navigator(screens, disposeBehavior, stateHolder, parent) } } private fun navigatorSaver( stateHolder: SaveableStateHolder, + disposeBehavior: NavigatorDisposeBehavior, parent: Navigator? ): Saver = listSaver( save = { navigator -> navigator.items }, - restore = { items -> Navigator(items, stateHolder, parent) } + restore = { items -> Navigator(items, disposeBehavior, stateHolder, parent) } ) diff --git a/voyager-tab-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/tab/TabNavigator.kt b/voyager-tab-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/tab/TabNavigator.kt index 85e4b17f..78cab410 100644 --- a/voyager-tab-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/tab/TabNavigator.kt +++ b/voyager-tab-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/tab/TabNavigator.kt @@ -17,11 +17,15 @@ public val LocalTabNavigator: ProvidableCompositionLocal = @Composable public fun TabNavigator( tab: Tab, + disposeNestedNavigators: Boolean = false, content: TabNavigatorContent = { CurrentTab() } ) { Navigator( screen = tab, - disposeBehavior = NavigatorDisposeBehavior(autoDisposeSteps = false), + disposeBehavior = NavigatorDisposeBehavior( + disposeNestedNavigators = disposeNestedNavigators, + disposeSteps = false + ), onBackPressed = null ) { navigator -> val tabNavigator = remember(navigator) {