Add a lot of icon + change the cache system.
|
|
@ -1,12 +1,17 @@
|
|||
package com.pixelized.rplexicon.data.model.item
|
||||
|
||||
import android.net.Uri
|
||||
import com.pixelized.rplexicon.data.model.roll.Throw
|
||||
|
||||
data class Item(
|
||||
val id: String,
|
||||
val prefix: String?,
|
||||
val name: String,
|
||||
val type: String?,
|
||||
val description: String?,
|
||||
val isContainer: Boolean,
|
||||
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,
|
||||
prefix = row.parse(column = PREFIX),
|
||||
name = name,
|
||||
type = row.parse(column = TYPE),
|
||||
description = row.parse(column = CONTEXT),
|
||||
isContainer = container,
|
||||
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
|
||||
}
|
||||
|
|
@ -47,10 +49,12 @@ class ItemLexiconParser @Inject constructor(
|
|||
private val ID = column("Id")
|
||||
private val PREFIX = column("Préfix")
|
||||
private val NAME = column("Nom")
|
||||
private val TYPE = column("Type")
|
||||
private val CONTEXT = column("Contexte")
|
||||
private val CONTAINER = column("Contenant")
|
||||
private val EFFECT = column("Effet")
|
||||
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.network.ItemDto
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.inventory.InventoryItemUio
|
||||
import com.pixelized.rplexicon.utilitary.extentions.string.BaldurGageImageCache
|
||||
import javax.inject.Inject
|
||||
|
||||
class ItemUioFactory @Inject constructor() {
|
||||
class InventoryItemUioFactory @Inject constructor() {
|
||||
|
||||
fun toUio(
|
||||
items: Map<String, Item>,
|
||||
|
|
@ -19,7 +20,7 @@ class ItemUioFactory @Inject constructor() {
|
|||
name = item.name,
|
||||
amount = amount,
|
||||
container = item.isContainer,
|
||||
icon = item.icon,
|
||||
icon = BaldurGageImageCache.cache(item.icon),
|
||||
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.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
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.rememberLazyGridState
|
||||
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.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
|
|
@ -24,18 +27,21 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.compositeOver
|
||||
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.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.pixelized.rplexicon.LocalSnack
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.EquipmentItem
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.EquipmentItemUio
|
||||
import com.pixelized.rplexicon.R
|
||||
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.preview.rememberEquipmentState
|
||||
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.utilitary.DraggableItem
|
||||
import com.pixelized.rplexicon.utilitary.dragContainer
|
||||
|
|
@ -47,7 +53,8 @@ import kotlinx.coroutines.launch
|
|||
|
||||
@Composable
|
||||
fun InventoryPage(
|
||||
viewModel: InventoryViewModel,
|
||||
viewModel: InventoryViewModel = hiltViewModel(),
|
||||
itemViewModel: ItemListViewModel = hiltViewModel()
|
||||
) {
|
||||
val snack = LocalSnack.current
|
||||
val snackJob = remember { mutableStateOf<Job?>(null) }
|
||||
|
|
@ -55,18 +62,19 @@ fun InventoryPage(
|
|||
|
||||
InventoryPageContent(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
equipments = viewModel.equipments,
|
||||
inventory = viewModel.inventory,
|
||||
onEquipment = {
|
||||
snackJob.value?.cancel()
|
||||
viewModel.showSkillDetailDialog(item = it)
|
||||
},
|
||||
onAddItem = itemViewModel::show,
|
||||
onInventoryItemMove = viewModel::onMove,
|
||||
onInventoryIsMoveEnable = viewModel::isMoveEnable,
|
||||
onInventoryItemDrop = viewModel::onDrop,
|
||||
onInventoryItemDropOver = viewModel::onDropOver,
|
||||
)
|
||||
|
||||
ItemListDialog(
|
||||
viewModel = itemViewModel,
|
||||
onDismissRequest = itemViewModel::hide,
|
||||
)
|
||||
|
||||
SkillDetailDialog(
|
||||
dialog = viewModel.dialog,
|
||||
onDismissRequest = viewModel::hideSkillDetailDialog,
|
||||
|
|
@ -85,9 +93,8 @@ fun InventoryPage(
|
|||
@Composable
|
||||
private fun InventoryPageContent(
|
||||
modifier: Modifier = Modifier,
|
||||
equipments: State<EquipmentItemUio?>,
|
||||
inventory: State<List<InventoryItemUio>>,
|
||||
onEquipment: (String) -> Unit,
|
||||
onAddItem: () -> Unit,
|
||||
onInventoryItemMove: (Int, Int) -> Unit,
|
||||
onInventoryIsMoveEnable: (Int, Int) -> Boolean,
|
||||
onInventoryItemDrop: (Int) -> Unit,
|
||||
|
|
@ -103,16 +110,9 @@ private fun InventoryPageContent(
|
|||
onDragRelease = onInventoryItemDrop,
|
||||
onDropReleaseOver = onInventoryItemDropOver,
|
||||
)
|
||||
Column(
|
||||
Box(
|
||||
modifier = modifier,
|
||||
) {
|
||||
equipments.value?.let {
|
||||
EquipmentItem(
|
||||
modifier = Modifier.padding(bottom = 16.dp),
|
||||
equipments = it,
|
||||
onClick = onEquipment,
|
||||
)
|
||||
}
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(5),
|
||||
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 {
|
||||
InventoryPageContent(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
equipments = rememberEquipmentState(),
|
||||
inventory = rememberInventoryListState(),
|
||||
onEquipment = { },
|
||||
onAddItem = { },
|
||||
onInventoryItemMove = { _, _ -> },
|
||||
onInventoryIsMoveEnable = { _, _ -> true },
|
||||
onInventoryItemDrop = { _ -> },
|
||||
|
|
|
|||
|
|
@ -13,16 +13,13 @@ import com.pixelized.rplexicon.R
|
|||
import com.pixelized.rplexicon.data.model.item.Item
|
||||
import com.pixelized.rplexicon.data.network.ItemDto
|
||||
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.firebase.RealtimeDatabaseRepository
|
||||
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.factory.ItemUioFactory
|
||||
import com.pixelized.rplexicon.ui.screens.character.factory.InventoryItemUioFactory
|
||||
import com.pixelized.rplexicon.utilitary.extentions.context
|
||||
import com.pixelized.rplexicon.utilitary.extentions.string.BaldurGageImageCache.equipmentsIcon
|
||||
import com.pixelized.rplexicon.utilitary.extentions.uri
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
|
|
@ -33,24 +30,19 @@ import kotlinx.coroutines.flow.combine
|
|||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class InventoryViewModel @Inject constructor(
|
||||
private val equipmentRepository: EquipmentRepository,
|
||||
private val descriptionRepository: DescriptionRepository,
|
||||
private val fireRepository: RealtimeDatabaseRepository,
|
||||
private val itemFactory: ItemUioFactory,
|
||||
private val itemFactory: InventoryItemUioFactory,
|
||||
itemsRepository: ItemsRepository,
|
||||
savedStateHandle: SavedStateHandle,
|
||||
application: Application
|
||||
) : AndroidViewModel(application) {
|
||||
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)
|
||||
private val itemLocalIndex =
|
||||
MutableStateFlow<Map<String, Int>>(hashMapOf())
|
||||
|
|
@ -120,32 +112,6 @@ class InventoryViewModel @Inject constructor(
|
|||
}.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) {
|
||||
fireRepository.setInventory(
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ 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
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
|
|
@ -18,13 +19,15 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Alignment
|
||||
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.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.composable.images.AsyncImage
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.string.BaldurGageImageCache.cache
|
||||
|
||||
@Stable
|
||||
data class ItemUio(
|
||||
|
|
@ -49,8 +52,10 @@ fun Item(
|
|||
.padding(paddingValues)
|
||||
.then(other = modifier),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
AsyncImage(
|
||||
modifier = Modifier.size(size = 42.dp),
|
||||
model = item.icon,
|
||||
)
|
||||
Column(
|
||||
|
|
@ -62,11 +67,17 @@ fun Item(
|
|||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = item.name,
|
||||
)
|
||||
item.description?.let {
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
fontWeight = FontWeight.Normal,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = it,
|
||||
)
|
||||
}
|
||||
|
|
@ -93,19 +104,13 @@ private class ItemProvider : PreviewParameterProvider<ItemUio> {
|
|||
id = "7d27561b-f2f4-4899-a2fc-df3501b1b66b",
|
||||
name = "Bourse",
|
||||
description = "Un 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"),
|
||||
icon = R.drawable.icbg_pouch_a_unfaded,
|
||||
),
|
||||
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"),
|
||||
description = null,
|
||||
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 {
|
||||
// https://bg3.wiki/wiki/Category:Controller_UI_Icons
|
||||
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
|
||||
"https://bg3.wiki/w/images/5/56/Generic_Darkness_Icon.webp" to R.drawable.icbg_generic_darkness_icon,
|
||||
// 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/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/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/4/4e/Leather_Pouch_Old_Unfaded.webp" to R.drawable.icbg_leather_pouch_old_unfaded,
|
||||
// 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/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
|
||||
"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(
|
||||
|
|
@ -287,7 +362,8 @@ object BaldurGageImageCache {
|
|||
@DrawableRes
|
||||
fun spellIcon(name: String): Int? = spells[name]
|
||||
|
||||
fun cache(uri: Uri?): Any = cache(uri = uri.toString())
|
||||
|
||||
fun cache(uri: String?): Any = this.uri[uri.toString()] ?: R.drawable.icbg_generic_darkness_icon
|
||||
fun cache(uri: Uri?): Any = when (uri) {
|
||||
null -> 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_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_expertise">Expertise \"%1$s\" </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_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__critical_success">CRITICAL SUCCESS</string>
|
||||
<string name="roll_overlay__critical_failure">CRITICAL FAILURE</string>
|
||||
|
|
|
|||