adrielcafe / voyager

🛸 A pragmatic navigation library for Jetpack Compose
https://voyager.adriel.cafe
MIT License
2.27k stars 109 forks source link

Recommended way to implement application that requires login? #370

Closed tethridge closed 1 month ago

tethridge commented 2 months ago

The documentation doesn't show the best practice for using voyager with a login screen.

I'm hoping that there is a way to collect from a flow that has states unauthenticated, loading, and authenticated. When unauthenticated, the login page is shown. After the user enters their credentials and submits them the loading screen is shown. If the credentials are valid, then the main screen is shown. Otherwise, the user is returned to the login screen.

I'm having difficulty getting it to work properly with transitions. Can somebody provide an example?

maxoertel commented 2 months ago

Hey @tethridge , I'm trying the same right now. This is my approach, but even thoughh currentContent2 changes, the navigator does not redraw.

class MainScreen : Screen {

    override val key: ScreenKey = uniqueScreenKey

    @Composable
    override fun Content() {
        val screenModel = getScreenModel<MainScreenModel>()
        val userRepository = koinInject<UserRepository>()

        var currentContent by remember { mutableStateOf<Screen>(SplashScreen()) }

        LaunchedEffect(true) {
            userRepository.isLoggedIn.collect { value ->
                when (value) {
                    true -> {
                        currentContent = HomeScreen().also { println("set to Home") }
                    }
                    false -> {
                        currentContent = LoginScreen().also { println("set to Login") }
                    }
                }
            }
        }

        Navigator(currentContent)
    }
}

Maybe we find a solution together?

tethridge commented 2 months ago
    // This sort of works, but I'd like to have transitions.
    @Composable
    fun App() {
        MyAppTheme {
            Navigator(MainScreen()) { navigator ->
                val rootScreenModel = navigator.getNavigatorScreenModel<RootScreenModel>()
                val state by rootScreenModel.state.collectAsState()

                when (state) {
                    is RootScreenModel.State.Authenticated -> {
                        println("Authenticated")
                    }

                    is RootScreenModel.State.Unauthenticated -> {
                        println("Unauthenticated: pushing login screen")
                        navigator.push(StartLoginScreen())
                    }
                }

                CurrentScreen()

                // Adding transitions causes issues with reloading of content
                //SlideTransition(navigator)
            }
        }
    }
maxoertel commented 2 months ago

I understand. Works for me too without transitions. I'll try around with transitions and let you know if I find sth!

DevSrSouza commented 1 month ago

I would encourage to go on Discussions, issues are more focus on bugs and feature request.