33package com.slack.circuitx.navigation.intercepting
44
55import androidx.compose.runtime.Composable
6- import androidx.compose.runtime.ExperimentalComposeRuntimeApi
76import androidx.compose.runtime.Immutable
7+ import androidx.compose.runtime.SideEffect
88import androidx.compose.runtime.getValue
99import androidx.compose.runtime.mutableStateOf
1010import androidx.compose.runtime.remember
@@ -24,7 +24,6 @@ import kotlinx.collections.immutable.persistentListOf
2424 *
2525 * @see CircuitInterceptingNavigator
2626 */
27- @OptIn(ExperimentalComposeRuntimeApi ::class )
2827@Composable
2928public fun rememberCircuitInterceptingNavigator (
3029 navigator : Navigator ,
@@ -45,14 +44,23 @@ public fun rememberCircuitInterceptingNavigator(
4544 }
4645 // Handle the back button here to get pop events from it.
4746 if (enableBackHandler) {
48- var handledRoot by remember(navigator.peekBackStack()) { mutableStateOf(false ) }
49- BackHandler (enabled = ! handledRoot) {
50- // Check the backStack on each call as the `BackHandler` enabled state only updates on
51- // composition.
52- if (navigator.peekBackStack().size <= 1 ) {
53- handledRoot = true
47+ var trigger by remember { mutableStateOf(false ) }
48+ BackHandler (! trigger && enableBackHandler) {
49+ // Root pop check to prevent an infinite loop if this is used with the Android variant of
50+ // rememberCircuitNavigator that calls `OnBackPressedDispatcher.onBackPressed`. We need to
51+ // unload this BackHandler from the composition before the root pop is triggered, so dealy
52+ // calling pop until after the next composition.
53+ if (navigator.peekBackStack().size > 1 ) {
54+ interceptingNavigator.pop()
55+ } else {
56+ trigger = true
57+ }
58+ }
59+ if (trigger) {
60+ SideEffect {
61+ interceptingNavigator.pop()
62+ trigger = false
5463 }
55- interceptingNavigator.pop()
5664 }
5765 }
5866 // Handle backstack changed event listeners.
0 commit comments