diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index a15f29e..e2b65ae 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -2,6 +2,7 @@ import org.jetbrains.compose.desktop.application.dsl.TargetFormat plugins { alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.kotlinSerialization) alias(libs.plugins.composeMultiplatform) alias(libs.plugins.composeCompiler) } @@ -23,6 +24,9 @@ kotlin { implementation(libs.androidx.lifecycle.runtime.compose) implementation(libs.androidx.navigation.compose) implementation(libs.androidx.datastore.preferences) + + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3") + } commonTest.dependencies { @@ -55,5 +59,10 @@ compose.desktop { // Use system theming fot the app toolbars. jvmArgs("-Dapple.awt.application.appearance=system") } + + buildTypes.release.proguard { + obfuscate.set(false) // Obfuscation crash when try to use datastore. + configurationFiles.from(project.file("compose-desktop.pro")) + } } } diff --git a/composeApp/compose-desktop.pro b/composeApp/compose-desktop.pro new file mode 100644 index 0000000..a9bbc0e --- /dev/null +++ b/composeApp/compose-desktop.pro @@ -0,0 +1,12 @@ +## Data Store old dependancies not removed properly. +-dontwarn okio.AsyncTimeout$Watchdog + +-keep class androidx.compose.runtime.** { *; } +-keep class androidx.collection.** { *; } +-keep class androidx.lifecycle.** { *; } + +# We're excluding Material 2 from the project as we're using Material 3 +-dontwarn androidx.compose.material.** + +# Kotlinx coroutines rules seems to be outdated with the latest version of Kotlin and Proguard +-keep class kotlinx.coroutines.** { *; } \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml index 0d81a5f..896deb3 100644 --- a/composeApp/src/commonMain/composeResources/values/strings.xml +++ b/composeApp/src/commonMain/composeResources/values/strings.xml @@ -10,9 +10,9 @@ Création de personnage Nom - Ajouter un lancé + Ajouter un lancer Sauvegarder - Charactéristiques + Caractéristiques Force Dextérité Constitution @@ -20,14 +20,14 @@ Intelligence Pouvoir Charisme - Charactéristiques dérivées + Caractéristiques dérivées Déplacement Points de vie Points de pouvoir Bonus aux dégats Armure - Compétances - Ajouter une compétance + Compétences + Ajouter une compétence Bagarre Esquive Saisie @@ -56,7 +56,7 @@ Intelligence Pouvoir Charisme - Charactéristiques dérivées + Caractéristiques dérivées Déplacement Points de vie Points de pouvoir diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/RollUseCase.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/RollUseCase.kt index a0a67ec..a6f0739 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/RollUseCase.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/RollUseCase.kt @@ -24,21 +24,21 @@ object RollUseCase { fun roll(characterSheet: CharacterSheet, roll: String): Int { println(roll) - return diceParser.findAll(roll).sumOf { - val (sign, modifier, quantity, faces) = it.destructured + return diceParser.findAll(roll).sumOf { match -> + val (sign, modifier, quantity, faces) = match.destructured ((if (sign == "-") -1 else 1) * roll( quantity = quantity.toInt(), faces = faces.toInt() )).also { println("roll ${sign}${quantity}d${faces} -> $it") } - } + flatParser.findAll(roll).sumOf { - val (sign, value) = it.destructured + } + flatParser.findAll(roll).sumOf { match -> + val (sign, value) = match.destructured ((if (sign == "-") -1 else 1) * value.toInt()).also { println("flat: ${sign}${value} -> $it") } - } + paramParser.findAll(roll).sumOf { - val (sign, param) = it.destructured + } + paramParser.findAll(roll).sumOf { match -> + val (sign, param) = match.destructured (if (sign == "-") -1 else 1) * when (param) { "BDGT" -> diceParser.findAll(characterSheet.damageBonus).sumOf { val (sign, modifier, quantity, faces) = it.destructured diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/createDataStore.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/createDataStore.kt index fb5009c..b54706d 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/createDataStore.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/createDataStore.kt @@ -3,8 +3,18 @@ package com.pixelized.desktop.lwa import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.PreferenceDataStoreFactory import androidx.datastore.preferences.core.Preferences +import com.pixelized.desktop.lwa.utils.OperatingSystem import okio.Path.Companion.toPath fun createDataStore(producePath: () -> String): DataStore { return PreferenceDataStoreFactory.createWithPath(produceFile = { producePath().toPath() }) +} + +fun dataStorePath(): String { + val root = when { + OperatingSystem.isWindows() -> "${OperatingSystem.home}\\AppData\\Roaming\\Pixelized\\" + OperatingSystem.isMacintosh() -> "" + else -> "" + } + return "${root}characterssheet.preferences_pb" } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheet.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheet.kt index f473606..9aa5756 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheet.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheet.kt @@ -1,7 +1,8 @@ package com.pixelized.desktop.lwa.repository.characterSheet -import java.io.Serializable +import kotlinx.serialization.Serializable +@Serializable data class CharacterSheet( val id: String, val name: String, @@ -29,16 +30,17 @@ data class CharacterSheet( val magics: List, // attack val rolls: List, -) : Serializable { - +) { + @Serializable data class Skill( val label: String, val value: Int, val used: Boolean, - ) : Serializable + ) + @Serializable data class Roll( val label: String, val roll: String, - ) : Serializable + ) } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetPreference.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetPreference.kt index 5bdb152..8357108 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetPreference.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetPreference.kt @@ -2,20 +2,20 @@ package com.pixelized.desktop.lwa.repository.characterSheet import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences -import androidx.datastore.preferences.core.byteArrayPreferencesKey import androidx.datastore.preferences.core.edit -import com.pixelized.desktop.lwa.utils.extention.fromByteArray -import com.pixelized.desktop.lwa.utils.extention.toByteArray +import androidx.datastore.preferences.core.stringPreferencesKey import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json class CharacterSheetPreference( private val dataStore: DataStore, ) { suspend fun save(sheets: List) { dataStore.edit { - it[characterSheetKey] = sheets.toByteArray() + it[characterSheetKey] = Json.encodeToString(sheets) } } @@ -25,11 +25,13 @@ class CharacterSheetPreference( fun loadFlow(): Flow> { return dataStore.data.map { - it[characterSheetKey]?.fromByteArray>() ?: emptyList() + it[characterSheetKey]?.let { json -> + Json.decodeFromString>(json) + } ?: emptyList() } } companion object { - private val characterSheetKey = byteArrayPreferencesKey("CharacterSheetsPrefKey") + private val characterSheetKey = stringPreferencesKey("CharacterSheetsPrefKey") } } \ 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 711c9be..28c938b 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 @@ -1,6 +1,7 @@ package com.pixelized.desktop.lwa.repository.characterSheet import com.pixelized.desktop.lwa.createDataStore +import com.pixelized.desktop.lwa.dataStorePath import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.SharingStarted @@ -10,9 +11,8 @@ import kotlinx.coroutines.flow.stateIn object CharacterSheetRepository { private val scope = CoroutineScope(Dispatchers.IO) - private val preferences = CharacterSheetPreference( - dataStore = createDataStore { "characterssheet.preferences_pb" } + dataStore = createDataStore { dataStorePath() } ) private val sheets = preferences.loadFlow() diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/SystemExt.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/SystemExt.kt new file mode 100644 index 0000000..e43af3e --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/SystemExt.kt @@ -0,0 +1,14 @@ +package com.pixelized.desktop.lwa.utils + +object OperatingSystem { + private val name get() = System.getProperty("os.name") + + val home: String + get() = when { + isWindows() -> System.getProperty("user.home") + else -> "" + } + + fun isWindows(): Boolean = name.contains("win", ignoreCase = true) + fun isMacintosh(): Boolean = name.contains("mac", ignoreCase = true) +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 74c55c5..c40d174 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,4 +23,5 @@ kotlinx-coroutines-swing = { group = "org.jetbrains.kotlinx", name = "kotlinx-co [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" } \ No newline at end of file