From 1d715f9d42111e1152c39a1502a89d372b53307b Mon Sep 17 00:00:00 2001 From: Jay Ohms Date: Thu, 28 Apr 2022 18:05:55 -0400 Subject: [PATCH 1/3] Allow multiple modals with different destination IDs in the backstack. Pop all modal context destinations off the backstack when navigating back to the default context. --- .../dev/hotwire/turbo/nav/TurboNavRule.kt | 10 ++++---- .../dev/hotwire/turbo/nav/TurboNavigator.kt | 24 +++++++++++++++++-- 2 files changed, 28 insertions(+), 6 deletions(-) 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..574e1ad7 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) + putString("presentation-context", newPresentationContext.name) + } } 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..7b9fe0a6 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,15 @@ internal class TurboNavigator(private val navDestination: TurboNavDestination) { ) } + private val NavBackStackEntry?.isModalContext: Boolean + get() = try { + val value = this?.arguments?.getString("presentation-context").orEmpty() + val context = TurboNavPresentationContext.valueOf(value) + context == TurboNavPresentationContext.MODAL + } catch (e: IllegalArgumentException) { + false + } + private fun logEvent(event: String, vararg params: Pair) { val attributes = params.toMutableList().apply { add(0, "session" to session.sessionName) From a3cc7551967c0b32b7b32853d5c13d22981a4bf5 Mon Sep 17 00:00:00 2001 From: Jay Ohms Date: Thu, 28 Apr 2022 18:35:08 -0400 Subject: [PATCH 2/3] Save the bundle arg as a serializable enum instead of a String --- turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavRule.kt | 2 +- .../src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) 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 574e1ad7..cf1b7f54 100644 --- a/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavRule.kt +++ b/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavRule.kt @@ -127,7 +127,7 @@ internal class TurboNavRule( val bundle = this ?: bundleOf() return bundle.apply { putString("location", newLocation) - putString("presentation-context", newPresentationContext.name) + putSerializable("presentation-context", newPresentationContext) } } 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 7b9fe0a6..15057048 100644 --- a/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt +++ b/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt @@ -276,9 +276,8 @@ internal class TurboNavigator(private val navDestination: TurboNavDestination) { private val NavBackStackEntry?.isModalContext: Boolean get() = try { - val value = this?.arguments?.getString("presentation-context").orEmpty() - val context = TurboNavPresentationContext.valueOf(value) - context == TurboNavPresentationContext.MODAL + val context = this?.arguments?.getSerializable("presentation-context") + context as? TurboNavPresentationContext == TurboNavPresentationContext.MODAL } catch (e: IllegalArgumentException) { false } From 66fdd5607d35dea087ca7761b6b45316fc7695bc Mon Sep 17 00:00:00 2001 From: Jay Ohms Date: Fri, 29 Apr 2022 12:41:19 -0400 Subject: [PATCH 3/3] Remove unnecessary try/catch --- .../src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) 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 15057048..baf1f461 100644 --- a/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt +++ b/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt @@ -275,11 +275,9 @@ internal class TurboNavigator(private val navDestination: TurboNavDestination) { } private val NavBackStackEntry?.isModalContext: Boolean - get() = try { + get() { val context = this?.arguments?.getSerializable("presentation-context") - context as? TurboNavPresentationContext == TurboNavPresentationContext.MODAL - } catch (e: IllegalArgumentException) { - false + return context as? TurboNavPresentationContext == TurboNavPresentationContext.MODAL } private fun logEvent(event: String, vararg params: Pair) {