diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index 3501227..0df87e7 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -242,6 +242,7 @@
Ajouter aux Npcs
Retirer des Npcs
Créer un personnage
+ Édition d'Altération
Filtrer par nom :
Créer une altération
Supprimer l'altération
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/App.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/App.kt
index b2e5a63..acd03fc 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/App.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/App.kt
@@ -1,5 +1,8 @@
package com.pixelized.desktop.lwa
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.MaterialTheme
@@ -10,11 +13,13 @@ import androidx.compose.material.SnackbarDefaults
import androidx.compose.material.SnackbarDuration
import androidx.compose.material.SnackbarHost
import androidx.compose.material.SnackbarHostState
+import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
@@ -47,6 +52,7 @@ 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.overlay.roll.RollHostState
import com.pixelized.desktop.lwa.ui.screen.characterSheet.CharacterSheetMainNavHost
+import com.pixelized.desktop.lwa.ui.screen.gamemaster.GameMasterNavHost
import com.pixelized.desktop.lwa.ui.screen.gamemaster.GameMasterScreen
import com.pixelized.desktop.lwa.ui.screen.rollhistory.RollHistoryPage
import com.pixelized.desktop.lwa.ui.theme.LwaTheme
@@ -146,7 +152,7 @@ private fun MainWindowScreen(
}
LwaScaffold(
- modifier = Modifier.fillMaxSize(),
+ modifier = Modifier.fillMaxSize()
) {
MainNavHost()
@@ -179,7 +185,7 @@ private fun WindowsHandler(
is RollHistoryWindow -> RollHistoryPage()
is GameMasterWindow -> LwaScaffold {
- GameMasterScreen()
+ GameMasterNavHost()
}
}
}
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/DataSyncViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/DataSyncViewModel.kt
index 349d046..4cc3f87 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/DataSyncViewModel.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/DataSyncViewModel.kt
@@ -6,6 +6,7 @@ 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.repository.settings.SettingsRepository
+import com.pixelized.desktop.lwa.repository.tag.TagRepository
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -19,6 +20,7 @@ class DataSyncViewModel(
private val characterRepository: CharacterSheetRepository,
private val alterationRepository: AlterationRepository,
private val campaignRepository: CampaignRepository,
+ private val tagRepository: TagRepository,
private val settingsRepository: SettingsRepository,
private val networkRepository: NetworkRepository,
) : ViewModel() {
@@ -40,10 +42,10 @@ class DataSyncViewModel(
networkRepository.status
.filter { status -> status == NetworkRepository.Status.CONNECTED }
.onEach {
+ tagRepository.updateAlterationTags()
alterationRepository.updateAlterations()
- alterationRepository.updateTags()
+ tagRepository.updateCharacterTags()
characterRepository.updateCharacterPreviews()
- characterRepository.updateTags()
campaignRepository.updateCampaign()
}
.launchIn(this)
@@ -54,9 +56,8 @@ class DataSyncViewModel(
.distinctUntilChanged()
.onEach { instances ->
instances.forEach { characterSheetId ->
- characterRepository.characterDetail(
+ characterRepository.updateCharacterSheet(
characterSheetId = characterSheetId,
- forceUpdate = true,
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt
index 9d9574f..4c03877 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt
@@ -13,6 +13,8 @@ import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository
import com.pixelized.desktop.lwa.repository.settings.SettingsFactory
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
import com.pixelized.desktop.lwa.repository.settings.SettingsStore
+import com.pixelized.desktop.lwa.repository.tag.TagRepository
+import com.pixelized.desktop.lwa.repository.tag.TagStore
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.diminished.CharacterSheetDiminishedDialogFactory
@@ -37,9 +39,9 @@ import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common.SkillField
import com.pixelized.desktop.lwa.ui.screen.gamemaster.GameMasterViewModel
import com.pixelized.desktop.lwa.ui.screen.gamemaster.action.GMActionViewModel
import com.pixelized.desktop.lwa.ui.screen.gamemaster.alteration.edit.GMAlterationEditFactory
+import com.pixelized.desktop.lwa.ui.screen.gamemaster.alteration.edit.GMAlterationEditViewModel
import com.pixelized.desktop.lwa.ui.screen.gamemaster.alteration.list.GMAlterationFactory
import com.pixelized.desktop.lwa.ui.screen.gamemaster.alteration.list.GMAlterationViewModel
-import com.pixelized.desktop.lwa.ui.screen.gamemaster.alteration.edit.GMAlterationEditViewModel
import com.pixelized.desktop.lwa.ui.screen.gamemaster.character.list.GMCharacterFactory
import com.pixelized.desktop.lwa.ui.screen.gamemaster.character.list.GMCharacterViewModel
import com.pixelized.desktop.lwa.ui.screen.gamemaster.common.tag.GMTagFactory
@@ -100,6 +102,7 @@ val storeDependencies
singleOf(::SettingsStore)
singleOf(::AlterationStore)
singleOf(::CampaignStore)
+ singleOf(::TagStore)
}
val repositoryDependencies
@@ -110,6 +113,7 @@ val repositoryDependencies
singleOf(::SettingsRepository)
singleOf(::AlterationRepository)
singleOf(::CampaignRepository)
+ singleOf(::TagRepository)
}
val factoryDependencies
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 24e8365..e3c66b8 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
@@ -5,83 +5,89 @@ import com.pixelized.shared.lwa.model.campaign.CampaignJson
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJson
import com.pixelized.shared.lwa.model.tag.TagJson
import com.pixelized.shared.lwa.protocol.rest.CharacterPreviewJson
+import com.pixelized.shared.lwa.protocol.rest.APIResponse
interface LwaClient {
// Alteration
- suspend fun alterations(): List
+ suspend fun getAlterations(): APIResponse>
- suspend fun alterations(
+ suspend fun getAlteration(
alterationId: String,
- ): AlterationJson?
+ ): APIResponse
- suspend fun updateAlteration(
- alterationJson: AlterationJson
- )
+ suspend fun putAlteration(
+ alterationJson: AlterationJson,
+ create: Boolean,
+ ): APIResponse
suspend fun deleteAlteration(
alterationId: String,
- )
+ ): APIResponse
- suspend fun alterationTags(): List
+ suspend fun getAlterationTags(): APIResponse>
// Campaign
- suspend fun campaign(): CampaignJson
+ suspend fun getCampaign(): APIResponse
- suspend fun campaignAddCharacter(
+ suspend fun putCampaignCharacter(
characterSheetId: String,
- )
+ ): APIResponse
- suspend fun campaignRemoveCharacter(
+ suspend fun removeCampaignCharacter(
characterSheetId: String,
- )
+ ): APIResponse
- suspend fun campaignAddNpc(
+ suspend fun putCampaignNpc(
characterSheetId: String,
- )
+ ): APIResponse
- suspend fun campaignRemoveNpc(
+ suspend fun removeCampaignNpc(
characterSheetId: String,
- )
+ ): APIResponse
// Character
- suspend fun characters(): List
+ suspend fun getCharacters(): APIResponse>
- suspend fun characterTags(): List
+ suspend fun getCharacterTags(): APIResponse>
- suspend fun character(
+ suspend fun getCharacter(
characterSheetId: String,
- ): CharacterSheetJson
+ ): APIResponse
- suspend fun updateCharacter(
+ suspend fun putCharacter(
sheet: CharacterSheetJson,
- )
+ ): APIResponse
- suspend fun updateCharacterDamage(
+ suspend fun putCharacterDamage(
characterSheetId: String,
damage: Int,
- )
+ ): APIResponse
- suspend fun updateCharacterFatigue(
+ suspend fun putCharacterFatigue(
characterSheetId: String,
fatigue: Int,
- )
+ ): APIResponse
- suspend fun updateCharacterDiminished(
+ suspend fun putCharacterDiminished(
characterSheetId: String,
diminished: Int,
- )
+ ): APIResponse
- suspend fun updateCharacterAlteration(
+ suspend fun putCharacterAlteration(
characterSheetId: String,
alterationId: Int,
active: Boolean,
- )
+ ): APIResponse
suspend fun deleteCharacterSheet(
characterSheetId: String,
- )
+ ): APIResponse
+
+ companion object {
+ fun error(error: APIResponse<*>): Nothing = throw LwaNetworkException(error)
+ }
}
\ No newline at end of file
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 62d2449..cf4bf3a 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
@@ -5,6 +5,7 @@ import com.pixelized.shared.lwa.model.alteration.AlterationJson
import com.pixelized.shared.lwa.model.campaign.CampaignJson
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJson
import com.pixelized.shared.lwa.model.tag.TagJson
+import com.pixelized.shared.lwa.protocol.rest.APIResponse
import com.pixelized.shared.lwa.protocol.rest.CharacterPreviewJson
import io.ktor.client.HttpClient
import io.ktor.client.call.body
@@ -21,114 +22,134 @@ class LwaClientImpl(
) : LwaClient {
private val root = setting.settings().network.root
- override suspend fun alterations(): List = client
+ @Throws
+ override suspend fun getAlterations(): APIResponse> = client
.get("$root/alteration/all")
.body()
- override suspend fun alterations(
+ @Throws
+ override suspend fun getAlteration(
alterationId: String,
- ): AlterationJson? = client
+ ): APIResponse = client
.get("$root/alteration/detail?alterationId=$alterationId")
.body()
- override suspend fun updateAlteration(
- alterationJson: AlterationJson
+ @Throws
+ override suspend fun putAlteration(
+ alterationJson: AlterationJson,
+ create: Boolean,
) = client
- .put("$root/alteration/update") {
+ .put("$root/alteration/update?create=$create") {
contentType(ContentType.Application.Json)
setBody(alterationJson)
}
- .body()
+ .body>()
+ @Throws
override suspend fun deleteAlteration(alterationId: String) = client
.delete("$root/alteration/delete?alterationId=$alterationId")
- .body()
+ .body>()
- override suspend fun alterationTags(): List = client
+ @Throws
+ override suspend fun getAlterationTags(): APIResponse> = client
.get("$root/alteration/tags")
.body()
- override suspend fun campaign(): CampaignJson = client
+ @Throws
+ override suspend fun getCampaign(): APIResponse = client
.get("$root/campaign")
.body()
- override suspend fun campaignAddCharacter(
+ @Throws
+ override suspend fun putCampaignCharacter(
characterSheetId: String,
) = client
.put("$root/campaign/character/add?characterSheetId=$characterSheetId")
- .body()
+ .body>()
- override suspend fun campaignRemoveCharacter(
+ @Throws
+ override suspend fun removeCampaignCharacter(
characterSheetId: String,
) = client
.delete("$root/campaign/character/delete?characterSheetId=$characterSheetId")
- .body()
+ .body>()
- override suspend fun campaignAddNpc(
+ @Throws
+ override suspend fun putCampaignNpc(
characterSheetId: String,
) = client
.put("$root/campaign/npc/add?characterSheetId=$characterSheetId")
- .body()
+ .body>()
- override suspend fun campaignRemoveNpc(
+ @Throws
+ override suspend fun removeCampaignNpc(
characterSheetId: String,
) = client
.delete("$root/campaign/npc/delete?characterSheetId=$characterSheetId")
- .body()
+ .body>()
- override suspend fun characters(): List = client
+ @Throws
+ override suspend fun getCharacters(): APIResponse> = client
.get("$root/character/all")
.body()
- override suspend fun characterTags(): List = client
+ @Throws
+ override suspend fun getCharacterTags(): APIResponse> = client
.get("$root/character/tags")
.body()
- override suspend fun character(
+ @Throws
+ override suspend fun getCharacter(
characterSheetId: String,
- ): CharacterSheetJson = client
+ ): APIResponse = client
.get("$root/character/detail?characterSheetId=$characterSheetId")
.body()
- override suspend fun updateCharacter(
+ @Throws
+ override suspend fun putCharacter(
sheet: CharacterSheetJson,
) = client
.put("$root/character/update/sheet") {
contentType(ContentType.Application.Json)
setBody(sheet)
}
- .body()
+ .body>()
- override suspend fun updateCharacterDamage(
+ @Throws
+ override suspend fun putCharacterDamage(
characterSheetId: String,
damage: Int,
) = client
.put("$root/character/update/damage?characterSheetId=$characterSheetId&damage=$damage")
- .body()
+ .body>()
- override suspend fun updateCharacterFatigue(
+ @Throws
+ override suspend fun putCharacterFatigue(
characterSheetId: String,
fatigue: Int,
) = client
.put("$root/character/update/fatigue?characterSheetId=$characterSheetId&fatigue=$fatigue")
- .body()
+ .body>()
- override suspend fun updateCharacterDiminished(
+ @Throws
+ override suspend fun putCharacterDiminished(
characterSheetId: String,
diminished: Int,
) = client
.put("$root/character/update/diminished?characterSheetId=$characterSheetId&diminished=$diminished")
- .body()
+ .body>()
- override suspend fun updateCharacterAlteration(
+ @Throws
+ override suspend fun putCharacterAlteration(
characterSheetId: String,
alterationId: Int,
active: Boolean,
) = client
.put("$root/character/update/alteration?characterSheetId=$characterSheetId&alterationId=$alterationId&active=$active")
- .body()
+ .body>()
+ @Throws
override suspend fun deleteCharacterSheet(characterSheetId: String) = client
.delete("$root/character/delete?characterSheetId=$characterSheetId")
- .body()
+ .body>()
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/network/LwaNetworkException.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/network/LwaNetworkException.kt
new file mode 100644
index 0000000..753751a
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/network/LwaNetworkException.kt
@@ -0,0 +1,15 @@
+package com.pixelized.desktop.lwa.network
+
+import com.pixelized.shared.lwa.protocol.rest.APIResponse
+
+class LwaNetworkException(
+ val status: Int,
+ val code: APIResponse.ErrorCode?,
+ message: String,
+) : Exception(message) {
+ constructor(error: APIResponse<*>) : this(
+ status = error.status,
+ code = error.code,
+ message = error.message ?: "An unknown error occurred"
+ )
+}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/alteration/AlterationRepository.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/alteration/AlterationRepository.kt
index 7687eaa..18be883 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/alteration/AlterationRepository.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/alteration/AlterationRepository.kt
@@ -19,6 +19,7 @@ import kotlinx.coroutines.flow.stateIn
class AlterationRepository(
private val alterationStore: AlterationStore,
+
campaignRepository: CampaignRepository,
characterRepository: CharacterSheetRepository,
) {
@@ -26,8 +27,6 @@ class AlterationRepository(
val alterationFlow get() = alterationStore.alterationsFlow
- val tagsFlow get() = alterationStore.tagsFlow
-
/**
* This flow transform the campaign instance (player + npc) into a
* Map>.
@@ -66,11 +65,7 @@ class AlterationRepository(
)
suspend fun updateAlterations() {
- alterationStore.updateAlterations()
- }
-
- suspend fun updateTags() {
- alterationStore.updateTags()
+ alterationStore.updateAlterationsFlow()
}
fun alteration(
@@ -91,10 +86,15 @@ class AlterationRepository(
return activeAlterationMapFlow.map { it[characterSheetId] ?: emptyMap() }
}
+ @Throws
suspend fun updateAlteration(
- alteration: Alteration
+ alteration: Alteration,
+ create: Boolean,
) {
- alterationStore.putAlteration(alteration)
+ alterationStore.putAlteration(
+ alteration = alteration,
+ create = create,
+ )
}
suspend fun deleteAlteration(
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/alteration/AlterationStore.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/alteration/AlterationStore.kt
index 1924f74..708f579 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/alteration/AlterationStore.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/alteration/AlterationStore.kt
@@ -4,8 +4,6 @@ import com.pixelized.desktop.lwa.network.LwaClient
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
import com.pixelized.shared.lwa.model.alteration.Alteration
import com.pixelized.shared.lwa.model.alteration.AlterationJsonFactory
-import com.pixelized.shared.lwa.model.tag.Tag
-import com.pixelized.shared.lwa.model.tag.TagJsonFactory
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
import kotlinx.coroutines.CoroutineScope
@@ -17,26 +15,18 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
class AlterationStore(
- private val networkRepository: NetworkRepository,
- private val alterationFactory: AlterationJsonFactory,
- private val tagFactory: TagJsonFactory,
+ private val network: NetworkRepository,
+ private val factory: AlterationJsonFactory,
private val client: LwaClient,
) {
private val _alterationsFlow = MutableStateFlow