Update client to add throw consume equip to InventoryItem.
This commit is contained in:
parent
9fce3f1cb8
commit
ae820f5979
22 changed files with 791 additions and 121 deletions
|
|
@ -184,8 +184,9 @@
|
|||
<string name="character_sheet__delete_dialog__title">Supprimer la feuille de personnage</string>
|
||||
<string name="character_sheet__delete_dialog__description">Êtes-vous sûr de vouloir supprimer "%1$s" ?</string>
|
||||
|
||||
<string name="character__inventory__add_to_inventory__action">Ajouter un objet</string>
|
||||
<string name="character__inventory__filter_inventory__label">Filtrer l'inventaire</string>
|
||||
<string name="character__inventory__add_to_inventory__action">Ajouter un objet</string>
|
||||
<string name="character__inventory__use__action">Utiliser</string>
|
||||
<string name="character__inventory__add_to_purse__title">Ajouter à la bourse</string>
|
||||
<string name="character__inventory__remove_from_purse__title">Retirer de la bourse</string>
|
||||
<string name="character__inventory__filter_item_inventory__label">Filtrer les objets</string>
|
||||
|
|
@ -193,6 +194,9 @@
|
|||
<string name="character__inventory__inventory__dialog__action">Ajouter à l'inventaire</string>
|
||||
<string name="character__inventory__inventory__dialog__count">Quantité</string>
|
||||
<string name="character__inventory__inventory__dialog__count_action">Modifier</string>
|
||||
<string name="character__inventory__inventory__dialog__throw_action">Jetter</string>
|
||||
<string name="character__inventory__inventory__dialog__equip_action">Equiper</string>
|
||||
<string name="character__inventory__inventory__dialog__consume_action">Utiliser</string>
|
||||
<string name="character__inventory__description_empty__label">Cet objet n'a pas de description.</string>
|
||||
|
||||
<string name="tooltip__characteristics__characteristics">Les caractéristiques constituent les aptitudes innées d’un personnage comme son intelligence, sa force, son charisme, etc. Elles ne sont pas acquises, mais peuvent être parfois augmentées par un entraînement ou une utilisation réussie. Les caractéristiques des humains normaux varient de 2 (niveau extrêmement bas) à 20 (maximum du potentiel humain), avec une moyenne de 10 ou 11. Plus une caractéristique est élevée plus le personnage est puissant dans cette aptitude.\nÀ la création de votre personnage, répartissez les valeurs suivantes dans les différentes caractéristiques : 15, 15, 13, 11, 10, 9 et 7.</string>
|
||||
|
|
|
|||
|
|
@ -115,13 +115,35 @@ interface LwaClient {
|
|||
create: Boolean,
|
||||
): APIResponse<Unit>
|
||||
|
||||
suspend fun deleteInventory(
|
||||
characterSheetId: String,
|
||||
): APIResponse<Unit>
|
||||
|
||||
suspend fun createInventoryItem(
|
||||
characterSheetId: String,
|
||||
itemId: String,
|
||||
): APIResponse<String>
|
||||
|
||||
suspend fun deleteInventory(
|
||||
suspend fun changeInventoryItemCount(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
count: Float,
|
||||
): APIResponse<Unit>
|
||||
|
||||
suspend fun equipInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
equip: Boolean,
|
||||
): APIResponse<Unit>
|
||||
|
||||
suspend fun consumeInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
): APIResponse<Unit>
|
||||
|
||||
suspend fun deleteInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
): APIResponse<Unit>
|
||||
|
||||
// Tags
|
||||
|
|
|
|||
|
|
@ -192,18 +192,52 @@ class LwaClientImpl(
|
|||
}
|
||||
.body<APIResponse<Unit>>()
|
||||
|
||||
@Throws
|
||||
override suspend fun deleteInventory(characterSheetId: String): APIResponse<Unit> = client
|
||||
.delete("$root/inventory/delete?characterSheetId=$characterSheetId")
|
||||
.body()
|
||||
|
||||
@Throws
|
||||
override suspend fun createInventoryItem(
|
||||
characterSheetId: String,
|
||||
itemId: String,
|
||||
): APIResponse<String> = client
|
||||
.put("$root/inventory/create?characterSheetId=$characterSheetId&itemId=$itemId")
|
||||
.put("$root/inventory/item/create?characterSheetId=$characterSheetId&itemId=$itemId")
|
||||
.body<APIResponse<String>>()
|
||||
|
||||
@Throws
|
||||
override suspend fun deleteInventory(characterSheetId: String): APIResponse<Unit> = client
|
||||
.delete("$root/inventory/delete?characterSheetId=$characterSheetId")
|
||||
.body()
|
||||
override suspend fun changeInventoryItemCount(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
count: Float,
|
||||
): APIResponse<Unit> = client
|
||||
.put("$root/inventory/item/count?characterSheetId=$characterSheetId&inventoryId=$inventoryId&count=$count")
|
||||
.body<APIResponse<Unit>>()
|
||||
|
||||
@Throws
|
||||
override suspend fun equipInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
equip: Boolean,
|
||||
): APIResponse<Unit> = client
|
||||
.put("$root/inventory/item/equip?characterSheetId=$characterSheetId&inventoryId=$inventoryId&equip=$equip")
|
||||
.body<APIResponse<Unit>>()
|
||||
|
||||
@Throws
|
||||
override suspend fun consumeInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
): APIResponse<Unit> = client
|
||||
.put("$root/inventory/item/consume?characterSheetId=$characterSheetId&inventoryId=$inventoryId")
|
||||
.body<APIResponse<Unit>>()
|
||||
|
||||
@Throws
|
||||
override suspend fun deleteInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
): APIResponse<Unit> = client
|
||||
.delete("$root/inventory/item/delete?characterSheetId=$characterSheetId&inventoryId=$inventoryId")
|
||||
.body<APIResponse<Unit>>()
|
||||
|
||||
@Throws
|
||||
override suspend fun getAlterationTags(): APIResponse<List<TagJson>> = client
|
||||
|
|
|
|||
|
|
@ -53,11 +53,52 @@ class InventoryRepository(
|
|||
}
|
||||
|
||||
@Throws
|
||||
suspend fun deleteItem(
|
||||
suspend fun changeInventoryItemCount(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
count: Float,
|
||||
) {
|
||||
inventoryStore.deleteInventory(
|
||||
inventoryStore.changeInventoryItemCount(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
count = count,
|
||||
)
|
||||
}
|
||||
|
||||
@Throws
|
||||
suspend fun consumeInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
) {
|
||||
inventoryStore.consumeInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
)
|
||||
}
|
||||
|
||||
@Throws
|
||||
suspend fun equipInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
) {
|
||||
val inventory = inventory(characterSheetId = characterSheetId)
|
||||
val inventoryItem = inventory.items.firstOrNull { it.inventoryId == inventoryId }
|
||||
|
||||
inventoryStore.equipInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
equip = inventoryItem?.equipped?.not() ?: true,
|
||||
)
|
||||
}
|
||||
|
||||
@Throws
|
||||
suspend fun deleteInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
) {
|
||||
inventoryStore.deleteInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -73,6 +73,16 @@ class InventoryStore(
|
|||
}
|
||||
}
|
||||
|
||||
@Throws
|
||||
suspend fun deleteInventory(
|
||||
characterSheetId: String,
|
||||
) {
|
||||
val request = client.deleteInventory(characterSheetId = characterSheetId)
|
||||
if (request.success.not()) {
|
||||
LwaClient.error(error = request)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws
|
||||
suspend fun createInventoryItem(
|
||||
characterSheetId: String,
|
||||
|
|
@ -89,10 +99,60 @@ class InventoryStore(
|
|||
}
|
||||
|
||||
@Throws
|
||||
suspend fun deleteInventory(
|
||||
suspend fun changeInventoryItemCount(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
count: Float,
|
||||
) {
|
||||
val request = client.deleteInventory(characterSheetId = characterSheetId)
|
||||
val request = client.changeInventoryItemCount(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
count = count,
|
||||
)
|
||||
if (request.success.not()) {
|
||||
LwaClient.error(error = request)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws
|
||||
suspend fun consumeInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
) {
|
||||
val request = client.consumeInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
)
|
||||
if (request.success.not()) {
|
||||
LwaClient.error(error = request)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws
|
||||
suspend fun equipInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
equip: Boolean,
|
||||
) {
|
||||
val request = client.equipInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
equip = equip,
|
||||
)
|
||||
if (request.success.not()) {
|
||||
LwaClient.error(error = request)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws
|
||||
suspend fun deleteInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
) {
|
||||
val request = client.deleteInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
)
|
||||
if (request.success.not()) {
|
||||
LwaClient.error(error = request)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package com.pixelized.desktop.lwa.ui.composable.character.item
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
|
|
@ -42,7 +45,10 @@ import com.pixelized.desktop.lwa.ui.theme.lwa
|
|||
import com.pixelized.desktop.lwa.utils.rememberSaturationFilter
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__action
|
||||
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__consume_action
|
||||
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__count_action
|
||||
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__equip_action
|
||||
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__throw_action
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_close_24dp
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
|
|
@ -59,12 +65,14 @@ data class ItemDetailDialogUio(
|
|||
val count: Float,
|
||||
// options
|
||||
val countable: LwaTextFieldUio?,
|
||||
val consumable: Boolean,
|
||||
val equipable: Boolean,
|
||||
)
|
||||
|
||||
@Stable
|
||||
object ItemDetailDialogDefault {
|
||||
@Stable
|
||||
val paddings = PaddingValues(all = 16.dp)
|
||||
val paddings = PaddingValues(top = 16.dp, start = 16.dp, end = 16.dp, bottom = 8.dp)
|
||||
|
||||
@Stable
|
||||
val spacings = 8.dp
|
||||
|
|
@ -78,6 +86,9 @@ fun ItemDetailDialog(
|
|||
onDismissRequest: () -> Unit,
|
||||
onConfirm: (ItemDetailDialogUio) -> Unit,
|
||||
onAddItem: (ItemDetailDialogUio) -> Unit,
|
||||
onEquip: (ItemDetailDialogUio) -> Unit,
|
||||
onConsume: (ItemDetailDialogUio) -> Unit,
|
||||
onThrow: (ItemDetailDialogUio) -> Unit,
|
||||
) {
|
||||
LwaDialog(
|
||||
state = dialog,
|
||||
|
|
@ -85,7 +96,8 @@ fun ItemDetailDialog(
|
|||
onConfirm = { dialog.value?.let(onConfirm) ?: onDismissRequest },
|
||||
) { state ->
|
||||
val layoutDirection = LocalLayoutDirection.current
|
||||
val end = remember(layoutDirection, paddings) { paddings.calculateEndPadding(layoutDirection) }
|
||||
val end =
|
||||
remember(layoutDirection, paddings) { paddings.calculateEndPadding(layoutDirection) }
|
||||
val top = remember(paddings) { paddings.calculateTopPadding() }
|
||||
|
||||
takeIf { state.image?.isNotEmpty() == true }?.let {
|
||||
|
|
@ -140,6 +152,7 @@ fun ItemDetailDialog(
|
|||
|
||||
AnimatedContent(
|
||||
targetState = state.inventoryId,
|
||||
transitionSpec = { fadeIn() togetherWith fadeOut() },
|
||||
) {
|
||||
when (it) {
|
||||
null -> Row(
|
||||
|
|
@ -158,14 +171,12 @@ fun ItemDetailDialog(
|
|||
else -> Column(
|
||||
verticalArrangement = Arrangement.spacedBy(space = spacings)
|
||||
) {
|
||||
if (state.countable != null) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
space = spacings,
|
||||
Alignment.End,
|
||||
)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = spacings),
|
||||
verticalAlignment = Alignment.Bottom,
|
||||
) {
|
||||
if (state.countable != null) {
|
||||
LwaTextField(
|
||||
modifier = Modifier.width(width = 128.dp),
|
||||
colors = LwaTextFieldColors(
|
||||
|
|
@ -188,6 +199,34 @@ fun ItemDetailDialog(
|
|||
)
|
||||
}
|
||||
}
|
||||
Spacer(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
)
|
||||
TextButton(
|
||||
onClick = { onThrow(state) },
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(Res.string.character__inventory__inventory__dialog__throw_action),
|
||||
)
|
||||
}
|
||||
if (state.equipable) {
|
||||
TextButton(
|
||||
onClick = { onEquip(state) },
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(Res.string.character__inventory__inventory__dialog__equip_action),
|
||||
)
|
||||
}
|
||||
}
|
||||
if (state.consumable) {
|
||||
TextButton(
|
||||
onClick = { onConsume(state) },
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(Res.string.character__inventory__inventory__dialog__consume_action),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ class ItemDetailDialogFactory {
|
|||
countable = takeIf { item.options.stackable }
|
||||
?.let { createFieldFlow(value = format.format(count)) }
|
||||
?.createTextField(label = getString(Res.string.character__inventory__inventory__dialog__count)),
|
||||
consumable = item.options.consumable,
|
||||
equipable = item.options.equipable,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,49 +83,99 @@ class ItemDetailDialogViewModel(
|
|||
suspend fun onAddInventoryItem(
|
||||
characterSheetId: String,
|
||||
itemId: String,
|
||||
) {
|
||||
) : Boolean {
|
||||
try {
|
||||
// create the inventory item on the server, get the newly create id from that.
|
||||
val inventoryId = inventoryRepository.createInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
itemId = itemId,
|
||||
)
|
||||
return true
|
||||
// update the dialog with the id only if this dialog still correspond to this item. (should always be the case but hey).
|
||||
if (selectedItemId.value?.let { it.itemId == itemId && it.characterSheetId == characterSheetId } == true) {
|
||||
selectedItemId.update {
|
||||
it?.copy(inventoryId = inventoryId)
|
||||
}
|
||||
}
|
||||
// if (selectedItemId.value?.let { it.itemId == itemId && it.characterSheetId == characterSheetId } == true) {
|
||||
// selectedItemId.update {
|
||||
// it?.copy(inventoryId = inventoryId)
|
||||
// }
|
||||
// }
|
||||
} catch (exception: Exception) {
|
||||
val message = ErrorSnackUio.from(exception)
|
||||
_error.emit(message)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun throwInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String?,
|
||||
): Boolean {
|
||||
if (inventoryId == null) return false
|
||||
try {
|
||||
inventoryRepository.deleteInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
)
|
||||
return true
|
||||
} catch (exception: Exception) {
|
||||
val message = ErrorSnackUio.from(exception)
|
||||
_error.emit(message)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun consumeInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String?,
|
||||
): Boolean {
|
||||
if (inventoryId == null) return false
|
||||
try {
|
||||
inventoryRepository.consumeInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
)
|
||||
return true
|
||||
} catch (exception: Exception) {
|
||||
val message = ErrorSnackUio.from(exception)
|
||||
_error.emit(message)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun equipInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String?,
|
||||
) : Boolean {
|
||||
if (inventoryId == null) return false
|
||||
try {
|
||||
inventoryRepository.equipInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
)
|
||||
return true
|
||||
} catch (exception: Exception) {
|
||||
val message = ErrorSnackUio.from(exception)
|
||||
_error.emit(message)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun changeInventoryItemQuantity(
|
||||
dialog: ItemDetailDialogUio
|
||||
) : Boolean {
|
||||
dialog: ItemDetailDialogUio,
|
||||
): Boolean {
|
||||
if (dialog.countable?.isError?.value == true) return false
|
||||
|
||||
val characterSheetId = dialog.characterSheetId
|
||||
val inventoryId = dialog.inventoryId ?: return false
|
||||
val quantity = dialog.countable?.valueFlow?.value ?: return false
|
||||
|
||||
val count = factory.parse(quantity = quantity) ?: return false
|
||||
|
||||
val inventory = inventoryRepository.inventory(characterSheetId = characterSheetId)
|
||||
val count = factory.parse(quantity = quantity)
|
||||
?: quantity.toFloatOrNull()
|
||||
?: return false
|
||||
|
||||
try {
|
||||
inventoryRepository.updateInventory(
|
||||
inventory = inventory.copy(
|
||||
items = inventory.items.toMutableList().also { items ->
|
||||
val index = items.indexOfFirst { item -> item.inventoryId == inventoryId }
|
||||
items[index] = items[index].copy(
|
||||
count = count,
|
||||
)
|
||||
}
|
||||
),
|
||||
create = false,
|
||||
inventoryRepository.changeInventoryItemCount(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
count = count
|
||||
)
|
||||
return true
|
||||
} catch (exception: Exception) {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil3.compose.rememberDrawScopeSizeResolver
|
||||
import com.pixelized.desktop.lwa.LocalBlurController
|
||||
import com.pixelized.desktop.lwa.ui.composable.character.inventory.InventoryDialog
|
||||
import com.pixelized.desktop.lwa.ui.composable.character.inventory.InventoryDialogViewModel
|
||||
|
|
@ -118,6 +117,14 @@ fun CharacterDetailInventory(
|
|||
inventoryDialogViewModel.showInventoryDialog(
|
||||
characterSheetId = it,
|
||||
)
|
||||
},
|
||||
onConsume = {
|
||||
scope.launch {
|
||||
itemDetailDialogViewModel.consumeInventoryItem(
|
||||
characterSheetId = it.characterSheetId,
|
||||
inventoryId = it.inventoryId,
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -165,10 +172,14 @@ fun CharacterDetailInventory(
|
|||
},
|
||||
onAddItem = { dialog ->
|
||||
scope.launch {
|
||||
itemDetailDialogViewModel.onAddInventoryItem(
|
||||
val result = itemDetailDialogViewModel.onAddInventoryItem(
|
||||
characterSheetId = dialog.characterSheetId,
|
||||
itemId = dialog.itemId,
|
||||
)
|
||||
if (result) {
|
||||
blur.hide()
|
||||
itemDetailDialogViewModel.hideItemDialog()
|
||||
}
|
||||
}
|
||||
},
|
||||
onConfirm = { dialog ->
|
||||
|
|
@ -181,12 +192,51 @@ fun CharacterDetailInventory(
|
|||
itemDetailDialogViewModel.hideItemDialog()
|
||||
}
|
||||
}
|
||||
},
|
||||
onEquip = { dialog ->
|
||||
scope.launch {
|
||||
val result = itemDetailDialogViewModel.equipInventoryItem(
|
||||
characterSheetId = dialog.characterSheetId,
|
||||
inventoryId = dialog.inventoryId,
|
||||
)
|
||||
if (result) {
|
||||
blur.hide()
|
||||
itemDetailDialogViewModel.hideItemDialog()
|
||||
}
|
||||
}
|
||||
},
|
||||
onConsume = { dialog ->
|
||||
scope.launch {
|
||||
val result = itemDetailDialogViewModel.consumeInventoryItem(
|
||||
characterSheetId = dialog.characterSheetId,
|
||||
inventoryId = dialog.inventoryId,
|
||||
)
|
||||
if (result) {
|
||||
blur.hide()
|
||||
itemDetailDialogViewModel.hideItemDialog()
|
||||
}
|
||||
}
|
||||
},
|
||||
onThrow = { dialog ->
|
||||
scope.launch {
|
||||
val result = itemDetailDialogViewModel.throwInventoryItem(
|
||||
characterSheetId = dialog.characterSheetId,
|
||||
inventoryId = dialog.inventoryId,
|
||||
)
|
||||
if (result) {
|
||||
blur.hide()
|
||||
itemDetailDialogViewModel.hideItemDialog()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
ErrorSnackHandler(
|
||||
error = purseViewModel.error,
|
||||
)
|
||||
ErrorSnackHandler(
|
||||
error = itemDetailDialogViewModel.error,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -197,6 +247,7 @@ private fun CharacterDetailInventoryContent(
|
|||
inventory: CharacterDetailInventoryUio,
|
||||
onPurse: (String) -> Unit,
|
||||
onItem: (InventoryItemUio) -> Unit,
|
||||
onConsume: (InventoryItemUio) -> Unit,
|
||||
onAddItem: (String) -> Unit,
|
||||
) {
|
||||
Box(
|
||||
|
|
@ -257,6 +308,7 @@ private fun CharacterDetailInventoryContent(
|
|||
modifier = Modifier.animateItem(),
|
||||
item = it,
|
||||
onClick = { onItem(it) },
|
||||
onConsume = { onConsume(it) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ class CharacterDetailInventoryFactory(
|
|||
label = item.metadata.label,
|
||||
count = it.count,
|
||||
equipped = it.equipped,
|
||||
consumable = item.options.consumable,
|
||||
tooltips = takeIf { item.metadata.description.isNotEmpty() }?.let {
|
||||
InventoryItemUio.Tooltips(
|
||||
label = item.metadata.label,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import androidx.compose.foundation.layout.size
|
|||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.material.minimumInteractiveComponentSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
|
|
@ -38,6 +39,9 @@ import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipLayout2
|
|||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import com.pixelized.desktop.lwa.utils.extention.ribbon
|
||||
import com.pixelized.desktop.lwa.utils.rememberSaturationFilter
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.character__inventory__use__action
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
|
||||
@Stable
|
||||
data class InventoryItemUio(
|
||||
|
|
@ -47,6 +51,7 @@ data class InventoryItemUio(
|
|||
val label: String,
|
||||
val count: Float,
|
||||
val equipped: Boolean,
|
||||
val consumable: Boolean,
|
||||
val tooltips: Tooltips?,
|
||||
) {
|
||||
@Stable
|
||||
|
|
@ -60,7 +65,7 @@ data class InventoryItemUio(
|
|||
@Stable
|
||||
object GMCharacterPreviewDefault {
|
||||
@Stable
|
||||
val paddings = PaddingValues(horizontal = 16.dp, vertical = 4.dp)
|
||||
val paddings = PaddingValues(horizontal = 16.dp)
|
||||
|
||||
@Stable
|
||||
val spacing: Dp = 4.dp
|
||||
|
|
@ -74,6 +79,7 @@ fun InventoryItem(
|
|||
spacing: Dp = GMCharacterPreviewDefault.spacing,
|
||||
item: InventoryItemUio,
|
||||
onClick: () -> Unit,
|
||||
onConsume: () -> Unit,
|
||||
) {
|
||||
TooltipLayout2(
|
||||
modifier = modifier,
|
||||
|
|
@ -134,30 +140,41 @@ fun InventoryItem(
|
|||
.fillMaxWidth()
|
||||
.padding(paddingValues = padding)
|
||||
.then(other = modifier),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = spacing),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.lwa.typography.base.body1,
|
||||
fontWeight = FontWeight.Bold,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = item.label,
|
||||
)
|
||||
AnimatedContent(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
targetState = item.count,
|
||||
transitionSpec = { fadeIn() togetherWith fadeOut() },
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = spacing),
|
||||
) {
|
||||
when (it) {
|
||||
0f, 1f -> Unit
|
||||
else -> Text(
|
||||
style = MaterialTheme.lwa.typography.base.caption,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = "x${it}",
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.lwa.typography.base.body1,
|
||||
fontWeight = FontWeight.Bold,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = item.label,
|
||||
)
|
||||
AnimatedContent(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
targetState = item.count,
|
||||
transitionSpec = { fadeIn() togetherWith fadeOut() },
|
||||
) {
|
||||
when (it) {
|
||||
0f, 1f -> Unit
|
||||
else -> Text(
|
||||
style = MaterialTheme.lwa.typography.base.caption,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = "x${it}",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item.consumable) {
|
||||
TextButton(
|
||||
onClick = onConsume,
|
||||
) {
|
||||
Text(text = stringResource(Res.string.character__inventory__use__action))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.pixelized.server.lwa.model.inventory
|
||||
|
||||
import com.pixelized.server.lwa.model.item.ItemStore
|
||||
import com.pixelized.server.lwa.server.exception.BusinessException
|
||||
import com.pixelized.shared.lwa.model.inventory.Inventory
|
||||
import com.pixelized.shared.lwa.model.inventory.InventoryJson
|
||||
import com.pixelized.shared.lwa.model.inventory.factory.InventoryJsonFactory
|
||||
|
|
@ -9,9 +11,11 @@ import kotlinx.coroutines.Job
|
|||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import java.util.UUID
|
||||
|
||||
class InventoryService(
|
||||
private val inventoryStore: InventoryStore,
|
||||
private val itemStore: ItemStore,
|
||||
private val factory: InventoryJsonFactory,
|
||||
) {
|
||||
private val scope = CoroutineScope(Dispatchers.IO + Job())
|
||||
|
|
@ -51,13 +55,185 @@ class InventoryService(
|
|||
}
|
||||
|
||||
@Throws
|
||||
fun createItem(
|
||||
fun createInventoryItem(
|
||||
characterSheetId: String,
|
||||
itemId: String,
|
||||
) : String {
|
||||
return inventoryStore.createItem(
|
||||
characterSheetId = characterSheetId,
|
||||
): String {
|
||||
// get the inventory of the character, if none create one.
|
||||
val inventory = inventoryStore.inventoryFlow().value[characterSheetId]
|
||||
?: Inventory.empty(characterSheetId = characterSheetId)
|
||||
// create an inventoryId.
|
||||
val inventoryId = inventory.items.createInventoryId()
|
||||
// create an inventory Item.
|
||||
val item = Inventory.Item(
|
||||
inventoryId = inventoryId,
|
||||
itemId = itemId,
|
||||
count = 1f,
|
||||
equipped = false,
|
||||
)
|
||||
// update the inventory with the updated item.
|
||||
val updatedInventory = inventory.copy(
|
||||
items = inventory.items.toMutableList().also {
|
||||
it.add(item)
|
||||
}
|
||||
)
|
||||
// save the inventory
|
||||
inventoryStore.save(
|
||||
inventory = updatedInventory,
|
||||
create = false,
|
||||
)
|
||||
return inventoryId
|
||||
}
|
||||
|
||||
@Throws
|
||||
fun changeInventoryItemCount(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
count: Float,
|
||||
) {
|
||||
if (count < 0) {
|
||||
throw BusinessException(
|
||||
message = "InventoryItem (id:$inventoryId) quantity cannot go below 0.",
|
||||
)
|
||||
}
|
||||
// get the inventory of the character, if none create one.
|
||||
val inventory = inventoryStore.inventoryFlow().value[characterSheetId]
|
||||
?: Inventory.empty(characterSheetId = characterSheetId)
|
||||
// Guard case.
|
||||
val inventoryItemIndex = inventory.items.indexOfFirst { it.inventoryId == inventoryId }
|
||||
if (inventoryItemIndex < 0) {
|
||||
throw BusinessException(
|
||||
message = "InventoryItem (id:$inventoryId) not found in Inventory(characterSheetId:$characterSheetId).",
|
||||
)
|
||||
}
|
||||
// update the inventory with the updated item.
|
||||
val updatedInventory = inventory.copy(
|
||||
items = inventory.items.toMutableList().also { items ->
|
||||
if (count == 0f) {
|
||||
items.removeAt(inventoryItemIndex)
|
||||
} else {
|
||||
items[inventoryItemIndex] = items[inventoryItemIndex].copy(count = count)
|
||||
}
|
||||
}
|
||||
)
|
||||
// save the inventory
|
||||
inventoryStore.save(
|
||||
inventory = updatedInventory,
|
||||
create = false,
|
||||
)
|
||||
}
|
||||
|
||||
@Throws
|
||||
fun consumeInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
) {
|
||||
// get the inventory of the character, if none create one.
|
||||
val inventory = inventoryStore.inventoryFlow().value[characterSheetId]
|
||||
?: Inventory.empty(characterSheetId = characterSheetId)
|
||||
// Guard case.
|
||||
val inventoryItemIndex = inventory.items.indexOfFirst { it.inventoryId == inventoryId }
|
||||
if (inventoryItemIndex < 0) {
|
||||
throw BusinessException(
|
||||
message = "InventoryItem (id:$inventoryId) not found in Inventory(characterSheetId:$characterSheetId).",
|
||||
)
|
||||
}
|
||||
// other Guard case.
|
||||
val itemId = inventory.items[inventoryItemIndex].itemId
|
||||
val item = itemStore.item(itemId = itemId)
|
||||
?: throw BusinessException(message = "Item (id:$itemId) not found.")
|
||||
if (item.options.consumable.not()) {
|
||||
throw BusinessException(message = "Item (id:$itemId) is not consumable.")
|
||||
}
|
||||
// update the inventory with the updated item.
|
||||
val updatedInventory = inventory.copy(
|
||||
items = inventory.items.toMutableList().also { items ->
|
||||
val inventoryItem = inventory.items[inventoryItemIndex]
|
||||
if (inventoryItem.count - 1f <= 0f) {
|
||||
items.removeAt(inventoryItemIndex)
|
||||
} else {
|
||||
items[inventoryItemIndex] = inventoryItem.copy(count = inventoryItem.count - 1f)
|
||||
}
|
||||
}
|
||||
)
|
||||
// save the inventory
|
||||
inventoryStore.save(
|
||||
inventory = updatedInventory,
|
||||
create = false,
|
||||
)
|
||||
}
|
||||
|
||||
@Throws
|
||||
fun equipInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
equip: Boolean,
|
||||
) {
|
||||
// get the inventory of the character, if none create one.
|
||||
val inventory = inventoryStore.inventoryFlow().value[characterSheetId]
|
||||
?: Inventory.empty(characterSheetId = characterSheetId)
|
||||
// Guard case.
|
||||
val inventoryItemIndex = inventory.items.indexOfFirst { it.inventoryId == inventoryId }
|
||||
if (inventoryItemIndex < 0) {
|
||||
throw BusinessException(
|
||||
message = "InventoryItem (id:$inventoryId) not found in Inventory(characterSheetId:$characterSheetId).",
|
||||
)
|
||||
}
|
||||
// other Guard case.
|
||||
val itemId = inventory.items[inventoryItemIndex].itemId
|
||||
val item = itemStore.item(itemId = itemId)
|
||||
?: throw BusinessException(message = "Item (id:$itemId) not found.")
|
||||
if (item.options.equipable.not()) {
|
||||
throw BusinessException(message = "Item (id:$itemId) is not equipable.")
|
||||
}
|
||||
// update the inventory with the updated item.
|
||||
val updatedInventory = inventory.copy(
|
||||
items = inventory.items.toMutableList().also { items ->
|
||||
items[inventoryItemIndex] = inventory.items[inventoryItemIndex].copy(
|
||||
equipped = equip
|
||||
)
|
||||
}
|
||||
)
|
||||
// save the inventory
|
||||
inventoryStore.save(
|
||||
inventory = updatedInventory,
|
||||
create = false,
|
||||
)
|
||||
}
|
||||
|
||||
@Throws
|
||||
fun deleteInventoryItem(
|
||||
characterSheetId: String,
|
||||
inventoryId: String,
|
||||
) {
|
||||
// get the inventory of the character, if none create one.
|
||||
val inventory = inventoryStore.inventoryFlow().value[characterSheetId]
|
||||
?: Inventory.empty(characterSheetId = characterSheetId)
|
||||
// Guard case.
|
||||
val inventoryItemIndex = inventory.items.indexOfFirst { it.inventoryId == inventoryId }
|
||||
if (inventoryItemIndex < 0) {
|
||||
throw BusinessException(
|
||||
message = "InventoryItem (id:$inventoryId) not found in Inventory(characterSheetId:$characterSheetId)",
|
||||
)
|
||||
}
|
||||
// update the inventory with the updated item.
|
||||
val updatedInventory = inventory.copy(
|
||||
items = inventory.items.toMutableList().also { items ->
|
||||
items.removeAt(inventoryItemIndex)
|
||||
}
|
||||
)
|
||||
// save the inventory
|
||||
inventoryStore.save(
|
||||
inventory = updatedInventory,
|
||||
create = false,
|
||||
)
|
||||
}
|
||||
|
||||
private fun List<Inventory.Item>.createInventoryId(): String {
|
||||
var inventoryId: String
|
||||
do {
|
||||
inventoryId = UUID.randomUUID().toString()
|
||||
} while (any { inventoryId == it.inventoryId })
|
||||
return inventoryId
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,49 +153,7 @@ class InventoryStore(
|
|||
}
|
||||
}
|
||||
|
||||
@Throws
|
||||
fun createItem(
|
||||
characterSheetId: String,
|
||||
itemId: String,
|
||||
): String {
|
||||
val (updatedInventory, inventoryId) = inventoryFlow.value.toMutableMap().let { characters ->
|
||||
// get the inventory of the character, if none create one.
|
||||
val inventory = characters[characterSheetId]
|
||||
?: Inventory.empty(characterSheetId = characterSheetId)
|
||||
// create an inventoryId.
|
||||
val inventoryId = inventory.items.createInventoryId()
|
||||
// create an inventory Item.
|
||||
val item = Inventory.Item(
|
||||
inventoryId = inventoryId,
|
||||
itemId = itemId,
|
||||
count = 1f,
|
||||
equipped = false,
|
||||
)
|
||||
// update the inventory with the updated item.
|
||||
inventory.copy(
|
||||
items = inventory.items.toMutableList().also {
|
||||
it.add(item)
|
||||
}
|
||||
) to inventoryId
|
||||
}
|
||||
// save the inventory
|
||||
save(
|
||||
inventory = updatedInventory,
|
||||
create = false,
|
||||
)
|
||||
// return the inventory ID.
|
||||
return inventoryId
|
||||
}
|
||||
|
||||
private fun inventoryFile(id: String): File {
|
||||
return File("${pathProvider.inventoryPath()}${id}.json")
|
||||
}
|
||||
|
||||
private fun List<Inventory.Item>.createInventoryId(): String {
|
||||
var inventoryId: String
|
||||
do {
|
||||
inventoryId = UUID.randomUUID().toString()
|
||||
} while (any { inventoryId == it.inventoryId })
|
||||
return inventoryId
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@ class ItemStore(
|
|||
}
|
||||
}
|
||||
|
||||
fun item(itemId: String?): Item? {
|
||||
return itemFlow.value.firstOrNull { it.id == itemId }
|
||||
}
|
||||
|
||||
fun itemsFlow(): StateFlow<List<Item>> = itemFlow
|
||||
|
||||
private fun updateItemsFlow() {
|
||||
|
|
|
|||
|
|
@ -19,8 +19,12 @@ import com.pixelized.server.lwa.server.rest.character.putCharacterAlteration
|
|||
import com.pixelized.server.lwa.server.rest.character.putCharacterDamage
|
||||
import com.pixelized.server.lwa.server.rest.character.putCharacterDiminished
|
||||
import com.pixelized.server.lwa.server.rest.character.putCharacterFatigue
|
||||
import com.pixelized.server.lwa.server.rest.inventory.createInventory
|
||||
import com.pixelized.server.lwa.server.rest.inventory.changeInventoryItemCount
|
||||
import com.pixelized.server.lwa.server.rest.inventory.consumeInventoryItem
|
||||
import com.pixelized.server.lwa.server.rest.inventory.createInventoryItem
|
||||
import com.pixelized.server.lwa.server.rest.inventory.equipInventoryItem
|
||||
import com.pixelized.server.lwa.server.rest.inventory.deleteInventory
|
||||
import com.pixelized.server.lwa.server.rest.inventory.deleteInventoryItem
|
||||
import com.pixelized.server.lwa.server.rest.inventory.getInventory
|
||||
import com.pixelized.server.lwa.server.rest.inventory.putInventory
|
||||
import com.pixelized.server.lwa.server.rest.item.deleteItem
|
||||
|
|
@ -218,7 +222,7 @@ class LocalServer {
|
|||
body = engine.deleteAlteration()
|
||||
)
|
||||
}
|
||||
route(path = "item") {
|
||||
route(path = "/item") {
|
||||
get(
|
||||
path = "/all",
|
||||
body = engine.getItems(),
|
||||
|
|
@ -236,7 +240,7 @@ class LocalServer {
|
|||
body = engine.deleteItem(),
|
||||
)
|
||||
}
|
||||
route(path = "tag") {
|
||||
route(path = "/tag") {
|
||||
get(
|
||||
path = "/character",
|
||||
body = engine.getCharacterTags(),
|
||||
|
|
@ -250,7 +254,7 @@ class LocalServer {
|
|||
body = engine.getItemTags(),
|
||||
)
|
||||
}
|
||||
route(path = "inventory") {
|
||||
route(path = "/inventory") {
|
||||
get(
|
||||
path = "/detail",
|
||||
body = engine.getInventory(),
|
||||
|
|
@ -259,14 +263,34 @@ class LocalServer {
|
|||
path = "/update",
|
||||
body = engine.putInventory()
|
||||
)
|
||||
put(
|
||||
path = "/create",
|
||||
body = engine.createInventory()
|
||||
)
|
||||
delete(
|
||||
path = "/delete",
|
||||
body = engine.deleteInventory()
|
||||
)
|
||||
route(
|
||||
path = "/item"
|
||||
) {
|
||||
put(
|
||||
path = "/create",
|
||||
body = engine.createInventoryItem()
|
||||
)
|
||||
put(
|
||||
path = "/count",
|
||||
body = engine.changeInventoryItemCount()
|
||||
)
|
||||
put(
|
||||
path = "/consume",
|
||||
body = engine.consumeInventoryItem()
|
||||
)
|
||||
put(
|
||||
path = "/equip",
|
||||
body = engine.equipInventoryItem()
|
||||
)
|
||||
delete(
|
||||
path = "/delete",
|
||||
body = engine.deleteInventoryItem()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package com.pixelized.server.lwa.server.rest.inventory
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.server.lwa.utils.extentions.exception
|
||||
import com.pixelized.server.lwa.utils.extentions.inventoryId
|
||||
import com.pixelized.server.lwa.utils.extentions.itemId
|
||||
import com.pixelized.shared.lwa.protocol.rest.APIResponse
|
||||
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||
import io.ktor.server.response.respond
|
||||
import io.ktor.server.routing.RoutingContext
|
||||
|
||||
fun Engine.deleteInventoryItem(): suspend RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
val inventoryId = call.queryParameters.inventoryId
|
||||
// add the item to the inventory.
|
||||
inventoryService.deleteInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
)
|
||||
// API & WebSocket responses.
|
||||
call.respond(
|
||||
message = APIResponse.success(),
|
||||
)
|
||||
webSocket.emit(
|
||||
value = ApiSynchronisation.InventoryUpdate(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = characterSheetId,
|
||||
),
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.exception(
|
||||
exception = exception,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.pixelized.server.lwa.server.rest.inventory
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.server.lwa.utils.extentions.count
|
||||
import com.pixelized.server.lwa.utils.extentions.exception
|
||||
import com.pixelized.server.lwa.utils.extentions.inventoryId
|
||||
import com.pixelized.shared.lwa.protocol.rest.APIResponse
|
||||
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||
import io.ktor.server.response.respond
|
||||
import io.ktor.server.routing.RoutingContext
|
||||
|
||||
fun Engine.changeInventoryItemCount(): suspend RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
val inventoryId = call.queryParameters.inventoryId
|
||||
val count = call.queryParameters.count
|
||||
// add the item to the inventory.
|
||||
inventoryService.changeInventoryItemCount(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
count = count,
|
||||
)
|
||||
// API & WebSocket responses.
|
||||
call.respond(
|
||||
message = APIResponse.success(),
|
||||
)
|
||||
webSocket.emit(
|
||||
value = ApiSynchronisation.InventoryUpdate(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = characterSheetId,
|
||||
),
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.exception(
|
||||
exception = exception,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.pixelized.server.lwa.server.rest.inventory
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.server.lwa.utils.extentions.exception
|
||||
import com.pixelized.server.lwa.utils.extentions.inventoryId
|
||||
import com.pixelized.shared.lwa.protocol.rest.APIResponse
|
||||
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||
import io.ktor.server.response.respond
|
||||
import io.ktor.server.routing.RoutingContext
|
||||
|
||||
fun Engine.consumeInventoryItem(): suspend RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
val inventoryId = call.queryParameters.inventoryId
|
||||
// add the item to the inventory.
|
||||
inventoryService.consumeInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
)
|
||||
// API & WebSocket responses.
|
||||
call.respond(
|
||||
message = APIResponse.success(),
|
||||
)
|
||||
webSocket.emit(
|
||||
value = ApiSynchronisation.InventoryUpdate(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = characterSheetId,
|
||||
),
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.exception(
|
||||
exception = exception,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.pixelized.server.lwa.server.rest.inventory
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.server.lwa.utils.extentions.equip
|
||||
import com.pixelized.server.lwa.utils.extentions.exception
|
||||
import com.pixelized.server.lwa.utils.extentions.inventoryId
|
||||
import com.pixelized.shared.lwa.protocol.rest.APIResponse
|
||||
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||
import io.ktor.server.response.respond
|
||||
import io.ktor.server.routing.RoutingContext
|
||||
|
||||
fun Engine.equipInventoryItem(): suspend RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
val inventoryId = call.queryParameters.inventoryId
|
||||
val equip = call.queryParameters.equip
|
||||
|
||||
// add the item to the inventory.
|
||||
inventoryService.equipInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
inventoryId = inventoryId,
|
||||
equip = equip,
|
||||
)
|
||||
// API & WebSocket responses.
|
||||
call.respond(
|
||||
message = APIResponse.success(),
|
||||
)
|
||||
webSocket.emit(
|
||||
value = ApiSynchronisation.InventoryUpdate(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = characterSheetId,
|
||||
),
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.exception(
|
||||
exception = exception,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,14 +9,14 @@ import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
|||
import io.ktor.server.response.respond
|
||||
import io.ktor.server.routing.RoutingContext
|
||||
|
||||
fun Engine.createInventory(): suspend RoutingContext.() -> Unit {
|
||||
fun Engine.createInventoryItem(): suspend RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
val itemId = call.queryParameters.itemId
|
||||
// add the item to the inventory.
|
||||
val inventoryId = inventoryService.createItem(
|
||||
val inventoryId = inventoryService.createInventoryItem(
|
||||
characterSheetId = characterSheetId,
|
||||
itemId = itemId,
|
||||
)
|
||||
|
|
@ -10,6 +10,7 @@ inline fun <reified T> Parameters.param(
|
|||
): T {
|
||||
return when (T::class) {
|
||||
String::class -> this[name] as? T
|
||||
Float::class -> this[name]?.toFloatOrNull() as? T
|
||||
Boolean::class -> this[name]?.toBooleanStrictOrNull() as? T
|
||||
else -> null
|
||||
} ?: throw MissingParameterException(
|
||||
|
|
@ -30,12 +31,24 @@ val Parameters.alterationId: String
|
|||
code = APIResponse.ErrorCode.AlterationId,
|
||||
)
|
||||
|
||||
val Parameters.inventoryId: String
|
||||
get() = param(
|
||||
name = "inventoryId",
|
||||
code = APIResponse.ErrorCode.InventoryId,
|
||||
)
|
||||
|
||||
val Parameters.itemId: String
|
||||
get() = param(
|
||||
name = "itemId",
|
||||
code = APIResponse.ErrorCode.ItemId,
|
||||
)
|
||||
|
||||
val Parameters.count: Float
|
||||
get() = param(
|
||||
name = "count",
|
||||
code = APIResponse.ErrorCode.Count,
|
||||
)
|
||||
|
||||
val Parameters.create: Boolean
|
||||
get() = param(
|
||||
name = "create",
|
||||
|
|
@ -47,3 +60,9 @@ val Parameters.active: Boolean
|
|||
name = "active",
|
||||
code = APIResponse.ErrorCode.Active,
|
||||
)
|
||||
|
||||
val Parameters.equip: Boolean
|
||||
get() = param(
|
||||
name = "equip",
|
||||
code = APIResponse.ErrorCode.Equip,
|
||||
)
|
||||
|
|
@ -15,13 +15,16 @@ data class APIResponse<T>(
|
|||
AlterationId,
|
||||
AlterationName,
|
||||
ItemId,
|
||||
InventoryId,
|
||||
ItemName,
|
||||
CharacterSheetId,
|
||||
Create,
|
||||
Active,
|
||||
Equip,
|
||||
Damage,
|
||||
Fatigue,
|
||||
Diminished,
|
||||
Count,
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue