From 08b6c8628302e1777528cb6ada3d25a501966c90 Mon Sep 17 00:00:00 2001 From: Anthony Date: Thu, 4 Apr 2024 10:15:05 +0200 Subject: [PATCH] feat(connector): add Koin dependency injection --- connector/composeApp/build.gradle.kts | 15 ++++++ .../composeApp/src/desktopMain/kotlin/App.kt | 16 +++++-- .../src/desktopMain/kotlin/di/CommonModule.kt | 20 ++++++++ .../src/desktopMain/kotlin/di/KoinInit.kt | 18 ++++++++ .../composeApp/src/desktopMain/kotlin/main.kt | 21 +++++++-- .../kotlin/tab/project/ProjectsScreenModel.kt | 46 +++++++++++++++++++ 6 files changed, 128 insertions(+), 8 deletions(-) create mode 100644 connector/composeApp/src/desktopMain/kotlin/di/CommonModule.kt create mode 100644 connector/composeApp/src/desktopMain/kotlin/di/KoinInit.kt create mode 100644 connector/composeApp/src/desktopMain/kotlin/tab/project/ProjectsScreenModel.kt diff --git a/connector/composeApp/build.gradle.kts b/connector/composeApp/build.gradle.kts index 356cd95..537302a 100644 --- a/connector/composeApp/build.gradle.kts +++ b/connector/composeApp/build.gradle.kts @@ -8,6 +8,9 @@ plugins { val material3Version = "1.6.1" val voyagerVersion = "1.0.0" +val kotlinxVersion = "1.8.0" +val koinVersion = "3.5.3" +val kodeinVersion = "7.21.2" kotlin { jvm("desktop") @@ -29,6 +32,11 @@ kotlin { implementation(compose.desktop.currentOs) implementation("org.jetbrains.compose.material3:material3-desktop:$material3Version") + // Koin + implementation(project.dependencies.platform("io.insert-koin:koin-bom:$koinVersion")) + implementation("io.insert-koin:koin-core:$koinVersion") + implementation("io.insert-koin:koin-compose:1.1.2") + // Voyager - Navigation // Multiplatform @@ -47,6 +55,11 @@ kotlin { // Transitions implementation("cafe.adriel.voyager:voyager-transitions:$voyagerVersion") + // Koin integration + implementation("cafe.adriel.voyager:voyager-koin:$voyagerVersion") + + + // Desktop + Android // Kodein integration @@ -54,6 +67,8 @@ kotlin { // RxJava integration implementation("cafe.adriel.voyager:voyager-rxjava:$voyagerVersion") + + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:$kotlinxVersion") } } } diff --git a/connector/composeApp/src/desktopMain/kotlin/App.kt b/connector/composeApp/src/desktopMain/kotlin/App.kt index 3b56af9..4504340 100644 --- a/connector/composeApp/src/desktopMain/kotlin/App.kt +++ b/connector/composeApp/src/desktopMain/kotlin/App.kt @@ -1,3 +1,4 @@ + import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState @@ -18,12 +19,15 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.ui.tooling.preview.Preview -import tab.* +import org.koin.compose.KoinContext +import tab.About +import tab.Settings +import tab.SimulatorTest +import tab.TestResults import tab.procedure.Procedures import tab.project.Projects import theme.AppTheme -@OptIn(ExperimentalResourceApi::class) @Composable @Preview fun App() { @@ -37,7 +41,7 @@ fun AppScaffold() { val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed) val scope = rememberCoroutineScope() - TabNavigator(Projects) { + TabNavigator(Projects()) { Scaffold( topBar = { TopBar(drawerState, scope) @@ -47,7 +51,9 @@ fun AppScaffold() { modifier = Modifier.padding(innerPadding) ) { NavigationDrawer(drawerState) { - CurrentTab() + KoinContext { + CurrentTab() + } } } } @@ -114,7 +120,7 @@ fun NavigationDrawer( ModalDrawerSheet { Column(modifier = Modifier.verticalScroll(rememberScrollState()) ) { Text("Project Name...", modifier = Modifier.padding(16.dp)) - TabNavigationItem(Projects) + TabNavigationItem(Projects()) HorizontalDivider() Text("Tester", modifier = Modifier.padding(16.dp)) diff --git a/connector/composeApp/src/desktopMain/kotlin/di/CommonModule.kt b/connector/composeApp/src/desktopMain/kotlin/di/CommonModule.kt new file mode 100644 index 0000000..5cc17db --- /dev/null +++ b/connector/composeApp/src/desktopMain/kotlin/di/CommonModule.kt @@ -0,0 +1,20 @@ +package di + +import io.anthonyberg.connector.shared.ProjectTransaction +import io.anthonyberg.connector.shared.database.DriverFactory +import org.koin.dsl.module +import tab.project.ProjectsScreenModel + +fun commonModule() = module { + single { + DriverFactory() + } + + single { + ProjectTransaction(driverFactory = get()) + } + + single { + ProjectsScreenModel(db = get()) + } +} diff --git a/connector/composeApp/src/desktopMain/kotlin/di/KoinInit.kt b/connector/composeApp/src/desktopMain/kotlin/di/KoinInit.kt new file mode 100644 index 0000000..8f79576 --- /dev/null +++ b/connector/composeApp/src/desktopMain/kotlin/di/KoinInit.kt @@ -0,0 +1,18 @@ +package di + +import org.koin.core.Koin +import org.koin.core.context.startKoin +import org.koin.dsl.KoinAppDeclaration + +class KoinInit { + fun init(appDeclaration: KoinAppDeclaration = {}): Koin { + return startKoin { + modules( + listOf( + commonModule() + ), + ) + appDeclaration() + }.koin + } +} diff --git a/connector/composeApp/src/desktopMain/kotlin/main.kt b/connector/composeApp/src/desktopMain/kotlin/main.kt index a71b0b0..eb806c9 100644 --- a/connector/composeApp/src/desktopMain/kotlin/main.kt +++ b/connector/composeApp/src/desktopMain/kotlin/main.kt @@ -3,12 +3,27 @@ import androidx.compose.ui.window.Window import androidx.compose.ui.window.application import connector.composeapp.generated.resources.Res import connector.composeapp.generated.resources.rule_24px +import di.KoinInit import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.painterResource +import org.koin.core.Koin + +lateinit var koin: Koin @OptIn(ExperimentalResourceApi::class) -fun main() = application { - Window(onCloseRequest = ::exitApplication, title = "Checklist Tester", icon = painterResource(Res.drawable.rule_24px)) { - App() +fun main() { + koin = KoinInit().init() + koin.loadModules( + listOf(), + ) + + return application { + Window( + onCloseRequest = ::exitApplication, + title = "Checklist Tester", + icon = painterResource(Res.drawable.rule_24px) + ) { + App() + } } } diff --git a/connector/composeApp/src/desktopMain/kotlin/tab/project/ProjectsScreenModel.kt b/connector/composeApp/src/desktopMain/kotlin/tab/project/ProjectsScreenModel.kt new file mode 100644 index 0000000..df50704 --- /dev/null +++ b/connector/composeApp/src/desktopMain/kotlin/tab/project/ProjectsScreenModel.kt @@ -0,0 +1,46 @@ +package tab.project + +import cafe.adriel.voyager.core.model.StateScreenModel +import cafe.adriel.voyager.core.model.screenModelScope +import io.anthonyberg.connector.shared.ProjectTransaction +import io.anthonyberg.connector.shared.entity.Project +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +class ProjectsScreenModel ( + private val db: ProjectTransaction +) : StateScreenModel(State.UnInit) { + + override fun onDispose() { + println("Project Disposed") + } + + sealed class State { + object UnInit : State() + object Init : State() + object Loading : State() + data class Result(val projects: List) : State() + } + + fun projectExists() { + screenModelScope.launch { + mutableState.value = State.Loading + delay(5000) + val exists = db.projectExists() + + if (exists) { + getProjects() + } else { + mutableState.value = State.Init + } + } + } + + fun getProjects() { + mutableState.value = State.Loading + val projects = db.getProjects() + + mutableState.value = State.Result(projects) + } + +}