Small UI / UX adjustment on the character sheet detail/edit

This commit is contained in:
Thomas Andres Gomez 2024-11-28 13:36:21 +01:00
parent d1a98b9075
commit 34a0ee13f0
24 changed files with 359 additions and 207 deletions

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<string name="dialog__confirm_action">Confirmer</string>
<string name="dialog__cancel_action">Annuler</string>
<string name="main_page__create_action">Créer une feuille de personnage</string>
<string name="main_page__network_action">Configuration de la table</string>
<string name="main_page__roll_history_action">Consulter l'historique des lancers</string>
@ -19,8 +22,7 @@
<string name="character_sheet_edit__create__title">Création de personnage</string>
<string name="character_sheet_edit__edit__title">Édition de personnage</string>
<string name="character_sheet_edit__name_placeholder">Nom</string>
<string name="character_sheet_edit__add_roll_action">Ajouter une action</string>
<string name="character_sheet_edit__name_label">Nom</string>
<string name="character_sheet_edit__save_action">Sauvegarder</string>
<string name="character_sheet_edit__characteristics__title">Caractéristiques</string>
<string name="character_sheet_edit__characteristics__str">Force</string>
@ -32,7 +34,9 @@
<string name="character_sheet_edit__characteristics__cha">Charisme</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__max_hit_point">Points de vie maximum</string>
<string name="character_sheet_edit__sub_characteristics__hit_point">Points de vie</string>
<string name="character_sheet_edit__sub_characteristics__max_power_point">Points de pouvoir maximum</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__armor">Armure</string>
@ -64,9 +68,10 @@
<string name="character_sheet_edit__occupation__title">Occupations</string>
<string name="character_sheet_edit__occupation__add_action">Ajouter une occupation</string>
<string name="character_sheet_edit__actions__name_label">Nom</string>
<string name="character_sheet_edit__actions__action_label">Bonus</string>
<string name="character_sheet_edit__actions__action_label">Action de lancé</string>
<string name="character_sheet_edit__magic__title">Compétences magiques</string>
<string name="character_sheet_edit__magic__add_action">Ajouter une compétence magique</string>
<string name="character_sheet_edit__add_roll_action">Ajouter une action de lancé</string>
<string name="character_sheet_edit__delete__label">Supprimer</string>
<string name="character_sheet_edit__occupation__label">Compétence d'occupation</string>
@ -91,8 +96,6 @@
<string name="character_sheet__skills__magic_title">Compétences magiques</string>
<string name="character_sheet__delete_dialog__title">Supprimer la feuille de personnage</string>
<string name="character_sheet__delete_dialog__description">Êtes-vous sûr de vouloir supprimer "%1$s" ?</string>
<string name="character_sheet__delete_dialog__confirm_action">Confirmer</string>
<string name="character_sheet__delete_dialog__cancel_action">Annuler</string>
<string name="tooltip__characteristics__characteristics">Les caractéristiques constituent les aptitudes innées dun personnage comme son intelligence, sa force, son charisme, etc. Elles ne sont pas acquises, mais peuvent être parfois augmentées par un entraînement ou une utilisation réussie. Les caractéristiques des humains normaux varient de 2 (niveau extrêmement bas) à 20 (maximum du potentiel humain), avec une moyenne de 10 ou 11. Plus une caractéristique est élevée plus le personnage est puissant dans cette aptitude.\nÀ la création de votre personnage, répartissez les valeurs suivantes dans les différentes caractéristiques : 15, 15, 13, 11, 10, 9 et 7.</string>
<string name="tooltip__characteristics__strength">La Force représente essentiellement la puissance musculaire du personnage. Elle ne décrit pas nécessairement la masse musculaire brute, mais lefficacité avec laquelle le personnage exerce ses muscles pour accomplir des actions physiques pénibles.</string>

View file

@ -1,18 +1,21 @@
package com.pixelized.desktop.lwa
import com.pixelized.desktop.lwa.business.DamageBonusUseCase
import com.pixelized.desktop.lwa.business.RollUseCase
import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase
import com.pixelized.desktop.lwa.business.SkillStepUseCase
import com.pixelized.desktop.lwa.business.SkillValueComputationUseCase
import com.pixelized.desktop.lwa.parser.arithmetic.ArithmeticParser
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetJsonFactory
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.edit.common.SkillFieldFactory
import com.pixelized.desktop.lwa.repository.roll_history.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.CharacterSheetEditFactory
import com.pixelized.desktop.lwa.screen.characterSheet.edit.CharacterSheetEditViewModel
import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.SkillFieldFactory
import com.pixelized.desktop.lwa.screen.main.MainPageViewModel
import com.pixelized.desktop.lwa.screen.network.NetworkFactory
import com.pixelized.desktop.lwa.screen.network.NetworkViewModel
@ -67,5 +70,8 @@ val parserDependencies
val useCaseDependencies
get() = module {
factoryOf(::DamageBonusUseCase)
factoryOf(::SkillStepUseCase)
factoryOf(::SkillNormalizerUseCase)
factoryOf(::RollUseCase)
factoryOf(::SkillValueComputationUseCase)
}

View file

@ -1,6 +1,6 @@
package com.pixelized.desktop.lwa.business
object RollUseCase {
class RollUseCase {
fun rollD100(): Int {
return roll(quantity = 1, faces = 100)

View file

@ -2,8 +2,7 @@ package com.pixelized.desktop.lwa.business
import kotlin.math.truncate
object SkillNormalizerUseCase {
class SkillNormalizerUseCase {
fun normalize(value: Int): Int {
return (truncate(value.toFloat() / 5f) * 5f).toInt()
}

View file

@ -5,8 +5,7 @@ import kotlin.math.max
import kotlin.math.min
import kotlin.math.round
object SkillStepUseCase {
val NONE: IntRange = -1..-1
class SkillStepUseCase {
data class SkillStep(
val criticalSuccess: IntRange,
@ -21,7 +20,8 @@ object SkillStepUseCase {
*/
fun computeSkillStep(skill: Int): SkillStep {
val criticalSuccess = 1..min(roundToInt { skill * 0.05f }, 99)
val specialSuccess = (roundToInt { skill * 0.05f } + 1)..min(roundToInt { skill * 0.2f }, 99)
val specialSuccess =
(roundToInt { skill * 0.05f } + 1)..min(roundToInt { skill * 0.2f }, 99)
val success = (roundToInt { skill * 0.2f } + 1)..min(skill, 99)
val criticalFailure = 100 - max(4 - criticalSuccess.last, 0)..100
val failure = (success.last + 1) until criticalFailure.first
@ -64,4 +64,8 @@ object SkillStepUseCase {
}
println(")")
}
companion object {
private val NONE: IntRange = -1..-1
}
}

View file

@ -7,6 +7,7 @@ import kotlin.math.max
class SkillValueComputationUseCase(
private val arithmeticParser: ArithmeticParser,
private val rollUseCase: RollUseCase,
) {
fun computeSkillValue(
sheet: CharacterSheet,
@ -53,7 +54,7 @@ class SkillValueComputationUseCase(
print("Roll ->")
return arithmeticParser.parse(roll).sumOf { instruction ->
val value = when (instruction) {
is Instruction.Dice -> RollUseCase.roll(
is Instruction.Dice -> rollUseCase.roll(
quantity = instruction.quantity,
faces = instruction.faces
)
@ -67,7 +68,7 @@ class SkillValueComputationUseCase(
.parse(sheet.damageBonus)
.firstOrNull()
if (damageBonusInstructions is Instruction.Dice) {
RollUseCase.roll(
rollUseCase.roll(
quantity = damageBonusInstructions.quantity,
faces = damageBonusInstructions.faces
)
@ -81,7 +82,7 @@ class SkillValueComputationUseCase(
.parse(sheet.damageBonus)
.firstOrNull()
if (damageBonusInstructions is Instruction.Dice) {
RollUseCase.roll(
rollUseCase.roll(
quantity = damageBonusInstructions.quantity,
faces = damageBonusInstructions.faces / 2,
)

View file

@ -4,7 +4,6 @@ import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
import com.pixelized.desktop.lwa.screen.main.MainPage
import com.pixelized.desktop.lwa.screen.main.MainPageViewModel
object MainDestination {
private const val ROUTE = "main"

View file

@ -1,4 +1,4 @@
package com.pixelized.desktop.lwa.repository.roll
package com.pixelized.desktop.lwa.repository.roll_history
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
import com.pixelized.desktop.lwa.repository.network.protocol.Message

View file

@ -235,10 +235,11 @@ fun CharacterSheetPage(
value = it.value().text.toIntOrNull() ?: 0,
)
viewModel.hideSubCharacteristicDialog()
blurController.hide()
},
onDismissRequest = {
blurController.hide()
viewModel.hideSubCharacteristicDialog()
blurController.hide()
}
)
@ -249,10 +250,11 @@ fun CharacterSheetPage(
dialog = it
)
viewModel.hideDiminishedDialog()
blurController.hide()
},
onDismissRequest = {
blurController.hide()
viewModel.hideDiminishedDialog()
blurController.hide()
},
)
}

View file

@ -1,14 +1,12 @@
package com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
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.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
@ -29,13 +27,17 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.unit.dp
import com.pixelized.desktop.lwa.theme.LwaColorPalette
import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__cancel_action
import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__confirm_action
import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__description
import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__title
import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action
import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action
import org.jetbrains.compose.resources.stringResource
@Stable
@ -90,55 +92,64 @@ private fun Dialog(
indication = null,
onClick = onDismissRequest,
)
.onPreviewKeyEvent {
when {
it.key == Key.Escape -> {
onDismissRequest()
true
}
else -> false
}
}
.fillMaxSize()
.padding(all = 32.dp),
contentAlignment = Alignment.Center,
) {
Surface(
shape = remember { RoundedCornerShape(size = 16.dp) },
) {
Column(
verticalArrangement = Arrangement.spacedBy(space = 24.dp),
) {
Text(
modifier = Modifier
.padding(horizontal = 24.dp)
.padding(top = 24.dp),
style = MaterialTheme.typography.h6,
text = stringResource(Res.string.character_sheet__delete_dialog__title),
)
Text(
modifier = Modifier
.padding(horizontal = 24.dp),
style = MaterialTheme.typography.body1,
text = stringResource(
Res.string.character_sheet__delete_dialog__description,
dialog.name
),
)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
.padding(bottom = 4.dp),
horizontalArrangement = Arrangement.spacedBy(
space = 4.dp,
alignment = Alignment.End
)
DecoratedBox {
Surface {
Column(
verticalArrangement = Arrangement.spacedBy(space = 24.dp),
) {
TextButton(
onClick = onDismissRequest,
) {
Text(
text = stringResource(Res.string.character_sheet__delete_dialog__cancel_action)
Text(
modifier = Modifier
.padding(horizontal = 24.dp)
.padding(top = 24.dp),
style = MaterialTheme.typography.h6,
text = stringResource(Res.string.character_sheet__delete_dialog__title),
)
Text(
modifier = Modifier
.padding(horizontal = 24.dp),
style = MaterialTheme.typography.body1,
text = stringResource(
Res.string.character_sheet__delete_dialog__description,
dialog.name
),
)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
.padding(bottom = 4.dp),
horizontalArrangement = Arrangement.spacedBy(
space = 4.dp,
alignment = Alignment.End
)
}
TextButton(
onClick = { onConfirm(dialog) },
) {
Text(
text = stringResource(Res.string.character_sheet__delete_dialog__confirm_action)
)
TextButton(
onClick = onDismissRequest,
) {
Text(
text = stringResource(Res.string.dialog__cancel_action)
)
}
TextButton(
onClick = { onConfirm(dialog) },
) {
Text(
text = stringResource(Res.string.dialog__confirm_action)
)
}
}
}
}

View file

@ -22,6 +22,7 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
@ -32,12 +33,19 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action
import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action
import org.jetbrains.compose.resources.stringResource
@Stable
data class StatChangeDialogUio(
@ -102,6 +110,15 @@ private fun Dialog(
indication = null,
onClick = onDismissRequest,
)
.onPreviewKeyEvent {
when {
it.key == Key.Escape -> {
onDismissRequest()
true
}
else -> false
}
}
.fillMaxSize()
.padding(all = 32.dp),
contentAlignment = Alignment.Center,
@ -109,11 +126,11 @@ private fun Dialog(
DecoratedBox {
Surface {
Column(
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp),
verticalArrangement = Arrangement.spacedBy(space = 8.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
modifier = Modifier.padding(top = 16.dp, start = 24.dp, end = 24.dp),
style = MaterialTheme.typography.caption,
text = dialog.label,
)
@ -148,6 +165,32 @@ private fun Dialog(
text = dialog.maxValue,
)
}
Row(
modifier = Modifier
.padding(bottom = 4.dp)
.padding(horizontal = 16.dp)
.align(alignment = Alignment.End),
horizontalArrangement = Arrangement.spacedBy(
space = 4.dp,
alignment = Alignment.End
)
) {
TextButton(
onClick = onDismissRequest,
) {
Text(
color = MaterialTheme.colors.primary.copy(alpha = .7f),
text = stringResource(Res.string.dialog__cancel_action)
)
}
TextButton(
onClick = { onConfirm(dialog) },
) {
Text(
text = stringResource(Res.string.dialog__confirm_action)
)
}
}
}
}
}

View file

@ -12,6 +12,7 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
@ -21,6 +22,7 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
@ -31,12 +33,19 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action
import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action
import org.jetbrains.compose.resources.stringResource
@Stable
data class DiminishedStatDialogUio(
@ -99,6 +108,16 @@ private fun Dialog(
indication = null,
onClick = onDismissRequest,
)
.onPreviewKeyEvent {
when {
it.key == Key.Escape -> {
onDismissRequest()
true
}
else -> false
}
}
.fillMaxSize()
.padding(all = 32.dp),
contentAlignment = Alignment.Center,
@ -106,11 +125,11 @@ private fun Dialog(
DecoratedBox {
Surface {
Column(
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp),
verticalArrangement = Arrangement.spacedBy(space = 8.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
modifier = Modifier.padding(start = 24.dp, end = 24.dp, top = 16.dp),
style = MaterialTheme.typography.caption,
text = dialog.label,
)
@ -132,6 +151,32 @@ private fun Dialog(
value = dialog.value(),
onValueChange = dialog.onValueChange,
)
Row(
modifier = Modifier
.padding(top = 4.dp)
.padding(horizontal = 16.dp)
.align(alignment = Alignment.End),
horizontalArrangement = Arrangement.spacedBy(
space = 4.dp,
alignment = Alignment.End
)
) {
TextButton(
onClick = onDismissRequest,
) {
Text(
color = MaterialTheme.colors.primary.copy(alpha = .7f),
text = stringResource(Res.string.dialog__cancel_action)
)
}
TextButton(
onClick = { onConfirm(dialog) },
) {
Text(
text = stringResource(Res.string.dialog__confirm_action)
)
}
}
}
}
}

View file

@ -4,7 +4,7 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.mutableStateOf
import com.pixelized.desktop.lwa.business.DamageBonusUseCase
import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase.normalize
import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.SkillFieldFactory
import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.occupation
@ -21,7 +21,7 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__ch
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__int
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__pow
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__str
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__name_placeholder
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__name_label
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__acrobatics
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__aid
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__athletics
@ -45,6 +45,8 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sk
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__armor
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__damage_bonus
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__hit_point
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__max_hit_point
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__max_power_point
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__movement
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__power_point
import org.jetbrains.compose.resources.getString
@ -56,17 +58,12 @@ import kotlin.math.min
class CharacterSheetEditFactory(
private val bonusDamageUseCase: DamageBonusUseCase,
private val skillFactory: SkillFieldFactory,
private val normalizer: SkillNormalizerUseCase,
) {
fun updateCharacterSheet(
currentSheet: CharacterSheet?,
editedSheet: CharacterSheetEditPageUio,
): CharacterSheet {
val maxHp = editedSheet.maxHp.unpack()?.toIntOrNull()
?: currentSheet?.maxHp
?: 0
val maxPp = editedSheet.maxPp.unpack()?.toIntOrNull()
?: currentSheet?.maxPp
?: 0
return CharacterSheet(
id = editedSheet.id,
name = editedSheet.name.value.value,
@ -96,11 +93,19 @@ class CharacterSheetEditFactory(
?: currentSheet?.movement
?: 10,
overrideMaxHp = editedSheet.maxHp.value.value.value.isNotBlank(),
maxHp = maxHp,
currentHp = max(0, min(maxHp, currentSheet?.currentHp ?: maxHp)),
maxHp = editedSheet.maxHp.unpack()?.toIntOrNull()
?: currentSheet?.maxHp
?: 0,
currentHp = editedSheet.currentHp.unpack()?.toIntOrNull()
?: currentSheet?.currentHp
?: 0,
overrideMaxPP = editedSheet.maxPp.value.value.value.isNotBlank(),
maxPp = maxPp,
currentPp = max(0, min(maxPp, currentSheet?.currentPp ?: maxPp)),
maxPp = editedSheet.maxPp.unpack()?.toIntOrNull()
?: currentSheet?.maxPp
?: 0,
currentPp = editedSheet.currentPp.unpack()?.toIntOrNull()
?: currentSheet?.currentPp
?: 0,
overrideDamageBonus = editedSheet.damageBonus.value.value.value.isNotBlank(),
damageBonus = editedSheet.damageBonus.unpack()
?: currentSheet?.damageBonus
@ -226,10 +231,25 @@ class CharacterSheetEditFactory(
val specialSkillsLabel = getString(Res.string.character_sheet_edit__skills__special_title)
val magicSkillsLabel = getString(Res.string.character_sheet_edit__skills__magic_title)
val maxHitPoint = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__sub_characteristics__max_hit_point),
value = skillFactory.createWrapper(
value = if (sheet?.overrideMaxHp == true) "${sheet.maxHp}" else "",
placeholder = derivedStateOf { "${ceil((con() + hei()) / 2f).toInt()}" },
)
)
val maxPowerPoint = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__sub_characteristics__max_power_point),
value = skillFactory.createWrapper(
value = if (sheet?.overrideMaxPP == true) "${sheet.maxPp}" else "",
placeholder = derivedStateOf { "${pow()}" },
)
)
return CharacterSheetEditPageUio(
id = sheet?.id ?: UUID.randomUUID().toString(),
name = skillFactory.createWrapper(
label = getString(Res.string.character_sheet_edit__name_placeholder),
label = mutableStateOf(getString(Res.string.character_sheet_edit__name_label)),
value = sheet?.name ?: ""
),
strength = str,
@ -246,18 +266,32 @@ class CharacterSheetEditFactory(
placeholder = mutableStateOf("10"),
)
),
maxHp = SimpleFieldUio(
maxHp = maxHitPoint,
currentHp = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__sub_characteristics__hit_point),
value = skillFactory.createWrapper(
value = if (sheet?.overrideMaxHp == true) "${sheet.maxHp}" else "",
placeholder = derivedStateOf { "${ceil((con() + hei()) / 2f).toInt()}" },
enable = false,
placeholder = derivedStateOf {
val min = min(
sheet?.currentHp ?: Int.MAX_VALUE,
maxHitPoint.unpack()?.toIntOrNull() ?: Int.MAX_VALUE,
)
if (min != Int.MAX_VALUE) "$min" else ""
},
)
),
maxPp = SimpleFieldUio(
maxPp = maxPowerPoint,
currentPp = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__sub_characteristics__power_point),
value = skillFactory.createWrapper(
value = if (sheet?.overrideMaxPP == true) "${sheet.maxPp}" else "",
placeholder = derivedStateOf { "${pow()}" },
enable = false,
placeholder = derivedStateOf {
val min = min(
sheet?.currentPp ?: Int.MAX_VALUE,
maxPowerPoint.unpack()?.toIntOrNull() ?: Int.MAX_VALUE,
)
if (min != Int.MAX_VALUE) "$min" else ""
},
)
),
damageBonus = SimpleFieldUio(
@ -284,97 +318,97 @@ class CharacterSheetEditFactory(
sheet = sheet,
id = CharacterSheet.CommonSkillId.COMBAT_ID,
label = getString(Res.string.character_sheet_edit__skills__combat),
base = derivedStateOf { normalize(dex() * 2) },
base = derivedStateOf { normalizer.normalize(dex() * 2) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.DODGE_ID,
label = getString(Res.string.character_sheet_edit__skills__dodge),
base = derivedStateOf { normalize(dex() * 2) },
base = derivedStateOf { normalizer.normalize(dex() * 2) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.GRAB_ID,
label = getString(Res.string.character_sheet_edit__skills__grab),
base = derivedStateOf { normalize(str() + hei()) },
base = derivedStateOf { normalizer.normalize(str() + hei()) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.THROW_ID,
label = getString(Res.string.character_sheet_edit__skills__throw),
base = derivedStateOf { normalize(str() + dex()) },
base = derivedStateOf { normalizer.normalize(str() + dex()) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.ATHLETICS_ID,
label = getString(Res.string.character_sheet_edit__skills__athletics),
base = derivedStateOf { normalize(str() + con() * 2) },
base = derivedStateOf { normalizer.normalize(str() + con() * 2) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.ACROBATICS_ID,
label = getString(Res.string.character_sheet_edit__skills__acrobatics),
base = derivedStateOf { normalize(dex() + con() * 2) },
base = derivedStateOf { normalizer.normalize(dex() + con() * 2) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.PERCEPTION_ID,
label = getString(Res.string.character_sheet_edit__skills__perception),
base = derivedStateOf { normalize(10 + int() * 2) },
base = derivedStateOf { normalizer.normalize(10 + int() * 2) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.SEARCH_ID,
label = getString(Res.string.character_sheet_edit__skills__search),
base = derivedStateOf { normalize(10 + int() * 2) },
base = derivedStateOf { normalizer.normalize(10 + int() * 2) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.EMPATHY_ID,
label = getString(Res.string.character_sheet_edit__skills__empathy),
base = derivedStateOf { normalize(cha() + int()) },
base = derivedStateOf { normalizer.normalize(cha() + int()) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.PERSUASION_ID,
label = getString(Res.string.character_sheet_edit__skills__persuasion),
base = derivedStateOf { normalize(cha() * 3) },
base = derivedStateOf { normalizer.normalize(cha() * 3) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.INTIMIDATION_ID,
label = getString(Res.string.character_sheet_edit__skills__intimidation),
base = derivedStateOf { normalize(cha() + max(pow(), hei()) * 2) },
base = derivedStateOf { normalizer.normalize(cha() + max(pow(), hei()) * 2) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.SPIEL_ID,
label = getString(Res.string.character_sheet_edit__skills__spiel),
base = derivedStateOf { normalize(cha() * 2 + int()) },
base = derivedStateOf { normalizer.normalize(cha() * 2 + int()) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.BARGAIN_ID,
label = getString(Res.string.character_sheet_edit__skills__bargain),
base = derivedStateOf { normalize(cha() * 2) },
base = derivedStateOf { normalizer.normalize(cha() * 2) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.DISCRETION_ID,
label = getString(Res.string.character_sheet_edit__skills__discretion),
base = derivedStateOf { normalize(cha() + dex() * 2 - hei()) },
base = derivedStateOf { normalizer.normalize(cha() + dex() * 2 - hei()) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID,
label = getString(Res.string.character_sheet_edit__skills__sleight_of_hand),
base = derivedStateOf { normalize(dex() * 2) },
base = derivedStateOf { normalizer.normalize(dex() * 2) },
),
createBaseSkill(
sheet = sheet,
id = CharacterSheet.CommonSkillId.AID_ID,
label = getString(Res.string.character_sheet_edit__skills__aid),
base = derivedStateOf { normalize(int() + dex()) },
base = derivedStateOf { normalizer.normalize(int() + dex()) },
),
),
specialSkills = sheet?.specialSkills?.map { skill ->
@ -415,11 +449,11 @@ class CharacterSheetEditFactory(
ActionFieldUio(
id = action.id,
label = skillFactory.createWrapper(
label = getString(Res.string.character_sheet_edit__actions__name_label),
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__name_label)),
value = action.label,
),
action = skillFactory.createWrapper(
label = getString(Res.string.character_sheet_edit__actions__action_label),
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__action_label)),
value = action.roll,
),
option = skillFactory.deleteOption { onDeleteSkill(action.id) },
@ -441,11 +475,11 @@ class CharacterSheetEditFactory(
label = label,
base = base,
bonus = skillFactory.createWrapper(
label = getString(Res.string.character_sheet_edit__skills__bonus_label),
label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__bonus_label)),
value = skill?.bonus?.toString() ?: "",
),
level = skillFactory.createWrapper(
label = getString(Res.string.character_sheet_edit__skills__level_label),
label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__level_label)),
value = skill?.level?.toString() ?: "",
),
option = skillFactory.occupationOption(skill?.occupation ?: false),

View file

@ -69,7 +69,9 @@ data class CharacterSheetEditPageUio(
val charisma: SimpleFieldUio,
val movement: SimpleFieldUio,
val maxHp: SimpleFieldUio,
val currentHp: SimpleFieldUio,
val maxPp: SimpleFieldUio,
val currentPp: SimpleFieldUio,
val damageBonus: SimpleFieldUio,
val armor: SimpleFieldUio,
val commonSkills: List<BaseSkillFieldUio>,
@ -92,7 +94,9 @@ data class CharacterSheetEditPageUio(
get() = listOf(
movement,
maxHp,
currentHp,
maxPp,
currentPp,
damageBonus,
armor,
)
@ -187,54 +191,60 @@ fun CharacterSheetEdit(
wrapper = form.name,
)
DecoratedBox(
modifier = Modifier.animateContentSize(),
Row(
horizontalArrangement = Arrangement.spacedBy(space = 16.dp)
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
DecoratedBox(
modifier = Modifier.weight(weight = 1f),
) {
Text(
modifier = Modifier.padding(vertical = 8.dp),
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = MaterialTheme.typography.caption,
text = stringResource(Res.string.character_sheet_edit__characteristics__title),
)
form.characteristics.forEach {
SimpleField(
modifier = Modifier.fillMaxWidth(),
field = it,
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
modifier = Modifier.padding(vertical = 8.dp),
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = MaterialTheme.typography.caption,
text = stringResource(Res.string.character_sheet_edit__characteristics__title),
)
form.characteristics.forEach {
SimpleField(
modifier = Modifier.fillMaxWidth(),
field = it,
)
}
}
}
DecoratedBox(
modifier = Modifier.weight(weight = 1f),
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
modifier = Modifier.padding(vertical = 8.dp),
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = MaterialTheme.typography.caption,
text = stringResource(Res.string.character_sheet_edit__sub_characteristics__title),
)
form.subCharacteristics.forEach {
SimpleField(
modifier = Modifier.fillMaxWidth(),
field = it,
)
}
}
}
}
DecoratedBox(
modifier = Modifier.animateContentSize(),
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
modifier = Modifier.padding(vertical = 8.dp),
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = MaterialTheme.typography.caption,
text = stringResource(Res.string.character_sheet_edit__sub_characteristics__title),
)
form.subCharacteristics.forEach {
SimpleField(
modifier = Modifier.fillMaxWidth(),
field = it,
)
}
}
}
DecoratedBox(
modifier = Modifier.animateContentSize(),
modifier = Modifier
.fillMaxWidth()
.animateContentSize(),
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
@ -256,9 +266,12 @@ fun CharacterSheetEdit(
}
DecoratedBox(
modifier = Modifier.animateContentSize(),
modifier = Modifier
.fillMaxWidth()
.animateContentSize(),
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
@ -299,9 +312,12 @@ fun CharacterSheetEdit(
}
DecoratedBox(
modifier = Modifier.animateContentSize(),
modifier = Modifier
.fillMaxWidth()
.animateContentSize(),
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(

View file

@ -79,10 +79,10 @@ class CharacterSheetEditViewModel(
val field = ActionFieldUio(
id = id,
label = skillFactory.createWrapper(
label = getString(Res.string.character_sheet_edit__actions__name_label),
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__name_label)),
),
action = skillFactory.createWrapper(
label = getString(Res.string.character_sheet_edit__actions__action_label),
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__action_label)),
),
option = skillFactory.deleteOption { deleteSkill(id) },
)

View file

@ -3,6 +3,7 @@ package com.pixelized.desktop.lwa.screen.characterSheet.edit.common
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.mutableStateOf
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.SkillFieldUio
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.ActionOption
@ -29,22 +30,28 @@ class SkillFieldFactory {
levelValue: String = "",
options: List<OptionUio> = emptyList(),
): SkillFieldUio {
val baseLabel = getString(Res.string.character_sheet_edit__skills__base_label)
return SkillFieldUio(
id = id,
label = createWrapper(
label = label,
label = mutableStateOf(labelValue),
value = labelValue,
),
base = createWrapper(
label = getString(Res.string.character_sheet_edit__skills__base_label),
label = derivedStateOf {
options
.firstOrNull { it is CheckedOption && it.checked.value }
?.let { "$baseLabel *" }
?: baseLabel
},
value = baseValue,
),
bonus = createWrapper(
label = getString(Res.string.character_sheet_edit__skills__bonus_label),
label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__bonus_label)),
value = bonusValue,
),
level = createWrapper(
label = getString(Res.string.character_sheet_edit__skills__level_label),
label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__level_label)),
value = levelValue,
),
options = options,
@ -53,7 +60,7 @@ class SkillFieldFactory {
fun createWrapper(
enable: Boolean = true,
label: String? = null,
label: State<String?> = mutableStateOf(null),
placeholder: State<String?> = mutableStateOf(null),
value: String = "",
): TextFieldWrapperUio {

View file

@ -17,6 +17,7 @@ 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.derivedStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
@ -47,6 +48,17 @@ fun BaseSkillForm(
field: BaseSkillFieldUio,
) {
val showMenu = remember { mutableStateOf(false) }
val baseLabel = stringResource(Res.string.character_sheet_edit__skills__base_label)
.let { label ->
remember {
derivedStateOf {
when (field.option.checked.value) {
true -> "$label *"
else -> label
}
}
}
}
Row(
modifier = modifier,
@ -73,7 +85,7 @@ fun BaseSkillForm(
overflow = TextOverflow.Ellipsis,
maxLines = 1,
color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
text = stringResource(Res.string.character_sheet_edit__skills__base_label),
text = baseLabel.value,
)
Text(
style = MaterialTheme.typography.body1,

View file

@ -1,10 +1,7 @@
package com.pixelized.desktop.lwa.screen.characterSheet.edit.composable
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.width
import androidx.compose.material.DropdownMenu
@ -12,7 +9,6 @@ import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
@ -21,15 +17,10 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.singleWindowApplication
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapper
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.ActionOption
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.CheckedOption
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.DropDownMenuItemWrapper
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.OptionUio
import com.pixelized.desktop.lwa.utils.preview.ContentPreview
import java.util.UUID
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapper
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio
@Stable
class SkillFieldUio(

View file

@ -1,5 +1,6 @@
package com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield
import androidx.compose.foundation.layout.height
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextField
@ -7,17 +8,18 @@ import androidx.compose.material.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.pixelized.desktop.lwa.utils.rememberKeyboardActions
@Stable
data class TextFieldWrapperUio(
val enable: Boolean,
val label: String?,
val label: State<String?>,
val value: State<String>,
val placeholder: State<String?>,
val onValueChange: (String) -> Unit,
@ -28,12 +30,18 @@ fun TextFieldWrapper(
modifier: Modifier = Modifier,
wrapper: TextFieldWrapperUio,
) {
val colorScheme = MaterialTheme.colors
val focus = LocalFocusManager.current
TextField(
modifier = modifier,
modifier = Modifier.height(height = 56.dp).then(other = modifier),
colors = TextFieldDefaults.textFieldColors(
backgroundColor = MaterialTheme.colors.onSurface.copy(alpha = 0.03f),
backgroundColor = remember(wrapper.enable) {
when (wrapper.enable) {
true -> colorScheme.onSurface.copy(alpha = 0.03f)
else -> colorScheme.surface
}
},
),
keyboardActions = rememberKeyboardActions {
focus.moveFocus(FocusDirection.Next)
@ -49,7 +57,7 @@ fun TextFieldWrapper(
)
}
},
label = wrapper.label?.let {
label = wrapper.label.value?.let {
{
Text(
overflow = TextOverflow.Ellipsis,

View file

@ -10,7 +10,7 @@ import com.pixelized.desktop.lwa.business.SkillStepUseCase
import com.pixelized.desktop.lwa.business.SkillValueComputationUseCase
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
import com.pixelized.desktop.lwa.repository.roll.RollHistoryRepository
import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio
import com.pixelized.desktop.lwa.screen.roll.DifficultyUio.Difficulty
import kotlinx.coroutines.Job
@ -34,6 +34,7 @@ class RollViewModel(
private val characterSheetRepository: CharacterSheetRepository,
private val rollHistoryRepository: RollHistoryRepository,
private val skillComputation: SkillValueComputationUseCase,
private val skillStepUseCase: SkillStepUseCase,
) : ViewModel() {
private lateinit var sheet: CharacterSheet
@ -107,7 +108,7 @@ class RollViewModel(
this.rollSuccessValue = rollSuccessValue
val rollStep = rollSuccessValue?.let {
SkillStepUseCase.computeSkillStep(skill = it)
skillStepUseCase.computeSkillStep(skill = it)
}
_rollResult.value = null
@ -158,7 +159,7 @@ class RollViewModel(
delay(500)
val rollStep = rollSuccessValue?.let {
SkillStepUseCase.computeSkillStep(
skillStepUseCase.computeSkillStep(
skill = when (_rollDifficulty.value?.difficulty) {
Difficulty.EASY -> it * 2
Difficulty.NORMAL -> it
@ -221,7 +222,7 @@ class RollViewModel(
difficulty = difficulty,
)
val rollStep = rollSuccessValue?.let {
SkillStepUseCase.computeSkillStep(
skillStepUseCase.computeSkillStep(
skill = when (_rollDifficulty.value?.difficulty) {
Difficulty.EASY -> it * 2
Difficulty.NORMAL -> it

View file

@ -20,7 +20,6 @@ import androidx.compose.runtime.State
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.navigation.screen.LocalScreenController
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.roll_history__title

View file

@ -5,7 +5,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.pixelized.desktop.lwa.repository.network.protocol.RollMessage
import com.pixelized.desktop.lwa.repository.roll.RollHistoryRepository
import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository
import kotlinx.coroutines.launch
class RollHistoryViewModel(

View file

@ -1,27 +0,0 @@
package com.pixelized.desktop.lwa.utils.extention
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
@Suppress("UNCHECKED_CAST")
fun <T> ByteArray.fromByteArray(): T {
val byteArrayInputStream = ByteArrayInputStream(this)
val objectInput = ObjectInputStream(byteArrayInputStream)
val result = objectInput.readObject() as T
objectInput.close()
byteArrayInputStream.close()
return result
}
fun Any.toByteArray(): ByteArray {
val byteArrayOutputStream = ByteArrayOutputStream()
val objectOutputStream = ObjectOutputStream(byteArrayOutputStream)
objectOutputStream.writeObject(this)
objectOutputStream.flush()
val result = byteArrayOutputStream.toByteArray()
byteArrayOutputStream.close()
objectOutputStream.close()
return result
}

View file

@ -7,7 +7,6 @@ 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" }
@ -15,7 +14,6 @@ composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "k
kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
[libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }