Remove Int as id for LexiconItem

This commit is contained in:
Thomas Andres Gomez 2023-11-12 18:30:27 +01:00
parent 003390e844
commit 3880807372
11 changed files with 73 additions and 55 deletions

View file

@ -5,8 +5,7 @@ import androidx.compose.runtime.Stable
@Stable
data class Lexicon(
val id: Int,
val sheetIndex: Int,
val id: String,
val name: String,
val diminutive: String?,
val gender: Gender,

View file

@ -12,7 +12,7 @@ class LexiconParser @Inject constructor(
) {
@Throws(IncompatibleSheetStructure::class)
fun parse(sheet: ValueRange): List<Lexicon> = parserScope {
var id = 0
val ids = hashMapOf<String, Int>()
val lexicons = mutableListOf<Lexicon>()
sheet.forEachRowIndexed { index, row ->
@ -22,9 +22,9 @@ class LexiconParser @Inject constructor(
else -> {
val name = row.parse(column = NAME)
if (name != null) {
ids[name] = ids.getOrDefault(name, 0) + 1
val lexicon = Lexicon(
id = id++,
sheetIndex = index,
id = "$name-${ids[name]}",
name = name,
diminutive = row.parse(column = SHORT),
gender = genderParser.parse(row.parse(column = GENDER)),

View file

@ -22,7 +22,11 @@ class LexiconRepository @Inject constructor(
var lastSuccessFullUpdate: Update = Update.INITIAL
private set
fun findId(name: String?): Int? {
fun find(id: String?): Lexicon? {
return id?.let { _data.value.firstOrNull { item -> item.id == it } }
}
fun findId(name: String?): String? {
return name?.let { _data.value.firstOrNull { item -> item.name == it }?.id }
}

View file

@ -33,7 +33,7 @@ val LEXICON_DETAIL_ROUTE = ROUTE +
@Stable
@Immutable
data class LexiconDetailArgument(
val id: Int,
val id: String,
val highlight: String?,
val race: Lexicon.Race,
val highlightRace: Boolean,
@ -61,7 +61,7 @@ fun NavGraphBuilder.composableLexiconDetail() {
route = LEXICON_DETAIL_ROUTE,
arguments = listOf(
navArgument(name = ARG_ID) {
type = NavType.IntType
type = NavType.StringType
},
navArgument(name = ARG_HIGHLIGHT) {
type = NavType.StringType
@ -87,7 +87,7 @@ fun NavGraphBuilder.composableLexiconDetail() {
}
fun NavHostController.navigateToLexiconDetail(
id: Int,
id: String,
highlight: String? = null,
race: Lexicon.Race? = null,
gender: Lexicon.Gender? = null,

View file

@ -106,6 +106,7 @@ data class AnnotatedLexiconDetailUio(
@Stable
fun LexiconDetailUio.annotate(): AnnotatedLexiconDetailUio {
val colorScheme = MaterialTheme.colorScheme
val typography = MaterialTheme.lexicon.typography
val highlight = remember { SpanStyle(color = colorScheme.primary) }
val trimmedSearch = remember(search) { search.searchCriterion() }
val highlightRegex = remember(search) { trimmedSearch.highlightRegex }
@ -117,10 +118,16 @@ fun LexiconDetailUio.annotate(): AnnotatedLexiconDetailUio {
portrait = portrait,
name = AnnotatedString(
text = name,
spanStyles = highlightRegex?.annotatedSpan(
spanStyles = (highlightRegex?.annotatedSpan(
input = name,
spanStyle = highlight,
) ?: emptyList()
) ?: emptyList()) + listOf(
AnnotatedString.Range(
item = typography.headlineSmallDropCap,
start = 0,
end = 1,
)
)
),
diminutive = diminutive?.let {
highlightRegex.annotatedString(input = it, spanStyle = highlight)
@ -165,7 +172,9 @@ fun LexiconDetailScreen(
) {
val screen = LocalScreenNavHost.current
Surface {
Surface(
modifier = Modifier.fillMaxSize(),
) {
LexiconDetailContent(
modifier = Modifier.fillMaxSize(),
item = viewModel.character,
@ -186,7 +195,7 @@ fun LexiconDetailScreen(
private fun LexiconDetailContent(
modifier: Modifier = Modifier,
state: ScrollState = rememberScrollState(),
item: State<LexiconDetailUio>,
item: State<LexiconDetailUio?>,
haveCharacterSheet: State<Boolean>,
onBack: () -> Unit,
onCharacterSheet: (String) -> Unit,
@ -194,9 +203,9 @@ private fun LexiconDetailContent(
) {
val colorScheme = MaterialTheme.colorScheme
val typography = MaterialTheme.typography
val annotatedItem = item.value.annotate()
val annotatedItem = item.value?.annotate()
val backgroundUri = remember(annotatedItem) {
annotatedItem.portrait.firstOrNull()
annotatedItem?.portrait?.firstOrNull()
}
Scaffold(
@ -215,7 +224,7 @@ private fun LexiconDetailContent(
},
actions = {
AnimatedVisibility(visible = haveCharacterSheet.value) {
IconButton(onClick = { onCharacterSheet(item.value.name) }) {
IconButton(onClick = { item.value?.name?.let(onCharacterSheet) }) {
Icon(
painter = painterResource(id = R.drawable.ic_d20_24),
contentDescription = null
@ -257,14 +266,14 @@ private fun LexiconDetailContent(
modifier = Modifier.padding(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
annotatedItem.name.let {
annotatedItem?.name?.let {
Text(
modifier = Modifier.alignByBaseline(),
style = typography.headlineSmall,
text = it,
)
}
annotatedItem.diminutive?.let {
annotatedItem?.diminutive?.let {
Text(
modifier = Modifier.alignByBaseline(),
style = typography.labelMedium,
@ -278,23 +287,27 @@ private fun LexiconDetailContent(
modifier = Modifier.padding(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
annotatedItem?.gender?.let {
Text(
style = typography.labelMedium,
fontStyle = FontStyle.Italic,
text = annotatedItem.gender,
)
Text(
style = typography.labelMedium,
fontStyle = FontStyle.Italic,
text = annotatedItem.race,
text = it,
)
}
annotatedItem?.race?.let {
Text(
style = typography.labelMedium,
fontStyle = FontStyle.Italic,
text = it,
)
}
}
if (annotatedItem.status != null || annotatedItem.location != null) {
if (annotatedItem?.status != null || annotatedItem?.location != null) {
Spacer(modifier = Modifier.height(8.dp))
}
annotatedItem.status?.let {
annotatedItem?.status?.let {
Row(
modifier = Modifier.padding(start = 16.dp, end = 16.dp),
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
@ -320,7 +333,7 @@ private fun LexiconDetailContent(
}
}
annotatedItem.location?.let {
annotatedItem?.location?.let {
Row(
modifier = Modifier.padding(start = 16.dp, end = 16.dp),
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
@ -346,7 +359,7 @@ private fun LexiconDetailContent(
}
}
annotatedItem.description?.let {
annotatedItem?.description?.let {
Text(
modifier = Modifier.padding(start = 16.dp, top = 24.dp, end = 16.dp),
style = typography.titleMedium,
@ -366,7 +379,7 @@ private fun LexiconDetailContent(
)
}
annotatedItem.history?.let {
annotatedItem?.history?.let {
Text(
modifier = Modifier.padding(start = 16.dp, top = 24.dp, end = 16.dp),
style = typography.titleMedium,
@ -379,7 +392,7 @@ private fun LexiconDetailContent(
)
}
if (annotatedItem.portrait.isNotEmpty()) {
if (annotatedItem?.portrait?.isNotEmpty() == true) {
val maxSize = rememberPortraitWidth()
Text(
modifier = Modifier.padding(start = 16.dp, top = 24.dp, end = 16.dp),
@ -407,7 +420,7 @@ private fun LexiconDetailContent(
}
}
annotatedItem.tags?.let {
annotatedItem?.tags?.let {
Text(
modifier = Modifier.padding(start = 16.dp, top = 24.dp, end = 16.dp),
style = typography.labelSmall,
@ -454,7 +467,7 @@ private fun LexiconDetailPreview() {
description = "Brulkhai, ou plus simplement Bru, est solidement bâti. Elle mesure 192 cm pour 110 kg de muscles lorsquelle est en bonne santé. Elle a les cheveux châtains, les yeux noisettes et la peau couleur gris-vert typique de son espèce. Dun tempérament taciturne, elle parle peu et de façon concise. Elle est parfois brutale, aussi bien physiquement que verbalement, Elle ne prend cependant aucun plaisir à malmener ceux quelle considère plus faibles quelle. Dune nature simple et honnête, elle ne mâche pas ses mots et ne dissimule généralement pas ses pensées. Son intelligence modeste est plus le reflet dun manque déducation et dune capacité limitée à gérer ses émotions quà une débilité congénitale. Elle voue à la force un culte car cest par son expression quelle se sent vraiment vivante et éprouve de grandes difficultés vis à vis de ceux quelle nomme foshnu (bébé, chouineur en commun).",
history = null,
tags = "protagoniste, brute",
search = null,
search = "Bru",
highlightGender = true,
highlightRace = true,
)

View file

@ -16,15 +16,17 @@ class LexiconDetailViewModel @Inject constructor(
lexiconRepository: LexiconRepository,
characterSheetRepository: CharacterSheetRepository,
) : ViewModel() {
val character: State<LexiconDetailUio>
val haveCharacterSheet: State<Boolean>
private val _character = mutableStateOf<LexiconDetailUio?>(null)
val character: State<LexiconDetailUio?> get() = _character
init {
val argument = savedStateHandle.lexiconDetailArgument
val source = lexiconRepository.data.value[argument.id]
val source = lexiconRepository.find(id = argument.id)
character = mutableStateOf(
LexiconDetailUio(
if (source != null) {
_character.value = LexiconDetailUio(
name = source.name,
diminutive = source.diminutive?.let { "./ $it" },
gender = source.gender,
@ -39,10 +41,10 @@ class LexiconDetailViewModel @Inject constructor(
highlightGender = argument.highlightGender && argument.gender == source.gender,
highlightRace = argument.highlightRace && argument.race == source.race,
)
)
}
haveCharacterSheet = mutableStateOf(
characterSheetRepository.find(source.name) != null
characterSheetRepository.find(name = source?.name) != null
)
}
}

View file

@ -34,7 +34,7 @@ import com.pixelized.rplexicon.utilitary.extentions.placeholder
@Stable
data class LexiconItemUio(
val id: Int,
val id: String,
val name: String,
val diminutive: String?,
@StringRes val gender: Int,
@ -45,7 +45,7 @@ data class LexiconItemUio(
companion object {
@Stable
fun preview(
id: Int = 0,
id: String = "Brulkhai-1",
name: String = "Brulkhai",
diminutive: String? = null,
@StringRes gender: Int = R.string.gender_female_short,

View file

@ -207,7 +207,7 @@ private fun LexiconScreenContentPreview() {
mutableStateOf(
listOf(
LexiconItemUio(
id = 0,
id = "Brulkhai-1",
name = "Brulkhai",
diminutive = "Bru",
gender = R.string.gender_female_short,

View file

@ -43,7 +43,7 @@ import com.pixelized.rplexicon.utilitary.extentions.searchCriterion
@Stable
class SearchItemUio(
val id: Int,
val id: String,
val name: String,
val diminutive: String?,
val gender: Lexicon.Gender,
@ -59,7 +59,7 @@ class SearchItemUio(
) {
companion object {
fun preview(
id: Int = 0,
id: String = "Brulkhai-1",
name: String = "Brulkhai",
diminutive: String? = "Bru",
gender: Lexicon.Gender = Lexicon.Gender.FEMALE,
@ -93,7 +93,7 @@ class SearchItemUio(
@Stable
class AnnotatedSearchItemUio(
val id: Int,
val id: String,
val name: AnnotatedString,
val diminutive: AnnotatedString?,
val gender: AnnotatedString,

View file

@ -218,35 +218,35 @@ private fun SearchScreenContentPreview() {
mutableStateOf(
listOf(
SearchItemUio.preview(
id = 0,
id = "Brulkhai-1",
name = "Brulkhai",
diminutive = "Bru",
gender = Lexicon.Gender.FEMALE,
race = Lexicon.Race.HALF_ORC,
),
SearchItemUio.preview(
id = 1,
id = "Léandre-1",
name = "Léandre",
diminutive = null,
gender = Lexicon.Gender.MALE,
race = Lexicon.Race.HUMAN,
),
SearchItemUio.preview(
id = 2,
id = "Nélia-1",
name = "Nélia",
diminutive = null,
gender = Lexicon.Gender.FEMALE,
race = Lexicon.Race.ELF,
),
SearchItemUio.preview(
id = 3,
id = "Tigrane-1",
name = "Tigrane",
diminutive = null,
gender = Lexicon.Gender.MALE,
race = Lexicon.Race.TIEFLING,
),
SearchItemUio.preview(
id = 4,
id = "Unathana-1",
name = "Unathana",
diminutive = "Una",
gender = Lexicon.Gender.FEMALE,

View file

@ -71,7 +71,7 @@ data class QuestDetailUio(
@Stable
data class QuestStep(
val subtitle: String? = null,
val giverId: Int? = null,
val giverId: String? = null,
val giver: String? = null,
val placeId: String? = null,
val place: String? = null,
@ -112,7 +112,7 @@ private fun QuestDetailContent(
state: ScrollState = rememberScrollState(),
item: State<QuestDetailUio>,
onBack: () -> Unit,
onGiver: (Int) -> Unit,
onGiver: (String) -> Unit,
onLocation: (String) -> Unit,
onImage: (Uri) -> Unit,
) {