diff --git a/app/src/main/java/com/pixelized/rplexicon/business/DiceThrowUseCase.kt b/app/src/main/java/com/pixelized/rplexicon/business/DiceThrowUseCase.kt index df474c9..ec3afcf 100644 --- a/app/src/main/java/com/pixelized/rplexicon/business/DiceThrowUseCase.kt +++ b/app/src/main/java/com/pixelized/rplexicon/business/DiceThrowUseCase.kt @@ -56,7 +56,11 @@ class DiceThrowUseCase @Inject constructor( private val skillRepository: SkillRepository, private val alterationRepository: AlterationRepository, ) { - fun roll(diceThrow: DiceThrow, alterationId: List): DiceThrowResult? { + fun roll( + diceThrow: DiceThrow, + isThrowHidden: Boolean, + alterationId: List, + ): DiceThrowResult? { val sheet = characterSheetRepository.find(name = diceThrow.character) val alterations = alterationRepository.getAlterations(character = diceThrow.character) .filter { alterationId.contains(it.name) } @@ -70,6 +74,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_dexterity) }, ability = Property.INITIATIVE, relatedStat = Property.DEXTERITY, + isThrowHidden = isThrowHidden, ) is DiceThrow.Strength -> abilityThrow( @@ -79,6 +84,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_strength) }, ability = Property.STRENGTH_THROW, relatedStat = Property.STRENGTH, + isThrowHidden = isThrowHidden, ) is DiceThrow.Dexterity -> abilityThrow( @@ -88,6 +94,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_dexterity) }, ability = Property.DEXTERITY_THROW, relatedStat = Property.DEXTERITY, + isThrowHidden = isThrowHidden, ) is DiceThrow.Constitution -> abilityThrow( @@ -97,6 +104,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_constitution) }, ability = Property.CONSTITUTION_THROW, relatedStat = Property.CONSTITUTION, + isThrowHidden = isThrowHidden, ) is DiceThrow.Intelligence -> abilityThrow( @@ -106,6 +114,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_intelligence) }, ability = Property.INTELLIGENCE_THROW, relatedStat = Property.INTELLIGENCE, + isThrowHidden = isThrowHidden, ) is DiceThrow.Wisdom -> abilityThrow( @@ -114,7 +123,8 @@ class DiceThrowUseCase @Inject constructor( abilityLabel = { getString(R.string.character_sheet_stat_wisdom) }, relatedLabel = { getString(R.string.character_sheet_stat_wisdom) }, ability = Property.WISDOM_THROW, - relatedStat = Property.WISDOM + relatedStat = Property.WISDOM, + isThrowHidden = isThrowHidden, ) is DiceThrow.Charisma -> abilityThrow( @@ -123,7 +133,8 @@ class DiceThrowUseCase @Inject constructor( abilityLabel = { getString(R.string.character_sheet_stat_charisma) }, relatedLabel = { getString(R.string.character_sheet_stat_charisma) }, ability = Property.CHARISMA_THROW, - relatedStat = Property.CHARISMA + relatedStat = Property.CHARISMA, + isThrowHidden = isThrowHidden, ) is DiceThrow.StrengthSavingThrow -> savingThrow( @@ -133,6 +144,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_strength) }, ability = Property.STRENGTH_SAVING_THROW, relatedStat = Property.STRENGTH, + isThrowHidden = isThrowHidden, ) is DiceThrow.DexteritySavingThrow -> savingThrow( @@ -142,6 +154,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_dexterity) }, ability = Property.DEXTERITY_SAVING_THROW, relatedStat = Property.DEXTERITY, + isThrowHidden = isThrowHidden, ) is DiceThrow.ConstitutionSavingThrow -> savingThrow( @@ -151,6 +164,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_constitution) }, ability = Property.CONSTITUTION_SAVING_THROW, relatedStat = Property.CONSTITUTION, + isThrowHidden = isThrowHidden, ) is DiceThrow.IntelligenceSavingThrow -> savingThrow( @@ -160,6 +174,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_intelligence) }, ability = Property.INTELLIGENCE_SAVING_THROW, relatedStat = Property.INTELLIGENCE, + isThrowHidden = isThrowHidden, ) is DiceThrow.WisdomSavingThrow -> savingThrow( @@ -168,7 +183,8 @@ class DiceThrowUseCase @Inject constructor( abilityLabel = { getString(R.string.character_sheet_stat_wisdom) }, relatedLabel = { getString(R.string.character_sheet_stat_wisdom) }, ability = Property.WISDOM_SAVING_THROW, - relatedStat = Property.WISDOM + relatedStat = Property.WISDOM, + isThrowHidden = isThrowHidden, ) is DiceThrow.CharismaSavingThrow -> savingThrow( @@ -177,7 +193,8 @@ class DiceThrowUseCase @Inject constructor( abilityLabel = { getString(R.string.character_sheet_stat_charisma) }, relatedLabel = { getString(R.string.character_sheet_stat_charisma) }, ability = Property.CHARISMA_SAVING_THROW, - relatedStat = Property.CHARISMA + relatedStat = Property.CHARISMA, + isThrowHidden = isThrowHidden, ) is DiceThrow.DeathSavingThrow -> savingThrow( @@ -187,6 +204,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_death) }, ability = Property.DEATH_SAVING_THROW, relatedStat = null, + isThrowHidden = isThrowHidden, ) is DiceThrow.Acrobatics -> abilityThrow( @@ -196,6 +214,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_dexterity) }, ability = Property.ACROBATICS, relatedStat = Property.DEXTERITY, + isThrowHidden = isThrowHidden, ) is DiceThrow.AnimalHandling -> abilityThrow( @@ -205,6 +224,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_wisdom) }, ability = Property.ANIMAL_HANDLING, relatedStat = Property.WISDOM, + isThrowHidden = isThrowHidden, ) is DiceThrow.Arcana -> abilityThrow( @@ -214,6 +234,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_intelligence) }, ability = Property.ARCANA, relatedStat = Property.INTELLIGENCE, + isThrowHidden = isThrowHidden, ) is DiceThrow.Athletics -> abilityThrow( @@ -223,6 +244,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_strength) }, ability = Property.ATHLETICS, relatedStat = Property.STRENGTH, + isThrowHidden = isThrowHidden, ) is DiceThrow.Deception -> abilityThrow( @@ -232,6 +254,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_charisma) }, ability = Property.DECEPTION, relatedStat = Property.CHARISMA, + isThrowHidden = isThrowHidden, ) is DiceThrow.History -> abilityThrow( @@ -241,6 +264,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_intelligence) }, ability = Property.HISTORY, relatedStat = Property.INTELLIGENCE, + isThrowHidden = isThrowHidden, ) is DiceThrow.Insight -> abilityThrow( @@ -250,6 +274,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_wisdom) }, ability = Property.INSIGHT, relatedStat = Property.WISDOM, + isThrowHidden = isThrowHidden, ) is DiceThrow.Intimidation -> abilityThrow( @@ -259,6 +284,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_charisma) }, ability = Property.INTIMIDATION, relatedStat = Property.CHARISMA, + isThrowHidden = isThrowHidden, ) is DiceThrow.Investigation -> abilityThrow( @@ -268,6 +294,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_intelligence) }, ability = Property.INVESTIGATION, relatedStat = Property.INTELLIGENCE, + isThrowHidden = isThrowHidden, ) is DiceThrow.Medicine -> abilityThrow( @@ -277,6 +304,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_wisdom) }, ability = Property.MEDICINE, relatedStat = Property.WISDOM, + isThrowHidden = isThrowHidden, ) is DiceThrow.Nature -> abilityThrow( @@ -286,6 +314,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_intelligence) }, ability = Property.NATURE, relatedStat = Property.INTELLIGENCE, + isThrowHidden = isThrowHidden, ) is DiceThrow.Perception -> abilityThrow( @@ -295,6 +324,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_wisdom) }, ability = Property.PERCEPTION, relatedStat = Property.WISDOM, + isThrowHidden = isThrowHidden, ) is DiceThrow.Performance -> abilityThrow( @@ -304,6 +334,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_charisma) }, ability = Property.PERFORMANCE, relatedStat = Property.CHARISMA, + isThrowHidden = isThrowHidden, ) is DiceThrow.Persuasion -> abilityThrow( @@ -313,6 +344,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_charisma) }, ability = Property.PERSUASION, relatedStat = Property.CHARISMA, + isThrowHidden = isThrowHidden, ) is DiceThrow.Religion -> abilityThrow( @@ -322,6 +354,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_intelligence) }, ability = Property.RELIGION, relatedStat = Property.INTELLIGENCE, + isThrowHidden = isThrowHidden, ) is DiceThrow.SleightOfHand -> abilityThrow( @@ -331,6 +364,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_dexterity) }, ability = Property.SLEIGHT_OF_HAND, relatedStat = Property.DEXTERITY, + isThrowHidden = isThrowHidden, ) is DiceThrow.Stealth -> abilityThrow( @@ -340,6 +374,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_dexterity) }, ability = Property.STEALTH, relatedStat = Property.DEXTERITY, + isThrowHidden = isThrowHidden, ) is DiceThrow.Survival -> abilityThrow( @@ -349,6 +384,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = { getString(R.string.character_sheet_stat_wisdom) }, ability = Property.SURVIVAL, relatedStat = Property.WISDOM, + isThrowHidden = isThrowHidden, ) is DiceThrow.PhysicalMeleeAttack -> { @@ -505,6 +541,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel: Context.() -> String?, ability: Property, relatedStat: Property, + isThrowHidden: Boolean, ): DiceThrowResult = rollAbility( character = character, alterations = alterations, @@ -514,6 +551,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = relatedLabel, ability = ability, relatedStat = relatedStat, + isThrowHidden = isThrowHidden, ) private fun savingThrow( @@ -523,6 +561,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel: Context.() -> String?, ability: Property, relatedStat: Property?, + isThrowHidden: Boolean, ): DiceThrowResult = rollAbility( character = character, alterations = alterations, @@ -532,6 +571,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel = relatedLabel, ability = ability, relatedStat = relatedStat, + isThrowHidden = isThrowHidden, ) private fun rollAbility( @@ -543,6 +583,7 @@ class DiceThrowUseCase @Inject constructor( relatedLabel: Context.() -> String?, ability: Property, relatedStat: Property?, + isThrowHidden: Boolean, ): DiceThrowResult { with(ThrowScope(context = application, character = character, alterations = alterations)) { // retrieve some wording. @@ -655,7 +696,7 @@ class DiceThrowUseCase @Inject constructor( timestamp = System.currentTimeMillis(), title = abilityTitleString.uppercase(), highlight = abilityLabelString.uppercase(), - hidden = ability == Property.DEATH_SAVING_THROW, + hidden = isThrowHidden, face = 20, roll = allValue.toLabel(), result = rollResult, diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/rolls/RollOverlay.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/rolls/RollOverlay.kt index 1fd3759..0c2d59d 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/rolls/RollOverlay.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/rolls/RollOverlay.kt @@ -13,12 +13,16 @@ import androidx.compose.animation.fadeOut import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutVertically import androidx.compose.animation.togetherWith +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons @@ -52,6 +56,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.composed import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.font.FontWeight @@ -101,6 +106,7 @@ fun RollOverlay( card = viewModel.card, groups = viewModel.alterations, showDetail = viewModel.showDetail, + isThrowHidden = viewModel.isThrowHidden, onMenu = { scope.launch { drawer.open() } }, @@ -122,6 +128,9 @@ fun RollOverlay( onAlteration = { viewModel.onAlteration(it) }, + onThrowVisibilityChange = { + viewModel.onThrowVisibilityChange(it) + }, ) BackHandler( @@ -144,6 +153,7 @@ private fun RollOverlayContent( card: State, groups: State>, showDetail: State, + isThrowHidden: State, onMenu: () -> Unit, onMenuClose: () -> Unit, onClose: () -> Unit, @@ -151,6 +161,7 @@ private fun RollOverlayContent( onCard: () -> Unit, onAlterationInfo: (id: String) -> Unit, onAlteration: (id: String) -> Unit, + onThrowVisibilityChange: (Boolean) -> Unit, ) { val density = LocalDensity.current val enableDrawer = remember { @@ -214,14 +225,30 @@ private fun RollOverlayContent( } } - TextButton( - modifier = Modifier.align(alignment = Alignment.End), - onClick = onMenuClose, + Row( + modifier = Modifier.fillMaxWidth(4f / 5f), + horizontalArrangement = Arrangement.SpaceBetween ) { - Text( - modifier = Modifier.padding(horizontal = 8.dp), - text = stringResource(id = R.string.roll_overlay__close_action), - ) + IconButton( + onClick = { onThrowVisibilityChange(isThrowHidden.value.not()) }, + ) { + Icon( + painter = when (isThrowHidden.value) { + true -> painterResource(id = R.drawable.ic_visibility_off_24) + else -> painterResource(id = R.drawable.ic_visibility_24) + }, + tint = MaterialTheme.colorScheme.primary, + contentDescription = null, + ) + } + TextButton( + onClick = onMenuClose, + ) { + Text( + modifier = Modifier.padding(horizontal = 8.dp), + text = stringResource(id = R.string.roll_overlay__close_action), + ) + } } } } @@ -352,6 +379,7 @@ private fun RollOverlayPreview( card = preview.card, groups = rememberRollAlterations(), showDetail = remember { mutableStateOf(true) }, + isThrowHidden = remember { mutableStateOf(true) }, onMenu = { }, onMenuClose = { }, onClose = { }, @@ -359,6 +387,7 @@ private fun RollOverlayPreview( onCard = { }, onAlterationInfo = { }, onAlteration = { }, + onThrowVisibilityChange = { }, ) } } diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/rolls/RollOverlayViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/rolls/RollOverlayViewModel.kt index a077c46..c253111 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/rolls/RollOverlayViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/rolls/RollOverlayViewModel.kt @@ -68,11 +68,15 @@ class RollOverlayViewModel @Inject constructor( private val _showDetail = mutableStateOf(true) val showDetail: State get() = _showDetail + private val _isThrowHidden = mutableStateOf(false) + val isThrowHidden: State get() = _isThrowHidden + private val _alterationDetail = mutableStateOf(null) val alterationDetail: State get() = _alterationDetail fun prepareRoll(diceThrow: DiceThrow) { this.diceThrow = diceThrow + _isThrowHidden.value = diceThrow is DiceThrow.DeathSavingThrow _card.value = null sheet = characterSheetRepository.find(name = diceThrow.character) _dice.value = diceFactory.convertDiceThrow(diceThrow) @@ -95,6 +99,7 @@ class RollOverlayViewModel @Inject constructor( // roll the dice ;) val result = rollUseCase.roll( diceThrow = diceThrow, + isThrowHidden = _isThrowHidden.value, alterationId = _alterations.value.mapNotNull { if (it.checked) it.label else null }, ) // share the result @@ -123,6 +128,10 @@ class RollOverlayViewModel @Inject constructor( _showDetail.switch() } + fun onThrowVisibilityChange(hidden: Boolean) { + _isThrowHidden.value = hidden + } + fun showAlterationDetail(id: String) { val alteration = diceThrow?.character?.let { character -> alterationRepository.getAlterations(character = character).firstOrNull { it.name == id } diff --git a/app/src/main/res/drawable/ic_visibility_24.xml b/app/src/main/res/drawable/ic_visibility_24.xml new file mode 100644 index 0000000..c9e095f --- /dev/null +++ b/app/src/main/res/drawable/ic_visibility_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_visibility_off_24.xml b/app/src/main/res/drawable/ic_visibility_off_24.xml new file mode 100644 index 0000000..899a185 --- /dev/null +++ b/app/src/main/res/drawable/ic_visibility_off_24.xml @@ -0,0 +1,9 @@ + + +