Skip to content
Open
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.

1 change: 0 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ dependencies {
implementation(project(":domain:main")) // needed for di
implementation(project(":data:main")) // needed for di
implementation(project(":core:network")) // needed for di
implementation(libs.composeNavigation)

api platform(libs.firebaseBoM)
implementation(libs.firebaseCrashlytics)
Expand Down
56 changes: 37 additions & 19 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,19 @@ 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 co.touchlab.kermit.Logger
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.deeplink.DeeplinkParser
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 @@ -31,19 +37,37 @@ import org.koin.android.ext.android.inject

class MainActivity : ComponentActivity() {

private val appDeepLinkScheme: AppScheme by inject()

private val snackbarPresenter: SnackbarPresenter by inject()

private val deeplinkParser: DeeplinkParser by inject()

@OptIn(ExperimentalAnimationApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge() // must be called before super.onCreate
super.onCreate(savedInstanceState)

Logger.d { "onCreate received, ${intent.data}" }

val startDestination: Destination = deeplinkParser.parseIntent(intent) ?: Destination.Home
Logger.i { "Start destination: $startDestination" }

setContent {

val navigationState = rememberNavigationState(
startRoute = startDestination,
topLevelRoutes = setOf<NavKey>(
// the destinations that can be used to enter the app, typically the tabs in the bottom navigation bar.
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 @@ -52,22 +76,16 @@ class MainActivity : ComponentActivity() {
) {
AppTheme {

val navController = rememberNavController()

AppSurface(
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
5 changes: 4 additions & 1 deletion app/src/main/kotlin/nl/q42/template/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import nl.q42.template.core.network.di.networkModule
import nl.q42.template.data.main.di.dataModule
import nl.q42.template.domain.main.di.domainModule
import nl.q42.template.home.di.homeModule
import nl.q42.template.navigation.deeplink.DeeplinkParser
import nl.q42.template.navigation.di.navigationModule
import nl.q42.template.onboarding.di.onboardingModule
import nl.q42.template.ui.di.presentationModule
Expand All @@ -27,6 +28,8 @@ fun initDependencyInjection(application: MainApplication) {
}

val appModule = module {
single { DeeplinkParser() }

includes(
configModule,

Expand All @@ -45,4 +48,4 @@ val appModule = module {
// domain
domainModule
)
}
}
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 { parametersOf(key) }
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

The @Provided annotation is being used to mark the params parameter, but HomeViewModel does not accept a Destination.Home parameter and will fail when Koin tries to inject it with parametersOf(key). This inconsistency between HomeSecondViewModel (which has a params parameter) and HomeViewModel (which doesn't) needs to be resolved. Either remove the parametersOf(key) call in HomeEntry.kt for HomeViewModel, or add a @Provided params: Destination.Home parameter to HomeViewModel if the destination data is needed.

Suggested change
val viewModel: HomeViewModel = koinViewModel { parametersOf(key) }
val viewModel: HomeViewModel = koinViewModel()

Copilot uses AI. Check for mistakes.
InitNavigator(navigator = navigator, routeNavigator = viewModel)
HomeScreen(viewModel = viewModel)
}
entry<Destination.HomeSecond> { key ->
val viewModel: HomeSecondViewModel = koinViewModel { 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 { parametersOf(key) }
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

Similar to HomeViewModel, OnboardingStartViewModel does not accept a Destination.Onboarding parameter but parametersOf(key) is being passed during its construction. This will cause a DI injection failure at runtime. Either remove the parametersOf(key) call or add a @Provided params: Destination.Onboarding parameter to OnboardingStartViewModel if the destination data is needed.

Suggested change
val viewModel: OnboardingStartViewModel = koinViewModel { parametersOf(key) }
val viewModel: OnboardingStartViewModel = koinViewModel()

Copilot uses AI. Check for mistakes.
InitNavigator(navigator = navigator, viewModel)

OnboardingStartScreen(viewModel = viewModel)
}
Expand Down
Loading