Add the icon to the alteration edit page.

This commit is contained in:
Thomas Andres Gomez 2025-05-08 14:38:24 +02:00
parent e81b66e725
commit 05a6b496cb
10 changed files with 63 additions and 22 deletions

View file

@ -305,6 +305,7 @@
<string name="game_master__alteration__edit_id">Identifiant de l'altération</string>
<string name="game_master__alteration__edit_label">Nom</string>
<string name="game_master__alteration__edit_description">Description</string>
<string name="game_master__alteration__edit_icon">Icône</string>
<string name="game_master__alteration__edit_tags">Tags</string>
<string name="game_master__alteration__edit_field_id">Identifiant du champ</string>
<string name="game_master__alteration__edit_field_expression">Expression</string>

View file

@ -9,6 +9,8 @@ import com.pixelized.shared.lwa.model.alteration.Alteration
import com.pixelized.shared.lwa.model.alteration.FieldAlteration
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
private const val DEFAULT_ICON = "https://bg3.wiki/w/images/a/af/Arcana_Icon.png"
class CharacterRibbonFactory(
private val alteredCharacterSheetFactory: AlteredCharacterSheetFactory,
) {
@ -29,7 +31,7 @@ class CharacterRibbonFactory(
val status = alterations.map { alteration ->
CharacterRibbonAlterationUio(
icon = "https://bg3.wiki/w/images/2/2d/Map_Tutorial_Map_Icon.png",
icon = alteration.metadata.icon ?: DEFAULT_ICON,
tooltips = BasicTooltipUio(
title = alteration.metadata.name,
description = alteration.metadata.description,

View file

@ -1,5 +1,10 @@
package com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon.common
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.TooltipPlacement
import androidx.compose.foundation.layout.Arrangement
@ -46,6 +51,7 @@ fun CharacterRibbonAlteration(
) {
Row(
modifier = Modifier
.animateContentSize()
.size(size = size)
.then(other = modifier),
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
@ -55,6 +61,7 @@ fun CharacterRibbonAlteration(
) {
status.forEach { columns ->
Column(
modifier = Modifier.animateContentSize(),
verticalArrangement = Arrangement.spacedBy(space = 2.dp),
) {
columns.forEach {
@ -63,26 +70,31 @@ fun CharacterRibbonAlteration(
tooltip = it.tooltips,
tooltipPlacement = remember(currentDirection) {
TooltipPlacement.ComponentRect(
anchor = when(direction) {
anchor = when (direction) {
LayoutDirection.Ltr -> Alignment.TopStart
LayoutDirection.Rtl -> Alignment.TopEnd
},
alignment = when(direction) {
alignment = when (direction) {
LayoutDirection.Ltr -> Alignment.BottomEnd
LayoutDirection.Rtl -> Alignment.BottomStart
},
)
},
content = {
AsyncImage(
modifier = Modifier.size(24.dp),
model = ImageRequest.Builder(context = PlatformContext.INSTANCE)
.data(data = it.icon)
.size(size = 48)
.build(),
filterQuality = FilterQuality.High,
contentDescription = null,
)
AnimatedContent(
targetState = it.icon,
transitionSpec = { fadeIn() togetherWith fadeOut() },
) { icon ->
AsyncImage(
modifier = Modifier.size(24.dp),
model = ImageRequest.Builder(context = PlatformContext.INSTANCE)
.data(data = icon)
.size(size = 48)
.build(),
filterQuality = FilterQuality.High,
contentDescription = null,
)
}
}
)
}

View file

@ -11,6 +11,7 @@ import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.game_master__alteration__edit_description
import lwacharactersheet.composeapp.generated.resources.game_master__alteration__edit_field_expression
import lwacharactersheet.composeapp.generated.resources.game_master__alteration__edit_field_id
import lwacharactersheet.composeapp.generated.resources.game_master__alteration__edit_icon
import lwacharactersheet.composeapp.generated.resources.game_master__alteration__edit_id
import lwacharactersheet.composeapp.generated.resources.game_master__alteration__edit_label
import org.jetbrains.compose.resources.getString
@ -36,6 +37,10 @@ class GMAlterationEditFactory(
label = getString(Res.string.game_master__alteration__edit_description),
value = alteration?.metadata?.description ?: "",
)
val iconFlow = createLwaTextFieldFlow(
label = getString(Res.string.game_master__alteration__edit_icon),
value = alteration?.metadata?.icon ?: "",
)
val tagFlow = MutableStateFlow(
tagFactory.convertToGMTagItemUio(
tags = tags,
@ -48,6 +53,7 @@ class GMAlterationEditFactory(
idFlow = idFlow,
labelFlow = labelFlow,
descriptionFlow = descriptionFlow,
iconFlow = iconFlow,
tagFlow = tagFlow,
fieldsFlow = fieldsFlow,
)
@ -61,6 +67,7 @@ class GMAlterationEditFactory(
id = form.idFlow.createLwaTextField(enable = originId == null),
label = form.labelFlow.createLwaTextField(),
description = form.descriptionFlow.createLwaTextField(),
icon = form.iconFlow.createLwaTextField(),
tags = form.tagFlow,
fields = form.fieldsFlow,
)
@ -84,21 +91,22 @@ class GMAlterationEditFactory(
)
}
suspend fun createAlteration(
form: GMAlterationEditPageUio?,
fun createAlteration(
form: GMAlterationEditViewModel.GMAlterationEditForm?,
): Alteration? {
if (form == null) return null
return Alteration(
id = form.id.valueFlow.value,
id = form.idFlow.valueFlow.value,
metadata = Alteration.MetaData(
name = form.label.valueFlow.value,
description = form.description.valueFlow.value,
name = form.labelFlow.valueFlow.value,
description = form.descriptionFlow.valueFlow.value,
icon = form.iconFlow.valueFlow.value.takeIf { it.isNotBlank() },
),
tags = form.tags.value
tags = form.tagFlow.value
.filter { it.highlight }
.map { it.id },
fields = form.fields.value.mapNotNull { field ->
fields = form.fieldsFlow.value.mapNotNull { field ->
expressionParser.parse(input = field.expression.valueFlow.value)?.let {
Alteration.Field(
fieldId = field.id.valueFlow.value,

View file

@ -85,6 +85,7 @@ data class GMAlterationEditPageUio(
val id: LwaTextFieldUio,
val label: LwaTextFieldUio,
val description: LwaTextFieldUio,
val icon: LwaTextFieldUio,
val tags: MutableStateFlow<List<GMTagUio>>,
val fields: MutableStateFlow<List<SkillUio>>,
) {
@ -265,6 +266,16 @@ private fun GMAlterationEditContent(
singleLine = false,
)
}
item(key = "Icon") {
LwaTextField(
modifier = Modifier
.animateItem()
.fillMaxWidth()
.padding(paddingValues = horizontalPadding),
field = it.icon,
singleLine = false,
)
}
item(key = "Tags") {
LazyRow(
modifier = Modifier.draggable(

View file

@ -55,7 +55,7 @@ class GMAlterationEditViewModel(
}
suspend fun save(): Boolean {
val edited = factory.createAlteration(form = form.value) ?: return false
val edited = factory.createAlteration(form = _form.value) ?: return false
try {
alterationRepository.updateAlteration(
@ -108,6 +108,7 @@ class GMAlterationEditViewModel(
val idFlow: LwaTextFieldFlow,
val labelFlow: LwaTextFieldFlow,
val descriptionFlow: LwaTextFieldFlow,
val iconFlow: LwaTextFieldFlow,
val tagFlow: MutableStateFlow<List<GMTagUio>>,
val fieldsFlow: MutableStateFlow<List<GMAlterationEditPageUio.SkillUio>>,
)

View file

@ -61,7 +61,8 @@ class LevelUpFactory(
alterationId = CharacterSheet.CharacteristicId.LVL,
metadata = Alteration.MetaData(
name = "LevelUp-${CharacterSheet.CharacteristicId.LVL}",
description = "Fake alteration for a levelUp simulation. Alter the ${CharacterSheet.CharacteristicId.LVL} stat."
description = "Fake alteration for a levelUp simulation. Alter the ${CharacterSheet.CharacteristicId.LVL} stat.",
icon = null,
),
expression = Expression.Flat(1),
)
@ -78,7 +79,8 @@ class LevelUpFactory(
alterationId = it,
metadata = Alteration.MetaData(
name = "LevelUp-$it",
description = "Fake alteration for a levelUp simulation. Alter the $it stat."
description = "Fake alteration for a levelUp simulation. Alter the $it stat.",
icon = null,
),
expression = Expression.Flat(1),
)

View file

@ -9,6 +9,7 @@ data class Alteration(
val fields: List<Field>,
) {
data class MetaData(
val icon: String?,
val name: String,
val description: String,
)

View file

@ -32,6 +32,7 @@ class AlterationJsonFactory(
return Alteration.MetaData(
name = json.name,
description = json.description,
icon = json.icon,
)
}
@ -61,6 +62,7 @@ class AlterationJsonFactory(
return AlterationJsonV1.AlterationMetadataJsonV1(
name = data.name,
description = data.description,
icon = data.icon,
)
}

View file

@ -20,5 +20,6 @@ data class AlterationJsonV1(
data class AlterationMetadataJsonV1(
val name: String,
val description: String,
val icon: String?,
)
}