diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_delete_forever_24dp.xml b/composeApp/src/commonMain/composeResources/drawable/ic_delete_forever_24dp.xml new file mode 100644 index 0000000..f655d3c --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/ic_delete_forever_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetRepository.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetRepository.kt index 8568673..7d87359 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetRepository.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetRepository.kt @@ -59,15 +59,15 @@ class CharacterSheetRepository( } suspend fun updateCharacter( - characterSheet: CharacterSheet, + sheet: CharacterSheet, ) { - store.updateCharacterSheet(sheet = characterSheet) + store.updateCharacterSheet(sheet = sheet) } suspend fun deleteCharacter( - characterId: String, + characterSheetId: String, ) { - store.deleteCharacterSheet(characterId = characterId) + store.deleteCharacterSheet(characterSheetId = characterSheetId) } fun checkCharacterSheetIdValidity( diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetStore.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetStore.kt index 9c849b0..86ede52 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetStore.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetStore.kt @@ -84,11 +84,11 @@ class CharacterSheetStore( } suspend fun deleteCharacterSheet( - characterId: String, + characterSheetId: String, ) { try { - client.deleteCharacterSheet(id = characterId) - _detailFlow.delete(characterId = characterId) + client.deleteCharacterSheet(id = characterSheetId) + _detailFlow.delete(characterId = characterSheetId) } catch (exception: Exception) { println(exception) // TODO } diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/character/characteristic/CharacterSheetCharacteristicDialog.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/character/characteristic/CharacterSheetCharacteristicDialog.kt index 8216c67..f313932 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/character/characteristic/CharacterSheetCharacteristicDialog.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/character/characteristic/CharacterSheetCharacteristicDialog.kt @@ -42,6 +42,7 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox +import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape import com.pixelized.shared.lwa.model.campaign.Campaign import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action @@ -112,15 +113,7 @@ private fun Dialog( indication = null, onClick = onDismissRequest, ) - .onPreviewKeyEvent { - when { - it.key == Key.Escape -> { - onDismissRequest() - true - } - else -> false - } - } + .onPreviewEscape(event = onDismissRequest) .fillMaxSize() .padding(all = 32.dp), contentAlignment = Alignment.Center, diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/copy/CharacterSheetCopyDialog.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/copy/CharacterSheetCopyDialog.kt index 98e292c..dd70ca2 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/copy/CharacterSheetCopyDialog.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/copy/CharacterSheetCopyDialog.kt @@ -39,6 +39,7 @@ import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextField import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio import com.pixelized.desktop.lwa.ui.theme.lwa +import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__copy__error import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action @@ -109,16 +110,7 @@ private fun Dialog( indication = null, onClick = onDismissRequest, ) - .onPreviewKeyEvent { - when { - it.key == Key.Escape -> { - onDismissRequest() - true - } - - else -> false - } - } + .onPreviewEscape(event = onDismissRequest) .fillMaxSize() .padding(all = 32.dp), contentAlignment = Alignment.Center, diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/delete/CharacterSheetDeleteDialog.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/delete/CharacterSheetDeleteDialog.kt new file mode 100644 index 0000000..03a27ec --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/delete/CharacterSheetDeleteDialog.kt @@ -0,0 +1,151 @@ +package com.pixelized.desktop.lwa.ui.screen.characterSheet.delete + +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.SizeTransform +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.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +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.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Surface +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.Stable +import androidx.compose.runtime.State +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.unit.dp +import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox +import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape +import lwacharactersheet.composeapp.generated.resources.Res +import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__description +import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__title +import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action +import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action +import org.jetbrains.compose.resources.stringResource + +@Stable +data class CharacterSheetDeleteDialogUio( + val characterSheetId: String, + val name: String, +) + +@Composable +fun CharacterSheetDeleteDialog( + dialog: State, + onConfirm: (CharacterSheetDeleteDialogUio) -> Unit, + onDismissRequest: () -> Unit, +) { + AnimatedContent( + modifier = Modifier.fillMaxSize(), + targetState = dialog.value, + transitionSpec = { + val enter = fadeIn() + slideInVertically { 32 } + val exit = fadeOut() + slideOutVertically { 32 } + enter togetherWith exit using SizeTransform(clip = false) + }, + ) { + Box( + modifier = Modifier.fillMaxSize() + ) { + when (it) { + null -> Box( + modifier = Modifier, + ) + + else -> { + Dialog( + dialog = it, + onConfirm = onConfirm, + onDismissRequest = onDismissRequest, + ) + } + } + } + } +} + +@Composable +private fun Dialog( + dialog: CharacterSheetDeleteDialogUio, + onConfirm: (CharacterSheetDeleteDialogUio) -> Unit, + onDismissRequest: () -> Unit, +) { + Box( + modifier = Modifier + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = onDismissRequest, + ) + .onPreviewEscape(event = onDismissRequest) + .fillMaxSize() + .padding(all = 32.dp), + contentAlignment = Alignment.Center, + ) { + DecoratedBox { + Surface { + Column( + verticalArrangement = Arrangement.spacedBy(space = 24.dp), + ) { + Text( + modifier = Modifier + .padding(horizontal = 24.dp) + .padding(top = 24.dp), + style = MaterialTheme.typography.h6, + text = stringResource(Res.string.character_sheet__delete_dialog__title), + ) + Text( + modifier = Modifier + .padding(horizontal = 24.dp), + style = MaterialTheme.typography.body1, + text = stringResource( + Res.string.character_sheet__delete_dialog__description, + dialog.name + ), + ) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + .padding(bottom = 4.dp), + horizontalArrangement = Arrangement.spacedBy( + space = 4.dp, + alignment = Alignment.End + ) + ) { + TextButton( + onClick = onDismissRequest, + ) { + Text( + text = stringResource(Res.string.dialog__cancel_action) + ) + } + TextButton( + onClick = { onConfirm(dialog) }, + ) { + Text( + text = stringResource(Res.string.dialog__confirm_action) + ) + } + } + } + } + } + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetViewModel.kt index 34ff48e..f50abc4 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetViewModel.kt @@ -74,7 +74,7 @@ class CharacterSheetViewModel( ) suspend fun deleteCharacter(id: String) { - characterRepository.deleteCharacter(characterId = id) + characterRepository.deleteCharacter(characterSheetId = id) } fun onUseSkill(skill: CharacterSheetPageUio.Node) { diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/dialog/CharacterSheetDeleteConfirmationDialog.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/dialog/CharacterSheetDeleteConfirmationDialog.kt index 2b75493..502c6b9 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/dialog/CharacterSheetDeleteConfirmationDialog.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/dialog/CharacterSheetDeleteConfirmationDialog.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.input.key.key import androidx.compose.ui.input.key.onPreviewKeyEvent import androidx.compose.ui.unit.dp import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox +import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__description @@ -91,15 +92,7 @@ private fun Dialog( indication = null, onClick = onDismissRequest, ) - .onPreviewKeyEvent { - when { - it.key == Key.Escape -> { - onDismissRequest() - true - } - else -> false - } - } + .onPreviewEscape(event = onDismissRequest) .fillMaxSize() .padding(all = 32.dp), contentAlignment = Alignment.Center, diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/dialog/DiminishedStatDialog.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/dialog/DiminishedStatDialog.kt index a00c0b6..581980d 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/dialog/DiminishedStatDialog.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/dialog/DiminishedStatDialog.kt @@ -42,6 +42,7 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox +import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape import com.pixelized.shared.lwa.model.campaign.Campaign import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action @@ -110,16 +111,7 @@ private fun Dialog( indication = null, onClick = onDismissRequest, ) - .onPreviewKeyEvent { - when { - it.key == Key.Escape -> { - onDismissRequest() - true - } - - else -> false - } - } + .onPreviewEscape(event = onDismissRequest) .fillMaxSize() .padding(all = 32.dp), contentAlignment = Alignment.Center, diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditPage.kt index 87414b0..dafdaa4 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditPage.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditPage.kt @@ -33,6 +33,8 @@ import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController import com.pixelized.desktop.lwa.ui.navigation.window.LocalWindow import com.pixelized.desktop.lwa.ui.screen.characterSheet.copy.CharacterSheetCopyDialog +import com.pixelized.desktop.lwa.ui.screen.characterSheet.delete.CharacterSheetDeleteDialog +import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialog import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.ActionField import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.ActionFieldUio import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.BaseSkillFieldUio @@ -56,6 +58,7 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__ch import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__save_action import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__magic_action import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__special_action +import lwacharactersheet.composeapp.generated.resources.ic_delete_forever_24dp import lwacharactersheet.composeapp.generated.resources.ic_save_24dp import lwacharactersheet.composeapp.generated.resources.ic_save_as_24dp import org.jetbrains.compose.resources.painterResource @@ -124,6 +127,11 @@ fun CharacterSheetEditPage( viewModel.onNewAction() } }, + onDelete = { + scope.launch { + viewModel.showDeleteCharacterSheetDialog() + } + }, onCopy = { scope.launch { viewModel.showCopyCharacterSheetDialog() @@ -155,6 +163,21 @@ fun CharacterSheetEditPage( viewModel.hideCopyCharacterSheetDialog() } ) + + CharacterSheetDeleteDialog( + dialog = viewModel.deleteCharacterSheetDialog, + onConfirm = { dialog -> + scope.launch { + viewModel.delete(characterSheetId = dialog.characterSheetId) + if (screen.popBackStack().not()) { + windowController.hideWindow(window = window) + } + } + }, + onDismissRequest = { + viewModel.hideDeleteCharacterSheetDialog() + } + ) } @Composable @@ -165,6 +188,7 @@ fun CharacterSheetEdit( onNewSpecialSkill: () -> Unit, onNewMagicSkill: () -> Unit, onNewAction: () -> Unit, + onDelete: () -> Unit, onCopy: () -> Unit, onSave: () -> Unit, ) { @@ -180,6 +204,15 @@ fun CharacterSheetEdit( ) }, actions = { + IconButton( + onClick = onDelete, + ) { + Icon( + painter = painterResource(Res.drawable.ic_delete_forever_24dp), + tint = MaterialTheme.colors.primary, + contentDescription = null, + ) + } IconButton( onClick = onCopy, ) { diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditViewModel.kt index c9741e9..54116ab 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditViewModel.kt @@ -8,6 +8,7 @@ import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetReposit import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio import com.pixelized.desktop.lwa.ui.navigation.screen.destination.CharacterSheetEditDestination import com.pixelized.desktop.lwa.ui.screen.characterSheet.copy.CharacterSheetCopyDialogUio +import com.pixelized.desktop.lwa.ui.screen.characterSheet.delete.CharacterSheetDeleteDialogUio import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common.SkillFieldFactory import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.ActionFieldUio import kotlinx.coroutines.flow.MutableStateFlow @@ -34,6 +35,9 @@ class CharacterSheetEditViewModel( private val copyDialog = mutableStateOf(null) val copyCharacterSheetDialog: State = copyDialog + private val deleteDialog = mutableStateOf(null) + val deleteCharacterSheetDialog: State = deleteDialog + private val _characterSheet = mutableStateOf( runBlocking { sheetFactory.convertToUio( @@ -44,7 +48,6 @@ class CharacterSheetEditViewModel( ) val characterSheet: State get() = _characterSheet - // TODO suspend fun showCopyCharacterSheetDialog() { val characterSheetId = MutableStateFlow(argument.id ?: "") val error = MutableStateFlow(false) @@ -67,11 +70,21 @@ class CharacterSheetEditViewModel( ) } - // TODO fun hideCopyCharacterSheetDialog() { copyDialog.value = null } + fun showDeleteCharacterSheetDialog() { + deleteDialog.value = CharacterSheetDeleteDialogUio( + characterSheetId = argument.id ?: "", + name = characterSheet.value.name.value.value, + ) + } + + fun hideDeleteCharacterSheetDialog() { + deleteDialog.value = null + } + suspend fun onNewSpecialSkill() { val id = UUID.randomUUID().toString() val skill = skillFactory.createSkill( @@ -148,7 +161,7 @@ class CharacterSheetEditViewModel( editedSheet = _characterSheet.value, ) characterSheetRepository.updateCharacter( - characterSheet = updatedSheet, + sheet = updatedSheet, ) } @@ -160,7 +173,15 @@ class CharacterSheetEditViewModel( editedSheet = _characterSheet.value, ) characterSheetRepository.updateCharacter( - characterSheet = updatedSheet.copy(id = characterSheetId), + sheet = updatedSheet.copy(id = characterSheetId), + ) + } + + suspend fun delete( + characterSheetId: String, + ) { + characterSheetRepository.deleteCharacter( + characterSheetId = characterSheetId ) } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/levelup/LevelUpViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/levelup/LevelUpViewModel.kt index 8cc25ed..79e0477 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/levelup/LevelUpViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/levelup/LevelUpViewModel.kt @@ -151,7 +151,7 @@ class LevelUpViewModel( ) characterSheetRepository.updateCharacter( - characterSheet = levelUpCharacter, + sheet = levelUpCharacter, ) } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/extention/ModifierEx+KeyEvent.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/extention/ModifierEx+KeyEvent.kt new file mode 100644 index 0000000..852898f --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/extention/ModifierEx+KeyEvent.kt @@ -0,0 +1,17 @@ +package com.pixelized.desktop.lwa.utils.extention + +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.onPreviewKeyEvent + +fun Modifier.onPreviewEscape(event: () -> Unit): Modifier = this.onPreviewKeyEvent { + when { + it.key == Key.Escape -> { + event() + true + } + + else -> false + } +} \ No newline at end of file diff --git a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/character/DELETE_Character.kt b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/character/DELETE_Character.kt index afb6733..93efcb6 100644 --- a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/character/DELETE_Character.kt +++ b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/character/DELETE_Character.kt @@ -9,7 +9,11 @@ import io.ktor.server.response.respondText fun Engine.deleteCharacter(): suspend io.ktor.server.routing.RoutingContext.() -> Unit { return { val characterSheetId = call.parameters.characterSheetId - val deleted = characterService.deleteCharacterSheet(characterId = characterSheetId) + + val deleted = characterService.deleteCharacterSheet( + characterId = characterSheetId + ) + // TODO campaign & alteration cleanup. if (deleted) { call.respondText(