diff --git a/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavRule.kt b/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavRule.kt index b1953267..cf1b7f54 100644 --- a/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavRule.kt +++ b/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavRule.kt @@ -25,16 +25,15 @@ internal class TurboNavRule( val currentLocation = checkNotNull(controller.currentBackStackEntry.location) val currentProperties = pathConfiguration.properties(currentLocation) val currentPresentationContext = currentProperties.context - val currentDestination = checkNotNull(controller.currentDestination) val isAtStartDestination = controller.previousBackStackEntry == null // New destination val newLocation = location + val newProperties = pathConfiguration.properties(newLocation) + val newPresentationContext = newProperties.context val newVisitOptions = visitOptions val newBundle = bundle.withNavArguments() val newExtras = extras - val newProperties = pathConfiguration.properties(newLocation) - val newPresentationContext = newProperties.context val newQueryStringPresentation = newProperties.queryStringPresentation val newPresentation = newPresentation() val newNavigationMode = newNavigationMode() @@ -126,7 +125,10 @@ internal class TurboNavRule( private fun Bundle?.withNavArguments(): Bundle { val bundle = this ?: bundleOf() - return bundle.apply { putString("location", newLocation) } + return bundle.apply { + putString("location", newLocation) + putSerializable("presentation-context", newPresentationContext) + } } private val NavBackStackEntry?.location: String? diff --git a/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt b/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt index 493b298c..baf1f461 100644 --- a/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt +++ b/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt @@ -2,6 +2,7 @@ package dev.hotwire.turbo.nav import android.os.Bundle import androidx.fragment.app.DialogFragment +import androidx.navigation.NavBackStackEntry import androidx.navigation.NavController import androidx.navigation.NavOptions import androidx.navigation.fragment.FragmentNavigator @@ -155,11 +156,21 @@ internal class TurboNavigator(private val navDestination: TurboNavDestination) { // underlying fragment is still active and will receive the // result immediately. This allows the modal result flow to // behave exactly like full screen fragments. - rule.controller.popBackStack(rule.currentDestination.id, true) + do { + rule.controller.popBackStack() + } while ( + rule.controller.currentBackStackEntry.isModalContext + ) + sendModalResult(rule) } else { sendModalResult(rule) - rule.controller.popBackStack(rule.currentDestination.id, true) + + do { + rule.controller.popBackStack() + } while ( + rule.controller.currentBackStackEntry.isModalContext + ) } } } @@ -263,6 +274,12 @@ internal class TurboNavigator(private val navDestination: TurboNavDestination) { ) } + private val NavBackStackEntry?.isModalContext: Boolean + get() { + val context = this?.arguments?.getSerializable("presentation-context") + return context as? TurboNavPresentationContext == TurboNavPresentationContext.MODAL + } + private fun logEvent(event: String, vararg params: Pair) { val attributes = params.toMutableList().apply { add(0, "session" to session.sessionName)