Add favorite skill edit.

This commit is contained in:
Thomas Andres Gomez 2023-12-13 09:27:51 +01:00
parent d256ba70ac
commit 6fb3b2c10c
6 changed files with 78 additions and 44 deletions

View file

@ -65,6 +65,7 @@ import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.ui.composable.KeepOnScreen
import com.pixelized.rplexicon.ui.composable.Loader
import com.pixelized.rplexicon.ui.composable.edit.HandleHitPointEditDialog
import com.pixelized.rplexicon.ui.composable.edit.HandleSkillEditDialog
import com.pixelized.rplexicon.ui.composable.error.HandleFetchError
import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
import com.pixelized.rplexicon.ui.navigation.screens.navigateToSearch
@ -74,6 +75,7 @@ import com.pixelized.rplexicon.ui.screens.character.CharacterTabUio.Inventory
import com.pixelized.rplexicon.ui.screens.character.CharacterTabUio.Proficiency
import com.pixelized.rplexicon.ui.screens.character.composable.character.CharacterSheetHeader
import com.pixelized.rplexicon.ui.screens.character.composable.character.CharacterSheetHeaderUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.ResourcePointUio
import com.pixelized.rplexicon.ui.screens.character.composable.preview.rememberCharacterHeaderStatePreview
import com.pixelized.rplexicon.ui.screens.character.pages.actions.ActionPage
import com.pixelized.rplexicon.ui.screens.character.pages.actions.ActionPagePreview
@ -156,7 +158,7 @@ fun CharacterSheetScreen(
},
onHitPoint = headerViewModel::toggleHitPointDialog,
onResource = {
// TODO()
headerViewModel.showSkillEditDialog(item = it)
},
onDeathRoll = {
overlay.prepareRoll(diceThrow = headerViewModel.onDeathThrow())
@ -226,6 +228,12 @@ fun CharacterSheetScreen(
onConfirm = headerViewModel::applyHitPointChange,
)
HandleSkillEditDialog(
dialog = headerViewModel.skillEditDialog,
onDismissRequest = headerViewModel::hideSkillEditDialog,
onConfirm = headerViewModel::applySkillChange,
)
HandleFetchError(
errors = viewModel.error,
)
@ -261,7 +269,7 @@ private fun CharacterSheetContent(
tabs: State<List<CharacterTabUio>>,
header: State<CharacterSheetHeaderUio?>,
onHitPoint: () -> Unit,
onResource: () -> Unit,
onResource: (ResourcePointUio) -> Unit,
onDeathRoll: () -> Unit,
onDeathSuccess: () -> Unit,
onDeathFailure: () -> Unit,

View file

@ -37,7 +37,7 @@ fun CharacterSheetHeader(
padding: PaddingValues = PaddingValues(start = 16.dp, end = 16.dp, bottom = 4.dp),
header: State<CharacterSheetHeaderUio?>,
onHitPoint: () -> Unit,
onResource: () -> Unit,
onResource: (ResourcePointUio) -> Unit,
onDeathRoll: () -> Unit,
onDeathSuccess: () -> Unit,
onDeathFailure: () -> Unit,
@ -58,7 +58,7 @@ fun CharacterSheetHeader(
),
) {
header.value?.resource?.let {
ResourcePoint(label = it, onClick = onResource)
ResourcePoint(resource = it, onClick = onResource)
}
header.value?.armorClass?.let {
LabelPoint(label = it)

View file

@ -26,9 +26,10 @@ import com.pixelized.rplexicon.ui.theme.LexiconTheme
@Stable
data class ResourcePointUio(
val label: Int?,
val value: String?,
val max: String? = null,
val id: String,
val label: Int,
val value: Int,
val max: Int,
)
@Composable
@ -37,26 +38,24 @@ fun ResourcePoint(
labelStyle: TextStyle = MaterialTheme.typography.labelSmall,
valueStyle: TextStyle = MaterialTheme.typography.headlineSmall,
maxStyle: TextStyle = MaterialTheme.typography.titleSmall,
label: ResourcePointUio,
onClick: (() -> Unit)? = null,
resource: ResourcePointUio,
onClick: (ResourcePointUio) -> Unit,
) {
Column(
modifier = Modifier
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(bounded = false),
enabled = onClick != null, onClick = { onClick?.invoke() }
onClick = { onClick(resource) }
)
.then(other = modifier),
horizontalAlignment = Alignment.CenterHorizontally
) {
label.label?.let {
Text(
style = labelStyle,
fontWeight = FontWeight.Light,
text = stringResource(id = it),
text = stringResource(id = resource.label),
)
}
Row(
horizontalArrangement = Arrangement.spacedBy(4.dp),
) {
@ -68,18 +67,16 @@ fun ResourcePoint(
else -> MaterialTheme.colorScheme.primary
},
fontWeight = FontWeight.Bold,
text = label.value ?: "0"
text = "${resource.value}"
)
label.max?.let {
Text(
modifier = Modifier.alignByBaseline(),
style = maxStyle,
text = it,
text = "/ ${resource.max}",
)
}
}
}
}
@Composable
@Preview(uiMode = UI_MODE_NIGHT_NO)
@ -88,10 +85,11 @@ private fun LabelPointPreview() {
LexiconTheme {
Surface {
ResourcePoint(
label = ResourcePointUio(
resource = ResourcePointUio(
id = "Inspiration Bardique",
label = R.string.character_sheet_title_inspiration,
value = "2",
max = "/ 2",
value = 2,
max = 2,
),
onClick = { },
)

View file

@ -36,9 +36,10 @@ fun rememberCharacterHeaderStatePreview(
value = "13",
),
resource = ResourcePointUio(
id = "Rage",
label = R.string.character_sheet_title_rage,
value = "2",
max = "/ 2",
value = 2,
max = 2,
),
death = death,
)

View file

@ -1,6 +1,7 @@
package com.pixelized.rplexicon.ui.screens.character.factory
import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.data.repository.character.SkillRepository
import com.pixelized.rplexicon.ui.screens.character.composable.character.CharacterSheetHeaderUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.DeathThrowUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.LabelPointUio
@ -8,12 +9,19 @@ import com.pixelized.rplexicon.ui.screens.character.composable.character.Resourc
import com.pixelized.rplexicon.ui.screens.character.pages.actions.HeaderViewModel
import javax.inject.Inject
class CharacterSheetHeaderUioFactory @Inject constructor() {
class CharacterSheetHeaderUioFactory @Inject constructor(
private val skillRepository: SkillRepository,
) {
fun convert(
character: String,
sheetHeaderData: HeaderViewModel.SheetHeaderData?,
fireHeaderData: HeaderViewModel.FireHeaderData?,
): CharacterSheetHeaderUio {
val characterClass = sheetHeaderData?.characterClass
val favoriteSkill = skillRepository.find(
character = character,
skill = sheetHeaderData?.characterClass?.resource
)
return CharacterSheetHeaderUio(
armorClass = LabelPointUio(
label = R.string.character_sheet_title_ca,
@ -36,11 +44,12 @@ class CharacterSheetHeaderUioFactory @Inject constructor() {
value = "$it",
)
},
resource = if (sheetHeaderData?.resourceMax != null) {
resource = if (characterClass?.label != null && favoriteSkill?.amount != null) {
ResourcePointUio(
label = sheetHeaderData.resourceLabel,
value = "${fireHeaderData?.resource ?: 0}",
max = "/ ${sheetHeaderData.resourceMax}"
id = favoriteSkill.name,
label = characterClass.label,
value = fireHeaderData?.resource ?: 0,
max = favoriteSkill.amount,
)
} else {
null

View file

@ -7,6 +7,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.pixelized.rplexicon.data.model.CharacterSheet
import com.pixelized.rplexicon.data.model.DiceThrow
import com.pixelized.rplexicon.data.model.Property
import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository
@ -14,8 +15,10 @@ import com.pixelized.rplexicon.data.repository.character.AlterationRepository
import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository
import com.pixelized.rplexicon.data.repository.character.SkillRepository
import com.pixelized.rplexicon.ui.composable.edit.HpPointDialogUio
import com.pixelized.rplexicon.ui.composable.edit.SkillEditDialogUio
import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument
import com.pixelized.rplexicon.ui.screens.character.composable.character.CharacterSheetHeaderUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.ResourcePointUio
import com.pixelized.rplexicon.ui.screens.character.factory.CharacterSheetHeaderUioFactory
import com.pixelized.rplexicon.utilitary.extentions.local.sum
import dagger.hilt.android.lifecycle.HiltViewModel
@ -41,6 +44,7 @@ class HeaderViewModel @Inject constructor(
val header: State<CharacterSheetHeaderUio?> = derivedStateOf {
headerFactory.convert(
character = character,
sheetHeaderData = sheetData.value,
fireHeaderData = fireData.value,
)
@ -49,6 +53,9 @@ class HeaderViewModel @Inject constructor(
private val _hitPointDialog = mutableStateOf<HpPointDialogUio?>(null)
val hitPointDialog: State<HpPointDialogUio?> get() = _hitPointDialog
private val _skillEditDialog = mutableStateOf<SkillEditDialogUio?>(null)
val skillEditDialog: State<SkillEditDialogUio?> get() = _skillEditDialog
init {
viewModelScope.launch {
launch(context = Dispatchers.IO) {
@ -60,14 +67,9 @@ class HeaderViewModel @Inject constructor(
val alterations = alterationRepository.getActiveAlterationsStatus(
character = sheet.name,
)
val resource = sheet.characterClass.firstOrNull()
val data = SheetHeaderData(
hpMax = sheet.hitPoint + alterations[Property.HIT_POINT].sum,
resourceLabel = resource?.label,
resourceMax = skillRepository.find(
character = character,
skill = resource?.resource,
)?.amount,
characterClass = sheet.characterClass.firstOrNull(),
speed = sheet.speed,
ca = sheet.armorClass + alterations[Property.ARMOR_CLASS].sum,
dc = sheet.dC,
@ -150,11 +152,27 @@ class HeaderViewModel @Inject constructor(
_hitPointDialog.value = null
}
fun showSkillEditDialog(item: ResourcePointUio) {
_skillEditDialog.value = SkillEditDialogUio(
label = item.id,
value = item.value,
max = item.max,
)
}
fun hideSkillEditDialog() {
_skillEditDialog.value = null
}
fun applySkillChange(id: String, value: Int) {
firebaseRepository.setSkill(character = character, name = id, value = value)
hideSkillEditDialog()
}
@Stable
data class SheetHeaderData(
val hpMax: Int,
val resourceLabel: Int?,
val resourceMax: Int?,
val characterClass: CharacterSheet.Class?,
val speed: Int,
val ca: Int,
val dc: Int?,