diff --git a/app/src/main/java/com/pixelized/rplexicon/data/model/Attack.kt b/app/src/main/java/com/pixelized/rplexicon/data/model/Attack.kt index 39d76f6..6279f7f 100644 --- a/app/src/main/java/com/pixelized/rplexicon/data/model/Attack.kt +++ b/app/src/main/java/com/pixelized/rplexicon/data/model/Attack.kt @@ -3,7 +3,7 @@ package com.pixelized.rplexicon.data.model import android.net.Uri import com.pixelized.rplexicon.data.model.roll.Throw import com.pixelized.rplexicon.script.Script -import com.pixelized.rplexicon.utilitary.extentions.string.ImageCache.attackIcon +import com.pixelized.rplexicon.utilitary.ImageCache.attackIcon data class Attack( diff --git a/app/src/main/java/com/pixelized/rplexicon/data/model/ObjectAction.kt b/app/src/main/java/com/pixelized/rplexicon/data/model/ObjectAction.kt index 364596f..a62b13f 100644 --- a/app/src/main/java/com/pixelized/rplexicon/data/model/ObjectAction.kt +++ b/app/src/main/java/com/pixelized/rplexicon/data/model/ObjectAction.kt @@ -2,7 +2,7 @@ package com.pixelized.rplexicon.data.model import android.net.Uri import com.pixelized.rplexicon.data.model.roll.Throw -import com.pixelized.rplexicon.utilitary.extentions.string.ImageCache.objectIcon +import com.pixelized.rplexicon.utilitary.ImageCache.objectIcon data class ObjectAction( val prefix: String?, diff --git a/app/src/main/java/com/pixelized/rplexicon/data/model/Skill.kt b/app/src/main/java/com/pixelized/rplexicon/data/model/Skill.kt index 80c8b13..551e451 100644 --- a/app/src/main/java/com/pixelized/rplexicon/data/model/Skill.kt +++ b/app/src/main/java/com/pixelized/rplexicon/data/model/Skill.kt @@ -3,7 +3,7 @@ package com.pixelized.rplexicon.data.model import android.net.Uri import com.pixelized.rplexicon.data.model.roll.Throw import com.pixelized.rplexicon.script.Script -import com.pixelized.rplexicon.utilitary.extentions.string.ImageCache.skillIcon +import com.pixelized.rplexicon.utilitary.ImageCache.skillIcon data class Skill( val name: String, diff --git a/app/src/main/java/com/pixelized/rplexicon/data/model/Spell.kt b/app/src/main/java/com/pixelized/rplexicon/data/model/Spell.kt index 136359e..5359947 100644 --- a/app/src/main/java/com/pixelized/rplexicon/data/model/Spell.kt +++ b/app/src/main/java/com/pixelized/rplexicon/data/model/Spell.kt @@ -1,7 +1,7 @@ package com.pixelized.rplexicon.data.model import android.net.Uri -import com.pixelized.rplexicon.utilitary.extentions.string.ImageCache.spellIcon +import com.pixelized.rplexicon.utilitary.ImageCache.spellIcon data class Spell( val name: String, diff --git a/app/src/main/java/com/pixelized/rplexicon/data/model/alteration/Alteration.kt b/app/src/main/java/com/pixelized/rplexicon/data/model/alteration/Alteration.kt index 75e3510..a611f38 100644 --- a/app/src/main/java/com/pixelized/rplexicon/data/model/alteration/Alteration.kt +++ b/app/src/main/java/com/pixelized/rplexicon/data/model/alteration/Alteration.kt @@ -5,7 +5,7 @@ import com.pixelized.rplexicon.data.model.Property import com.pixelized.rplexicon.data.model.roll.Dice import com.pixelized.rplexicon.data.model.roll.Flat import com.pixelized.rplexicon.script.Script -import com.pixelized.rplexicon.utilitary.extentions.string.ImageCache.alterationIcon +import com.pixelized.rplexicon.utilitary.ImageCache.alterationIcon data class Alteration( val name: String, diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/factory/InventoryItemUioFactory.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/factory/InventoryItemUioFactory.kt index 2c460db..8121b0d 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/factory/InventoryItemUioFactory.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/factory/InventoryItemUioFactory.kt @@ -4,7 +4,7 @@ import com.pixelized.rplexicon.data.model.item.InventoryPath import com.pixelized.rplexicon.data.model.item.Item import com.pixelized.rplexicon.data.network.ItemDto import com.pixelized.rplexicon.ui.screens.character.pages.inventory.InventoryItemUio -import com.pixelized.rplexicon.utilitary.extentions.string.ImageCache +import com.pixelized.rplexicon.utilitary.ImageCache import javax.inject.Inject class InventoryItemUioFactory @Inject constructor() { diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/factory/ItemElementUioFactory.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/factory/ItemElementUioFactory.kt index 2a180bc..6827fc3 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/factory/ItemElementUioFactory.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/factory/ItemElementUioFactory.kt @@ -3,9 +3,10 @@ package com.pixelized.rplexicon.ui.screens.character.factory import android.content.Context import com.pixelized.rplexicon.R import com.pixelized.rplexicon.data.model.item.Item +import com.pixelized.rplexicon.data.network.ItemDto import com.pixelized.rplexicon.ui.screens.character.pages.inventory.item.ItemCategoryUio import com.pixelized.rplexicon.ui.screens.character.pages.inventory.item.ItemUio -import com.pixelized.rplexicon.utilitary.extentions.string.ImageCache +import com.pixelized.rplexicon.utilitary.ImageCache import javax.inject.Inject class ItemElementUioFactory @Inject constructor() { @@ -13,6 +14,7 @@ class ItemElementUioFactory @Inject constructor() { fun toUio( context: Context, items: List, + fire: List, ): List { return items .groupBy { it.type } @@ -21,14 +23,27 @@ class ItemElementUioFactory @Inject constructor() { title = group.key ?: context.getString(R.string.character_sheet__item_list__uncategorized), items = group.value.map { item -> + val fireItem = fire.find(id = item.id) ItemUio( id = item.id, name = item.fullName, context = item.context, icon = ImageCache.cache(uri = item.icon), + enabled = (fireItem?.amount ?: 0) < 1, + quantity = fireItem?.amount?.takeIf { it > 0 }?.let { "$it" }, ) } ) } } + + fun List.find(id: String): ItemDto? { + return this.firstNotNullOfOrNull { + if (it.id == id) { + it + } else { + it.children.find(id = id) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/inventory/item/Item.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/inventory/item/Item.kt index e1d47e5..1e653f0 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/inventory/item/Item.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/inventory/item/Item.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size @@ -19,6 +18,13 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.DrawModifier +import androidx.compose.ui.geometry.Rect +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.ColorMatrix +import androidx.compose.ui.graphics.Paint +import androidx.compose.ui.graphics.drawscope.ContentDrawScope +import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview @@ -26,6 +32,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import com.pixelized.rplexicon.R +import com.pixelized.rplexicon.data.model.item.InventoryPath import com.pixelized.rplexicon.ui.composable.images.AsyncImage import com.pixelized.rplexicon.ui.theme.LexiconTheme @@ -35,6 +42,8 @@ data class ItemUio( val name: String, val context: String?, val icon: Any?, + val enabled: Boolean, + val quantity: String?, ) @Composable @@ -46,7 +55,8 @@ fun Item( ) { Row( modifier = Modifier - .clickable(enabled = onClick != null) { onClick?.invoke() } + .greyScale(enabled = item.enabled.not()) + .clickable(enabled = onClick != null && item.enabled) { onClick?.invoke() } .minimumInteractiveComponentSize() .height(intrinsicSize = IntrinsicSize.Min) .padding(paddingValues) @@ -59,7 +69,7 @@ fun Item( model = item.icon, ) Column( - modifier = Modifier.fillMaxSize(), + modifier = Modifier.weight(weight = 1f), verticalArrangement = Arrangement.spacedBy( space = 4.dp, alignment = Alignment.CenterVertically @@ -82,6 +92,13 @@ fun Item( ) } } + Text( + style = MaterialTheme.typography.bodyMedium, + fontWeight = FontWeight.Bold, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + text = item.quantity?.let { "$it" } ?: "", + ) } } @@ -98,6 +115,23 @@ private fun ItemPreview( } } +class GreyScaleModifier : DrawModifier { + override fun ContentDrawScope.draw() { + val saturationMatrix = ColorMatrix().apply { this.setToSaturation(0f) } + val saturationFilter = ColorFilter.colorMatrix(saturationMatrix) + val paint = Paint().apply { + colorFilter = saturationFilter + } + drawIntoCanvas { + it.saveLayer(Rect(0f, 0f, size.width, size.height), paint) + drawContent() + it.restore() + } + } +} + +fun Modifier.greyScale(enabled: Boolean) = if (enabled) this.then(GreyScaleModifier()) else this + private class ItemProvider : PreviewParameterProvider { override val values: Sequence = sequenceOf( ItemUio( @@ -105,12 +139,16 @@ private class ItemProvider : PreviewParameterProvider { name = "Bourse", context = "Un petite bourse.", icon = R.drawable.icbg_pouch_a_unfaded, + enabled = true, + quantity = null, ), ItemUio( id = "2ecf41c2-06b1-4f2d-a6d9-b6adcaf05aba", name = "Sac à dos", context = null, icon = R.drawable.icbg_backpack_b_unfaded, + enabled = false, + quantity = "1", ), ) } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/inventory/item/ItemListDialog.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/inventory/item/ItemListDialog.kt index a811e58..c9d3d72 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/inventory/item/ItemListDialog.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/inventory/item/ItemListDialog.kt @@ -294,24 +294,32 @@ private fun ItemLisPreview() { name = "Bourse", context = "Une petite bourse en cuir.", icon = R.drawable.icbg_leather_pouch_a_unfaded, + enabled = false, + quantity = "1", ), ItemUio( id = "7d27561b-f2f4-4899-a2fc-df3501b1b66b", name = "Bourse", context = "Une petite bourse.", icon = R.drawable.icbg_pouch_a_unfaded, + enabled = true, + quantity = null, ), ItemUio( id = "2ecf41c2-06b1-4f2d-a6d9-b6adcaf05aba", name = "Sac à dos", context = "Sac à dos pour aventurier.", icon = R.drawable.icbg_backpack_a_unfaded, + enabled = true, + quantity = null, ), ItemUio( id = "43424bbc-0117-44f8-b512-6d469a05e6c2", name = "Sac à dos", context = "Sac à dos pour aventurier.", icon = R.drawable.icbg_backpack_b_unfaded, + enabled = true, + quantity = null, ), ), ), @@ -323,12 +331,16 @@ private fun ItemLisPreview() { name = "Parchemin d'Arme spirituelle", context = null, icon = R.drawable.icbg_book_signedtradebisa_unfaded, + enabled = true, + quantity = null, ), ItemUio( id = "eda09856-5a91-4411-ac75-248a16ce1060", name = "Parchemin de Bénédiction", context = null, icon = R.drawable.icbg_scroll_of_bless_unfaded, + enabled = true, + quantity = null, ), ) ), diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/inventory/item/ItemListViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/inventory/item/ItemListViewModel.kt index aebff89..5a17def 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/inventory/item/ItemListViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/inventory/item/ItemListViewModel.kt @@ -7,23 +7,29 @@ import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.pixelized.rplexicon.data.model.item.Item +import com.pixelized.rplexicon.data.model.item.InventoryPath +import com.pixelized.rplexicon.data.model.item.InventoryPath.Companion.ROOT import com.pixelized.rplexicon.data.repository.character.ItemsRepository +import com.pixelized.rplexicon.data.repository.firebase.InventoryFireRepository +import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument import com.pixelized.rplexicon.ui.screens.character.factory.ItemElementUioFactory import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class ItemListViewModel @Inject constructor( private val itemsRepository: ItemsRepository, + private val fireRepository: InventoryFireRepository, private val factory: ItemElementUioFactory, + savedStateHandle: SavedStateHandle, ) : ViewModel() { + private val character = savedStateHandle.characterSheetArgument.name private val filter = MutableStateFlow("") @@ -43,21 +49,23 @@ class ItemListViewModel @Inject constructor( @Stable get() { val context = LocalContext.current - return itemsRepository.data.combine(filter) { items, filter -> items to filter } - .map { (items: Map, filter: String) -> - items.values - .filter { - val name = it.fullName.contains(other = filter, ignoreCase = true) - val type = it.type?.contains(other = filter, ignoreCase = true) == true - name || type - } - .sortedWith(compareBy(Collator.getInstance()) { it.fullName }) - .sortedBy { it.type } - } - .map { items: List -> - factory.toUio(context = context, items = items) - } - .collectAsState(initial = emptyList()) + return combine( + filter, + itemsRepository.data, + fireRepository.getInventory(character = character, path = ROOT), + ) { filter, items, fires -> + val filteredItems = items.values + .filter { + val name = it.fullName.contains(other = filter, ignoreCase = true) + val type = it.type?.contains(other = filter, ignoreCase = true) == true + name || type + } + .sortedWith(compareBy(Collator.getInstance()) { it.fullName }) + .sortedBy { it.type } + factory.toUio(context = context, items = filteredItems, fire = fires) + }.collectAsState( + initial = emptyList() + ) } fun updateItemList() { diff --git a/app/src/main/java/com/pixelized/rplexicon/utilitary/extentions/string/ImageCache.kt b/app/src/main/java/com/pixelized/rplexicon/utilitary/ImageCache.kt similarity index 99% rename from app/src/main/java/com/pixelized/rplexicon/utilitary/extentions/string/ImageCache.kt rename to app/src/main/java/com/pixelized/rplexicon/utilitary/ImageCache.kt index a052d9a..31d84ed 100644 --- a/app/src/main/java/com/pixelized/rplexicon/utilitary/extentions/string/ImageCache.kt +++ b/app/src/main/java/com/pixelized/rplexicon/utilitary/ImageCache.kt @@ -1,4 +1,4 @@ -package com.pixelized.rplexicon.utilitary.extentions.string +package com.pixelized.rplexicon.utilitary import android.net.Uri import android.util.Log @@ -90,6 +90,7 @@ object ImageCache { "https://drive.google.com/uc?export=view&id=1AeSHg792EwVbkjCNjJaqzC4v0uNj9NRn" to R.drawable.ic_drive_fire_starter, "https://drive.google.com/uc?export=view&id=1Dc0hBGXTNP8dnYqHJlSsK1WgWAsWtCV9" to R.drawable.ic_drive_lantern_of_revealing, "https://drive.google.com/uc?export=view&id=1KPlgQK1C3lfZn3ZHTHd-dqiSINjQpnH9" to R.drawable.ic_drive_ring_of_kazan, + "https://drive.google.com/uc?export=view&id=1YYgZ2SlSn6TkRiphpIf62KgwTZWQZHQJ" to R.drawable.ic_drive_tome_of_strahd, ) private val alterations = hashMapOf( @@ -358,7 +359,7 @@ object ImageCache { fun cache(uri: Uri?): Any = when (uri) { null -> R.drawable.icbg_generic_darkness_icon - else -> this.uri[uri.toString()] ?: kotlin.run { + else -> ImageCache.uri[uri.toString()] ?: kotlin.run { Log.v("ImageCache", "$uri") uri } diff --git a/app/src/main/res/drawable/ic_copper_coin_pile_unfaded.png b/app/src/main/res/drawable/ic_copper_coin_pile_unfaded.png deleted file mode 100644 index c9ca827..0000000 Binary files a/app/src/main/res/drawable/ic_copper_coin_pile_unfaded.png and /dev/null differ diff --git a/app/src/main/res/drawable/ic_copper_coin_pile_unfaded.webp b/app/src/main/res/drawable/ic_copper_coin_pile_unfaded.webp new file mode 100644 index 0000000..1432573 Binary files /dev/null and b/app/src/main/res/drawable/ic_copper_coin_pile_unfaded.webp differ diff --git a/app/src/main/res/drawable/ic_drive_tome_of_strahd.webp b/app/src/main/res/drawable/ic_drive_tome_of_strahd.webp new file mode 100644 index 0000000..6de9792 Binary files /dev/null and b/app/src/main/res/drawable/ic_drive_tome_of_strahd.webp differ diff --git a/app/src/main/res/drawable/ic_electrum_coin_pile_unfaded.png b/app/src/main/res/drawable/ic_electrum_coin_pile_unfaded.png deleted file mode 100644 index 2a0e19b..0000000 Binary files a/app/src/main/res/drawable/ic_electrum_coin_pile_unfaded.png and /dev/null differ diff --git a/app/src/main/res/drawable/ic_electrum_coin_pile_unfaded.webp b/app/src/main/res/drawable/ic_electrum_coin_pile_unfaded.webp new file mode 100644 index 0000000..2039a39 Binary files /dev/null and b/app/src/main/res/drawable/ic_electrum_coin_pile_unfaded.webp differ diff --git a/app/src/main/res/drawable/ic_gold_coin_pile_unfaded.png b/app/src/main/res/drawable/ic_gold_coin_pile_unfaded.png deleted file mode 100644 index 27d42ae..0000000 Binary files a/app/src/main/res/drawable/ic_gold_coin_pile_unfaded.png and /dev/null differ diff --git a/app/src/main/res/drawable/ic_gold_coin_pile_unfaded.webp b/app/src/main/res/drawable/ic_gold_coin_pile_unfaded.webp new file mode 100644 index 0000000..8a4842b Binary files /dev/null and b/app/src/main/res/drawable/ic_gold_coin_pile_unfaded.webp differ diff --git a/app/src/main/res/drawable/ic_silver_coin_pile_unfaded.png b/app/src/main/res/drawable/ic_silver_coin_pile_unfaded.png deleted file mode 100644 index b072975..0000000 Binary files a/app/src/main/res/drawable/ic_silver_coin_pile_unfaded.png and /dev/null differ diff --git a/app/src/main/res/drawable/ic_silver_coin_pile_unfaded.webp b/app/src/main/res/drawable/ic_silver_coin_pile_unfaded.webp new file mode 100644 index 0000000..8c66fe9 Binary files /dev/null and b/app/src/main/res/drawable/ic_silver_coin_pile_unfaded.webp differ