Jetpack Compose Navigation Stack after navigating to Child Screen

66 Views Asked by At

Currently I am refactoring an application for Deep Linking and I had to add a composable to act as a proxy due to some Deep Link destinations having to take different routes since we are doing OAuth authentication with a 3rd party app and this is the callback.

Before triggering the 3rd party app I save the route of the Screen I am currently at and when the callbacks comes back in via Deep Link I grab those values to navigate to the original page so the user is back where he started.

This works really well for first level Screens, but when I attempt this with a 2nd level Screen the Navigation Stack is broken. When I attempt to go back to its parent I am just redirected to the same Screen.

Lets say the parent is the account section of the app and the deep link is pointing to a settings page.

I am setting a route of account/Settings which works fine to get navigated to that 2nd level Screen, but when I go back I run into the above mentioned problem and instead of the Account Screen I see the Sttings Screen again.

Here is the NavHost code for my proxy page:

private fun NavGraphBuilder.addProxy(
    navController: NavController,
    root: Screen,
    logViewModel: LogViewModel,
    deeplinkViewModel: DeeplinkViewModel
) {
    composable(
        route = LeafScreen.Account.Proxy.createRoute(root),
        arguments = listOf(
            navArgument("backRoute") {
                type = NavType.StringType
                nullable = true
            },
            navArgument("loggedInRoute") {
                type = NavType.StringType
                nullable = true
            }
        ),
        deepLinks = listOf(navDeepLink { uriPattern = "$uri/proxy/?code={code}&state={state}" })
    ) {
        val code = it.arguments?.getString("code")
        Logger.d("oauth code - $code")
        if (!code.isNullOrBlank()) {
            val oldBackRoute = loadValueFromStorage("backRoute")
            val oldLoggedInRoute = loadValueFromStorage("loggedInRoute")
            if (!oldBackRoute.isNullOrBlank()) {
                it.arguments!!.putString("backRoute", oldBackRoute)
            }
            if (!oldLoggedInRoute.isNullOrBlank()) {
                it.arguments!!.putString("loggedInRoute", oldLoggedInRoute)
            }
        }

        ProxyScreen(
            logViewModel = logViewModel,
            deeplinkViewModel = deeplinkViewModel,
            goBack = it.arguments
                ?.getString("backRoute")
                ?.let { { navController.navigate(it) } },
            goOnSuccess = it.arguments
                ?.getString("loggedInRoute")
                ?.let { { navController.navigate(it) } },
            intentData = it.arguments
        )
    }
}

And this is the code for the Composable itself:

@Composable
fun ProxyScreen (
    logViewModel: LogViewModel,
    deeplinkViewModel: DeeplinkViewModel,
    goBack: (() -> Unit)? = null,
    goOnSuccess: (() -> Unit)? = null,
    intentData: Bundle?
) {
    LaunchedEffect(true) {
        delay(timeMillis = 500)
        val code = intentData?.getString("code")
        sharedIntentData = intentData
        if (!code.isNullOrBlank() && goOnSuccess != null) goOnSuccess()
        else goBack?.let { it() }
    }

    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        Box(
            modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center,
        ) {
            LoadingCircle()
        }
    }
}

The above code is work in progress so it is not fully cleaned up yet.

0

There are 0 best solutions below