From 7fc99f579905ba4e02d35e025c1aceb2963bf3a7 Mon Sep 17 00:00:00 2001 From: Thomas Andres Gomez Date: Fri, 15 Nov 2024 21:18:45 +0100 Subject: [PATCH] Add koin dependencies injections. --- composeApp/build.gradle.kts | 6 ++ .../composeResources/values/strings.xml | 2 + .../kotlin/com/pixelized/desktop/lwa/App.kt | 4 +- .../com/pixelized/desktop/lwa/Module.kt | 51 ++++++++++++++ .../CharacterSheetRepository.kt | 5 +- .../repository/network/NetworkRepository.kt | 8 ++- .../repository/roll/RollHistoryRepository.kt | 5 +- .../detail/CharacterSheetPage.kt | 68 ++++++++++++++----- .../detail/CharacterSheetViewModel.kt | 4 +- .../edit/CharacterSheetEditPage.kt | 12 ++-- .../edit/CharacterSheetEditViewModel.kt | 6 +- .../desktop/lwa/screen/main/MainPage.kt | 6 +- .../lwa/screen/main/MainPageViewModel.kt | 7 +- .../desktop/lwa/screen/network/NetworkPage.kt | 10 ++- .../lwa/screen/network/NetworkViewModel.kt | 11 ++- .../desktop/lwa/screen/roll/RollPage.kt | 5 +- .../desktop/lwa/screen/roll/RollViewModel.kt | 13 ++-- .../lwa/screen/rollhistory/RollHistoryPage.kt | 5 +- .../rollhistory/RollHistoryViewModel.kt | 6 +- .../kotlin/com/pixelized/desktop/lwa/main.kt | 10 ++- gradle/libs.versions.toml | 11 +-- 21 files changed, 181 insertions(+), 74 deletions(-) create mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index 3f09148..f01e0d7 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -15,6 +15,7 @@ kotlin { val desktopMain by getting commonMain.dependencies { + // compose implementation(compose.runtime) implementation(compose.foundation) implementation(compose.material) @@ -24,6 +25,11 @@ kotlin { implementation(libs.androidx.lifecycle.viewmodel) implementation(libs.androidx.lifecycle.runtime.compose) implementation(libs.androidx.navigation.compose) + // injection + api(libs.koin.core) + implementation(libs.koin.compose) + implementation(libs.koin.compose.viewmodel) + // network. implementation(libs.kotlinx.serialization.json) implementation(libs.ktor.client.core) implementation(libs.ktor.client.cio) diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml index 523356f..e5d22ba 100644 --- a/composeApp/src/commonMain/composeResources/values/strings.xml +++ b/composeApp/src/commonMain/composeResources/values/strings.xml @@ -59,6 +59,8 @@ Ajouter une compétence magique État diminuer + Modifier + Supprimer Force Dextérité Constitution diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/App.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/App.kt index ccd1628..7a9bff5 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/App.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/App.kt @@ -46,6 +46,7 @@ import lwacharactersheet.composeapp.generated.resources.network__connect__messag import lwacharactersheet.composeapp.generated.resources.network__disconnect__message import org.jetbrains.compose.resources.getString import org.jetbrains.compose.ui.tooling.preview.Preview +import org.koin.compose.koinInject val LocalWindowController = compositionLocalOf { error("Local Window Controller is not yet ready") @@ -155,10 +156,11 @@ private fun WindowsHandler( private fun NetworkSnackHandler( snack: SnackbarHostState, ) { + val networkRepository = koinInject() LaunchedEffect(Unit) { launch { var ignoreInitial = true - NetworkRepository.status.collect { + networkRepository.status.collect { if (ignoreInitial) { ignoreInitial = false } else { diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt new file mode 100644 index 0000000..5c6a2af --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt @@ -0,0 +1,51 @@ +package com.pixelized.desktop.lwa + +import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository +import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetStore +import com.pixelized.desktop.lwa.repository.network.NetworkRepository +import com.pixelized.desktop.lwa.repository.roll.RollHistoryRepository +import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetFactory +import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetViewModel +import com.pixelized.desktop.lwa.screen.characterSheet.edit.CharacterSheetEditViewModel +import com.pixelized.desktop.lwa.screen.characterSheet.edit.CharacterSheetEditFactory +import com.pixelized.desktop.lwa.screen.main.MainPageViewModel +import com.pixelized.desktop.lwa.screen.network.NetworkFactory +import com.pixelized.desktop.lwa.screen.network.NetworkViewModel +import com.pixelized.desktop.lwa.screen.roll.RollViewModel +import com.pixelized.desktop.lwa.screen.rollhistory.RollHistoryViewModel +import org.koin.core.module.dsl.factoryOf +import org.koin.core.module.dsl.singleOf +import org.koin.core.module.dsl.viewModelOf +import org.koin.dsl.module + +val moduleDependencies + get() = listOf( + repositoryDependencies, + factoryDependencies, + viewModelDependencies, + ) + +val repositoryDependencies + get() = module { + singleOf(::CharacterSheetStore) + singleOf(::NetworkRepository) + singleOf(::CharacterSheetRepository) + singleOf(::RollHistoryRepository) + } + +val factoryDependencies + get() = module { + factoryOf(::CharacterSheetFactory) + factoryOf(::CharacterSheetEditFactory) + factoryOf(::NetworkFactory) + } + +val viewModelDependencies + get() = module { + viewModelOf(::MainPageViewModel) + viewModelOf(::CharacterSheetViewModel) + viewModelOf(::CharacterSheetEditViewModel) + viewModelOf(::RollViewModel) + viewModelOf(::RollHistoryViewModel) + viewModelOf(::NetworkViewModel) + } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetRepository.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetRepository.kt index fc33978..d405176 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetRepository.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetRepository.kt @@ -8,9 +8,10 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn -object CharacterSheetRepository { +class CharacterSheetRepository( + private val store: CharacterSheetStore, +) { private val scope = CoroutineScope(Dispatchers.IO) - private val store = CharacterSheetStore() private val sheets = store.loadFlow() .stateIn( diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/network/NetworkRepository.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/network/NetworkRepository.kt index d5221b6..95cb46d 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/network/NetworkRepository.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/network/NetworkRepository.kt @@ -26,9 +26,11 @@ import kotlinx.serialization.json.encodeToJsonElement typealias Server = EmbeddedServer typealias Client = HttpClient -object NetworkRepository { - const val DEFAULT_PORT = 16030 - const val DEFAULT_HOST = "pixelized.freeboxos.fr" +class NetworkRepository { + companion object { + const val DEFAULT_PORT = 16030 + const val DEFAULT_HOST = "pixelized.freeboxos.fr" + } private val scope = CoroutineScope(Dispatchers.IO) private var networkJob: Job? = null diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/roll/RollHistoryRepository.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/roll/RollHistoryRepository.kt index bd7d474..d478265 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/roll/RollHistoryRepository.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/roll/RollHistoryRepository.kt @@ -11,9 +11,10 @@ import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.launch -object RollHistoryRepository { +class RollHistoryRepository( + private val network: NetworkRepository, +) { private val scope = CoroutineScope(Dispatchers.IO) - private val network = NetworkRepository val rolls: SharedFlow = network.data .mapNotNull { it.takeIf { it.value is RollMessage } } diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetPage.kt index a7c388a..1611dc6 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetPage.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetPage.kt @@ -12,7 +12,6 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight @@ -27,6 +26,8 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.Checkbox import androidx.compose.material.CheckboxDefaults +import androidx.compose.material.DropdownMenu +import androidx.compose.material.DropdownMenuItem import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme @@ -37,9 +38,11 @@ import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Edit +import androidx.compose.material.icons.filled.MoreVert import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment @@ -48,8 +51,6 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.lifecycle.createSavedStateHandle -import androidx.lifecycle.viewmodel.compose.viewModel import com.pixelized.desktop.lwa.LocalWindowController import com.pixelized.desktop.lwa.composable.blur.BlurContent import com.pixelized.desktop.lwa.composable.blur.BlurContentController @@ -64,6 +65,8 @@ import com.pixelized.desktop.lwa.screen.roll.RollPage import com.pixelized.desktop.lwa.screen.roll.RollViewModel import kotlinx.coroutines.launch import lwacharactersheet.composeapp.generated.resources.Res +import lwacharactersheet.composeapp.generated.resources.character_sheet__delete__label +import lwacharactersheet.composeapp.generated.resources.character_sheet__edit__label import lwacharactersheet.composeapp.generated.resources.character_sheet__magics__title import lwacharactersheet.composeapp.generated.resources.character_sheet__occupations_title import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__title @@ -72,6 +75,8 @@ import lwacharactersheet.composeapp.generated.resources.ic_d20_32dp import lwacharactersheet.composeapp.generated.resources.ic_skull_32dp import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource +import org.koin.compose.viewmodel.koinViewModel +import org.koin.core.annotation.KoinExperimentalAPI @Stable data class CharacterSheetPageUio( @@ -106,12 +111,11 @@ data class CharacterSheetPageUio( ) } +@OptIn(KoinExperimentalAPI::class) @Composable fun CharacterSheetPage( - viewModel: CharacterSheetViewModel = viewModel { - CharacterSheetViewModel(savedStateHandle = createSavedStateHandle()) - }, - rollViewModel: RollViewModel = viewModel { RollViewModel() }, + viewModel: CharacterSheetViewModel = koinViewModel(), + rollViewModel: RollViewModel = koinViewModel(), ) { val windowController = LocalWindowController.current val window = LocalWindow.current @@ -273,6 +277,7 @@ fun CharacterSheetPageContent( ) }, actions = { + var showMenu = remember { mutableStateOf(false) } Box { IconButton( onClick = onDiminished, @@ -301,24 +306,53 @@ fun CharacterSheetPageContent( ) } } - IconButton( - onClick = onEdit, + onClick = { showMenu.value = showMenu.value.not() }, ) { Icon( - imageVector = Icons.Default.Edit, + imageVector = Icons.Default.MoreVert, tint = MaterialTheme.colors.primary, contentDescription = null, ) } - IconButton( - onClick = onDelete, + DropdownMenu( + expanded = showMenu.value, + onDismissRequest = { showMenu.value = false } ) { - Icon( - imageVector = Icons.Default.Delete, - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) + DropdownMenuItem( + onClick = { + showMenu.value = false + onEdit() + }, + ) { + Icon( + imageVector = Icons.Default.Edit, + tint = MaterialTheme.colors.primary, + contentDescription = null, + ) + Text( + modifier = Modifier.padding(start = 8.dp), + color = MaterialTheme.colors.primary, + text = stringResource(Res.string.character_sheet__edit__label), + ) + } + DropdownMenuItem( + onClick = { + showMenu.value = false + onDelete() + }, + ) { + Icon( + imageVector = Icons.Default.Delete, + tint = MaterialTheme.colors.primary, + contentDescription = null, + ) + Text( + modifier = Modifier.padding(start = 8.dp), + color = MaterialTheme.colors.primary, + text = stringResource(Res.string.character_sheet__delete__label), + ) + } } }, ) diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetViewModel.kt index 5342bf0..3cc9e89 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetViewModel.kt @@ -30,12 +30,12 @@ import kotlin.math.min private typealias CSDCDialogUio = CharacterSheetDeleteConfirmationDialogUio class CharacterSheetViewModel( + private val repository: CharacterSheetRepository, + private val factory: CharacterSheetFactory, savedStateHandle: SavedStateHandle, ) : ViewModel() { private val argument = CharacterSheetDestination.Argument(savedStateHandle) - private val repository = CharacterSheetRepository - private val factory = CharacterSheetFactory() private val _displayDeleteConfirmationDialog = mutableStateOf(null) val displayDeleteConfirmationDialog: State get() = _displayDeleteConfirmationDialog diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditPage.kt index 3bc43f2..9a7b05c 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditPage.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditPage.kt @@ -28,8 +28,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.lifecycle.createSavedStateHandle -import androidx.lifecycle.viewmodel.compose.viewModel import com.pixelized.desktop.lwa.LocalWindowController import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController @@ -42,6 +40,8 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__ad import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__save_action import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__title import org.jetbrains.compose.resources.stringResource +import org.koin.compose.viewmodel.koinViewModel +import org.koin.core.annotation.KoinExperimentalAPI @Stable data class CharacterSheetEditPageUio( @@ -69,14 +69,10 @@ data class CharacterSheetEditPageUio( } } - +@OptIn(KoinExperimentalAPI::class) @Composable fun CharacterSheetEditPage( - viewModel: CharacterSheetEditViewModel = viewModel { - CharacterSheetEditViewModel( - savedStateHandle = createSavedStateHandle() - ) - }, + viewModel: CharacterSheetEditViewModel = koinViewModel(), ) { val windowController = LocalWindowController.current val window = LocalWindow.current diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditViewModel.kt index a327271..359d3bc 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditViewModel.kt @@ -11,17 +11,17 @@ import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio import kotlinx.coroutines.runBlocking class CharacterSheetEditViewModel( + private val characterSheetRepository: CharacterSheetRepository, savedStateHandle: SavedStateHandle, ) : ViewModel() { private val argument = CharacterSheetEditDestination.Argument(savedStateHandle) - private val repository = CharacterSheetRepository private val factory = CharacterSheetEditFactory() val enableBack = argument.enableBack private val _characterSheet = mutableStateOf( - repository.characterSheetFlow(id = argument.id).value.let { + characterSheetRepository.characterSheetFlow(id = argument.id).value.let { runBlocking { factory.convertToUio(it) } } ) @@ -78,6 +78,6 @@ class CharacterSheetEditViewModel( suspend fun save() { val sheet = _characterSheet.value val model = factory.convertToModel(sheet = sheet) - repository.save(characterSheet = model) + characterSheetRepository.save(characterSheet = model) } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/main/MainPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/main/MainPage.kt index 9c817c7..99a7a72 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/main/MainPage.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/main/MainPage.kt @@ -19,7 +19,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.lifecycle.viewmodel.compose.viewModel import com.pixelized.desktop.lwa.LocalWindowController import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController import com.pixelized.desktop.lwa.navigation.screen.destination.navigateToNetwork @@ -31,6 +30,8 @@ import lwacharactersheet.composeapp.generated.resources.main_page__create_action import lwacharactersheet.composeapp.generated.resources.main_page__network_action import lwacharactersheet.composeapp.generated.resources.main_page__roll_history_action import org.jetbrains.compose.resources.stringResource +import org.koin.compose.viewmodel.koinViewModel +import org.koin.core.annotation.KoinExperimentalAPI @Stable data class CharacterUio( @@ -38,9 +39,10 @@ data class CharacterUio( val name: String, ) +@OptIn(KoinExperimentalAPI::class) @Composable fun MainPage( - viewModel: MainPageViewModel = viewModel { MainPageViewModel() }, + viewModel: MainPageViewModel = koinViewModel(), ) { val window = LocalWindowController.current val screen = LocalScreenController.current diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/main/MainPageViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/main/MainPageViewModel.kt index 5190a83..db04142 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/main/MainPageViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/main/MainPageViewModel.kt @@ -7,10 +7,9 @@ import androidx.lifecycle.ViewModel import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository import com.pixelized.desktop.lwa.utils.extention.collectAsState -class MainPageViewModel : ViewModel() { - // using a variable to help with later injection. - private val repository = CharacterSheetRepository - +class MainPageViewModel( + private val repository: CharacterSheetRepository +) : ViewModel() { val characters: State> @Composable @Stable diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/network/NetworkPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/network/NetworkPage.kt index 9c26321..27bb1e9 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/network/NetworkPage.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/network/NetworkPage.kt @@ -1,11 +1,8 @@ package com.pixelized.desktop.lwa.screen.network import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.SizeTransform import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut -import androidx.compose.animation.slideInVertically -import androidx.compose.animation.slideOutVertically import androidx.compose.animation.togetherWith import androidx.compose.foundation.ScrollState import androidx.compose.foundation.layout.Arrangement @@ -41,12 +38,10 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.lifecycle.viewmodel.compose.viewModel import com.pixelized.desktop.lwa.LocalSnackHost import com.pixelized.desktop.lwa.composable.blur.BlurContent import com.pixelized.desktop.lwa.composable.error.snack.ErrorSnack import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController -import kotlinx.io.InternalIoApi import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.network__host__label import lwacharactersheet.composeapp.generated.resources.network__player_name__label @@ -56,6 +51,8 @@ import lwacharactersheet.composeapp.generated.resources.network__socket__disconn import lwacharactersheet.composeapp.generated.resources.network__socket__host_action import lwacharactersheet.composeapp.generated.resources.network__title import org.jetbrains.compose.resources.stringResource +import org.koin.compose.viewmodel.koinViewModel +import org.koin.core.annotation.KoinExperimentalAPI @Stable data class NetworkPageUio( @@ -67,9 +64,10 @@ data class NetworkPageUio( val enableCancel: Boolean, ) +@OptIn(KoinExperimentalAPI::class) @Composable fun NetworkPage( - viewModel: NetworkViewModel = viewModel { NetworkViewModel() }, + viewModel: NetworkViewModel = koinViewModel(), ) { val screen = LocalScreenController.current val snack = LocalSnackHost.current diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/network/NetworkViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/network/NetworkViewModel.kt index 85c2d8f..f753541 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/network/NetworkViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/network/NetworkViewModel.kt @@ -15,14 +15,11 @@ import com.pixelized.desktop.lwa.repository.network.NetworkRepository import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.launch -import lwacharactersheet.composeapp.generated.resources.Res -import lwacharactersheet.composeapp.generated.resources.network__connect__message -import lwacharactersheet.composeapp.generated.resources.network__disconnect__message -import org.jetbrains.compose.resources.getString -class NetworkViewModel : ViewModel() { - private val repository = NetworkRepository - private val factory = NetworkFactory() +class NetworkViewModel( + private val repository: NetworkRepository, + private val factory: NetworkFactory +) : ViewModel() { private val host = mutableStateOf(NetworkRepository.DEFAULT_HOST) private val port = mutableStateOf(NetworkRepository.DEFAULT_PORT) diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/roll/RollPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/roll/RollPage.kt index 9abd159..69fced2 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/roll/RollPage.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/roll/RollPage.kt @@ -59,6 +59,8 @@ import lwacharactersheet.composeapp.generated.resources.roll_page__roll__label import lwacharactersheet.composeapp.generated.resources.roll_page__roll__success_label import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource +import org.koin.compose.viewmodel.koinViewModel +import org.koin.core.annotation.KoinExperimentalAPI @Stable data class RollTitleUio( @@ -82,9 +84,10 @@ data class DifficultyUio( } } +@OptIn(KoinExperimentalAPI::class) @Composable fun RollPage( - viewModel: RollViewModel = viewModel { RollViewModel() }, + viewModel: RollViewModel = koinViewModel(), onDismissRequest: () -> Unit, ) { val scope = rememberCoroutineScope() diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/roll/RollViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/roll/RollViewModel.kt index 069b0fe..30b3655 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/roll/RollViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/roll/RollViewModel.kt @@ -30,9 +30,10 @@ import lwacharactersheet.composeapp.generated.resources.roll_page__special_succe import lwacharactersheet.composeapp.generated.resources.roll_page__success import org.jetbrains.compose.resources.getString -class RollViewModel : ViewModel() { - private val sheetRepository = CharacterSheetRepository - private val repository = RollHistoryRepository +class RollViewModel( + private val characterSheetRepository: CharacterSheetRepository, + private val rollHistoryRepository: RollHistoryRepository, +) : ViewModel() { private lateinit var sheet: CharacterSheet private lateinit var rollAction: String @@ -55,7 +56,7 @@ class RollViewModel : ViewModel() { sheet: CharacterSheetPageUio, characteristic: CharacterSheetPageUio.Characteristic, ) { - val diminished = sheetRepository.characterDiminishedFlow(id = sheet.id).value + val diminished = characterSheetRepository.characterDiminishedFlow(id = sheet.id).value prepareRoll( sheet = sheet, label = characteristic.label, @@ -96,7 +97,7 @@ class RollViewModel : ViewModel() { ) { runBlocking { rollRotation.snapTo(0f) } - this.sheet = CharacterSheetRepository.characterSheetFlow(id = sheet.id).value!! + this.sheet = characterSheetRepository.characterSheetFlow(id = sheet.id).value!! this.rollAction = rollAction this.rollSuccessValue = rollSuccessValue @@ -167,7 +168,7 @@ class RollViewModel : ViewModel() { value = roll, ) launch { - repository.share( + rollHistoryRepository.share( skillLabel = _rollTitle.value.label, rollDifficulty = when (_rollDifficulty.value?.difficulty) { Difficulty.EASY -> getString(Res.string.roll_page__dc_easy__label) diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/rollhistory/RollHistoryPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/rollhistory/RollHistoryPage.kt index 38e6e25..82fbaa5 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/rollhistory/RollHistoryPage.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/rollhistory/RollHistoryPage.kt @@ -25,11 +25,14 @@ import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.roll_history__title import org.jetbrains.compose.resources.stringResource +import org.koin.compose.viewmodel.koinViewModel +import org.koin.core.annotation.KoinExperimentalAPI +@OptIn(KoinExperimentalAPI::class) @Composable fun RollHistoryPage( - viewModel: RollHistoryViewModel = viewModel { RollHistoryViewModel() } + viewModel: RollHistoryViewModel = koinViewModel(), ) { val screen = LocalScreenController.current diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/rollhistory/RollHistoryViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/rollhistory/RollHistoryViewModel.kt index 898c81e..255afa1 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/rollhistory/RollHistoryViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/rollhistory/RollHistoryViewModel.kt @@ -8,9 +8,9 @@ import com.pixelized.desktop.lwa.repository.network.protocol.RollMessage import com.pixelized.desktop.lwa.repository.roll.RollHistoryRepository import kotlinx.coroutines.launch -class RollHistoryViewModel : ViewModel() { - - private val repository = RollHistoryRepository +class RollHistoryViewModel( + private val repository: RollHistoryRepository +) : ViewModel() { private val _rolls = mutableStateOf((emptyList())) val rolls: State> get() = _rolls diff --git a/composeApp/src/desktopMain/kotlin/com/pixelized/desktop/lwa/main.kt b/composeApp/src/desktopMain/kotlin/com/pixelized/desktop/lwa/main.kt index c3c5267..d50661b 100644 --- a/composeApp/src/desktopMain/kotlin/com/pixelized/desktop/lwa/main.kt +++ b/composeApp/src/desktopMain/kotlin/com/pixelized/desktop/lwa/main.kt @@ -1,10 +1,16 @@ package com.pixelized.desktop.lwa import androidx.compose.ui.window.application -import com.pixelized.desktop.lwa.business.SkillStepUseCase +import org.koin.compose.KoinContext +import org.koin.core.context.startKoin fun main() { + startKoin { + modules(modules = moduleDependencies) + } application { - App() + KoinContext { + App() + } } } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ac39250..d000d57 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,29 +2,32 @@ kotlin = "2.0.21" kotlinx-coroutines = "1.9.0" kotlinx-json = "1.7.3" -junit = "4.13.2" compose-multiplatform = "1.7.0" androidx-lifecycle = "2.8.3" androidx-navigation = "2.8.0-alpha10" ktor_version = "3.0.0" +koin = "4.0.0" +koinComposeMultiplatform = "1.2.0-Beta4" [plugins] composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" } composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } -kotlinKtor = { id = "io.ktor.plugin", version.ref = "ktor_version"} [libraries] kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } -kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" } -junit = { group = "junit", name = "junit", version.ref = "junit" } + androidx-lifecycle-viewmodel = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel", version.ref = "androidx-lifecycle" } androidx-lifecycle-runtime-compose = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidx-lifecycle" } androidx-navigation-compose = { group = "org.jetbrains.androidx.navigation", name = "navigation-compose", version.ref = "androidx-navigation" } kotlinx-coroutines-swing = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" } kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinx-json" } +koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" } +koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koin" } +koin-compose-viewmodel = { module = "io.insert-koin:koin-compose-viewmodel", version.ref = "koin" } + ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor_version" } ktor-client-cio = { group = 'io.ktor', name = "ktor-client-cio", version.ref = "ktor_version" } ktor-client-websockets = { group = 'io.ktor', name = "ktor-client-websockets", version.ref = "ktor_version" }