Add a lot of icon + change the cache system.
|
|
@ -1,12 +1,17 @@
|
||||||
package com.pixelized.rplexicon.data.model.item
|
package com.pixelized.rplexicon.data.model.item
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import com.pixelized.rplexicon.data.model.roll.Throw
|
import com.pixelized.rplexicon.data.model.roll.Throw
|
||||||
|
|
||||||
data class Item(
|
data class Item(
|
||||||
val id: String,
|
val id: String,
|
||||||
val prefix: String?,
|
val prefix: String?,
|
||||||
val name: String,
|
val name: String,
|
||||||
|
val type: String?,
|
||||||
|
val description: String?,
|
||||||
val isContainer: Boolean,
|
val isContainer: Boolean,
|
||||||
val effect: Throw?,
|
val effect: Throw?,
|
||||||
val icon: Any?,
|
val icon: Uri?,
|
||||||
)
|
) {
|
||||||
|
val fullName: String = prefix?.let { "$it${name}" } ?: name
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,11 @@ class ItemLexiconParser @Inject constructor(
|
||||||
id = id,
|
id = id,
|
||||||
prefix = row.parse(column = PREFIX),
|
prefix = row.parse(column = PREFIX),
|
||||||
name = name,
|
name = name,
|
||||||
|
type = row.parse(column = TYPE),
|
||||||
|
description = row.parse(column = CONTEXT),
|
||||||
isContainer = container,
|
isContainer = container,
|
||||||
effect = throwParser.parse(value = row.parse(column = EFFECT)),
|
effect = throwParser.parse(value = row.parse(column = EFFECT)),
|
||||||
icon = BaldurGageImageCache.cache(uri = row.parseUri(column = ICON)),
|
icon = row.parseUri(column = ICON),
|
||||||
)
|
)
|
||||||
inventories[item.id] = item
|
inventories[item.id] = item
|
||||||
}
|
}
|
||||||
|
|
@ -47,10 +49,12 @@ class ItemLexiconParser @Inject constructor(
|
||||||
private val ID = column("Id")
|
private val ID = column("Id")
|
||||||
private val PREFIX = column("Préfix")
|
private val PREFIX = column("Préfix")
|
||||||
private val NAME = column("Nom")
|
private val NAME = column("Nom")
|
||||||
|
private val TYPE = column("Type")
|
||||||
|
private val CONTEXT = column("Contexte")
|
||||||
private val CONTAINER = column("Contenant")
|
private val CONTAINER = column("Contenant")
|
||||||
private val EFFECT = column("Effet")
|
private val EFFECT = column("Effet")
|
||||||
private val ICON = column("Icone")
|
private val ICON = column("Icone")
|
||||||
|
|
||||||
private val COLUMNS = listOf(ID, PREFIX, NAME, CONTAINER, EFFECT, ICON)
|
private val COLUMNS = listOf(ID, PREFIX, NAME, TYPE, CONTEXT, CONTAINER, EFFECT, ICON)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,9 +3,10 @@ package com.pixelized.rplexicon.ui.screens.character.factory
|
||||||
import com.pixelized.rplexicon.data.model.item.Item
|
import com.pixelized.rplexicon.data.model.item.Item
|
||||||
import com.pixelized.rplexicon.data.network.ItemDto
|
import com.pixelized.rplexicon.data.network.ItemDto
|
||||||
import com.pixelized.rplexicon.ui.screens.character.pages.inventory.InventoryItemUio
|
import com.pixelized.rplexicon.ui.screens.character.pages.inventory.InventoryItemUio
|
||||||
|
import com.pixelized.rplexicon.utilitary.extentions.string.BaldurGageImageCache
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ItemUioFactory @Inject constructor() {
|
class InventoryItemUioFactory @Inject constructor() {
|
||||||
|
|
||||||
fun toUio(
|
fun toUio(
|
||||||
items: Map<String, Item>,
|
items: Map<String, Item>,
|
||||||
|
|
@ -19,7 +20,7 @@ class ItemUioFactory @Inject constructor() {
|
||||||
name = item.name,
|
name = item.name,
|
||||||
amount = amount,
|
amount = amount,
|
||||||
container = item.isContainer,
|
container = item.isContainer,
|
||||||
icon = item.icon,
|
icon = BaldurGageImageCache.cache(item.icon),
|
||||||
items = null // fire.children?.let { toUio(items = items, fires = it) },
|
items = null // fire.children?.let { toUio(items = items, fires = it) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
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.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.BaldurGageImageCache
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ItemElementUioFactory @Inject constructor() {
|
||||||
|
|
||||||
|
fun toUio(
|
||||||
|
context: Context,
|
||||||
|
items: List<Item>,
|
||||||
|
): List<ItemCategoryUio> {
|
||||||
|
return items
|
||||||
|
.groupBy { it.type }
|
||||||
|
.map { group: Map.Entry<String?, List<Item>> ->
|
||||||
|
ItemCategoryUio(
|
||||||
|
title = group.key
|
||||||
|
?: context.getString(R.string.character_sheet__item_list__uncategorized),
|
||||||
|
items = group.value.map { item ->
|
||||||
|
ItemUio(
|
||||||
|
id = item.id,
|
||||||
|
name = item.fullName,
|
||||||
|
description = item.description,
|
||||||
|
icon = BaldurGageImageCache.cache(uri = item.icon),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,6 @@ import androidx.compose.animation.animateColor
|
||||||
import androidx.compose.animation.core.updateTransition
|
import androidx.compose.animation.core.updateTransition
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
|
@ -15,8 +14,12 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||||
import androidx.compose.foundation.lazy.grid.itemsIndexed
|
import androidx.compose.foundation.lazy.grid.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
|
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Add
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.surfaceColorAtElevation
|
import androidx.compose.material3.surfaceColorAtElevation
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
|
@ -24,18 +27,21 @@ import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.compositeOver
|
import androidx.compose.ui.graphics.compositeOver
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import com.pixelized.rplexicon.LocalSnack
|
import com.pixelized.rplexicon.LocalSnack
|
||||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.EquipmentItem
|
import com.pixelized.rplexicon.R
|
||||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.EquipmentItemUio
|
import com.pixelized.rplexicon.ui.composable.FloatingActionButton
|
||||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDetailDialog
|
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDetailDialog
|
||||||
import com.pixelized.rplexicon.ui.screens.character.composable.preview.rememberEquipmentState
|
|
||||||
import com.pixelized.rplexicon.ui.screens.character.composable.preview.rememberInventoryListState
|
import com.pixelized.rplexicon.ui.screens.character.composable.preview.rememberInventoryListState
|
||||||
|
import com.pixelized.rplexicon.ui.screens.character.pages.inventory.item.ItemListDialog
|
||||||
|
import com.pixelized.rplexicon.ui.screens.character.pages.inventory.item.ItemListViewModel
|
||||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||||
import com.pixelized.rplexicon.utilitary.DraggableItem
|
import com.pixelized.rplexicon.utilitary.DraggableItem
|
||||||
import com.pixelized.rplexicon.utilitary.dragContainer
|
import com.pixelized.rplexicon.utilitary.dragContainer
|
||||||
|
|
@ -47,7 +53,8 @@ import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun InventoryPage(
|
fun InventoryPage(
|
||||||
viewModel: InventoryViewModel,
|
viewModel: InventoryViewModel = hiltViewModel(),
|
||||||
|
itemViewModel: ItemListViewModel = hiltViewModel()
|
||||||
) {
|
) {
|
||||||
val snack = LocalSnack.current
|
val snack = LocalSnack.current
|
||||||
val snackJob = remember { mutableStateOf<Job?>(null) }
|
val snackJob = remember { mutableStateOf<Job?>(null) }
|
||||||
|
|
@ -55,18 +62,19 @@ fun InventoryPage(
|
||||||
|
|
||||||
InventoryPageContent(
|
InventoryPageContent(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
equipments = viewModel.equipments,
|
|
||||||
inventory = viewModel.inventory,
|
inventory = viewModel.inventory,
|
||||||
onEquipment = {
|
onAddItem = itemViewModel::show,
|
||||||
snackJob.value?.cancel()
|
|
||||||
viewModel.showSkillDetailDialog(item = it)
|
|
||||||
},
|
|
||||||
onInventoryItemMove = viewModel::onMove,
|
onInventoryItemMove = viewModel::onMove,
|
||||||
onInventoryIsMoveEnable = viewModel::isMoveEnable,
|
onInventoryIsMoveEnable = viewModel::isMoveEnable,
|
||||||
onInventoryItemDrop = viewModel::onDrop,
|
onInventoryItemDrop = viewModel::onDrop,
|
||||||
onInventoryItemDropOver = viewModel::onDropOver,
|
onInventoryItemDropOver = viewModel::onDropOver,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ItemListDialog(
|
||||||
|
viewModel = itemViewModel,
|
||||||
|
onDismissRequest = itemViewModel::hide,
|
||||||
|
)
|
||||||
|
|
||||||
SkillDetailDialog(
|
SkillDetailDialog(
|
||||||
dialog = viewModel.dialog,
|
dialog = viewModel.dialog,
|
||||||
onDismissRequest = viewModel::hideSkillDetailDialog,
|
onDismissRequest = viewModel::hideSkillDetailDialog,
|
||||||
|
|
@ -85,9 +93,8 @@ fun InventoryPage(
|
||||||
@Composable
|
@Composable
|
||||||
private fun InventoryPageContent(
|
private fun InventoryPageContent(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
equipments: State<EquipmentItemUio?>,
|
|
||||||
inventory: State<List<InventoryItemUio>>,
|
inventory: State<List<InventoryItemUio>>,
|
||||||
onEquipment: (String) -> Unit,
|
onAddItem: () -> Unit,
|
||||||
onInventoryItemMove: (Int, Int) -> Unit,
|
onInventoryItemMove: (Int, Int) -> Unit,
|
||||||
onInventoryIsMoveEnable: (Int, Int) -> Boolean,
|
onInventoryIsMoveEnable: (Int, Int) -> Boolean,
|
||||||
onInventoryItemDrop: (Int) -> Unit,
|
onInventoryItemDrop: (Int) -> Unit,
|
||||||
|
|
@ -103,16 +110,9 @@ private fun InventoryPageContent(
|
||||||
onDragRelease = onInventoryItemDrop,
|
onDragRelease = onInventoryItemDrop,
|
||||||
onDropReleaseOver = onInventoryItemDropOver,
|
onDropReleaseOver = onInventoryItemDropOver,
|
||||||
)
|
)
|
||||||
Column(
|
Box(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
) {
|
) {
|
||||||
equipments.value?.let {
|
|
||||||
EquipmentItem(
|
|
||||||
modifier = Modifier.padding(bottom = 16.dp),
|
|
||||||
equipments = it,
|
|
||||||
onClick = onEquipment,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
LazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
columns = GridCells.Fixed(5),
|
columns = GridCells.Fixed(5),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
@ -180,6 +180,23 @@ private fun InventoryPageContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FloatingActionButton(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.BottomEnd)
|
||||||
|
.padding(all = 16.dp),
|
||||||
|
onClick = onAddItem,
|
||||||
|
expended = true,
|
||||||
|
icon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Add,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
Text(text = stringResource(id = R.string.character_sheet__inventory__add_item_action))
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,9 +208,8 @@ fun InventoryPagePreview() {
|
||||||
Surface {
|
Surface {
|
||||||
InventoryPageContent(
|
InventoryPageContent(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
equipments = rememberEquipmentState(),
|
|
||||||
inventory = rememberInventoryListState(),
|
inventory = rememberInventoryListState(),
|
||||||
onEquipment = { },
|
onAddItem = { },
|
||||||
onInventoryItemMove = { _, _ -> },
|
onInventoryItemMove = { _, _ -> },
|
||||||
onInventoryIsMoveEnable = { _, _ -> true },
|
onInventoryIsMoveEnable = { _, _ -> true },
|
||||||
onInventoryItemDrop = { _ -> },
|
onInventoryItemDrop = { _ -> },
|
||||||
|
|
|
||||||
|
|
@ -13,16 +13,13 @@ import com.pixelized.rplexicon.R
|
||||||
import com.pixelized.rplexicon.data.model.item.Item
|
import com.pixelized.rplexicon.data.model.item.Item
|
||||||
import com.pixelized.rplexicon.data.network.ItemDto
|
import com.pixelized.rplexicon.data.network.ItemDto
|
||||||
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
|
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.EquipmentRepository
|
|
||||||
import com.pixelized.rplexicon.data.repository.character.ItemsRepository
|
import com.pixelized.rplexicon.data.repository.character.ItemsRepository
|
||||||
import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository
|
import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository
|
||||||
import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument
|
import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument
|
||||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.EquipmentItemUio
|
|
||||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDialogDetailUio
|
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDialogDetailUio
|
||||||
import com.pixelized.rplexicon.ui.screens.character.factory.ItemUioFactory
|
import com.pixelized.rplexicon.ui.screens.character.factory.InventoryItemUioFactory
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.context
|
import com.pixelized.rplexicon.utilitary.extentions.context
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.string.BaldurGageImageCache.equipmentsIcon
|
import com.pixelized.rplexicon.utilitary.extentions.string.BaldurGageImageCache.equipmentsIcon
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.uri
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
|
@ -33,24 +30,19 @@ import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class InventoryViewModel @Inject constructor(
|
class InventoryViewModel @Inject constructor(
|
||||||
private val equipmentRepository: EquipmentRepository,
|
|
||||||
private val descriptionRepository: DescriptionRepository,
|
private val descriptionRepository: DescriptionRepository,
|
||||||
private val fireRepository: RealtimeDatabaseRepository,
|
private val fireRepository: RealtimeDatabaseRepository,
|
||||||
private val itemFactory: ItemUioFactory,
|
private val itemFactory: InventoryItemUioFactory,
|
||||||
itemsRepository: ItemsRepository,
|
itemsRepository: ItemsRepository,
|
||||||
savedStateHandle: SavedStateHandle,
|
savedStateHandle: SavedStateHandle,
|
||||||
application: Application
|
application: Application
|
||||||
) : AndroidViewModel(application) {
|
) : AndroidViewModel(application) {
|
||||||
private val character = savedStateHandle.characterSheetArgument.name
|
private val character = savedStateHandle.characterSheetArgument.name
|
||||||
|
|
||||||
private val _equipments = mutableStateOf<EquipmentItemUio?>(null)
|
|
||||||
val equipments: State<EquipmentItemUio?> get() = _equipments
|
|
||||||
|
|
||||||
// Target the local indexes form specific ids (change locally to avoid flooding of firebase)
|
// Target the local indexes form specific ids (change locally to avoid flooding of firebase)
|
||||||
private val itemLocalIndex =
|
private val itemLocalIndex =
|
||||||
MutableStateFlow<Map<String, Int>>(hashMapOf())
|
MutableStateFlow<Map<String, Int>>(hashMapOf())
|
||||||
|
|
@ -120,32 +112,6 @@ class InventoryViewModel @Inject constructor(
|
||||||
}.toMap()
|
}.toMap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
launch(Dispatchers.IO) {
|
|
||||||
equipmentRepository.data.collect {
|
|
||||||
val equipments = it[character]?.let { data ->
|
|
||||||
EquipmentItemUio(
|
|
||||||
silhouette = data.silhouette ?: R.drawable.ic_woman_archer_256.uri,
|
|
||||||
head = data.head,
|
|
||||||
face = data.face,
|
|
||||||
shoulder = data.shoulder,
|
|
||||||
neck = data.neck,
|
|
||||||
body = data.body,
|
|
||||||
chest = data.chest,
|
|
||||||
arm = data.arm,
|
|
||||||
waist = data.waist,
|
|
||||||
hands = data.hand,
|
|
||||||
ringRight = data.ring1,
|
|
||||||
foot = data.foot,
|
|
||||||
ringLeft = data.ring2,
|
|
||||||
mainHand = data.mainHand,
|
|
||||||
offHand = data.offHand,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
_equipments.value = equipments
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
launch(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
fireRepository.setInventory(
|
fireRepository.setInventory(
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
|
@ -18,13 +19,15 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.pixelized.rplexicon.R
|
||||||
import com.pixelized.rplexicon.ui.composable.images.AsyncImage
|
import com.pixelized.rplexicon.ui.composable.images.AsyncImage
|
||||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.string.BaldurGageImageCache.cache
|
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
data class ItemUio(
|
data class ItemUio(
|
||||||
|
|
@ -49,8 +52,10 @@ fun Item(
|
||||||
.padding(paddingValues)
|
.padding(paddingValues)
|
||||||
.then(other = modifier),
|
.then(other = modifier),
|
||||||
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
|
modifier = Modifier.size(size = 42.dp),
|
||||||
model = item.icon,
|
model = item.icon,
|
||||||
)
|
)
|
||||||
Column(
|
Column(
|
||||||
|
|
@ -62,11 +67,17 @@ fun Item(
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
maxLines = 1,
|
||||||
text = item.name,
|
text = item.name,
|
||||||
)
|
)
|
||||||
item.description?.let {
|
item.description?.let {
|
||||||
Text(
|
Text(
|
||||||
style = MaterialTheme.typography.labelSmall,
|
style = MaterialTheme.typography.labelSmall,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
maxLines = 1,
|
||||||
text = it,
|
text = it,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -93,19 +104,13 @@ private class ItemProvider : PreviewParameterProvider<ItemUio> {
|
||||||
id = "7d27561b-f2f4-4899-a2fc-df3501b1b66b",
|
id = "7d27561b-f2f4-4899-a2fc-df3501b1b66b",
|
||||||
name = "Bourse",
|
name = "Bourse",
|
||||||
description = "Un petite bourse.",
|
description = "Un petite bourse.",
|
||||||
icon = cache(uri = "https://bg3.wiki/w/images/c/c6/Pouch_A_Unfaded.webp"),
|
icon = R.drawable.icbg_pouch_a_unfaded,
|
||||||
),
|
|
||||||
ItemUio(
|
|
||||||
id = "43424bbc-0117-44f8-b512-6d469a05e6c2",
|
|
||||||
name = "Sac à dos",
|
|
||||||
description = "Sac à dos pour aventurier.",
|
|
||||||
icon = cache(uri = "https://bg3.wiki/w/images/6/6d/Backpack_B_Unfaded.webp"),
|
|
||||||
),
|
),
|
||||||
ItemUio(
|
ItemUio(
|
||||||
id = "2ecf41c2-06b1-4f2d-a6d9-b6adcaf05aba",
|
id = "2ecf41c2-06b1-4f2d-a6d9-b6adcaf05aba",
|
||||||
name = "Sac à dos",
|
name = "Sac à dos",
|
||||||
description = "Sac à dos pour aventurier.",
|
description = null,
|
||||||
icon = cache(uri = "https://bg3.wiki/w/images/3/39/Backpack_A_Unfaded.webp"),
|
icon = R.drawable.icbg_backpack_b_unfaded,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,307 @@
|
||||||
|
package com.pixelized.rplexicon.ui.screens.character.pages.inventory.item
|
||||||
|
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.fadeIn
|
||||||
|
import androidx.compose.animation.fadeOut
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.imePadding
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Refresh
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.OutlinedTextField
|
||||||
|
import androidx.compose.material3.OutlinedTextFieldDefaults
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.surfaceColorAtElevation
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Stable
|
||||||
|
import androidx.compose.runtime.State
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusManager
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.window.Dialog
|
||||||
|
import androidx.compose.ui.window.DialogProperties
|
||||||
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
|
import com.pixelized.rplexicon.R
|
||||||
|
import com.pixelized.rplexicon.ui.composable.CategoryHeader
|
||||||
|
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||||
|
|
||||||
|
@Stable
|
||||||
|
data class ItemCategoryUio(
|
||||||
|
val title: String,
|
||||||
|
val items: List<ItemUio>,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ItemListDialog(
|
||||||
|
viewModel: ItemListViewModel = hiltViewModel(),
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
) {
|
||||||
|
if (viewModel.display.value) {
|
||||||
|
Dialog(
|
||||||
|
properties = remember {
|
||||||
|
DialogProperties(
|
||||||
|
decorFitsSystemWindows = false,
|
||||||
|
usePlatformDefaultWidth = false,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
) {
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier
|
||||||
|
.imePadding()
|
||||||
|
.padding(all = 24.dp)
|
||||||
|
.fillMaxSize(),
|
||||||
|
shape = remember { RoundedCornerShape(size = 16.dp) },
|
||||||
|
) {
|
||||||
|
ItemListContent(
|
||||||
|
search = viewModel.search,
|
||||||
|
items = viewModel.items,
|
||||||
|
onClear = { viewModel.filter("") },
|
||||||
|
onSearchChange = viewModel::filter,
|
||||||
|
onRefresh = viewModel::updateItemList,
|
||||||
|
onItem = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
@Composable
|
||||||
|
private fun ItemListContent(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
search: State<String>,
|
||||||
|
items: State<List<ItemCategoryUio>>,
|
||||||
|
onClear: () -> Unit,
|
||||||
|
onRefresh: () -> Unit,
|
||||||
|
onSearchChange: (String) -> Unit,
|
||||||
|
onItem: () -> Unit,
|
||||||
|
) {
|
||||||
|
Scaffold(
|
||||||
|
modifier = modifier,
|
||||||
|
topBar = {
|
||||||
|
SearchTextField(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.padding(top = 16.dp),
|
||||||
|
value = search,
|
||||||
|
onClear = onClear,
|
||||||
|
onRefresh = onRefresh,
|
||||||
|
onValueChange = onSearchChange,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
content = { paddings ->
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.padding(paddingValues = paddings),
|
||||||
|
contentPadding = PaddingValues(vertical = 16.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||||
|
) {
|
||||||
|
items.value.forEachIndexed { index, category ->
|
||||||
|
stickyHeader(
|
||||||
|
key = "category:${category.title}",
|
||||||
|
) {
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
) {
|
||||||
|
CategoryHeader(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = if (index == 0) 0.dp else 16.dp)
|
||||||
|
.padding(horizontal = 16.dp),
|
||||||
|
text = category.title,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
items(
|
||||||
|
items = category.items,
|
||||||
|
key = { it.id },
|
||||||
|
) {
|
||||||
|
Item(
|
||||||
|
item = it,
|
||||||
|
onClick = onItem
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SearchTextField(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
focusManager: FocusManager = LocalFocusManager.current,
|
||||||
|
focusRequester: FocusRequester = remember { FocusRequester() },
|
||||||
|
value: State<String>,
|
||||||
|
onClear: () -> Unit,
|
||||||
|
onRefresh: () -> Unit,
|
||||||
|
onValueChange: (String) -> Unit,
|
||||||
|
) {
|
||||||
|
val surfaceColor = MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp)
|
||||||
|
OutlinedTextField(
|
||||||
|
modifier = Modifier
|
||||||
|
.focusRequester(focusRequester = focusRequester)
|
||||||
|
.then(other = modifier),
|
||||||
|
colors = OutlinedTextFieldDefaults.colors(
|
||||||
|
focusedContainerColor = surfaceColor,
|
||||||
|
unfocusedContainerColor = surfaceColor,
|
||||||
|
focusedBorderColor = Color.Transparent,
|
||||||
|
unfocusedBorderColor = Color.Transparent,
|
||||||
|
),
|
||||||
|
shape = CircleShape,
|
||||||
|
trailingIcon = {
|
||||||
|
Row {
|
||||||
|
AnimatedVisibility(
|
||||||
|
visible = value.value.isNotEmpty(),
|
||||||
|
enter = fadeIn(),
|
||||||
|
exit = fadeOut(),
|
||||||
|
) {
|
||||||
|
IconButton(
|
||||||
|
modifier = Modifier.size(size = 48.dp),
|
||||||
|
onClick = onClear,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(
|
||||||
|
color = MaterialTheme.colorScheme.surface,
|
||||||
|
shape = CircleShape
|
||||||
|
)
|
||||||
|
.padding(all = 12.dp)
|
||||||
|
.size(size = 18.dp),
|
||||||
|
painter = painterResource(id = R.drawable.ic_clear_24),
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconButton(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(size = 48.dp)
|
||||||
|
.padding(end = 4.dp),
|
||||||
|
onClick = onRefresh,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(
|
||||||
|
color = MaterialTheme.colorScheme.surface,
|
||||||
|
shape = CircleShape
|
||||||
|
)
|
||||||
|
.padding(all = 12.dp)
|
||||||
|
.size(size = 18.dp),
|
||||||
|
imageVector = Icons.Default.Refresh,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
keyboardOptions = KeyboardOptions(
|
||||||
|
keyboardType = KeyboardType.Text,
|
||||||
|
imeAction = ImeAction.Done,
|
||||||
|
),
|
||||||
|
keyboardActions = KeyboardActions(
|
||||||
|
onDone = { focusManager.clearFocus(true) },
|
||||||
|
),
|
||||||
|
maxLines = 1,
|
||||||
|
value = value.value,
|
||||||
|
onValueChange = onValueChange,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||||
|
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||||
|
private fun ItemLisPreview() {
|
||||||
|
LexiconTheme {
|
||||||
|
Surface {
|
||||||
|
ItemListContent(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
search = remember {
|
||||||
|
mutableStateOf("Pouet")
|
||||||
|
},
|
||||||
|
items = remember {
|
||||||
|
mutableStateOf(
|
||||||
|
listOf(
|
||||||
|
ItemCategoryUio(
|
||||||
|
title = "Container",
|
||||||
|
items = listOf(
|
||||||
|
ItemUio(
|
||||||
|
id = "70d0bcbe-47af-48ba-a9e5-9f9b97bc25a1",
|
||||||
|
name = "Bourse",
|
||||||
|
description = "Une petite bourse en cuir.",
|
||||||
|
icon = R.drawable.icbg_leather_pouch_a_unfaded,
|
||||||
|
),
|
||||||
|
ItemUio(
|
||||||
|
id = "7d27561b-f2f4-4899-a2fc-df3501b1b66b",
|
||||||
|
name = "Bourse",
|
||||||
|
description = "Une petite bourse.",
|
||||||
|
icon = R.drawable.icbg_pouch_a_unfaded,
|
||||||
|
),
|
||||||
|
ItemUio(
|
||||||
|
id = "2ecf41c2-06b1-4f2d-a6d9-b6adcaf05aba",
|
||||||
|
name = "Sac à dos",
|
||||||
|
description = "Sac à dos pour aventurier.",
|
||||||
|
icon = R.drawable.icbg_backpack_a_unfaded,
|
||||||
|
),
|
||||||
|
ItemUio(
|
||||||
|
id = "43424bbc-0117-44f8-b512-6d469a05e6c2",
|
||||||
|
name = "Sac à dos",
|
||||||
|
description = "Sac à dos pour aventurier.",
|
||||||
|
icon = R.drawable.icbg_backpack_b_unfaded,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ItemCategoryUio(
|
||||||
|
title = "Parchemin",
|
||||||
|
items = listOf(
|
||||||
|
ItemUio(
|
||||||
|
id = "471266fb-15a8-4346-9da0-d1c44e4c1569",
|
||||||
|
name = "Parchemin d'Arme spirituelle",
|
||||||
|
description = null,
|
||||||
|
icon = R.drawable.icbg_book_signedtradebisa_unfaded,
|
||||||
|
),
|
||||||
|
ItemUio(
|
||||||
|
id = "eda09856-5a91-4411-ac75-248a16ce1060",
|
||||||
|
name = "Parchemin de Bénédiction",
|
||||||
|
description = null,
|
||||||
|
icon = R.drawable.icbg_scroll_of_bless_unfaded,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onClear = { },
|
||||||
|
onRefresh = { },
|
||||||
|
onSearchChange = { },
|
||||||
|
onItem = { },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,129 +0,0 @@
|
||||||
package com.pixelized.rplexicon.ui.screens.character.pages.inventory.item
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.Stable
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.pixelized.rplexicon.R
|
|
||||||
import com.pixelized.rplexicon.ui.composable.form.TextFieldAppBar
|
|
||||||
import com.pixelized.rplexicon.ui.composable.form.TextFieldUio
|
|
||||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.modifier.lexiconShadow
|
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.string.BaldurGageImageCache.cache
|
|
||||||
|
|
||||||
@Stable
|
|
||||||
data class ItemListUio(
|
|
||||||
val search: TextFieldUio,
|
|
||||||
val items: List<ItemUio>,
|
|
||||||
)
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ItemListPage() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun ItemListContent(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
page: ItemListUio,
|
|
||||||
onBack: () -> Unit,
|
|
||||||
onClear: () -> Unit,
|
|
||||||
onSearchChange: (String) -> Unit,
|
|
||||||
) {
|
|
||||||
Scaffold(
|
|
||||||
modifier = modifier,
|
|
||||||
topBar = {
|
|
||||||
Surface(
|
|
||||||
modifier = Modifier.lexiconShadow(),
|
|
||||||
) {
|
|
||||||
TextFieldAppBar(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(height = 64.dp),
|
|
||||||
field = page.search,
|
|
||||||
onBack = onBack,
|
|
||||||
onClear = onClear,
|
|
||||||
onValueChange = onSearchChange,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
content = { paddings ->
|
|
||||||
LazyColumn(
|
|
||||||
modifier = Modifier.padding(paddingValues = paddings),
|
|
||||||
contentPadding = PaddingValues(vertical = 16.dp),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(space = 8.dp),
|
|
||||||
) {
|
|
||||||
items(
|
|
||||||
items = page.items,
|
|
||||||
key = { it.id },
|
|
||||||
) {
|
|
||||||
Item(item = it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
|
||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
|
||||||
private fun ItemLisPreview() {
|
|
||||||
LexiconTheme {
|
|
||||||
Surface {
|
|
||||||
ItemListContent(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
page = remember {
|
|
||||||
ItemListUio(
|
|
||||||
search = TextFieldUio(
|
|
||||||
label = R.string.search_field_title,
|
|
||||||
value = mutableStateOf("")
|
|
||||||
),
|
|
||||||
items = listOf(
|
|
||||||
ItemUio(
|
|
||||||
id = "70d0bcbe-47af-48ba-a9e5-9f9b97bc25a1",
|
|
||||||
name = "Bourse",
|
|
||||||
description = "Une petite bourse en cuir.",
|
|
||||||
icon = cache("https://bg3.wiki/w/images/5/5b/Leather_Pouch_A_Unfaded.webp"),
|
|
||||||
),
|
|
||||||
ItemUio(
|
|
||||||
id = "7d27561b-f2f4-4899-a2fc-df3501b1b66b",
|
|
||||||
name = "Bourse",
|
|
||||||
description = "Une petite bourse.",
|
|
||||||
icon = cache(uri = "https://bg3.wiki/w/images/c/c6/Pouch_A_Unfaded.webp"),
|
|
||||||
),
|
|
||||||
ItemUio(
|
|
||||||
id = "43424bbc-0117-44f8-b512-6d469a05e6c2",
|
|
||||||
name = "Sac à dos",
|
|
||||||
description = "Sac à dos pour aventurier.",
|
|
||||||
icon = cache(uri = "https://bg3.wiki/w/images/6/6d/Backpack_B_Unfaded.webp"),
|
|
||||||
),
|
|
||||||
ItemUio(
|
|
||||||
id = "2ecf41c2-06b1-4f2d-a6d9-b6adcaf05aba",
|
|
||||||
name = "Sac à dos",
|
|
||||||
description = "Sac à dos pour aventurier.",
|
|
||||||
icon = cache(uri = "https://bg3.wiki/w/images/3/39/Backpack_A_Unfaded.webp"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onBack = {},
|
|
||||||
onClear = {},
|
|
||||||
onSearchChange = {},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.pixelized.rplexicon.ui.screens.character.pages.inventory.item
|
||||||
|
|
||||||
|
import android.icu.text.Collator
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Stable
|
||||||
|
import androidx.compose.runtime.State
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.pixelized.rplexicon.data.model.item.Item
|
||||||
|
import com.pixelized.rplexicon.data.repository.character.ItemsRepository
|
||||||
|
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 factory: ItemElementUioFactory,
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
private val filter = MutableStateFlow("")
|
||||||
|
|
||||||
|
private val _display = mutableStateOf(false)
|
||||||
|
val display: State<Boolean> = _display
|
||||||
|
|
||||||
|
private val _refreshing = mutableStateOf(false)
|
||||||
|
val refreshing: State<Boolean> = _refreshing
|
||||||
|
|
||||||
|
val search: State<String>
|
||||||
|
@Composable
|
||||||
|
@Stable
|
||||||
|
get() = filter.collectAsState(initial = "")
|
||||||
|
|
||||||
|
val items: State<List<ItemCategoryUio>>
|
||||||
|
@Composable
|
||||||
|
@Stable
|
||||||
|
get() {
|
||||||
|
val context = LocalContext.current
|
||||||
|
return itemsRepository.data.combine(filter) { items, filter -> items to filter }
|
||||||
|
.map { (items: Map<String, Item>, 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<Item> ->
|
||||||
|
factory.toUio(context = context, items = items)
|
||||||
|
}
|
||||||
|
.collectAsState(initial = emptyList())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateItemList() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
try {
|
||||||
|
_refreshing.value = true
|
||||||
|
itemsRepository.fetchItems()
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
_refreshing.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun filter(filter: String) {
|
||||||
|
this.filter.value = filter
|
||||||
|
}
|
||||||
|
|
||||||
|
fun show() {
|
||||||
|
_display.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hide() {
|
||||||
|
_display.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,19 +7,94 @@ import com.pixelized.rplexicon.R
|
||||||
object BaldurGageImageCache {
|
object BaldurGageImageCache {
|
||||||
// https://bg3.wiki/wiki/Category:Controller_UI_Icons
|
// https://bg3.wiki/wiki/Category:Controller_UI_Icons
|
||||||
private val uri = mapOf(
|
private val uri = mapOf(
|
||||||
|
// Drive
|
||||||
|
"https://drive.google.com/uc?export=view&id=1Dc0hBGXTNP8dnYqHJlSsK1WgWAsWtCV9" to R.drawable.icbg_lantern_of_revealing,
|
||||||
// Category:Generic Controller Icons
|
// Category:Generic Controller Icons
|
||||||
"https://bg3.wiki/w/images/5/56/Generic_Darkness_Icon.webp" to R.drawable.icbg_generic_darkness_icon,
|
"https://bg3.wiki/w/images/5/56/Generic_Darkness_Icon.webp" to R.drawable.icbg_generic_darkness_icon,
|
||||||
// Category:Container Controller Icons
|
// Category:Container Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/1/1d/Alchemy_Pouch_Unfaded.webp" to R.drawable.icbg_alchemy_pouch_unfaded,
|
||||||
"https://bg3.wiki/w/images/5/5b/Leather_Pouch_A_Unfaded.webp" to R.drawable.icbg_leather_pouch_a_unfaded,
|
"https://bg3.wiki/w/images/5/5b/Leather_Pouch_A_Unfaded.webp" to R.drawable.icbg_leather_pouch_a_unfaded,
|
||||||
"https://bg3.wiki/w/images/c/c6/Pouch_A_Unfaded.webp" to R.drawable.icbg_pouch_a_unfaded,
|
"https://bg3.wiki/w/images/c/c6/Pouch_A_Unfaded.webp" to R.drawable.icbg_pouch_a_unfaded,
|
||||||
"https://bg3.wiki/w/images/3/39/Backpack_A_Unfaded.webp" to R.drawable.icbg_backpack_a_unfaded,
|
"https://bg3.wiki/w/images/3/39/Backpack_A_Unfaded.webp" to R.drawable.icbg_backpack_a_unfaded,
|
||||||
"https://bg3.wiki/w/images/6/6d/Backpack_B_Unfaded.webp" to R.drawable.icbg_backpack_b_unfaded,
|
"https://bg3.wiki/w/images/6/6d/Backpack_B_Unfaded.webp" to R.drawable.icbg_backpack_b_unfaded,
|
||||||
"https://bg3.wiki/w/images/c/c0/Keychain_Unfaded.png" to R.drawable.icbg_keychain_unfaded,
|
"https://bg3.wiki/w/images/c/c0/Keychain_Unfaded.png" to R.drawable.icbg_keychain_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/4/4e/Leather_Pouch_Old_Unfaded.webp" to R.drawable.icbg_leather_pouch_old_unfaded,
|
||||||
// Category:Potion Controller Icons
|
// Category:Potion Controller Icons
|
||||||
"https://bg3.wiki/w/images/c/ce/POT_Potion_of_Healing_Unfaded.png" to R.drawable.icbg_pot_potion_of_healing_unfaded,
|
"https://bg3.wiki/w/images/c/ce/POT_Potion_of_Healing_Unfaded.png" to R.drawable.icbg_pot_potion_of_healing_unfaded,
|
||||||
"https://bg3.wiki/w/images/7/73/POT_Potion_of_Superior_Healing_Unfaded.png" to R.drawable.icbg_potion_of_superior_healing_unfaded,
|
"https://bg3.wiki/w/images/7/73/POT_Potion_of_Superior_Healing_Unfaded.png" to R.drawable.icbg_potion_of_superior_healing_unfaded,
|
||||||
|
// Category:Grenade Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/2/2e/GRN_Holy_Water_Unfaded.png" to R.drawable.icbg_grn_holy_water_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/7/7c/GRN_Haste_Spore_Grenade_Unfaded.png" to R.drawable.icbg_haste_spore_grenade_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/0/00/GRN_Grease_Bottle_Unfaded.png" to R.drawable.icbg_grn_grease_bottle_unfaded,
|
||||||
|
// Category:Scroll Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/d/db/BOOK_SignedTradeVisa_Unfaded.png" to R.drawable.icbg_book_signedtradebisa_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/a/ac/Book_Parchment_L_Unfaded.png" to R.drawable.icbg_book_parchment_l_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/8/8f/Scroll_of_Bless_Unfaded.png" to R.drawable.icbg_scroll_of_bless_unfaded,
|
||||||
|
// Category:Key Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/8/8b/Key_Flower_B_Unfaded.png" to R.drawable.icbg_key_flower_b_unfaded,
|
||||||
|
// Category:Food Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/6/6e/FOOD_Goodberry_Unfaded.png" to R.drawable.icbg_food_goodberry_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/d/df/FOOD_Treacle_Tart_Unfaded.png" to R.drawable.icbg_food_treacle_tart_unfaded,
|
||||||
|
// Category:Drink Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/c/c8/ALCH_Arkhen%27s_Hoard_Unfaded.png" to R.drawable.icbg_alch_arkhens_hoard_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/d/dc/ALCH_Ashaba_Dusk_Unfaded.png" to R.drawable.icbg_alch_ashaba_dusk_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/d/d6/ALCH_Farsea_Marshwine_Unfaded.png" to R.drawable.icbg_alch_farsea_marshwine_unfaded,
|
||||||
|
// Category:Ingredient Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/7/72/Worg_Fang_Unfaded.png" to R.drawable.icbg_worg_fang_unfaded,
|
||||||
|
// Category:Miscellaneous Item Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/4/47/Enriched_Infernal_Iron_Unfaded.png" to R.drawable.icbg_enriched_infernal_iron_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/7/74/Candle_Unfaded.png" to R.drawable.icbg_candle_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/1/17/Rope_Unfaded.png" to R.drawable.icbg_rope_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/b/bc/Clutter_Wooden_Bowl_Unfaded.webp" to R.drawable.icbg_clutter_wooden_bowl_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/a/a9/VAL_MISC_Incense_Pile_A_Unfaded.png" to R.drawable.icbg_val_misc_incense_pile_a_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/7/78/VAL_MISC_Silver_Spoon_Unfaded.png" to R.drawable.icbg_val_misc_silver_spoon_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/4/40/Incense_Bowl_B_Unfaded.png" to R.drawable.icbg_incense_bowl_b_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/1/15/Silver_Ingot_Unfaded.png" to R.drawable.icbg_silver_ingot_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/2/2a/Thieves_Tools_Unfaded.png" to R.drawable.icbg_thieves_tools_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/4/46/MISC_Arrow_Unfaded.png" to R.drawable.icbg_misc_arrow_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/a/a1/Arrow_of_Many_Targets_Unfaded.png" to R.drawable.icbg_arrow_of_many_targets_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/4/49/Arrow_of_Piercing_Unfaded.png" to R.drawable.icbg_arrow_of_piercing_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/2/20/Water_Wicker_B_Unfaded.png" to R.drawable.icbg_water_wicker_b_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/0/0f/Clutter_Bedroll_Unfaded.webp" to R.drawable.icbg_clutter_bedroll_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/3/37/Quill_Unfaded.png" to R.drawable.icbg_quill_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/5/5f/Soap_Bar_Unfaded.png" to R.drawable.icbg_soap_bar_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/d/df/Toy_Block_B_Unfaded.png" to R.drawable.icbg_toy_block_b_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/f/f4/Cauldron_A_Unfaded.png" to R.drawable.icbg_cauldron_a_unfaded,
|
||||||
// Category:Cloak Controller Icons
|
// Category:Cloak Controller Icons
|
||||||
"https://bg3.wiki/w/images/8/85/Cloak_Of_Protection_Unfaded.png" to R.drawable.icbg_cloak_of_protection_unfaded,
|
"https://bg3.wiki/w/images/8/85/Cloak_Of_Protection_Unfaded.png" to R.drawable.icbg_cloak_of_protection_unfaded,
|
||||||
|
// Category:Ring Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/b/bf/Gemless_Ring_Unfaded.png" to R.drawable.icbg_gemless_ring_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/1/19/Partner_Ring_A_Unfaded.png" to R.drawable.icbg_partner_ring_a_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/9/9e/Bed_Linen_Unfaded.png" to R.drawable.icbg_bed_linen_unfaded,
|
||||||
|
// Category:Amulet Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/e/e5/Amulet_of_Lost_Voices_Unfaded.png" to R.drawable.icbg_amulet_of_lost_voices_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/a/aa/Amulet_Necklace_A_Silver_A_Unfaded.png" to R.drawable.icbg_amulet_necklace_a_silver_a_unfaded,
|
||||||
|
// Category:Armour Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/d/d4/Leather_Armour_Rogue_Unfaded.png" to R.drawable.icbg_leather_armour_rogue_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/6/68/Scale_Mail_Unfaded.png" to R.drawable.icbg_scale_mail_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/2/2f/Chain_Shirt_3_Unfaded.png" to R.drawable.icbg_chain_shirt_3_unfaded,
|
||||||
|
// Category:Weapon Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/b/b5/Dryad_Staff_Unfaded.png" to R.drawable.icbg_dryad_staff_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/2/2d/Dagger_Unfaded.png" to R.drawable.icbg_dagger_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/6/63/Dagger_PlusOne_Unfaded.png" to R.drawable.icbg_dagger_plusone_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/0/02/Shortsword_Unfaded.png" to R.drawable.icbg_shortsword_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/9/92/Shortsword_PlusOne_Unfaded.png" to R.drawable.icbg_shortsword_plusone_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/3/39/Mace_Unfaded.png" to R.drawable.icbg_mace_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/3/39/Battleaxe_Unfaded.png" to R.drawable.icbg_battleaxe_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/5/5d/Battleaxe_PlusOne_Unfaded.png" to R.drawable.icbg_battleaxe_plus_one_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/4/41/Rapier_Unfaded.png" to R.drawable.icbg_rapier_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/7/72/Hand_Crossbow_Unfaded.png" to R.drawable.icbg_hand_crossbow_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/7/74/Light_Crossbow_Unfaded.png" to R.drawable.icbg_light_crossbow_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/2/23/Heavy_Crossbow_Unfaded.png" to R.drawable.icbg_heavy_crossbow_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/b/b1/Longbow_Unfaded.png" to R.drawable.icbg_longbow_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/d/d6/Javelin_Unfaded.png" to R.drawable.icbg_javelin_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/1/14/Spear_PlusOne_Unfaded.png" to R.drawable.icbg_shortsword_plusone_unfaded,
|
||||||
|
// https://bg3.wiki/wiki/Category:Shield_Controller_Icons
|
||||||
|
"https://bg3.wiki/w/images/4/45/Studded_Shield_Unfaded.png" to R.drawable.icbg_studded_shield_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/1/1d/Item_WPN_HUM_Shield_D_0_Unfaded.png" to R.drawable.icbg_item_wpm_hum_shield_unfaded,
|
||||||
|
// Category:Instrument Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/0/08/Instrument_Lute_Unfaded.png" to R.drawable.icbg_instrument_lute_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/0/01/Instrument_PanFlute_Unfaded.png" to R.drawable.icbg_instrument_panflute_unfaded,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val alterations = hashMapOf(
|
private val alterations = hashMapOf(
|
||||||
|
|
@ -287,7 +362,8 @@ object BaldurGageImageCache {
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
fun spellIcon(name: String): Int? = spells[name]
|
fun spellIcon(name: String): Int? = spells[name]
|
||||||
|
|
||||||
fun cache(uri: Uri?): Any = cache(uri = uri.toString())
|
fun cache(uri: Uri?): Any = when (uri) {
|
||||||
|
null -> R.drawable.icbg_generic_darkness_icon
|
||||||
fun cache(uri: String?): Any = this.uri[uri.toString()] ?: R.drawable.icbg_generic_darkness_icon
|
else -> this.uri[uri.toString()] ?: uri
|
||||||
|
}
|
||||||
}
|
}
|
||||||
BIN
app/src/main/res/drawable/icbg_alch_arkhens_hoard_unfaded.webp
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
app/src/main/res/drawable/icbg_alch_ashaba_dusk_unfaded.webp
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
BIN
app/src/main/res/drawable/icbg_alchemy_pouch_unfaded.webp
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 12 KiB |
BIN
app/src/main/res/drawable/icbg_arrow_of_many_targets_unfaded.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
app/src/main/res/drawable/icbg_arrow_of_piercing_unfaded.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
app/src/main/res/drawable/icbg_battleaxe_unfaded.webp
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
app/src/main/res/drawable/icbg_bed_linen_unfaded.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
app/src/main/res/drawable/icbg_book_parchment_l_unfaded.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
app/src/main/res/drawable/icbg_candle_unfaded.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
app/src/main/res/drawable/icbg_cauldron_a_unfaded.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
app/src/main/res/drawable/icbg_chain_shirt_3_unfaded.webp
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
app/src/main/res/drawable/icbg_clutter_bedroll_unfaded.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable/icbg_clutter_wooden_bowl_unfaded.webp
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
app/src/main/res/drawable/icbg_dagger_plusone_unfaded.webp
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
app/src/main/res/drawable/icbg_dryad_staff_unfaded.webp
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
BIN
app/src/main/res/drawable/icbg_food_treacle_tart_unfaded.webp
Normal file
|
After Width: | Height: | Size: 9 KiB |
BIN
app/src/main/res/drawable/icbg_gemless_ring_unfaded.webp
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
app/src/main/res/drawable/icbg_grn_grease_bottle_unfaded.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
app/src/main/res/drawable/icbg_heavy_crossbow_unfaded.webp
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
app/src/main/res/drawable/icbg_incense_bowl_b_unfaded.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
app/src/main/res/drawable/icbg_instrument_lute_unfaded.webp
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
app/src/main/res/drawable/icbg_instrument_panflute_unfaded.webp
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
app/src/main/res/drawable/icbg_item_wpm_hum_shield_unfaded.webp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
app/src/main/res/drawable/icbg_javelin_unfaded.webp
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
app/src/main/res/drawable/icbg_key_flower_b_unfaded.webp
Normal file
|
After Width: | Height: | Size: 8 KiB |
BIN
app/src/main/res/drawable/icbg_leather_pouch_old_unfaded.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable/icbg_longbow_unfaded.webp
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
app/src/main/res/drawable/icbg_mace_unfaded.webp
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
app/src/main/res/drawable/icbg_misc_arrow_unfaded.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
app/src/main/res/drawable/icbg_partner_ring_a_unfaded.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
app/src/main/res/drawable/icbg_quill_unfaded.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
app/src/main/res/drawable/icbg_rope_unfaded.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
app/src/main/res/drawable/icbg_shortsword_plusone_unfaded.webp
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
app/src/main/res/drawable/icbg_silver_ingot_unfaded.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
app/src/main/res/drawable/icbg_soap_bar_unfaded.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
app/src/main/res/drawable/icbg_spear_plusone_unfaded.webp
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
app/src/main/res/drawable/icbg_thieves_tools_unfaded.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
app/src/main/res/drawable/icbg_toy_block_b_unfaded.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 27 KiB |
BIN
app/src/main/res/drawable/icbg_val_misc_silver_spoon_unfaded.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
app/src/main/res/drawable/icbg_water_wicker_b_unfaded.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -180,6 +180,9 @@
|
||||||
<string name="character_sheet_action_spell_level_0">Sorts mineurs</string>
|
<string name="character_sheet_action_spell_level_0">Sorts mineurs</string>
|
||||||
<string name="character_sheet_action_spell_level_X">Sorts de niveau %1$s</string>
|
<string name="character_sheet_action_spell_level_X">Sorts de niveau %1$s</string>
|
||||||
|
|
||||||
|
<string name="character_sheet__item_list__uncategorized">Non classé</string>
|
||||||
|
<string name="character_sheet__inventory__add_item_action">Ajouter</string>
|
||||||
|
|
||||||
<string name="dice_roll_mastery_proficiency">Maîtrise \"%1$s\" </string>
|
<string name="dice_roll_mastery_proficiency">Maîtrise \"%1$s\" </string>
|
||||||
<string name="dice_roll_mastery_expertise">Expertise \"%1$s\" </string>
|
<string name="dice_roll_mastery_expertise">Expertise \"%1$s\" </string>
|
||||||
<string name="dice_roll_mastery_saving_throw">Jet de sauvegarde</string>
|
<string name="dice_roll_mastery_saving_throw">Jet de sauvegarde</string>
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,9 @@
|
||||||
<string name="character_sheet_action_spell_level_0">Cantrip</string>
|
<string name="character_sheet_action_spell_level_0">Cantrip</string>
|
||||||
<string name="character_sheet_action_spell_level_X">Spell level %1$s</string>
|
<string name="character_sheet_action_spell_level_X">Spell level %1$s</string>
|
||||||
|
|
||||||
|
<string name="character_sheet__item_list__uncategorized">Uncategorized</string>
|
||||||
|
<string name="character_sheet__inventory__add_item_action">Add</string>
|
||||||
|
|
||||||
<string name="roll_overlay__close_action">Close</string>
|
<string name="roll_overlay__close_action">Close</string>
|
||||||
<string name="roll_overlay__critical_success">CRITICAL SUCCESS</string>
|
<string name="roll_overlay__critical_success">CRITICAL SUCCESS</string>
|
||||||
<string name="roll_overlay__critical_failure">CRITICAL FAILURE</string>
|
<string name="roll_overlay__critical_failure">CRITICAL FAILURE</string>
|
||||||
|
|
|
||||||