From b6b135cd40de6360713c53763f7ef38ba5ea83ee Mon Sep 17 00:00:00 2001 From: Thomas Andres Gomez Date: Wed, 26 Feb 2025 17:13:47 +0100 Subject: [PATCH] Add characteristic to the campagin detail panel. --- .../lwa/ui/composable/blur/BlurContent.kt | 15 + ...cterDetailCharacteristicDialogViewModel.kt | 4 +- .../lwa/ui/screen/campaign/CampaignScreen.kt | 144 +++++-- .../campaign/player/detail/CharacterDetail.kt | 381 ++++++------------ .../player/detail/CharacterDetailFactory.kt | 97 ++++- .../player/detail/CharacterDetailViewModel.kt | 76 ++-- .../detail/CharacterDiminishedViewModel.kt | 8 +- .../detail/header/CharacterDetailHeader.kt | 156 +++++++ .../CharacterDetailSheetCharacteristic.kt | 61 +++ .../detail/sheet/CharacterDetailSheetUio.kt | 47 +++ .../lwa/ui/screen/roll/RollViewModel.kt | 30 +- .../shared/lwa/usecase/RollUseCase.kt | 2 +- 12 files changed, 690 insertions(+), 331 deletions(-) create mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/header/CharacterDetailHeader.kt create mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/sheet/CharacterDetailSheetCharacteristic.kt create mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/sheet/CharacterDetailSheetUio.kt diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/blur/BlurContent.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/blur/BlurContent.kt index 618781f..c3f3f0c 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/blur/BlurContent.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/blur/BlurContent.kt @@ -9,6 +9,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.draw.BlurredEdgeTreatment import androidx.compose.ui.draw.blur @@ -36,6 +37,20 @@ class BlurContentController( } } +@Composable +@Stable +fun rememberBlurContentController( + blurred: Boolean = false, + blurredRadius: Dp = 8.dp, + scrimColor: Color = LwaColorPalette.DefaultScrimColor, +) = remember { + BlurContentController( + blurred = blurred, + blurredRadius = blurredRadius, + scrimColor = scrimColor, + ) +} + @Composable fun BlurContent( modifier: Modifier = Modifier, diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/character/characteristic/CharacterDetailCharacteristicDialogViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/character/characteristic/CharacterDetailCharacteristicDialogViewModel.kt index 54834de..e9ba1dd 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/character/characteristic/CharacterDetailCharacteristicDialogViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/character/characteristic/CharacterDetailCharacteristicDialogViewModel.kt @@ -33,9 +33,11 @@ class CharacterDetailCharacteristicDialogViewModel( } suspend fun showSubCharacteristicDialog( - characterInstanceId: Campaign.CharacterInstance.Id, + characterInstanceId: Campaign.CharacterInstance.Id?, characteristic: Characteristic, ) { + if (characterInstanceId == null) return + val sheet: CharacterSheet? = characterSheetRepository.characterDetail( characterSheetId = characterInstanceId.characterSheetId, ) diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/CampaignScreen.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/CampaignScreen.kt index 74120dd..6aa93b2 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/CampaignScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/CampaignScreen.kt @@ -1,5 +1,11 @@ package com.pixelized.desktop.lwa.ui.screen.campaign +import androidx.compose.animation.AnimatedContent +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.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxHeight @@ -7,12 +13,14 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.material.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.key.Key @@ -25,20 +33,29 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp +import com.pixelized.desktop.lwa.ui.composable.blur.BlurContent +import com.pixelized.desktop.lwa.ui.composable.blur.rememberBlurContentController +import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterDetailCharacteristicDialogViewModel +import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialog import com.pixelized.desktop.lwa.ui.composable.key.KeyHandler -import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDetail +import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDetailPanel import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDetailViewModel import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDiminishedViewModel import com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon.PlayerRibbon import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog.DiminishedStatDialog import com.pixelized.desktop.lwa.ui.screen.network.NetworkViewModel +import com.pixelized.desktop.lwa.ui.screen.roll.RollPage +import com.pixelized.desktop.lwa.ui.screen.roll.RollViewModel +import kotlinx.coroutines.launch import org.koin.compose.viewmodel.koinViewModel @Composable fun CampaignScreen( characterDetailViewModel: CharacterDetailViewModel = koinViewModel(), + characteristicDialogViewModel: CharacterDetailCharacteristicDialogViewModel = koinViewModel(), dismissedViewModel: CharacterDiminishedViewModel = koinViewModel(), networkViewModel: NetworkViewModel = koinViewModel(), + rollViewModel: RollViewModel = koinViewModel(), ) { LaunchedEffect(Unit) { networkViewModel.connect() @@ -55,48 +72,105 @@ fun CampaignScreen( } } - Surface { - CampaignScreenLayout( + val scope = rememberCoroutineScope() + val blurController = rememberBlurContentController() + + Surface( + modifier = Modifier.fillMaxSize(), + ) { + BlurContent( modifier = Modifier.fillMaxSize(), - top = { - Surface( - modifier = Modifier - .height(32.dp) - .fillMaxWidth(), - elevation = 1.dp, - ) { + controller = blurController + ) { + CampaignScreenLayout( + modifier = Modifier.fillMaxSize(), + top = { + Surface( + modifier = Modifier + .height(32.dp) + .fillMaxWidth(), + elevation = 1.dp, + ) { - } - }, - bottom = { - Surface( - modifier = Modifier - .height(48.dp) - .fillMaxWidth(), - elevation = 1.dp, - ) { + } + }, + bottom = { + Surface( + modifier = Modifier + .height(48.dp) + .fillMaxWidth(), + elevation = 1.dp, + ) { - } - }, - main = { + } + }, + main = { + }, + leftOverlay = { + PlayerRibbon( + modifier = Modifier.fillMaxHeight(), + onCharacter = { + characterDetailViewModel.showCharacter(id = it) + }, + ) + }, + rightOverlay = { + CharacterDetailPanel( + modifier = Modifier + .width(width = 128.dp * 4) + .fillMaxHeight() + .padding(all = 8.dp), + blurController = blurController, + detailViewModel = characterDetailViewModel, + rollViewModel = rollViewModel, + characterDiminishedViewModel = dismissedViewModel, + characteristicDialogViewModel = characteristicDialogViewModel, + ) + }, + ) + } + + AnimatedContent( + modifier = Modifier.fillMaxSize(), + targetState = rollViewModel.displayOverlay.value, + transitionSpec = { + val enter = fadeIn() + slideInVertically { 64 } + val exit = fadeOut() + slideOutVertically { 64 } + enter togetherWith exit }, - leftOverlay = { - PlayerRibbon( - modifier = Modifier.fillMaxHeight(), - onCharacter = { - characterDetailViewModel.showCharacter(id = it) + ) { roll -> + when (roll) { + true -> RollPage( + viewModel = rollViewModel, + onDismissRequest = { + blurController.hide() + rollViewModel.hideOverlay() }, ) - }, - rightOverlay = { - CharacterDetail( - modifier = Modifier - .padding(all = 8.dp) - .fillMaxHeight(), - detailViewModel = characterDetailViewModel, - dismissedViewModel = dismissedViewModel, + + else -> Box( + modifier = Modifier.fillMaxSize() ) + } + } + + CharacterSheetCharacteristicDialog( + dialog = characteristicDialogViewModel.statChangeDialog, + onConfirm = { dialog -> + scope.launch { + characteristicDialogViewModel.changeSubCharacteristic( + characterInstanceId = dialog.characterInstanceId, + characteristic = dialog.characteristic, + value = dialog.value().text.toIntOrNull() ?: 0, + ) + characteristicDialogViewModel.hideSubCharacteristicDialog() + blurController.hide() + } + }, + onDismissRequest = { + characteristicDialogViewModel.hideSubCharacteristicDialog() + blurController.hide() }, ) diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetail.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetail.kt index 76099d8..71eb2e9 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetail.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetail.kt @@ -6,141 +6,150 @@ import androidx.compose.animation.ExitTransition import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.slideInHorizontally +import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.togetherWith -import androidx.compose.foundation.clickable -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.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Icon -import androidx.compose.material.IconButton +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material.MaterialTheme import androidx.compose.material.Surface -import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable +import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.pixelized.desktop.lwa.ui.composable.blur.BlurContentController import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterDetailCharacteristicDialogViewModel import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialog +import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialogUio +import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.header.CharacterDetailHeader +import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.header.CharacterDetailHeaderUio +import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.sheet.CharacterDetailSheet +import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.sheet.CharacterDetailSheetCharacteristicUio +import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.sheet.CharacterDetailSheetUio +import com.pixelized.desktop.lwa.ui.screen.roll.RollViewModel import com.pixelized.desktop.lwa.ui.theme.lwa import com.pixelized.shared.lwa.model.campaign.Campaign +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch -import lwacharactersheet.composeapp.generated.resources.Res -import lwacharactersheet.composeapp.generated.resources.ic_close_24dp -import lwacharactersheet.composeapp.generated.resources.ic_heart_24dp -import lwacharactersheet.composeapp.generated.resources.ic_near_me -import lwacharactersheet.composeapp.generated.resources.ic_skull_24dp -import lwacharactersheet.composeapp.generated.resources.ic_water_drop_24dp -import org.jetbrains.compose.resources.painterResource -import org.koin.compose.viewmodel.koinViewModel @Stable -data class CharacterDetailHeaderUio( - val id: Campaign.CharacterInstance.Id, - val portrait: String?, - val name: String, - val hp: String, - val maxHp: String, - val pp: String, - val maxPp: String, - val mov: String, +data class CharacterDetailPanelUio( + val characterInstanceId: Campaign.CharacterInstance.Id?, + val header: StateFlow, + val sheet: StateFlow, ) @Composable -fun CharacterDetail( +fun CharacterDetailPanel( modifier: Modifier = Modifier, - dismissedViewModel: CharacterDiminishedViewModel, - detailViewModel: CharacterDetailViewModel = koinViewModel(), - characteristicDialogViewModel: CharacterDetailCharacteristicDialogViewModel = koinViewModel(), + blurController: BlurContentController, + detailViewModel: CharacterDetailViewModel, + characteristicDialogViewModel: CharacterDetailCharacteristicDialogViewModel, + characterDiminishedViewModel: CharacterDiminishedViewModel, + rollViewModel: RollViewModel, ) { - val blurController = remember { BlurContentController() } val scope = rememberCoroutineScope() - val detail = detailViewModel.detail.collectAsState() + val detail: State = detailViewModel.detail.collectAsState() - AnimatedContent( + CharacterDetailAnimatedPanel( modifier = modifier, - targetState = detail.value, - transitionSpec = { - if (initialState?.id != targetState?.id) { - (fadeIn() + slideInHorizontally { it / 2 }).togetherWith(fadeOut()) - } else { - EnterTransition.None togetherWith ExitTransition.None + detail = detail, + onDismissRequest = { + detailViewModel.hideCharacter() + }, + onDiminished = { + scope.launch { + characterDiminishedViewModel.showDiminishedDialog( + characterInstanceId = it + ) } - } - ) { - when (it) { - null -> Box( - modifier = Modifier.fillMaxHeight(), + }, + onHp = { + scope.launch { + blurController.show() + characteristicDialogViewModel.showSubCharacteristicDialog( + characterInstanceId = it, + characteristic = Campaign.CharacterInstance.Characteristic.Damage, + ) + } + }, + onPp = { + scope.launch { + blurController.show() + characteristicDialogViewModel.showSubCharacteristicDialog( + characterInstanceId = it, + characteristic = Campaign.CharacterInstance.Characteristic.Power, + ) + } + }, + onCharacteristic = { + rollViewModel.prepareRoll( + characterSheetId = detail.value.characterInstanceId?.characterSheetId!!, + label = it.label, + rollAction = "1d100", + rollSuccessValue = (it.value.toIntOrNull() ?: 0) * 5, ) + blurController.show() + rollViewModel.showOverlay() + }, + ) +} - else -> { - Box( - modifier = Modifier - .fillMaxHeight() - .width(width = 128.dp * 4), - ) { - CharacterDetailContent( +@Composable +fun CharacterDetailAnimatedPanel( + modifier: Modifier = Modifier, + detail: State, + onDismissRequest: (id: Campaign.CharacterInstance.Id) -> Unit, + onDiminished: (id: Campaign.CharacterInstance.Id) -> Unit, + onHp: (id: Campaign.CharacterInstance.Id) -> Unit, + onPp: (id: Campaign.CharacterInstance.Id) -> Unit, + onCharacteristic: (CharacterDetailSheetCharacteristicUio) -> Unit, +) { + Box( + modifier = modifier, + ) { + AnimatedContent( + modifier = Modifier.matchParentSize(), + targetState = detail.value, + transitionSpec = { + if (initialState.characterInstanceId != targetState.characterInstanceId) { + val enter = fadeIn() + slideInHorizontally { it / 2 } + val exit = fadeOut() + slideOutHorizontally { it / 2 } + enter togetherWith exit + } else { + EnterTransition.None togetherWith ExitTransition.None + } + } + ) { + when { + it.characterInstanceId == null -> Box( + modifier = Modifier.matchParentSize(), + ) + + else -> { + Box( modifier = Modifier.matchParentSize(), - character = it, - onDismissRequest = { - detailViewModel.hideCharacter() - }, - onDiminished = { - scope.launch { - dismissedViewModel.showDiminishedDialog(id = it.id) - } - }, - onHp = { - scope.launch { - characteristicDialogViewModel.showSubCharacteristicDialog( - characterInstanceId = it.id, - characteristic = Campaign.CharacterInstance.Characteristic.Damage, - ) - } - }, - onPp = { - scope.launch { - characteristicDialogViewModel.showSubCharacteristicDialog( - characterInstanceId = it.id, - characteristic = Campaign.CharacterInstance.Characteristic.Power, - ) - } - }, - ) - CharacterSheetCharacteristicDialog( - dialog = characteristicDialogViewModel.statChangeDialog, - onConfirm = { dialog -> - scope.launch { - characteristicDialogViewModel.changeSubCharacteristic( - characterInstanceId = dialog.characterInstanceId, - characteristic = dialog.characteristic, - value = dialog.value().text.toIntOrNull() ?: 0, - ) - characteristicDialogViewModel.hideSubCharacteristicDialog() - blurController.hide() - } - }, - onDismissRequest = { - characteristicDialogViewModel.hideSubCharacteristicDialog() - blurController.hide() - } - ) + ) { + CharacterDetailContent( + modifier = Modifier.matchParentSize(), + header = it.header.collectAsState(), + sheet = it.sheet.collectAsState(), + onDismissRequest = { onDismissRequest(it.characterInstanceId) }, + onDiminished = { onDiminished(it.characterInstanceId) }, + onHp = { onHp(it.characterInstanceId) }, + onPp = { onPp(it.characterInstanceId) }, + onCharacteristic = onCharacteristic, + ) + } } } } @@ -150,169 +159,35 @@ fun CharacterDetail( @Composable fun CharacterDetailContent( modifier: Modifier = Modifier, - character: CharacterDetailHeaderUio, + header: State, + sheet: State, onDismissRequest: () -> Unit, onDiminished: () -> Unit, onHp: () -> Unit, onPp: () -> Unit, -) { - Box( - modifier = modifier, - ) { - Background( - character = character, - ) - Column { - CharacterHeader( - modifier = Modifier.padding(start = 16.dp).fillMaxWidth(), - character = character, - onDismissRequest = onDismissRequest, - onDiminished = onDiminished, - onHp = onHp, - onPp = onPp, - ) - } - } -} - -@Composable -private fun Background( - modifier: Modifier = Modifier, - character: CharacterDetailHeaderUio, + onCharacteristic: (CharacterDetailSheetCharacteristicUio) -> Unit, ) { Surface( modifier = modifier.fillMaxSize(), color = MaterialTheme.lwa.colorScheme.elevatedSurface, ) { -// Image( -// modifier = Modifier.fillMaxSize().drawWithContent { -// drawContent() -// drawRect( -// brush = Brush.verticalGradient( -// listOfNotNull( -// color?.copy(alpha = 0.7f), -// color, -// ) -// ) -// ) -// }, -// painter = rememberAsyncImagePainter(model = character.portrait), -// contentDescription = null, -// contentScale = ContentScale.Crop, -// alignment = Alignment.TopCenter, -// ) - } -} - -@Composable -private fun CharacterHeader( - modifier: Modifier = Modifier, - character: CharacterDetailHeaderUio, - onDismissRequest: () -> Unit, - onDiminished: () -> Unit, - onHp: () -> Unit, - onPp: () -> Unit, -) { - Column( - modifier = modifier, - ) { - Row { - Text( - modifier = Modifier.weight(1f) - .align(alignment = Alignment.CenterVertically), - style = MaterialTheme.typography.h5, - text = character.name, - overflow = TextOverflow.Ellipsis, - maxLines = 1, + Column { + CharacterDetailHeader( + modifier = Modifier.padding(start = 16.dp).fillMaxWidth(), + header = header, + onDismissRequest = onDismissRequest, + onDiminished = onDiminished, + onHp = onHp, + onPp = onPp, + ) + CharacterDetailSheet( + modifier = Modifier + .weight(1f) + .verticalScroll(state = rememberScrollState()) + .padding(all = 16.dp), + sheet = sheet, + onCharacteristic = onCharacteristic, ) - IconButton( - onClick = onDiminished, - ) { - Icon( - modifier = Modifier.size(size = 24.dp), - painter = painterResource(Res.drawable.ic_skull_24dp), - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) - } - IconButton( - onClick = onDismissRequest, - ) { - Icon( - painter = painterResource(Res.drawable.ic_close_24dp), - tint = MaterialTheme.lwa.colorScheme.base.primary, - contentDescription = null, - ) - } - } - Row( - horizontalArrangement = Arrangement.spacedBy(space = 12.dp), - ) { - Row( - modifier = Modifier.clip(shape = CircleShape).clickable { onHp() }, - verticalAlignment = Alignment.Bottom, - ) { - Icon( - modifier = Modifier.padding(bottom = 4.dp, end = 2.dp).size(12.dp), - painter = painterResource(Res.drawable.ic_heart_24dp), - contentDescription = null - ) - Text( - modifier = Modifier.alignByBaseline(), - style = MaterialTheme.typography.h6, - color = MaterialTheme.lwa.colorScheme.base.primary, - fontWeight = FontWeight.Bold, - text = character.hp, - ) - Text( - modifier = Modifier.alignByBaseline(), - style = MaterialTheme.typography.caption, - fontWeight = FontWeight.Thin, - text = "/${character.maxHp}", - ) - } - Row( - modifier = Modifier.clip(shape = CircleShape).clickable { onPp() }, - verticalAlignment = Alignment.Bottom, - ) { - Icon( - modifier = Modifier.padding(bottom = 4.dp, end = 2.dp).size(12.dp), - painter = painterResource(Res.drawable.ic_water_drop_24dp), - contentDescription = null - ) - Text( - modifier = Modifier.alignByBaseline(), - style = MaterialTheme.typography.h6, - color = MaterialTheme.lwa.colorScheme.base.primary, - fontWeight = FontWeight.Bold, - text = character.pp, - ) - Text( - modifier = Modifier.alignByBaseline(), - style = MaterialTheme.typography.caption, - fontWeight = FontWeight.Thin, - text = "/${character.maxPp}", - ) - } - Row( - verticalAlignment = Alignment.Bottom, - ) { - Icon( - modifier = Modifier.padding(bottom = 4.dp, end = 2.dp).size(12.dp), - painter = painterResource(Res.drawable.ic_near_me), - contentDescription = null, - ) - Text( - modifier = Modifier.alignByBaseline(), - style = MaterialTheme.typography.h6, - text = character.mov, - ) - Text( - modifier = Modifier.alignByBaseline(), - style = MaterialTheme.typography.caption, - text = "m", - ) - } } } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailFactory.kt index a29ad35..809bb89 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailFactory.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailFactory.kt @@ -1,16 +1,35 @@ package com.pixelized.desktop.lwa.ui.screen.campaign.player.detail +import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio +import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.header.CharacterDetailHeaderUio +import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.sheet.CharacterDetailSheetCharacteristicUio +import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.sheet.CharacterDetailSheetUio import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory import com.pixelized.shared.lwa.model.alteration.FieldAlteration import com.pixelized.shared.lwa.model.campaign.Campaign import com.pixelized.shared.lwa.model.campaign.damage import com.pixelized.shared.lwa.model.campaign.power import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet +import lwacharactersheet.composeapp.generated.resources.Res +import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__cha +import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__con +import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__dex +import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__hei +import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__int +import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__pow +import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__str +import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__charisma +import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__constitution +import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__dexterity +import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__height +import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__intelligence +import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__power +import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__strength +import org.jetbrains.compose.resources.getString class CharacterDetailFactory( private val alteredCharacterSheetFactory: AlteredCharacterSheetFactory, ) { - fun convertToCharacterDetailHeaderUio( characterInstanceId: Campaign.CharacterInstance.Id, characterSheet: CharacterSheet?, @@ -38,4 +57,80 @@ class CharacterDetailFactory( mov = "${alteredCharacterSheet.movement}" ) } + + suspend fun convertToCharacterDetailSheetUio( + characterInstanceId: Campaign.CharacterInstance.Id, + characterSheet: CharacterSheet?, + characterInstance: Campaign.CharacterInstance, + alterations: Map>, + ): CharacterDetailSheetUio? { + if (characterSheet == null) return null + + val alteredCharacterSheet = alteredCharacterSheetFactory.sheet( + characterSheet = characterSheet, + alterations = alterations, + ) + + return CharacterDetailSheetUio( + characterInstanceId = characterInstanceId, + characteristics = listOf( + CharacterDetailSheetCharacteristicUio( + label = getString(Res.string.character_sheet__characteristics__str), + value = "${alteredCharacterSheet.strength}", + tooltips = TooltipUio( + title = getString(Res.string.character_sheet__characteristics__str), + description = getString(Res.string.tooltip__characteristics__strength), + ), + ), + CharacterDetailSheetCharacteristicUio( + label = getString(Res.string.character_sheet__characteristics__dex), + value = "${alteredCharacterSheet.dexterity}", + tooltips = TooltipUio( + title = getString(Res.string.character_sheet__characteristics__dex), + description = getString(Res.string.tooltip__characteristics__dexterity), + ), + ), + CharacterDetailSheetCharacteristicUio( + label = getString(Res.string.character_sheet__characteristics__con), + value = "${alteredCharacterSheet.constitution}", + tooltips = TooltipUio( + title = getString(Res.string.character_sheet__characteristics__con), + description = getString(Res.string.tooltip__characteristics__constitution), + ), + ), + CharacterDetailSheetCharacteristicUio( + label = getString(Res.string.character_sheet__characteristics__hei), + value = "${alteredCharacterSheet.height}", + tooltips = TooltipUio( + title = getString(Res.string.character_sheet__characteristics__hei), + description = getString(Res.string.tooltip__characteristics__height), + ), + ), + CharacterDetailSheetCharacteristicUio( + label = getString(Res.string.character_sheet__characteristics__int), + value = "${alteredCharacterSheet.intelligence}", + tooltips = TooltipUio( + title = getString(Res.string.character_sheet__characteristics__int), + description = getString(Res.string.tooltip__characteristics__intelligence), + ), + ), + CharacterDetailSheetCharacteristicUio( + label = getString(Res.string.character_sheet__characteristics__pow), + value = "${alteredCharacterSheet.power}", + tooltips = TooltipUio( + title = getString(Res.string.character_sheet__characteristics__pow), + description = getString(Res.string.tooltip__characteristics__power), + ), + ), + CharacterDetailSheetCharacteristicUio( + label = getString(Res.string.character_sheet__characteristics__cha), + value = "${alteredCharacterSheet.charisma}", + tooltips = TooltipUio( + title = getString(Res.string.character_sheet__characteristics__cha), + description = getString(Res.string.tooltip__characteristics__charisma), + ), + ), + ) + ) + } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailViewModel.kt index a7edc53..fb7fa88 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailViewModel.kt @@ -6,13 +6,11 @@ import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository import com.pixelized.shared.lwa.model.campaign.Campaign -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn class CharacterDetailViewModel( @@ -24,32 +22,50 @@ class CharacterDetailViewModel( private val displayedCharacterId = MutableStateFlow(null) - @OptIn(ExperimentalCoroutinesApi::class) - val detail: StateFlow = displayedCharacterId - .flatMapLatest { characterInstanceId -> - if (characterInstanceId != null) { - campaignRepository - .characterInstanceFlow(id = characterInstanceId) - .flatMapLatest { characterInstance -> - combine( - characterSheetRepository.characterDetailFlow(characterId = characterInstanceId.characterSheetId), - alterationRepository.alterationsFlow(characterId = characterInstanceId), - ) { characterSheet, alterations -> - characterDetailFactory.convertToCharacterDetailHeaderUio( - characterInstanceId = characterInstanceId, - characterSheet = characterSheet, - characterInstance = characterInstance, - alterations = alterations, - ) - } - } - } else { - flowOf(null) - } - }.stateIn( + val detail: StateFlow = displayedCharacterId + .map { characterInstanceId -> + if (characterInstanceId == null) return@map empty() + + CharacterDetailPanelUio( + characterInstanceId = characterInstanceId, + header = combine( + campaignRepository.characterInstanceFlow(id = characterInstanceId), + characterSheetRepository.characterDetailFlow(characterId = characterInstanceId.characterSheetId), + alterationRepository.alterationsFlow(characterId = characterInstanceId), + ) { characterInstance, characterSheet, alterations -> + characterDetailFactory.convertToCharacterDetailHeaderUio( + characterInstanceId = characterInstanceId, + characterSheet = characterSheet, + characterInstance = characterInstance, + alterations = alterations, + ) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.Eagerly, + initialValue = null, + ), + sheet = combine( + campaignRepository.characterInstanceFlow(id = characterInstanceId), + characterSheetRepository.characterDetailFlow(characterId = characterInstanceId.characterSheetId), + alterationRepository.alterationsFlow(characterId = characterInstanceId), + ) { characterInstance, characterSheet, alterations -> + characterDetailFactory.convertToCharacterDetailSheetUio( + characterInstanceId = characterInstanceId, + characterSheet = characterSheet, + characterInstance = characterInstance, + alterations = alterations, + ) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.Eagerly, + initialValue = null, + ), + ) + } + .stateIn( scope = viewModelScope, started = SharingStarted.Eagerly, - initialValue = null, + initialValue = empty(), ) fun showCharacter(id: Campaign.CharacterInstance.Id) { @@ -59,4 +75,10 @@ class CharacterDetailViewModel( fun hideCharacter() { displayedCharacterId.value = null } + + private fun empty() = CharacterDetailPanelUio( + characterInstanceId = null, + header = MutableStateFlow(null), + sheet = MutableStateFlow(null), + ) } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDiminishedViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDiminishedViewModel.kt index 748a436..0243695 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDiminishedViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDiminishedViewModel.kt @@ -20,14 +20,16 @@ class CharacterDiminishedViewModel( val diminishedDialog: State get() = _diminishedDialog suspend fun showDiminishedDialog( - id: Campaign.CharacterInstance.Id, + characterInstanceId: Campaign.CharacterInstance.Id?, ) { + if (characterInstanceId == null) return + val diminished = 0 // TODO repository.characterDiminishedFlow(id = id).value val textFieldValue = mutableStateOf( TextFieldValue("$diminished", selection = TextRange(index = 0)) ) _diminishedDialog.value = DiminishedStatDialogUio( - id = id, + id = characterInstanceId, label = getString(resource = Res.string.character_sheet__diminished__label), value = { textFieldValue.value }, onValueChange = { value -> @@ -51,6 +53,4 @@ class CharacterDiminishedViewModel( // diminished = value, // ) } - - } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/header/CharacterDetailHeader.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/header/CharacterDetailHeader.kt new file mode 100644 index 0000000..75f8866 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/header/CharacterDetailHeader.kt @@ -0,0 +1,156 @@ +package com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.header + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.State +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import com.pixelized.desktop.lwa.ui.theme.lwa +import com.pixelized.shared.lwa.model.campaign.Campaign +import lwacharactersheet.composeapp.generated.resources.Res +import lwacharactersheet.composeapp.generated.resources.ic_close_24dp +import lwacharactersheet.composeapp.generated.resources.ic_heart_24dp +import lwacharactersheet.composeapp.generated.resources.ic_near_me +import lwacharactersheet.composeapp.generated.resources.ic_skull_24dp +import lwacharactersheet.composeapp.generated.resources.ic_water_drop_24dp +import org.jetbrains.compose.resources.painterResource + +@Stable +data class CharacterDetailHeaderUio( + val id: Campaign.CharacterInstance.Id, + val portrait: String?, + val name: String, + val hp: String, + val maxHp: String, + val pp: String, + val maxPp: String, + val mov: String, +) + +@Composable +fun CharacterDetailHeader( + modifier: Modifier = Modifier, + header: State, + onDismissRequest: () -> Unit, + onDiminished: () -> Unit, + onHp: () -> Unit, + onPp: () -> Unit, +) { + Column( + modifier = modifier, + ) { + Row { + Text( + modifier = Modifier.weight(1f) + .align(alignment = Alignment.CenterVertically), + style = MaterialTheme.typography.h5, + text = header.value?.name ?: "", + overflow = TextOverflow.Ellipsis, + maxLines = 1, + ) + IconButton( + onClick = onDiminished, + ) { + Icon( + modifier = Modifier.size(size = 24.dp), + painter = painterResource(Res.drawable.ic_skull_24dp), + tint = MaterialTheme.colors.primary, + contentDescription = null, + ) + } + IconButton( + onClick = onDismissRequest, + ) { + Icon( + painter = painterResource(Res.drawable.ic_close_24dp), + tint = MaterialTheme.lwa.colorScheme.base.primary, + contentDescription = null, + ) + } + } + Row( + horizontalArrangement = Arrangement.spacedBy(space = 12.dp), + ) { + Row( + modifier = Modifier.clip(shape = CircleShape).clickable { onHp() }, + verticalAlignment = Alignment.Bottom, + ) { + Icon( + modifier = Modifier.padding(bottom = 4.dp, end = 2.dp).size(12.dp), + painter = painterResource(Res.drawable.ic_heart_24dp), + contentDescription = null + ) + Text( + modifier = Modifier.alignByBaseline(), + style = MaterialTheme.typography.h6, + color = MaterialTheme.lwa.colorScheme.base.primary, + fontWeight = FontWeight.Bold, + text = header.value?.hp ?: "", + ) + Text( + modifier = Modifier.alignByBaseline(), + style = MaterialTheme.typography.caption, + fontWeight = FontWeight.Thin, + text = "/${header.value?.maxHp ?: ""}", + ) + } + Row( + modifier = Modifier.clip(shape = CircleShape).clickable { onPp() }, + verticalAlignment = Alignment.Bottom, + ) { + Icon( + modifier = Modifier.padding(bottom = 4.dp, end = 2.dp).size(12.dp), + painter = painterResource(Res.drawable.ic_water_drop_24dp), + contentDescription = null + ) + Text( + modifier = Modifier.alignByBaseline(), + style = MaterialTheme.typography.h6, + color = MaterialTheme.lwa.colorScheme.base.primary, + fontWeight = FontWeight.Bold, + text = header.value?.pp ?: "", + ) + Text( + modifier = Modifier.alignByBaseline(), + style = MaterialTheme.typography.caption, + fontWeight = FontWeight.Thin, + text = "/${header.value?.maxPp ?: ""}", + ) + } + Row( + verticalAlignment = Alignment.Bottom, + ) { + Icon( + modifier = Modifier.padding(bottom = 4.dp, end = 2.dp).size(12.dp), + painter = painterResource(Res.drawable.ic_near_me), + contentDescription = null, + ) + Text( + modifier = Modifier.alignByBaseline(), + style = MaterialTheme.typography.h6, + text = header.value?.mov ?: "", + ) + Text( + modifier = Modifier.alignByBaseline(), + style = MaterialTheme.typography.caption, + text = "m", + ) + } + } + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/sheet/CharacterDetailSheetCharacteristic.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/sheet/CharacterDetailSheetCharacteristic.kt new file mode 100644 index 0000000..6cfaa8a --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/sheet/CharacterDetailSheetCharacteristic.kt @@ -0,0 +1,61 @@ +package com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.sheet + +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox +import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipLayout +import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio + +@Stable +data class CharacterDetailSheetCharacteristicUio( + val value: String, + val label: String, + val tooltips: TooltipUio?, +) + +@OptIn(ExperimentalFoundationApi::class) +@Composable +fun CharacterDetailSheetCharacteristic( + modifier: Modifier = Modifier, + paddingValues: PaddingValues = PaddingValues(all = 8.dp), + characteristic: CharacterDetailSheetCharacteristicUio, + onClick: () -> Unit, +) { + TooltipLayout( + tooltip = characteristic.tooltips, + content = { + DecoratedBox( + modifier = Modifier + .clickable(onClick = onClick) + .padding(paddingValues = paddingValues) + .then(other = modifier), + ) { + Text( + modifier = Modifier.align(alignment = Alignment.TopCenter), + style = MaterialTheme.typography.caption, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + text = characteristic.label, + ) + Text( + modifier = Modifier.align(alignment = Alignment.Center), + style = MaterialTheme.typography.h3, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + color = MaterialTheme.colors.primary, + text = characteristic.value + ) + } + }, + ) +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/sheet/CharacterDetailSheetUio.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/sheet/CharacterDetailSheetUio.kt new file mode 100644 index 0000000..23696d1 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/sheet/CharacterDetailSheetUio.kt @@ -0,0 +1,47 @@ +package com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.sheet + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.State +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.pixelized.shared.lwa.model.campaign.Campaign + +@Stable +data class CharacterDetailSheetUio( + val characterInstanceId: Campaign.CharacterInstance.Id, + val characteristics: List, +) + +@Composable +fun CharacterDetailSheet( + modifier: Modifier = Modifier, + sheet: State, + onCharacteristic: (CharacterDetailSheetCharacteristicUio) -> Unit, +) { + Row( + modifier = modifier + ) { + Column( + verticalArrangement = Arrangement.spacedBy(space = 8.dp) + ) { + sheet.value?.characteristics?.forEach { + CharacterDetailSheetCharacteristic( + modifier = Modifier.size(width = 80.dp, height = 120.dp), + characteristic = it, + onClick = { onCharacteristic(it) }, + ) + } + } + Column( + verticalArrangement = Arrangement.spacedBy(space = 8.dp) + ) { + + } + } +} + diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/roll/RollViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/roll/RollViewModel.kt index 6104ba5..a314dc9 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/roll/RollViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/roll/RollViewModel.kt @@ -6,13 +6,13 @@ import androidx.compose.animation.core.spring import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel -import com.pixelized.shared.lwa.usecase.ExpressionUseCase -import com.pixelized.shared.lwa.usecase.SkillStepUseCase import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetPageUio import com.pixelized.desktop.lwa.ui.screen.roll.DifficultyUio.Difficulty import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet +import com.pixelized.shared.lwa.usecase.ExpressionUseCase +import com.pixelized.shared.lwa.usecase.SkillStepUseCase import kotlinx.coroutines.Job import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay @@ -55,13 +55,17 @@ class RollViewModel( private val _rollDifficulty = mutableStateOf(null) val rollDifficulty: State get() = _rollDifficulty + private val _displayOverlay = mutableStateOf(false) + val displayOverlay: State get() = _displayOverlay + fun prepareRoll( sheet: CharacterSheetPageUio, characteristic: CharacterSheetPageUio.Characteristic, ) { - val diminished = 0 // TODO characterSheetRepository.characterDiminishedFlow(id = sheet.id).value + val diminished = + 0 // TODO characterSheetRepository.characterDiminishedFlow(id = sheet.id).value prepareRoll( - sheet = sheet, + characterSheetId = sheet.id, label = characteristic.label, rollAction = "1d100", rollSuccessValue = (characteristic.value.toIntOrNull() ?: 0) * 5 - diminished, @@ -73,7 +77,7 @@ class RollViewModel( node: CharacterSheetPageUio.Node, ) { prepareRoll( - sheet = sheet, + characterSheetId = sheet.id, label = node.label, rollAction = "1d100", rollSuccessValue = node.value, @@ -85,15 +89,15 @@ class RollViewModel( roll: CharacterSheetPageUio.Roll, ) { prepareRoll( - sheet = sheet, + characterSheetId = sheet.id, label = roll.label, rollAction = roll.value, rollSuccessValue = null, ) } - private fun prepareRoll( - sheet: CharacterSheetPageUio, + fun prepareRoll( + characterSheetId: String, label: String, rollAction: String, rollSuccessValue: Int?, @@ -101,7 +105,7 @@ class RollViewModel( this.sheet = runBlocking { rollRotation.snapTo(0f) rollScale.snapTo(1f) - characterSheetRepository.characterDetail(characterSheetId = sheet.id)!! + characterSheetRepository.characterDetail(characterSheetId = characterSheetId)!! } this.rollAction = rollAction @@ -238,4 +242,12 @@ class RollViewModel( value = rollStep?.success?.last ) } + + fun showOverlay() { + _displayOverlay.value = true + } + + fun hideOverlay() { + _displayOverlay.value = false + } } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/usecase/RollUseCase.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/usecase/RollUseCase.kt index f7e1bf2..f66ffd8 100644 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/usecase/RollUseCase.kt +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/usecase/RollUseCase.kt @@ -59,7 +59,7 @@ class RollUseCase { if (quantity > 1 && left != 1) print(",") } }.also { - print("}") + println("}") } }