Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .idea/copilotDiffState.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 33 additions & 13 deletions app/src/main/kotlin/nl/q42/template/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController
import androidx.navigation3.runtime.NavEntry
import androidx.navigation3.runtime.NavKey
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.scene.DialogSceneStrategy
import androidx.navigation3.ui.NavDisplay
import io.github.aakira.napier.Napier
import nl.q42.template.core.utils.config.AppScheme
import nl.q42.template.navigation.Destination
import nl.q42.template.navigation.homeGraph
import nl.q42.template.navigation.onboardingDestinations
import nl.q42.template.navigation.homeEntry
import nl.q42.template.navigation.onboardingEntry
import nl.q42.template.navigation.viewmodel.Navigator
import nl.q42.template.navigation.viewmodel.rememberNavigationState
import nl.q42.template.navigation.viewmodel.toEntries
import nl.q42.template.ui.compose.composables.widgets.AppSurface
import nl.q42.template.ui.compose.composables.window.LocalSnackbarHostState
import nl.q42.template.ui.compose.composables.window.toSnackBarVisuals
Expand All @@ -44,6 +51,23 @@ class MainActivity : ComponentActivity() {

setContent {

val navigationState = rememberNavigationState(
startRoute = Destination.Home,
topLevelRoutes = setOf<NavKey>(
// the destinations that can be used to enter the app
Destination.Home,
Destination.Onboarding
)
)

val navigator = remember { Navigator(navigationState) }
val entryProvider: (NavKey) -> NavEntry<NavKey> = entryProvider {
homeEntry(navigator = navigator)
onboardingEntry(navigator = navigator)
}



val snackbarHostState = remember { SnackbarHostState() }
SnackbarChangedEffect(snackbarHostState)

Expand All @@ -58,16 +82,12 @@ class MainActivity : ComponentActivity() {
modifier = Modifier.fillMaxSize(),
) {

NavHost(
navController = navController,
startDestination = Destination.HomeGraph
) {
homeGraph(
navController = navController,
appDeepLinkScheme = appDeepLinkScheme
)
onboardingDestinations(navController)
}
NavDisplay(
entries = navigationState.toEntries(entryProvider),
onBack = { navigator.goBack() },
sceneStrategy = remember { DialogSceneStrategy() }
)

}
}
}
Expand Down
25 changes: 25 additions & 0 deletions app/src/main/kotlin/nl/q42/template/navigation/HomeEntry.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package nl.q42.template.navigation

import androidx.navigation3.runtime.EntryProviderScope
import androidx.navigation3.runtime.NavKey
import nl.q42.template.home.main.presentation.HomeViewModel
import nl.q42.template.home.main.ui.HomeScreen
import nl.q42.template.home.second.presentation.HomeSecondViewModel
import nl.q42.template.home.second.ui.HomeSecondScreen
import nl.q42.template.navigation.viewmodel.InitNavigator
import nl.q42.template.navigation.viewmodel.Navigator
import org.koin.androidx.compose.koinViewModel
import org.koin.core.parameter.parametersOf

internal fun EntryProviderScope<NavKey>.homeEntry(navigator: Navigator) {
entry<Destination.Home> { key ->
val viewModel: HomeViewModel = koinViewModel(parameters = { parametersOf(key) })
InitNavigator(navigator = navigator, routeNavigator = viewModel)
HomeScreen(viewModel = viewModel)
}
entry<Destination.HomeSecond> { key ->
val viewModel: HomeSecondViewModel = koinViewModel(parameters = { parametersOf(key) })
InitNavigator(navigator = navigator, routeNavigator = viewModel)
HomeSecondScreen(viewModel = viewModel)
}
}
42 changes: 0 additions & 42 deletions app/src/main/kotlin/nl/q42/template/navigation/HomeGraph.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package nl.q42.template.navigation

import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
import androidx.navigation3.runtime.EntryProviderScope
import androidx.navigation3.runtime.NavKey
import nl.q42.template.navigation.viewmodel.InitNavigator
import nl.q42.template.navigation.viewmodel.Navigator
import nl.q42.template.onboarding.start.presentation.OnboardingStartViewModel
import nl.q42.template.onboarding.start.ui.OnboardingStartScreen
import org.koin.androidx.compose.koinViewModel
import org.koin.core.parameter.parametersOf

internal fun NavGraphBuilder.onboardingDestinations(navController: NavHostController) {
composable<Destination.Onboarding> {

val viewModel: OnboardingStartViewModel = koinViewModel()
InitNavigator(navController = navController, viewModel)
internal fun EntryProviderScope<NavKey>.onboardingEntry(navigator: Navigator) {
entry<Destination.Onboarding> { key ->
val viewModel: OnboardingStartViewModel = koinViewModel(parameters = { parametersOf(key) })
InitNavigator(navigator = navigator, viewModel)

OnboardingStartScreen(viewModel = viewModel)
}
Expand Down
5 changes: 5 additions & 0 deletions build.dep.navigation.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
dependencies {
implementation libs.composeNavigation
implementation(libs.androidx.navigation3.ui)
implementation(libs.androidx.navigation3.runtime)

// If using the ViewModel add-on library
implementation(libs.androidx.lifecycle.viewmodel.navigation3)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this used?

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package nl.q42.template.navigation

import androidx.navigation3.runtime.NavKey
import kotlinx.serialization.Serializable

/**
Expand All @@ -15,15 +16,15 @@ sealed class Destination {
* Main destination. If you add a bottom navigation component, make a graph per bottom tab.
*/
@Serializable
data object HomeGraph : Destination()
data object HomeGraph : Destination(), NavKey

@Serializable
data object Home : Destination()
data object Home : Destination(), NavKey

@Serializable
// all parameters should be path parameters of a deeplink in HomeGraph.kt: composable<Destination.HomeSecond>(deeplinks = listOf(...))
data class HomeSecond(val title: String) : Destination()
data class HomeSecond(val title: String) : Destination(), NavKey

@Serializable
data object Onboarding : Destination()
data object Onboarding : Destination(), NavKey
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package nl.q42.template.navigation.viewmodel

import nl.q42.template.navigation.Destination
import java.util.UUID

sealed class AppNavigationState {
data object Idle : AppNavigationState()
data class NavigateToRoute(
val destination: Destination,
val backstackBehavior: BackstackBehavior,
val id: String = UUID.randomUUID().toString()
) : AppNavigationState()

data class PopToDestination(val destination: Destination, val id: String = UUID.randomUUID().toString()) : AppNavigationState()

data class NavigateUp(val id: String = UUID.randomUUID().toString()) : AppNavigationState()
}

sealed class BackstackBehavior {
/**
* Adds the destination to the backstack as usual.
*/
data object Default : BackstackBehavior()

/**
* Removes the current destination from the backstack before navigating.
*
* When navigating A -> B -> C. If B -> C is set to RemoveCurrent,
* the backstack will be A -> C.
*/
data object RemoveCurrent : BackstackBehavior()

/**
* Clears the backstack and sets the target destination as the backstack's root.
*
* When navigating A -> B -> C. If B -> C is set to Clear, the backstack will be C.
*/
data object Clear : BackstackBehavior()
}
Loading
Loading