Tlaster / PreCompose

Compose Multiplatform Navigation && State Management

Home Page:https://tlaster.github.io/PreCompose/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[BUG] Nested Navigation Group with Bottom Navigation

iamnaran opened this issue · comments

Describe the bug
Let's say we've login flow, and once the user successfully logs in, they land on the main screen. However, when setting up two navigation groups within a NavHost, I'm encountering an issue where the start destination item in the bottom navigation isn't being automatically selected when navigating to that group route.

To Reproduce
Create two groups with one being BottomNavigation

@Composable
fun RootNavHost(navigator: Navigator) {
    NavHost(
        navigator = navigator,
        navTransition = NavTransition(),
        initialRoute = AppScreen.Auth.route,
    ) {

        group(
            route = AppScreen.Auth.route,
            initialRoute = AppScreen.Auth.Login.route
        ) {
            scene(
                route = AppScreen.Auth.Login.route,
                navTransition = NavTransition(),
            ) {
                LoginScreen(navigateToHome = {
                    navigator.navigate(AppScreen.Main.route)
                }, navigateToSignUp = {

                })
            }
        }


        group(
            route = AppScreen.Main.route,
            initialRoute = AppScreen.Main.Home.route,
        ) {

            scene(
                route = AppScreen.Main.Home.route,
                navTransition = NavTransition(),
            ) {

                HomeScreen(onProductClick = {

                })

            }

            scene(
                route = AppScreen.Main.Notification.route,
                navTransition = NavTransition(),
            ) {
                NotificationScreen()
            }

            scene(
                route = AppScreen.Main.Profile.route,
                navTransition = NavTransition(),
            ) {
                ProfileScreen()
            }

            }

        }

    }

}

@Composable
fun currentRoute(navigator: Navigator): String? {
    return navigator.currentEntry.collectAsState(null).value?.route?.route

}

And BottomAppBar.kt

@Composable
fun BottomBar(
    navigator: Navigator,
) {
    val navigationScreen = listOf(
        AppScreen.Main.Home,
        AppScreen.Main.Notification,
        AppScreen.Main.Explore,
        AppScreen.Main.Profile
    )

    NavigationBar {
        navigationScreen.forEach {
            NavigationBarItem(label = { Text(text = it.title) },
                selected = it.route == currentRoute(navigator),
                onClick = {
                    navigator.navigate(
                        it.route,
                        NavOptions(
                            launchSingleTop = true,
                        ),
                    )
                })
        }
    }
}

But when navigating to the initial route destination of the group, it works.

      navigator.navigate(AppScreen.Main.Home.route)

Expected behavior
When moving to the destination to a group, the initial route of group should correspond to the initial route, correct?
I believe in Jetpack Compose Navigation, this functionality operates by navigating to the navigation route. But here i have to navigate to the initial route of the group.

      navigator.navigate(AppScreen.Main.route)

Minimal reproducible example
Here's Github Repo Link - https://github.com/iamnaran/jellyfish/tree/main

Since PreCompose treats the group as a single route, so the currentRoute when you navigate to AppScreen.Main.route will be AppScreen.Main.route, not AppScreen.Main.Home.route, a workaround is to check both AppScreen.Main.route and AppScreen.Main.Home.route.
It can be fixed by changing currentRoute to the actual scene behind the group, but this will change the current behavior and I wonder if anyone is using such a behavior.

the 'group()' simliar to provide a route alias, because this api don't deal in it's closure
to complete your goal, you should use in this way:

NavHost(
            navigator = navigator,
            navTransition = NavTransition(),
            initialRoute = "/home",
        ) {
            scene(
                route = "/home",
                navTransition = NavTransition(),
            ) {
                Text(text = "Hello!")
            }

            group("/item", "/item/1") {
                for (i in 1..10) {
                    scene("/item/$i") {
                        Text("Hello $i")
                    }
                }
            }
        }

then you can navigate it like nested navigation:

navigator.navigate("/item/2")