Add character portrait display feature.
This commit is contained in:
parent
50c34c8520
commit
67e154ed4a
18 changed files with 214 additions and 20 deletions
|
|
@ -52,11 +52,11 @@ import com.pixelized.desktop.lwa.ui.navigation.window.destination.RollHistoryWin
|
||||||
import com.pixelized.desktop.lwa.ui.navigation.window.rememberMaxWindowHeight
|
import com.pixelized.desktop.lwa.ui.navigation.window.rememberMaxWindowHeight
|
||||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollHostState
|
import com.pixelized.desktop.lwa.ui.overlay.roll.RollHostState
|
||||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollOverlay
|
import com.pixelized.desktop.lwa.ui.overlay.roll.RollOverlay
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.CharacterPortraitDefault
|
|
||||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.CharacterSheetMainNavHost
|
import com.pixelized.desktop.lwa.ui.screen.characterSheet.CharacterSheetMainNavHost
|
||||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.GameMasterScreen
|
import com.pixelized.desktop.lwa.ui.screen.gamemaster.GameMasterScreen
|
||||||
import com.pixelized.desktop.lwa.ui.screen.rollhistory.RollHistoryPage
|
import com.pixelized.desktop.lwa.ui.screen.rollhistory.RollHistoryPage
|
||||||
import com.pixelized.desktop.lwa.ui.theme.LwaTheme
|
import com.pixelized.desktop.lwa.ui.theme.LwaTheme
|
||||||
|
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||||
import com.pixelized.desktop.lwa.utils.InstallCoil
|
import com.pixelized.desktop.lwa.utils.InstallCoil
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
@ -108,7 +108,7 @@ fun ApplicationScope.LwaApplication() {
|
||||||
size = DpSize(
|
size = DpSize(
|
||||||
width = 800.dp,
|
width = 800.dp,
|
||||||
height = min(
|
height = min(
|
||||||
a = 56.dp + CharacterPortraitDefault.size.height * 6 + 8.dp * 7 + 40.dp,
|
a = 56.dp + 128.dp * 6 + 8.dp * 7 + 40.dp, // 128 is the height of a minimized portrait.
|
||||||
b = maxWindowHeight,
|
b = maxWindowHeight,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
|
||||||
import com.pixelized.desktop.lwa.repository.settings.SettingsStore
|
import com.pixelized.desktop.lwa.repository.settings.SettingsStore
|
||||||
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterDetailCharacteristicDialogViewModel
|
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterDetailCharacteristicDialogViewModel
|
||||||
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialogFactory
|
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialogFactory
|
||||||
|
import com.pixelized.desktop.lwa.ui.overlay.portrait.PortraitOverlayViewModel
|
||||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollViewModel
|
import com.pixelized.desktop.lwa.ui.overlay.roll.RollViewModel
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.network.NetworkFactory
|
import com.pixelized.desktop.lwa.ui.screen.campaign.network.NetworkFactory
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.network.NetworkViewModel
|
import com.pixelized.desktop.lwa.ui.screen.campaign.network.NetworkViewModel
|
||||||
|
|
@ -138,6 +139,7 @@ val viewModelDependencies
|
||||||
viewModelOf(::SettingsViewModel)
|
viewModelOf(::SettingsViewModel)
|
||||||
viewModelOf(::LevelUpViewModel)
|
viewModelOf(::LevelUpViewModel)
|
||||||
viewModelOf(::GameMasterViewModel)
|
viewModelOf(::GameMasterViewModel)
|
||||||
|
viewModelOf(::PortraitOverlayViewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
val useCaseDependencies
|
val useCaseDependencies
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,8 @@ class CampaignRepository(
|
||||||
initialValue = campaignFlow.value.character(id = characterInstanceId),
|
initialValue = campaignFlow.value.character(id = characterInstanceId),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@Deprecated(message = "Check if deprecated")
|
|
||||||
|
|
||||||
|
@Deprecated(message = "Check if deprecated")
|
||||||
fun characterInstance(
|
fun characterInstance(
|
||||||
characterInstanceId: Campaign.CharacterInstance.Id,
|
characterInstanceId: Campaign.CharacterInstance.Id,
|
||||||
): Campaign.CharacterInstance {
|
): Campaign.CharacterInstance {
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||||
import com.pixelized.shared.lwa.model.campaign.character
|
import com.pixelized.shared.lwa.model.campaign.character
|
||||||
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
|
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
|
||||||
import com.pixelized.shared.lwa.model.campaign.npc
|
import com.pixelized.shared.lwa.model.campaign.npc
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
|
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.GameMasterEvent
|
import com.pixelized.shared.lwa.protocol.websocket.GameMasterEvent
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||||
|
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
|
||||||
import com.pixelized.shared.lwa.usecase.CampaignUseCase
|
import com.pixelized.shared.lwa.usecase.CampaignUseCase
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
package com.pixelized.desktop.lwa.ui.overlay.portrait
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedContent
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.fadeIn
|
||||||
|
import androidx.compose.animation.fadeOut
|
||||||
|
import androidx.compose.animation.togetherWith
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.IconButton
|
||||||
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.State
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
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.graphics.FilterQuality
|
||||||
|
import coil3.compose.AsyncImage
|
||||||
|
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.ic_cancel_24dp
|
||||||
|
import org.jetbrains.compose.resources.painterResource
|
||||||
|
import org.koin.compose.viewmodel.koinViewModel
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PortraitOverlay(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
viewModel: PortraitOverlayViewModel = koinViewModel(),
|
||||||
|
) {
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
val portrait = viewModel.portrait.collectAsState()
|
||||||
|
val isGameMaster = viewModel.isGameMaster.collectAsState()
|
||||||
|
|
||||||
|
PortraitContent(
|
||||||
|
modifier = modifier,
|
||||||
|
portrait = portrait,
|
||||||
|
isGameMaster = isGameMaster,
|
||||||
|
onGameMaster = {
|
||||||
|
scope.launch {
|
||||||
|
viewModel.dismissPortrait()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun PortraitContent(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
portrait: State<String?>,
|
||||||
|
isGameMaster: State<Boolean>,
|
||||||
|
onGameMaster: () -> Unit,
|
||||||
|
) {
|
||||||
|
AnimatedContent(
|
||||||
|
modifier = Modifier
|
||||||
|
.clip(shape = MaterialTheme.lwa.shapes.portrait)
|
||||||
|
.then(other = modifier),
|
||||||
|
targetState = portrait.value,
|
||||||
|
transitionSpec = {
|
||||||
|
fadeIn() togetherWith fadeOut()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
when (it) {
|
||||||
|
null -> Box(
|
||||||
|
modifier = Modifier.size(MaterialTheme.lwa.size.portrait.maximized)
|
||||||
|
)
|
||||||
|
|
||||||
|
else -> Box(
|
||||||
|
modifier = Modifier.size(MaterialTheme.lwa.size.portrait.maximized)
|
||||||
|
) {
|
||||||
|
AsyncImage(
|
||||||
|
modifier = Modifier.matchParentSize(),
|
||||||
|
model = it,
|
||||||
|
filterQuality = FilterQuality.High,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
|
||||||
|
AnimatedVisibility(
|
||||||
|
modifier = Modifier.align(alignment = Alignment.TopEnd),
|
||||||
|
visible = isGameMaster.value,
|
||||||
|
enter = fadeIn(),
|
||||||
|
exit = fadeOut(),
|
||||||
|
) {
|
||||||
|
IconButton(
|
||||||
|
onClick = onGameMaster,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(Res.drawable.ic_cancel_24dp),
|
||||||
|
tint = MaterialTheme.lwa.colorScheme.base.primary,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.pixelized.desktop.lwa.ui.overlay.portrait
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
||||||
|
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||||
|
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
|
||||||
|
import com.pixelized.shared.lwa.protocol.websocket.GameEvent
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.mapNotNull
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
|
||||||
|
class PortraitOverlayViewModel(
|
||||||
|
private val networkRepository: NetworkRepository,
|
||||||
|
settingsRepository: SettingsRepository,
|
||||||
|
characterSheetRepository: CharacterSheetRepository,
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
val portrait = networkRepository.data
|
||||||
|
.mapNotNull { it as? GameEvent.DisplayPortrait }
|
||||||
|
.flatMapLatest { characterSheetRepository.characterDetailFlow(characterSheetId = it.characterSheetId) }
|
||||||
|
.map { it?.portrait }
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.Eagerly,
|
||||||
|
initialValue = null
|
||||||
|
)
|
||||||
|
|
||||||
|
val isGameMaster = settingsRepository.settingsFlow()
|
||||||
|
.map { settings -> settings.isGameMaster ?: false }
|
||||||
|
.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.Eagerly,
|
||||||
|
initialValue = false
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun dismissPortrait() {
|
||||||
|
networkRepository.share(
|
||||||
|
GameEvent.DisplayPortrait(
|
||||||
|
timestamp = System.currentTimeMillis(),
|
||||||
|
characterSheetId = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.material.Surface
|
import androidx.compose.material.Surface
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
|
@ -35,6 +36,7 @@ import com.pixelized.desktop.lwa.ui.composable.character.characteristic.Characte
|
||||||
import com.pixelized.desktop.lwa.ui.composable.key.KeyHandler
|
import com.pixelized.desktop.lwa.ui.composable.key.KeyHandler
|
||||||
import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController
|
import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController
|
||||||
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.navigateToLevelScreen
|
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.navigateToLevelScreen
|
||||||
|
import com.pixelized.desktop.lwa.ui.overlay.portrait.PortraitOverlay
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDetailPanel
|
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.CharacterDetailViewModel
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDiminishedViewModel
|
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDiminishedViewModel
|
||||||
|
|
@ -84,7 +86,14 @@ fun CampaignScreen(
|
||||||
|
|
||||||
},
|
},
|
||||||
main = {
|
main = {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.matchParentSize(),
|
||||||
|
contentAlignment = Alignment.BottomCenter,
|
||||||
|
) {
|
||||||
|
PortraitOverlay(
|
||||||
|
modifier = Modifier.padding(all = 8.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
chat = {
|
chat = {
|
||||||
CampaignChat(
|
CampaignChat(
|
||||||
|
|
|
||||||
|
|
@ -54,11 +54,6 @@ import org.jetbrains.compose.resources.painterResource
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@Stable
|
|
||||||
object CharacterPortraitDefault {
|
|
||||||
val size = DpSize(96.dp, 128.dp)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
data class CharacterPortraitUio(
|
data class CharacterPortraitUio(
|
||||||
val id: Campaign.CharacterInstance.Id,
|
val id: Campaign.CharacterInstance.Id,
|
||||||
|
|
@ -82,7 +77,7 @@ data class CharacterPortraitUio(
|
||||||
@Composable
|
@Composable
|
||||||
fun CharacterPortrait(
|
fun CharacterPortrait(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
size: DpSize = CharacterPortraitDefault.size,
|
size: DpSize = MaterialTheme.lwa.size.portrait.minimized,
|
||||||
levelUpOffset: Dp = 9.dp,
|
levelUpOffset: Dp = 9.dp,
|
||||||
character: CharacterPortraitUio,
|
character: CharacterPortraitUio,
|
||||||
onCharacter: (id: Campaign.CharacterInstance.Id) -> Unit,
|
onCharacter: (id: Campaign.CharacterInstance.Id) -> Unit,
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.DpSize
|
import androidx.compose.ui.unit.DpSize
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import lwacharactersheet.composeapp.generated.resources.Res
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
|
|
@ -61,7 +62,7 @@ data class CharacterPortraitRollAnimation(
|
||||||
@Composable
|
@Composable
|
||||||
fun CharacterPortraitRoll(
|
fun CharacterPortraitRoll(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
size: DpSize = CharacterPortraitDefault.size,
|
size: DpSize = MaterialTheme.lwa.size.portrait.minimized,
|
||||||
value: CharacterPortraitRollUio?,
|
value: CharacterPortraitRollUio?,
|
||||||
onLeftClick: (CharacterPortraitRollUio) -> Unit,
|
onLeftClick: (CharacterPortraitRollUio) -> Unit,
|
||||||
onRightClick: (CharacterPortraitRollUio) -> Unit,
|
onRightClick: (CharacterPortraitRollUio) -> Unit,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.CharacterPortrait
|
import com.pixelized.desktop.lwa.ui.screen.campaign.player.CharacterPortrait
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.CharacterPortraitDefault
|
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.CharacterPortraitRoll
|
import com.pixelized.desktop.lwa.ui.screen.campaign.player.CharacterPortraitRoll
|
||||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||||
import org.koin.compose.viewmodel.koinViewModel
|
import org.koin.compose.viewmodel.koinViewModel
|
||||||
|
|
@ -38,7 +37,6 @@ fun NpcRibbon(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItem(),
|
||||||
) {
|
) {
|
||||||
CharacterPortraitRoll(
|
CharacterPortraitRoll(
|
||||||
size = CharacterPortraitDefault.size,
|
|
||||||
value = viewModel.roll(characterId = it.id).value,
|
value = viewModel.roll(characterId = it.id).value,
|
||||||
onRightClick = {
|
onRightClick = {
|
||||||
viewModel.onPortraitRollRightClick(characterId = it.characterId)
|
viewModel.onPortraitRollRightClick(characterId = it.characterId)
|
||||||
|
|
@ -48,7 +46,6 @@ fun NpcRibbon(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
CharacterPortrait(
|
CharacterPortrait(
|
||||||
size = CharacterPortraitDefault.size,
|
|
||||||
character = it,
|
character = it,
|
||||||
onCharacter = onCharacter,
|
onCharacter = onCharacter,
|
||||||
onLevelUp = onLevelUp,
|
onLevelUp = onLevelUp,
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ import androidx.compose.ui.window.WindowState
|
||||||
import com.pixelized.desktop.lwa.ui.navigation.window.LocalWindowState
|
import com.pixelized.desktop.lwa.ui.navigation.window.LocalWindowState
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.CampaignLayoutScope
|
import com.pixelized.desktop.lwa.ui.screen.campaign.CampaignLayoutScope
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.LocalCampaignLayoutScope
|
import com.pixelized.desktop.lwa.ui.screen.campaign.LocalCampaignLayoutScope
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.CharacterPortraitDefault
|
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.CharacteristicTextMessage
|
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.CharacteristicTextMessage
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.CharacteristicTextMessageUio
|
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.CharacteristicTextMessageUio
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.DiminishedTextMessage
|
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.DiminishedTextMessage
|
||||||
|
|
@ -90,7 +89,7 @@ fun CampaignChat(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.size(
|
.size(
|
||||||
width = animatedChatWidth.value,
|
width = animatedChatWidth.value,
|
||||||
height = CharacterPortraitDefault.size.height * 2 + 8.dp,
|
height = MaterialTheme.lwa.size.portrait.minimized.height * 2 + 8.dp,
|
||||||
)
|
)
|
||||||
.graphicsLayer {
|
.graphicsLayer {
|
||||||
alpha = chatViewModel.chatAnimatedVisibility.value
|
alpha = chatViewModel.chatAnimatedVisibility.value
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.TextMessage
|
||||||
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Damage
|
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Damage
|
||||||
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Power
|
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Power
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
||||||
|
import com.pixelized.shared.lwa.protocol.websocket.GameEvent
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.GameMasterEvent
|
import com.pixelized.shared.lwa.protocol.websocket.GameMasterEvent
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.RollMessage
|
import com.pixelized.shared.lwa.protocol.websocket.RollMessage
|
||||||
|
|
@ -105,6 +106,7 @@ class TextMessageFactory(
|
||||||
is ToggleActiveAlteration -> null
|
is ToggleActiveAlteration -> null
|
||||||
is UpdateSkillUsageMessage -> null
|
is UpdateSkillUsageMessage -> null
|
||||||
is GameMasterEvent -> null
|
is GameMasterEvent -> null
|
||||||
|
is GameEvent.DisplayPortrait -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,17 +1,25 @@
|
||||||
package com.pixelized.desktop.lwa.ui.screen.gamemaster
|
package com.pixelized.desktop.lwa.ui.screen.gamemaster
|
||||||
|
|
||||||
import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository
|
import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository
|
||||||
|
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacterUio.Action
|
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacterUio.Action
|
||||||
|
import com.pixelized.shared.lwa.protocol.websocket.GameEvent
|
||||||
|
|
||||||
class GameMasterActionUseCase(
|
class GameMasterActionUseCase(
|
||||||
private val campaignRepository: CampaignRepository,
|
private val campaignRepository: CampaignRepository,
|
||||||
|
private val networkRepository: NetworkRepository,
|
||||||
) {
|
) {
|
||||||
suspend fun handleAction(
|
suspend fun handleAction(
|
||||||
characterSheetId: String,
|
characterSheetId: String,
|
||||||
action: Action,
|
action: Action,
|
||||||
) {
|
) {
|
||||||
when (action) {
|
when (action) {
|
||||||
Action.DisplayPortrait -> TODO()
|
Action.DisplayPortrait -> networkRepository.share(
|
||||||
|
GameEvent.DisplayPortrait(
|
||||||
|
timestamp = System.currentTimeMillis(),
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
Action.AddToGroup -> campaignRepository.addCharacter(
|
Action.AddToGroup -> campaignRepository.addCharacter(
|
||||||
characterSheetId = characterSheetId,
|
characterSheetId = characterSheetId,
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ class GameMasterFactory {
|
||||||
}
|
}
|
||||||
// build the cell action list
|
// build the cell action list
|
||||||
val actions = buildList {
|
val actions = buildList {
|
||||||
|
add(Action.DisplayPortrait)
|
||||||
add(
|
add(
|
||||||
when (characterInstanceId) {
|
when (characterInstanceId) {
|
||||||
null -> Action.AddToGroup
|
null -> Action.AddToGroup
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import androidx.compose.material.IconButton
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Edit
|
|
||||||
import androidx.compose.material.icons.filled.MoreVert
|
import androidx.compose.material.icons.filled.MoreVert
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,15 @@ import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
|
||||||
data class LwaSize(
|
data class LwaSize(
|
||||||
|
val portrait: Portrait,
|
||||||
val sheet: Sheet,
|
val sheet: Sheet,
|
||||||
) {
|
) {
|
||||||
|
@Stable
|
||||||
|
data class Portrait(
|
||||||
|
val maximized: DpSize,
|
||||||
|
val minimized: DpSize,
|
||||||
|
)
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
data class Sheet(
|
data class Sheet(
|
||||||
val subCategory: Dp,
|
val subCategory: Dp,
|
||||||
|
|
@ -21,12 +28,17 @@ data class LwaSize(
|
||||||
@Composable
|
@Composable
|
||||||
@Stable
|
@Stable
|
||||||
fun lwaSize(
|
fun lwaSize(
|
||||||
|
portrait: LwaSize.Portrait = LwaSize.Portrait(
|
||||||
|
minimized = DpSize(width = 96.dp, height = 128.dp),
|
||||||
|
maximized = DpSize(width = 512.dp, height = 512.dp),
|
||||||
|
),
|
||||||
sheet: LwaSize.Sheet = LwaSize.Sheet(
|
sheet: LwaSize.Sheet = LwaSize.Sheet(
|
||||||
subCategory = 14.dp,
|
subCategory = 14.dp,
|
||||||
characteristic = DpSize(width = 76.dp, height = 110.dp),
|
characteristic = DpSize(width = 76.dp, height = 110.dp),
|
||||||
),
|
),
|
||||||
) = remember {
|
) = remember {
|
||||||
LwaSize(
|
LwaSize(
|
||||||
|
portrait = portrait,
|
||||||
sheet = sheet,
|
sheet = sheet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -5,11 +5,12 @@ import com.pixelized.server.lwa.model.campaign.CampaignService
|
||||||
import com.pixelized.server.lwa.model.character.CharacterSheetService
|
import com.pixelized.server.lwa.model.character.CharacterSheetService
|
||||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||||
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
|
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
|
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
||||||
|
import com.pixelized.shared.lwa.protocol.websocket.GameEvent
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.GameMasterEvent
|
import com.pixelized.shared.lwa.protocol.websocket.GameMasterEvent
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.RollMessage
|
import com.pixelized.shared.lwa.protocol.websocket.RollMessage
|
||||||
|
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.ToggleActiveAlteration
|
import com.pixelized.shared.lwa.protocol.websocket.ToggleActiveAlteration
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.UpdateSkillUsageMessage
|
import com.pixelized.shared.lwa.protocol.websocket.UpdateSkillUsageMessage
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
|
@ -65,6 +66,10 @@ class Engine(
|
||||||
is GameMasterEvent.TogglePlayer -> campaignService.updateToggleParty()
|
is GameMasterEvent.TogglePlayer -> campaignService.updateToggleParty()
|
||||||
is GameMasterEvent.ToggleNpc -> campaignService.updateToggleNpc()
|
is GameMasterEvent.ToggleNpc -> campaignService.updateToggleNpc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is GameEvent -> when (message) {
|
||||||
|
is GameEvent.DisplayPortrait -> Unit // Nothing to do here.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.pixelized.shared.lwa.protocol.websocket
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
sealed interface GameEvent : SocketMessage {
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class DisplayPortrait(
|
||||||
|
override val timestamp: Long,
|
||||||
|
val characterSheetId: String?,
|
||||||
|
) : GameEvent
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue