chore(frontend): refactor navigation and DI setup, remove unused shared module
- Replaced `initKoin` with `startKoin` for DI initialization consistency across platforms. - Introduced `StateNavigationPort` with `StateFlow` to streamline navigation state management. - Migrated `AppScreen` to sealed class with route mapping for better navigation handling. - Deleted unused `frontend/shared` module and removed related dependencies from build files. - Cleaned up legacy navigation and Redux-related code, aligning with MVVM architecture.
This commit is contained in:
@@ -63,7 +63,7 @@ kotlin {
|
||||
sourceSets {
|
||||
commonMain.dependencies {
|
||||
// Shared modules
|
||||
implementation(projects.frontend.shared)
|
||||
// implementation(projects.frontend.shared) // REMOVED: Shared module deleted
|
||||
implementation(projects.frontend.core.domain)
|
||||
implementation(projects.frontend.core.designSystem)
|
||||
implementation(projects.frontend.core.navigation)
|
||||
|
||||
@@ -6,7 +6,7 @@ import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import at.mocode.clients.shared.navigation.AppScreen
|
||||
import at.mocode.frontend.core.navigation.AppScreen
|
||||
import at.mocode.frontend.core.auth.data.AuthTokenManager
|
||||
import at.mocode.frontend.core.auth.presentation.LoginScreen
|
||||
import at.mocode.frontend.core.auth.presentation.LoginViewModel
|
||||
@@ -14,6 +14,7 @@ import at.mocode.ping.feature.presentation.PingScreen
|
||||
import at.mocode.ping.feature.presentation.PingViewModel
|
||||
import at.mocode.frontend.core.designsystem.components.AppFooter
|
||||
import at.mocode.frontend.core.designsystem.theme.AppTheme
|
||||
import navigation.StateNavigationPort
|
||||
import org.koin.compose.koinInject
|
||||
import org.koin.compose.viewmodel.koinViewModel
|
||||
|
||||
@@ -25,7 +26,9 @@ fun MainApp() {
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background
|
||||
) {
|
||||
var currentScreen by remember { mutableStateOf<AppScreen>(AppScreen.Landing) }
|
||||
// Resolve NavigationPort to observe state changes
|
||||
val navigationPort = koinInject<StateNavigationPort>()
|
||||
val currentScreen by navigationPort.currentScreen.collectAsState()
|
||||
|
||||
// Resolve AuthTokenManager from Koin
|
||||
val authTokenManager = koinInject<AuthTokenManager>()
|
||||
@@ -36,31 +39,31 @@ fun MainApp() {
|
||||
|
||||
when (currentScreen) {
|
||||
is AppScreen.Landing -> LandingScreen(
|
||||
onPrimaryCta = { currentScreen = AppScreen.Login },
|
||||
onSecondary = { currentScreen = AppScreen.Home }
|
||||
onPrimaryCta = { navigationPort.navigateToScreen(AppScreen.Login) },
|
||||
onSecondary = { navigationPort.navigateToScreen(AppScreen.Home) }
|
||||
)
|
||||
|
||||
is AppScreen.Home -> WelcomeScreen(
|
||||
authTokenManager = authTokenManager,
|
||||
onOpenPing = { currentScreen = AppScreen.Ping },
|
||||
onOpenLogin = { currentScreen = AppScreen.Login },
|
||||
onOpenProfile = { currentScreen = AppScreen.Profile }
|
||||
onOpenPing = { navigationPort.navigateToScreen(AppScreen.Ping) },
|
||||
onOpenLogin = { navigationPort.navigateToScreen(AppScreen.Login) },
|
||||
onOpenProfile = { navigationPort.navigateToScreen(AppScreen.Profile) }
|
||||
)
|
||||
|
||||
is AppScreen.Login -> LoginScreen(
|
||||
viewModel = loginViewModel,
|
||||
onLoginSuccess = { currentScreen = AppScreen.Profile },
|
||||
onBack = { currentScreen = AppScreen.Home }
|
||||
onLoginSuccess = { navigationPort.navigateToScreen(AppScreen.Profile) },
|
||||
onBack = { navigationPort.navigateToScreen(AppScreen.Home) }
|
||||
)
|
||||
|
||||
is AppScreen.Ping -> PingScreen(
|
||||
viewModel = pingViewModel,
|
||||
onBack = { currentScreen = AppScreen.Home } // Navigate back to Home
|
||||
onBack = { navigationPort.navigateToScreen(AppScreen.Home) } // Navigate back to Home
|
||||
)
|
||||
|
||||
is AppScreen.Profile -> AuthStatusScreen(
|
||||
authTokenManager = authTokenManager,
|
||||
onBackToHome = { currentScreen = AppScreen.Home }
|
||||
onBackToHome = { navigationPort.navigateToScreen(AppScreen.Home) }
|
||||
)
|
||||
|
||||
else -> {}
|
||||
|
||||
+22
-6
@@ -2,9 +2,13 @@ package navigation
|
||||
|
||||
import at.mocode.frontend.core.auth.data.AuthTokenManager
|
||||
import at.mocode.frontend.core.domain.models.User
|
||||
import at.mocode.frontend.core.navigation.AppScreen
|
||||
import at.mocode.frontend.core.navigation.CurrentUserProvider
|
||||
import at.mocode.frontend.core.navigation.DeepLinkHandler
|
||||
import at.mocode.frontend.core.navigation.NavigationPort
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import org.koin.dsl.module
|
||||
|
||||
class ShellCurrentUserProvider(
|
||||
@@ -23,17 +27,29 @@ class ShellCurrentUserProvider(
|
||||
}
|
||||
}
|
||||
|
||||
class NoopNavigationPort : NavigationPort {
|
||||
var lastRoute: String? = null
|
||||
/**
|
||||
* A real implementation of NavigationPort that updates a StateFlow.
|
||||
* This allows the MainApp to observe changes and update the UI.
|
||||
*/
|
||||
class StateNavigationPort : NavigationPort {
|
||||
private val _currentScreen = MutableStateFlow<AppScreen>(AppScreen.Landing)
|
||||
val currentScreen: StateFlow<AppScreen> = _currentScreen.asStateFlow()
|
||||
|
||||
override fun navigateTo(route: String) {
|
||||
lastRoute = route
|
||||
// Simple logging; actual routing is handled elsewhere in the shell
|
||||
println("[NavigationPort] navigateTo $route")
|
||||
val screen = AppScreen.fromRoute(route)
|
||||
println("[NavigationPort] navigateTo $route -> $screen")
|
||||
_currentScreen.value = screen
|
||||
}
|
||||
|
||||
fun navigateToScreen(screen: AppScreen) {
|
||||
_currentScreen.value = screen
|
||||
}
|
||||
}
|
||||
|
||||
val navigationModule = module {
|
||||
single<CurrentUserProvider> { ShellCurrentUserProvider(get()) }
|
||||
single<NavigationPort> { NoopNavigationPort() }
|
||||
// Bind as both NavigationPort (for Core) and StateNavigationPort (for Shell)
|
||||
single { StateNavigationPort() }
|
||||
single<NavigationPort> { get<StateNavigationPort>() }
|
||||
single { DeepLinkHandler(get(), get()) }
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@ import at.mocode.frontend.core.localdb.localDbModule
|
||||
import at.mocode.frontend.core.network.networkModule
|
||||
import at.mocode.frontend.core.sync.di.syncModule
|
||||
import at.mocode.ping.feature.di.pingFeatureModule
|
||||
import at.mocode.shared.di.initKoin
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import navigation.navigationModule
|
||||
import org.koin.core.context.GlobalContext
|
||||
import org.koin.core.context.startKoin
|
||||
import org.koin.core.context.loadKoinModules
|
||||
import org.koin.dsl.module
|
||||
import org.w3c.dom.HTMLElement
|
||||
@@ -23,7 +23,7 @@ fun main() {
|
||||
|
||||
// 1. Initialize DI (Koin) with static modules
|
||||
try {
|
||||
initKoin { modules(networkModule, localDbModule, syncModule, pingFeatureModule, authModule, navigationModule) }
|
||||
startKoin { modules(networkModule, localDbModule, syncModule, pingFeatureModule, authModule, navigationModule) }
|
||||
console.log("[WebApp] Koin initialized with static modules")
|
||||
} catch (e: dynamic) {
|
||||
console.warn("[WebApp] Koin initialization warning:", e)
|
||||
|
||||
@@ -2,7 +2,6 @@ import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import androidx.compose.ui.window.WindowState
|
||||
import androidx.compose.ui.unit.dp
|
||||
import at.mocode.shared.di.initKoin
|
||||
import at.mocode.frontend.core.network.networkModule
|
||||
import at.mocode.frontend.core.auth.di.authModule
|
||||
import at.mocode.frontend.core.sync.di.syncModule
|
||||
@@ -12,6 +11,7 @@ import at.mocode.frontend.core.localdb.DatabaseProvider
|
||||
import at.mocode.frontend.core.localdb.localDbModule
|
||||
import navigation.navigationModule
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.koin.core.context.startKoin
|
||||
import org.koin.core.context.loadKoinModules
|
||||
import org.koin.dsl.module
|
||||
|
||||
@@ -19,7 +19,7 @@ fun main() = application {
|
||||
// Initialize DI (Koin) with shared modules + network module
|
||||
try {
|
||||
// Updated: Only load the consolidated pingFeatureModule from at.mocode.ping.feature.di
|
||||
initKoin { modules(networkModule, syncModule, pingFeatureModule, authModule, navigationModule, localDbModule) }
|
||||
startKoin { modules(networkModule, syncModule, pingFeatureModule, authModule, navigationModule, localDbModule) }
|
||||
println("[DesktopApp] Koin initialized with networkModule + authModule + navigationModule + pingFeatureModule + localDbModule")
|
||||
} catch (e: Exception) {
|
||||
println("[DesktopApp] Koin initialization warning: ${e.message}")
|
||||
|
||||
Reference in New Issue
Block a user