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.