Add characteristic to the campagin detail panel.
This commit is contained in:
		
							parent
							
								
									29747dcb5c
								
							
						
					
					
						commit
						b6b135cd40
					
				
					 12 changed files with 690 additions and 331 deletions
				
			
		| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
        )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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()
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<CharacterDetailHeaderUio?>,
 | 
			
		||||
    val sheet: StateFlow<CharacterDetailSheetUio?>,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@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<CharacterDetailPanelUio> = 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<CharacterDetailPanelUio>,
 | 
			
		||||
    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<CharacterDetailHeaderUio?>,
 | 
			
		||||
    sheet: State<CharacterDetailSheetUio?>,
 | 
			
		||||
    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",
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<String, List<FieldAlteration>>,
 | 
			
		||||
    ): 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),
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<Campaign.CharacterInstance.Id?>(null)
 | 
			
		||||
 | 
			
		||||
    @OptIn(ExperimentalCoroutinesApi::class)
 | 
			
		||||
    val detail: StateFlow<CharacterDetailHeaderUio?> = 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<CharacterDetailPanelUio> = 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),
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -20,14 +20,16 @@ class CharacterDiminishedViewModel(
 | 
			
		|||
    val diminishedDialog: State<DiminishedStatDialogUio?> 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,
 | 
			
		||||
//        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<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 = 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",
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<CharacterDetailSheetCharacteristicUio>,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun CharacterDetailSheet(
 | 
			
		||||
    modifier: Modifier = Modifier,
 | 
			
		||||
    sheet: State<CharacterDetailSheetUio?>,
 | 
			
		||||
    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)
 | 
			
		||||
        ) {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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<DifficultyUio?>(null)
 | 
			
		||||
    val rollDifficulty: State<DifficultyUio?> get() = _rollDifficulty
 | 
			
		||||
 | 
			
		||||
    private val _displayOverlay = mutableStateOf(false)
 | 
			
		||||
    val displayOverlay: State<Boolean> 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
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue