Add "Heal" party feature into the GM menus.

This commit is contained in:
Thomas Andres Gomez 2025-04-04 18:08:05 +02:00
parent 5bcb4367d6
commit 225443dc0f
3 changed files with 81 additions and 10 deletions

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:pathData="M80,880v-186l350,-472 -70,-94 64,-48 56,75 56,-75 64,48 -70,94 350,472v186L80,880ZM480,289L160,720v80h120l200,-280 200,280h120v-80L480,289ZM378,800h204L480,658 378,800ZM480,520 L680,800 480,520 280,800 480,520Z"
android:fillColor="#5f6368"/>
</vector>

View file

@ -15,8 +15,10 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.pixelized.desktop.lwa.ui.composable.error.ErrorSnackHandler
import kotlinx.coroutines.launch
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.ic_camping_24dp
import lwacharactersheet.composeapp.generated.resources.ic_visibility_24dp
import lwacharactersheet.composeapp.generated.resources.ic_visibility_off_24dp
import org.koin.compose.viewmodel.koinViewModel
@ -38,6 +40,11 @@ fun GMActionPage(
GMActionContent(
actions = actions,
scroll = scroll,
onPartyHeal = {
scope.launch {
viewModel.onPartyHeal()
}
},
onPartyVisibility = {
scope.launch {
viewModel.onPlayerVisibility()
@ -49,6 +56,10 @@ fun GMActionPage(
}
},
)
ErrorSnackHandler(
error = viewModel.error,
)
}
@Composable
@ -57,6 +68,7 @@ fun GMActionContent(
scroll: ScrollState,
spacing: Dp = 8.dp,
actions: State<ActionPageUio?>,
onPartyHeal: () -> Unit,
onPartyVisibility: () -> Unit,
onNpcVisibility: () -> Unit,
) {
@ -66,6 +78,12 @@ fun GMActionContent(
.padding(vertical = spacing, horizontal = spacing),
verticalArrangement = Arrangement.spacedBy(space = spacing),
) {
GMAction(
modifier = Modifier.fillMaxWidth(),
icon = Res.drawable.ic_camping_24dp,
label = "Soigner le groupe de joueur",
onAction = onPartyHeal,
)
actions.value?.party?.let { party ->
GMAction(
modifier = Modifier.fillMaxWidth(),

View file

@ -3,8 +3,12 @@ package com.pixelized.desktop.lwa.ui.screen.gamemaster.action
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
import com.pixelized.desktop.lwa.ui.composable.error.ErrorSnackUio
import com.pixelized.shared.lwa.protocol.websocket.GameMasterEvent
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
@ -12,10 +16,14 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
class GMActionViewModel(
private val characterRepository: CharacterSheetRepository,
private val networkRepository: NetworkRepository,
campaignRepository: CampaignRepository,
private val campaignRepository: CampaignRepository,
) : ViewModel() {
private val _error = MutableSharedFlow<ErrorSnackUio>()
val error: SharedFlow<ErrorSnackUio> get() = _error
val actions: StateFlow<ActionPageUio?> = campaignRepository.campaignFlow
.map {
ActionPageUio(
@ -30,19 +38,55 @@ class GMActionViewModel(
initialValue = null,
)
suspend fun onNpcVisibility() {
networkRepository.share(
GameMasterEvent.ToggleNpc(
timestamp = System.currentTimeMillis(),
suspend fun onPartyHeal() {
campaignRepository.campaignFlow.value.characters.forEach { characterSheetId ->
val sheet = characterRepository.characterDetail(
characterSheetId = characterSheetId,
) ?: return@forEach
val updated = sheet.copy(
damage = 0,
fatigue = 0,
diminished = 0,
)
)
if (sheet != updated) {
try {
characterRepository.updateCharacter(
sheet = updated,
create = false,
)
} catch (exception: Exception) {
val message = ErrorSnackUio.from(exception = exception)
_error.emit(message)
}
}
}
}
suspend fun onNpcVisibility() {
try {
networkRepository.share(
GameMasterEvent.ToggleNpc(
timestamp = System.currentTimeMillis(),
)
)
} catch (exception: Exception) {
val message = ErrorSnackUio.from(exception = exception)
_error.emit(message)
}
}
suspend fun onPlayerVisibility() {
networkRepository.share(
GameMasterEvent.TogglePlayer(
timestamp = System.currentTimeMillis(),
try {
networkRepository.share(
GameMasterEvent.TogglePlayer(
timestamp = System.currentTimeMillis(),
)
)
)
} catch (exception: Exception) {
val message = ErrorSnackUio.from(exception = exception)
_error.emit(message)
}
}
}