diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_edit_note_24dp.xml b/composeApp/src/commonMain/composeResources/drawable/ic_edit_note_24dp.xml
new file mode 100644
index 0000000..6bdce88
--- /dev/null
+++ b/composeApp/src/commonMain/composeResources/drawable/ic_edit_note_24dp.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index dcb2884..393fff4 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -325,6 +325,7 @@
Édition de personnage
Synchronisation du serveur
Demander au serveur d'invalider son cache
+ Titre de la scène
Soigner les personnages joueurs
Cette action réinitialisera les points de vie, de pouvoir et d'état diminué de chaque personnage joueur présent dans le groupe.
Cacher le groupe de personnages joueur
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/network/LwaClient.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/network/LwaClient.kt
index 84d8ceb..b595475 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/network/LwaClient.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/network/LwaClient.kt
@@ -33,6 +33,10 @@ interface LwaClient {
suspend fun getCampaign(): APIResponse
+ suspend fun putCampaignScene(
+ scene: CampaignJson.SceneJson,
+ ): APIResponse
+
suspend fun putCampaignCharacter(
characterSheetId: String,
): APIResponse
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/network/LwaClientImpl.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/network/LwaClientImpl.kt
index 28f3b41..44b73cc 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/network/LwaClientImpl.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/network/LwaClientImpl.kt
@@ -58,6 +58,16 @@ class LwaClientImpl(
.get("$root/campaign")
.body()
+ @Throws
+ override suspend fun putCampaignScene(
+ scene: CampaignJson.SceneJson,
+ ): APIResponse = client
+ .put("$root/campaign/scene") {
+ contentType(ContentType.Application.Json)
+ setBody(scene)
+ }
+ .body>()
+
@Throws
override suspend fun putCampaignCharacter(
characterSheetId: String,
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/campaign/CampaignRepository.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/campaign/CampaignRepository.kt
index b61a3f2..d242d9c 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/campaign/CampaignRepository.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/campaign/CampaignRepository.kt
@@ -14,6 +14,12 @@ class CampaignRepository(
store.updateCampaignFlow()
}
+ suspend fun updateSceneTitle(
+ title: String,
+ ) {
+ store.changeSceneTitle(title = title)
+ }
+
@Throws
suspend fun addCharacter(
characterSheetId: String,
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/campaign/CampaignStore.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/campaign/CampaignStore.kt
index 402211f..3693f8a 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/campaign/CampaignStore.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/campaign/CampaignStore.kt
@@ -40,6 +40,17 @@ class CampaignStore(
}
}
+ @Throws
+ suspend fun changeSceneTitle(
+ title: String,
+ ) {
+ val scene = factory.createScene(title = title)
+ val request = client.putCampaignScene(scene = scene)
+ if (request.success.not()) {
+ LwaClient.error(error = request)
+ }
+ }
+
@Throws
suspend fun addCharacter(
characterSheetId: String,
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/common/CharacterRibbonAlteration.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/common/CharacterRibbonAlteration.kt
index 5da895b..000d761 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/common/CharacterRibbonAlteration.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/common/CharacterRibbonAlteration.kt
@@ -21,7 +21,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import coil3.PlatformContext
@@ -30,10 +29,10 @@ import coil3.request.ImageRequest
import com.pixelized.desktop.lwa.ui.composable.tooltip.BasicTooltipLayout
import com.pixelized.desktop.lwa.ui.composable.tooltip.BasicTooltipUio
import com.pixelized.desktop.lwa.ui.theme.lwa
+import com.pixelized.desktop.lwa.utils.extention.invert
@Stable
data class CharacterRibbonAlterationUio(
-
val icon: String,
val tooltips: BasicTooltipUio?,
)
@@ -63,14 +62,10 @@ fun CharacterRibbonAlteration(
delayMillis = 0,
tooltip = it.tooltips,
tooltipPlacement = remember(direction) {
- TooltipPlacement.ComponentRect(
- anchor = when (direction) {
- LayoutDirection.Ltr -> Alignment.CenterEnd
- LayoutDirection.Rtl -> Alignment.CenterStart
- },
- alignment = when (direction) {
- LayoutDirection.Ltr -> Alignment.CenterEnd
- LayoutDirection.Rtl -> Alignment.CenterStart
+ TooltipPlacement.CursorPoint(
+ alignment = when (direction.invert) {
+ LayoutDirection.Ltr -> Alignment.CenterStart
+ LayoutDirection.Rtl -> Alignment.CenterEnd
},
)
},
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMActionPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMActionPage.kt
index 74860c8..4b824fd 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMActionPage.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMActionPage.kt
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
@@ -15,11 +16,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import com.pixelized.desktop.lwa.ui.composable.error.ErrorSnackHandler
import com.pixelized.desktop.lwa.ui.composable.confirmation.ConfirmationDialog
+import com.pixelized.desktop.lwa.ui.composable.error.ErrorSnackHandler
+import com.pixelized.desktop.lwa.ui.theme.lwa
import kotlinx.coroutines.launch
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.ic_camping_24dp
+import lwacharactersheet.composeapp.generated.resources.ic_edit_note_24dp
import lwacharactersheet.composeapp.generated.resources.ic_sync_24dp
import lwacharactersheet.composeapp.generated.resources.ic_visibility_24dp
import lwacharactersheet.composeapp.generated.resources.ic_visibility_off_24dp
@@ -38,6 +41,7 @@ fun GMActionPage(
val scope = rememberCoroutineScope()
val scroll = rememberScrollState()
val actions = viewModel.actions.collectAsStateWithLifecycle()
+ val editDialog = viewModel.editDialog.collectAsStateWithLifecycle()
val validationDialog = viewModel.validationDialog.collectAsStateWithLifecycle()
GMActionContent(
@@ -48,6 +52,11 @@ fun GMActionPage(
viewModel.onServerSync()
}
},
+ onEditSession = {
+ scope.launch {
+ viewModel.onEditSession()
+ }
+ },
onPartyHeal = {
scope.launch {
viewModel.onPartyHeal()
@@ -72,15 +81,20 @@ fun GMActionPage(
ConfirmationDialog(
dialog = validationDialog,
)
+
+ GMEditDialog(
+ dialog = editDialog
+ )
}
@Composable
fun GMActionContent(
modifier: Modifier = Modifier,
scroll: ScrollState,
- spacing: Dp = 8.dp,
+ spacing: Dp = MaterialTheme.lwa.dimen.paddingValue,
actions: State,
onServerSync: () -> Unit,
+ onEditSession: () -> Unit,
onPartyHeal: () -> Unit,
onPartyVisibility: () -> Unit,
onNpcVisibility: () -> Unit,
@@ -97,6 +111,12 @@ fun GMActionContent(
label = "Synchronization du serveur",
onAction = onServerSync,
)
+ GMAction(
+ modifier = Modifier.fillMaxWidth(),
+ icon = Res.drawable.ic_edit_note_24dp,
+ label = "Edition du titre de session",
+ onAction = onEditSession,
+ )
GMAction(
modifier = Modifier.fillMaxWidth(),
icon = Res.drawable.ic_camping_24dp,
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMActionUseCase.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMActionUseCase.kt
index 895f9a0..e630144 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMActionUseCase.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMActionUseCase.kt
@@ -19,6 +19,16 @@ class GMActionUseCase(
)
}
+ fun currentSceneTitle(): String = campaignRepository.campaignFlow().value.scene.name
+
+ suspend fun updateSceneTitle(
+ title: String,
+ ) {
+ campaignRepository.updateSceneTitle(
+ title = title,
+ )
+ }
+
suspend fun healPlayerParty() {
campaignRepository.campaignFlow().value.characters.forEach { characterSheetId ->
val sheet = characterRepository.characterDetail(
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMActionViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMActionViewModel.kt
index c80f8be..e740823 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMActionViewModel.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMActionViewModel.kt
@@ -5,6 +5,8 @@ import androidx.lifecycle.viewModelScope
import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository
import com.pixelized.desktop.lwa.ui.composable.confirmation.ConfirmationDialogUio
import com.pixelized.desktop.lwa.ui.composable.error.ErrorSnackUio
+import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextField
+import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextFieldFlow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
@@ -15,6 +17,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import lwacharactersheet.composeapp.generated.resources.Res
+import lwacharactersheet.composeapp.generated.resources.game_master__actions__campaign_scene__title
import lwacharactersheet.composeapp.generated.resources.game_master__actions__hide_npc__description
import lwacharactersheet.composeapp.generated.resources.game_master__actions__hide_npc__title
import lwacharactersheet.composeapp.generated.resources.game_master__actions__hide_player__description
@@ -27,7 +30,6 @@ import lwacharactersheet.composeapp.generated.resources.game_master__actions__sh
import lwacharactersheet.composeapp.generated.resources.game_master__actions__show_npc__title
import lwacharactersheet.composeapp.generated.resources.game_master__actions__show_player__description
import lwacharactersheet.composeapp.generated.resources.game_master__actions__show_player__title
-import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.getString
class GMActionViewModel(
@@ -55,11 +57,14 @@ class GMActionViewModel(
private val _validationDialog = MutableStateFlow(null)
val validationDialog: StateFlow = _validationDialog
+ private val _editDialog = MutableStateFlow(null)
+ val editDialog: StateFlow = _editDialog
+
suspend fun onServerSync() {
showConfirmationDialog(
- title = Res.string.game_master__actions__on_server_sync__title,
- description = Res.string.game_master__actions__on_server_sync__description,
- onConfirmationRequest = {
+ title = getString(Res.string.game_master__actions__on_server_sync__title),
+ description = getString(Res.string.game_master__actions__on_server_sync__description),
+ onConfirmRequest = {
try {
actionUseCase.invalidateServerCache()
} catch (exception: Exception) {
@@ -73,11 +78,29 @@ class GMActionViewModel(
)
}
+ suspend fun onEditSession() {
+ showEditDialog(
+ title = getString(Res.string.game_master__actions__campaign_scene__title),
+ value = actionUseCase.currentSceneTitle(),
+ onConfirmRequest = {
+ try {
+ actionUseCase.updateSceneTitle(title = it)
+ } catch (exception: Exception) {
+ val message = ErrorSnackUio.from(exception = exception)
+ _error.emit(message)
+ }
+ },
+ onDismissRequest = {
+ _editDialog.value = null
+ },
+ )
+ }
+
suspend fun onPartyHeal() {
showConfirmationDialog(
- title = Res.string.game_master__actions__party_heal__title,
- description = Res.string.game_master__actions__party_heal__description,
- onConfirmationRequest = {
+ title = getString(Res.string.game_master__actions__party_heal__title),
+ description = getString(Res.string.game_master__actions__party_heal__description),
+ onConfirmRequest = {
try {
actionUseCase.healPlayerParty()
} catch (exception: Exception) {
@@ -91,14 +114,14 @@ class GMActionViewModel(
suspend fun onPlayerVisibility() {
showConfirmationDialog(
title = when (actions.value?.party) {
- true -> Res.string.game_master__actions__hide_player__title
- else -> Res.string.game_master__actions__show_player__title
+ true -> getString(Res.string.game_master__actions__hide_player__title)
+ else -> getString(Res.string.game_master__actions__show_player__title)
},
description = when (actions.value?.party) {
- true -> Res.string.game_master__actions__hide_player__description
- else -> Res.string.game_master__actions__show_player__description
+ true -> getString(Res.string.game_master__actions__hide_player__description)
+ else -> getString(Res.string.game_master__actions__show_player__description)
},
- onConfirmationRequest = {
+ onConfirmRequest = {
try {
actionUseCase.togglePlayerVisibility()
} catch (exception: Exception) {
@@ -112,14 +135,14 @@ class GMActionViewModel(
suspend fun onNpcVisibility() {
showConfirmationDialog(
title = when (actions.value?.npc) {
- true -> Res.string.game_master__actions__hide_npc__title
- else -> Res.string.game_master__actions__show_npc__title
+ true -> getString(Res.string.game_master__actions__hide_npc__title)
+ else -> getString(Res.string.game_master__actions__show_npc__title)
},
description = when (actions.value?.npc) {
- true -> Res.string.game_master__actions__hide_npc__description
- else -> Res.string.game_master__actions__show_npc__description
+ true -> getString(Res.string.game_master__actions__hide_npc__description)
+ else -> getString(Res.string.game_master__actions__show_npc__description)
},
- onConfirmationRequest = {
+ onConfirmRequest = {
try {
actionUseCase.toggleNpcVisibility()
} catch (exception: Exception) {
@@ -130,18 +153,42 @@ class GMActionViewModel(
)
}
- private suspend inline fun showConfirmationDialog(
- title: StringResource,
- description: StringResource,
- crossinline onConfirmationRequest: suspend () -> Unit,
+ private inline fun showConfirmationDialog(
+ title: String,
+ description: String,
+ crossinline onConfirmRequest: suspend () -> Unit,
crossinline onDismissRequest: () -> Unit = { _validationDialog.value = null },
) {
_validationDialog.value = ConfirmationDialogUio(
- title = getString(title),
- description = getString(description),
+ title = title,
+ description = description,
onConfirmRequest = {
viewModelScope.launch {
- onConfirmationRequest()
+ onConfirmRequest()
+ onDismissRequest()
+ }
+ },
+ onDismissRequest = {
+ onDismissRequest()
+ },
+ )
+ }
+
+ private inline fun showEditDialog(
+ title: String,
+ value: String,
+ crossinline onConfirmRequest: suspend (String) -> Unit,
+ crossinline onDismissRequest: () -> Unit = { _editDialog.value = null },
+ ) {
+ val edit = createLwaTextFieldFlow(
+ label = value,
+ )
+ _editDialog.value = GMEditDialogUio(
+ title = title,
+ edit = edit.createLwaTextField(),
+ onConfirmRequest = {
+ viewModelScope.launch {
+ onConfirmRequest(edit.valueFlow.value)
onDismissRequest()
}
},
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMEditDialog.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMEditDialog.kt
new file mode 100644
index 0000000..8b519c2
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/action/GMEditDialog.kt
@@ -0,0 +1,97 @@
+package com.pixelized.desktop.lwa.ui.screen.gamemaster.action
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
+import androidx.compose.material.TextButton
+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.unit.Dp
+import androidx.compose.ui.unit.dp
+import com.pixelized.desktop.lwa.LocalBlurController
+import com.pixelized.desktop.lwa.ui.composable.character.LwaDialog
+import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextField
+import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio
+import lwacharactersheet.composeapp.generated.resources.Res
+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 GMEditDialogUio(
+ val title: String,
+ val edit: LwaTextFieldUio,
+ val onConfirmRequest: () -> Unit,
+ val onDismissRequest: () -> Unit,
+)
+
+@Stable
+object GMEditDialogDefault {
+
+ @Stable
+ val paddings = PaddingValues(start = 16.dp, top = 16.dp, end = 16.dp)
+
+ @Stable
+ val spacings: Dp = 8.dp
+}
+
+@Composable
+fun GMEditDialog(
+ modifier: Modifier = Modifier,
+ paddingValues: PaddingValues = GMEditDialogDefault.paddings,
+ spacing: Dp = GMEditDialogDefault.spacings,
+ dialog: State,
+) {
+ LwaDialog(
+ modifier = modifier,
+ blur = LocalBlurController.current,
+ state = dialog,
+ onDismissRequest = { dialog.value?.onDismissRequest?.invoke() },
+ onConfirm = { dialog.value?.onConfirmRequest?.invoke() },
+ ) {
+ Column(
+ modifier = Modifier.padding(paddingValues = paddingValues),
+ verticalArrangement = Arrangement.spacedBy(space = spacing),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ Text(
+ style = MaterialTheme.typography.caption,
+ text = it.title,
+ )
+ LwaTextField(
+ field = it.edit,
+ )
+ Row(
+ modifier = Modifier.align(alignment = Alignment.End),
+ horizontalArrangement = Arrangement.spacedBy(
+ space = spacing / 2,
+ alignment = Alignment.End,
+ ),
+ ) {
+ TextButton(
+ onClick = it.onDismissRequest,
+ ) {
+ Text(
+ color = MaterialTheme.colors.primaryVariant,
+ text = stringResource(Res.string.dialog__cancel_action)
+ )
+ }
+ TextButton(
+ onClick = it.onConfirmRequest,
+ ) {
+ Text(
+ color = MaterialTheme.colors.primary,
+ text = stringResource(Res.string.dialog__confirm_action)
+ )
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/extention/LayoutDirection+Invert.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/extention/LayoutDirection+Invert.kt
index 35ca892..7600a6b 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/extention/LayoutDirection+Invert.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/extention/LayoutDirection+Invert.kt
@@ -1,8 +1,10 @@
package com.pixelized.desktop.lwa.utils.extention
+import androidx.compose.runtime.Stable
import androidx.compose.ui.unit.LayoutDirection
val LayoutDirection.invert: LayoutDirection
+ @Stable
get() = when (this) {
LayoutDirection.Ltr -> LayoutDirection.Rtl
LayoutDirection.Rtl -> LayoutDirection.Ltr
diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/factory/CampaignJsonFactory.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/factory/CampaignJsonFactory.kt
index ddda468..1a4314d 100644
--- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/factory/CampaignJsonFactory.kt
+++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/factory/CampaignJsonFactory.kt
@@ -29,6 +29,14 @@ class CampaignJsonFactory(
// Json conversion.
+ fun createScene(
+ title: String,
+ ): CampaignJsonV2.SceneJsonV2 {
+ return CampaignJsonV2.SceneJsonV2(
+ name = title,
+ )
+ }
+
fun convertToJson(
campaign: Campaign,
): CampaignJson {