From 6fb3b2c10c7dc244fa4eae3ebcc37efcf046dbc9 Mon Sep 17 00:00:00 2001 From: Thomas Andres Gomez Date: Wed, 13 Dec 2023 09:27:51 +0100 Subject: [PATCH] Add favorite skill edit. --- .../screens/character/CharacterSheetScreen.kt | 12 ++++- .../character/CharacterSheetHeader.kt | 4 +- .../composable/character/ResourcePoint.kt | 46 +++++++++---------- .../rememberCharacterHeaderStatePreview.kt | 5 +- .../factory/CharacterSheetHeaderUioFactory.kt | 21 ++++++--- .../pages/actions/HeaderViewModel.kt | 34 ++++++++++---- 6 files changed, 78 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/CharacterSheetScreen.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/CharacterSheetScreen.kt index 47a46dd..884006f 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/CharacterSheetScreen.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/CharacterSheetScreen.kt @@ -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>, header: State, onHitPoint: () -> Unit, - onResource: () -> Unit, + onResource: (ResourcePointUio) -> Unit, onDeathRoll: () -> Unit, onDeathSuccess: () -> Unit, onDeathFailure: () -> Unit, diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/composable/character/CharacterSheetHeader.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/composable/character/CharacterSheetHeader.kt index d496de7..a16f97d 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/composable/character/CharacterSheetHeader.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/composable/character/CharacterSheetHeader.kt @@ -37,7 +37,7 @@ fun CharacterSheetHeader( padding: PaddingValues = PaddingValues(start = 16.dp, end = 16.dp, bottom = 4.dp), header: State, 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) diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/composable/character/ResourcePoint.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/composable/character/ResourcePoint.kt index fffc6c5..436923a 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/composable/character/ResourcePoint.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/composable/character/ResourcePoint.kt @@ -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( + style = labelStyle, + fontWeight = FontWeight.Light, + text = stringResource(id = resource.label), + ) Row( horizontalArrangement = Arrangement.spacedBy(4.dp), ) { @@ -68,15 +67,13 @@ fun ResourcePoint( else -> MaterialTheme.colorScheme.primary }, fontWeight = FontWeight.Bold, - text = label.value ?: "0" + text = "${resource.value}" + ) + Text( + modifier = Modifier.alignByBaseline(), + style = maxStyle, + text = "/ ${resource.max}", ) - label.max?.let { - Text( - modifier = Modifier.alignByBaseline(), - style = maxStyle, - text = it, - ) - } } } } @@ -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 = { }, ) diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/composable/preview/rememberCharacterHeaderStatePreview.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/composable/preview/rememberCharacterHeaderStatePreview.kt index 2170560..d7d4be8 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/composable/preview/rememberCharacterHeaderStatePreview.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/composable/preview/rememberCharacterHeaderStatePreview.kt @@ -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, ) diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/factory/CharacterSheetHeaderUioFactory.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/factory/CharacterSheetHeaderUioFactory.kt index b51480e..01ffae0 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/factory/CharacterSheetHeaderUioFactory.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/factory/CharacterSheetHeaderUioFactory.kt @@ -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 diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/HeaderViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/HeaderViewModel.kt index 0e4d7e5..4ec37b8 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/HeaderViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/HeaderViewModel.kt @@ -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 = derivedStateOf { headerFactory.convert( + character = character, sheetHeaderData = sheetData.value, fireHeaderData = fireData.value, ) @@ -49,6 +53,9 @@ class HeaderViewModel @Inject constructor( private val _hitPointDialog = mutableStateOf(null) val hitPointDialog: State get() = _hitPointDialog + private val _skillEditDialog = mutableStateOf(null) + val skillEditDialog: State 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?,