Add release build support (MSI) with proguard disable because of Datastore

This commit is contained in:
Thomas Andres Gomez 2024-11-07 23:18:12 +01:00
parent 7af0c15a62
commit b348f8a327
10 changed files with 75 additions and 25 deletions

View file

@ -2,6 +2,7 @@ import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins { plugins {
alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.kotlinSerialization)
alias(libs.plugins.composeMultiplatform) alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler) alias(libs.plugins.composeCompiler)
} }
@ -23,6 +24,9 @@ kotlin {
implementation(libs.androidx.lifecycle.runtime.compose) implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.androidx.navigation.compose) implementation(libs.androidx.navigation.compose)
implementation(libs.androidx.datastore.preferences) implementation(libs.androidx.datastore.preferences)
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
} }
commonTest.dependencies { commonTest.dependencies {
@ -55,5 +59,10 @@ compose.desktop {
// Use system theming fot the app toolbars. // Use system theming fot the app toolbars.
jvmArgs("-Dapple.awt.application.appearance=system") 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"))
}
} }
} }

View file

@ -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.** { *; }

View file

@ -10,9 +10,9 @@
<string name="character_sheet_edit__title">Création de personnage</string> <string name="character_sheet_edit__title">Création de personnage</string>
<string name="character_sheet_edit__name_placeholder">Nom</string> <string name="character_sheet_edit__name_placeholder">Nom</string>
<string name="character_sheet_edit__add_roll_action">Ajouter un lancé</string> <string name="character_sheet_edit__add_roll_action">Ajouter un lancer</string>
<string name="character_sheet_edit__save_action">Sauvegarder</string> <string name="character_sheet_edit__save_action">Sauvegarder</string>
<string name="character_sheet_edit__characteristics__title">Charactéristiques</string> <string name="character_sheet_edit__characteristics__title">Caractéristiques</string>
<string name="character_sheet_edit__characteristics__str">Force</string> <string name="character_sheet_edit__characteristics__str">Force</string>
<string name="character_sheet_edit__characteristics__dex">Dextérité</string> <string name="character_sheet_edit__characteristics__dex">Dextérité</string>
<string name="character_sheet_edit__characteristics__con">Constitution</string> <string name="character_sheet_edit__characteristics__con">Constitution</string>
@ -20,14 +20,14 @@
<string name="character_sheet_edit__characteristics__int">Intelligence</string> <string name="character_sheet_edit__characteristics__int">Intelligence</string>
<string name="character_sheet_edit__characteristics__pow">Pouvoir</string> <string name="character_sheet_edit__characteristics__pow">Pouvoir</string>
<string name="character_sheet_edit__characteristics__cha">Charisme</string> <string name="character_sheet_edit__characteristics__cha">Charisme</string>
<string name="character_sheet_edit__sub_characteristics__title">Charactéristiques dérivées</string> <string name="character_sheet_edit__sub_characteristics__title">Caractéristiques dérivées</string>
<string name="character_sheet_edit__sub_characteristics__movement">Déplacement</string> <string name="character_sheet_edit__sub_characteristics__movement">Déplacement</string>
<string name="character_sheet_edit__sub_characteristics__hit_point">Points de vie</string> <string name="character_sheet_edit__sub_characteristics__hit_point">Points de vie</string>
<string name="character_sheet_edit__sub_characteristics__power_point">Points de pouvoir</string> <string name="character_sheet_edit__sub_characteristics__power_point">Points de pouvoir</string>
<string name="character_sheet_edit__sub_characteristics__damage_bonus">Bonus aux dégats</string> <string name="character_sheet_edit__sub_characteristics__damage_bonus">Bonus aux dégats</string>
<string name="character_sheet_edit__sub_characteristics__armor">Armure</string> <string name="character_sheet_edit__sub_characteristics__armor">Armure</string>
<string name="character_sheet_edit__skills__title">Compétances</string> <string name="character_sheet_edit__skills__title">Compétences</string>
<string name="character_sheet_edit__skills__add_action">Ajouter une compétance</string> <string name="character_sheet_edit__skills__add_action">Ajouter une compétence</string>
<string name="character_sheet_edit__skills__combat">Bagarre</string> <string name="character_sheet_edit__skills__combat">Bagarre</string>
<string name="character_sheet_edit__skills__dodge">Esquive</string> <string name="character_sheet_edit__skills__dodge">Esquive</string>
<string name="character_sheet_edit__skills__grab">Saisie</string> <string name="character_sheet_edit__skills__grab">Saisie</string>
@ -56,7 +56,7 @@
<string name="character_sheet__characteristics__int">Intelligence</string> <string name="character_sheet__characteristics__int">Intelligence</string>
<string name="character_sheet__characteristics__pow">Pouvoir</string> <string name="character_sheet__characteristics__pow">Pouvoir</string>
<string name="character_sheet__characteristics__cha">Charisme</string> <string name="character_sheet__characteristics__cha">Charisme</string>
<string name="character_sheet__sub_characteristics__title">Charactéristiques dérivées</string> <string name="character_sheet__sub_characteristics__title">Caractéristiques dérivées</string>
<string name="character_sheet__sub_characteristics__movement">Déplacement</string> <string name="character_sheet__sub_characteristics__movement">Déplacement</string>
<string name="character_sheet__sub_characteristics__hit_point">Points de vie</string> <string name="character_sheet__sub_characteristics__hit_point">Points de vie</string>
<string name="character_sheet__sub_characteristics__power_point">Points de pouvoir</string> <string name="character_sheet__sub_characteristics__power_point">Points de pouvoir</string>

View file

@ -24,21 +24,21 @@ object RollUseCase {
fun roll(characterSheet: CharacterSheet, roll: String): Int { fun roll(characterSheet: CharacterSheet, roll: String): Int {
println(roll) println(roll)
return diceParser.findAll(roll).sumOf { return diceParser.findAll(roll).sumOf { match ->
val (sign, modifier, quantity, faces) = it.destructured val (sign, modifier, quantity, faces) = match.destructured
((if (sign == "-") -1 else 1) * roll( ((if (sign == "-") -1 else 1) * roll(
quantity = quantity.toInt(), quantity = quantity.toInt(),
faces = faces.toInt() faces = faces.toInt()
)).also { )).also {
println("roll ${sign}${quantity}d${faces} -> $it") println("roll ${sign}${quantity}d${faces} -> $it")
} }
} + flatParser.findAll(roll).sumOf { } + flatParser.findAll(roll).sumOf { match ->
val (sign, value) = it.destructured val (sign, value) = match.destructured
((if (sign == "-") -1 else 1) * value.toInt()).also { ((if (sign == "-") -1 else 1) * value.toInt()).also {
println("flat: ${sign}${value} -> $it") println("flat: ${sign}${value} -> $it")
} }
} + paramParser.findAll(roll).sumOf { } + paramParser.findAll(roll).sumOf { match ->
val (sign, param) = it.destructured val (sign, param) = match.destructured
(if (sign == "-") -1 else 1) * when (param) { (if (sign == "-") -1 else 1) * when (param) {
"BDGT" -> diceParser.findAll(characterSheet.damageBonus).sumOf { "BDGT" -> diceParser.findAll(characterSheet.damageBonus).sumOf {
val (sign, modifier, quantity, faces) = it.destructured val (sign, modifier, quantity, faces) = it.destructured

View file

@ -3,8 +3,18 @@ package com.pixelized.desktop.lwa
import androidx.datastore.core.DataStore import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.PreferenceDataStoreFactory import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.Preferences
import com.pixelized.desktop.lwa.utils.OperatingSystem
import okio.Path.Companion.toPath import okio.Path.Companion.toPath
fun createDataStore(producePath: () -> String): DataStore<Preferences> { fun createDataStore(producePath: () -> String): DataStore<Preferences> {
return PreferenceDataStoreFactory.createWithPath(produceFile = { producePath().toPath() }) 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"
} }

View file

@ -1,7 +1,8 @@
package com.pixelized.desktop.lwa.repository.characterSheet package com.pixelized.desktop.lwa.repository.characterSheet
import java.io.Serializable import kotlinx.serialization.Serializable
@Serializable
data class CharacterSheet( data class CharacterSheet(
val id: String, val id: String,
val name: String, val name: String,
@ -29,16 +30,17 @@ data class CharacterSheet(
val magics: List<Skill>, val magics: List<Skill>,
// attack // attack
val rolls: List<Roll>, val rolls: List<Roll>,
) : Serializable { ) {
@Serializable
data class Skill( data class Skill(
val label: String, val label: String,
val value: Int, val value: Int,
val used: Boolean, val used: Boolean,
) : Serializable )
@Serializable
data class Roll( data class Roll(
val label: String, val label: String,
val roll: String, val roll: String,
) : Serializable )
} }

View file

@ -2,20 +2,20 @@ package com.pixelized.desktop.lwa.repository.characterSheet
import androidx.datastore.core.DataStore import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.byteArrayPreferencesKey
import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.edit
import com.pixelized.desktop.lwa.utils.extention.fromByteArray import androidx.datastore.preferences.core.stringPreferencesKey
import com.pixelized.desktop.lwa.utils.extention.toByteArray
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
class CharacterSheetPreference( class CharacterSheetPreference(
private val dataStore: DataStore<Preferences>, private val dataStore: DataStore<Preferences>,
) { ) {
suspend fun save(sheets: List<CharacterSheet>) { suspend fun save(sheets: List<CharacterSheet>) {
dataStore.edit { dataStore.edit {
it[characterSheetKey] = sheets.toByteArray() it[characterSheetKey] = Json.encodeToString(sheets)
} }
} }
@ -25,11 +25,13 @@ class CharacterSheetPreference(
fun loadFlow(): Flow<List<CharacterSheet>> { fun loadFlow(): Flow<List<CharacterSheet>> {
return dataStore.data.map { return dataStore.data.map {
it[characterSheetKey]?.fromByteArray<List<CharacterSheet>>() ?: emptyList() it[characterSheetKey]?.let { json ->
Json.decodeFromString<List<CharacterSheet>>(json)
} ?: emptyList()
} }
} }
companion object { companion object {
private val characterSheetKey = byteArrayPreferencesKey("CharacterSheetsPrefKey") private val characterSheetKey = stringPreferencesKey("CharacterSheetsPrefKey")
} }
} }

View file

@ -1,6 +1,7 @@
package com.pixelized.desktop.lwa.repository.characterSheet package com.pixelized.desktop.lwa.repository.characterSheet
import com.pixelized.desktop.lwa.createDataStore import com.pixelized.desktop.lwa.createDataStore
import com.pixelized.desktop.lwa.dataStorePath
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
@ -10,9 +11,8 @@ import kotlinx.coroutines.flow.stateIn
object CharacterSheetRepository { object CharacterSheetRepository {
private val scope = CoroutineScope(Dispatchers.IO) private val scope = CoroutineScope(Dispatchers.IO)
private val preferences = CharacterSheetPreference( private val preferences = CharacterSheetPreference(
dataStore = createDataStore { "characterssheet.preferences_pb" } dataStore = createDataStore { dataStorePath() }
) )
private val sheets = preferences.loadFlow() private val sheets = preferences.loadFlow()

View file

@ -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)
}

View file

@ -23,4 +23,5 @@ kotlinx-coroutines-swing = { group = "org.jetbrains.kotlinx", name = "kotlinx-co
[plugins] [plugins]
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" } composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" }
composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } 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" } kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }