Make landing page dynamic based on the character sheets
|
|
@ -13,7 +13,7 @@ object AlterationSortUseCase {
|
|||
}.thenByDescending {
|
||||
PLAYER == it
|
||||
}.thenByDescending {
|
||||
sheet?.characterClass?.any { clazz -> clazz.value == it }
|
||||
sheet?.characterClass?.any { clazz -> clazz.id == it }
|
||||
}.thenByDescending {
|
||||
sheet?.race == it
|
||||
}.thenByDescending {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.pixelized.rplexicon.data.model
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import com.pixelized.rplexicon.R
|
||||
|
||||
data class CharacterSheet(
|
||||
|
|
@ -57,45 +58,84 @@ data class CharacterSheet(
|
|||
val others: List<String>, // others masteries
|
||||
) {
|
||||
val isWarlock: Boolean get() = characterClass.contains(Class.WARLOCK)
|
||||
val resource: String? get() = characterClass.firstNotNullOfOrNull { it.resource }
|
||||
val resource: String? get() = characterClass.firstNotNullOfOrNull { it.resourceId }
|
||||
|
||||
enum class Class(
|
||||
val value: String,
|
||||
val resource: String? = null,
|
||||
val label: Int? = null,
|
||||
val id: String,
|
||||
@StringRes
|
||||
val label: Int,
|
||||
val resourceId: String? = null,
|
||||
@StringRes
|
||||
val resourceLabel: Int? = null,
|
||||
@DrawableRes val icon: Int,
|
||||
) {
|
||||
BARBARIAN(
|
||||
value = "Barbare",
|
||||
resource = "Rage",
|
||||
label = R.string.character_sheet_title_rage,
|
||||
icon = R.drawable.ic_class_barbarian_24
|
||||
id = "Barbare",
|
||||
label = R.string.class_barbarian,
|
||||
resourceId = "Rage",
|
||||
resourceLabel = R.string.character_sheet_title_rage,
|
||||
icon = R.drawable.icbg_class_barbarian,
|
||||
),
|
||||
BARD(
|
||||
value = "Barde",
|
||||
resource = "Inspiration bardique",
|
||||
label = R.string.character_sheet_title_inspiration,
|
||||
icon = R.drawable.ic_class_bard_24
|
||||
id = "Barde",
|
||||
label = R.string.class_bard,
|
||||
resourceId = "Inspiration bardique",
|
||||
resourceLabel = R.string.character_sheet_title_inspiration,
|
||||
icon = R.drawable.icbg_class_bard,
|
||||
),
|
||||
CLERIC(
|
||||
value = "Clerc",
|
||||
resource = "Conduit divin",
|
||||
label = R.string.character_sheet_title_conduit,
|
||||
icon = R.drawable.ic_class_cleric_24
|
||||
id = "Clerc",
|
||||
label = R.string.class_cleric,
|
||||
resourceId = "Conduit divin",
|
||||
resourceLabel = R.string.character_sheet_title_conduit,
|
||||
icon = R.drawable.icbg_class_cleric,
|
||||
),
|
||||
DRUID(
|
||||
value = "Druide",
|
||||
resource = "Forme sauvage",
|
||||
label = R.string.character_sheet_title_wild_shape,
|
||||
id = "Druide",
|
||||
label = R.string.class_druid,
|
||||
resourceId = "Forme sauvage",
|
||||
resourceLabel = R.string.character_sheet_title_wild_shape,
|
||||
icon = R.drawable.ic_class_druid_24,
|
||||
),
|
||||
FIGHTER(value = "Guerrier", icon = R.drawable.ic_class_fighter_24),
|
||||
MONK(value = "Moine", icon = R.drawable.ic_class_monk_24),
|
||||
PALADIN(value = "Paladin", icon = R.drawable.ic_class_paladin_24),
|
||||
RANGER(value = "Rodeur", icon = R.drawable.ic_class_ranger_24),
|
||||
ROGUE(value = "Roublard", icon = R.drawable.ic_class_rogue_24),
|
||||
SORCERER(value = "Ensorceleur", icon = R.drawable.ic_class_sorcerer_24),
|
||||
WARLOCK(value = "Occultiste", icon = R.drawable.ic_class_warlock_24),
|
||||
WIZARD(value = "Magicien", icon = R.drawable.ic_class_wizard_24),
|
||||
FIGHTER(
|
||||
id = "Guerrier",
|
||||
label = R.string.class_fighter,
|
||||
icon = R.drawable.ic_class_fighter_24,
|
||||
),
|
||||
MONK(
|
||||
id = "Moine",
|
||||
label = R.string.class_monk,
|
||||
icon = R.drawable.ic_class_monk_24,
|
||||
),
|
||||
PALADIN(
|
||||
id = "Paladin",
|
||||
label = R.string.class_paladin,
|
||||
icon = R.drawable.ic_class_paladin_24,
|
||||
),
|
||||
RANGER(
|
||||
id = "Rodeur",
|
||||
label = R.string.class_ranger,
|
||||
icon = R.drawable.icbg_class_ranger,
|
||||
),
|
||||
ROGUE(
|
||||
id = "Roublard",
|
||||
label = R.string.class_rogue,
|
||||
icon = R.drawable.ic_class_rogue_24,
|
||||
),
|
||||
SORCERER(
|
||||
id = "Ensorceleur",
|
||||
label = R.string.class_sorcerer,
|
||||
icon = R.drawable.ic_class_sorcerer_24,
|
||||
),
|
||||
WARLOCK(
|
||||
id = "Occultiste",
|
||||
label = R.string.class_warlock,
|
||||
icon = R.drawable.icbg_class_warlock,
|
||||
),
|
||||
WIZARD(
|
||||
id = "Magicien",
|
||||
label = R.string.class_wizard,
|
||||
icon = R.drawable.ic_class_wizard_24,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ class AlterationParser @Inject constructor(
|
|||
characterSheets
|
||||
.filter { // check if the alteration is applicable to the character
|
||||
alteration.target.let { target ->
|
||||
target == ALL || target == it.name || target == it.race || it.characterClass.any { it.value == target }
|
||||
target == ALL || target == it.name || target == it.race || it.characterClass.any { it.id == target }
|
||||
}
|
||||
}
|
||||
.forEach { sheet -> // check the default alteration state for that character
|
||||
|
|
|
|||
|
|
@ -12,18 +12,18 @@ class CharacterClassParser @Inject constructor() {
|
|||
?.map { it.trim() }
|
||||
?.mapNotNull {
|
||||
when (it) {
|
||||
CharacterSheet.Class.BARBARIAN.value -> CharacterSheet.Class.BARBARIAN
|
||||
CharacterSheet.Class.BARD.value -> CharacterSheet.Class.BARD
|
||||
CharacterSheet.Class.CLERIC.value -> CharacterSheet.Class.CLERIC
|
||||
CharacterSheet.Class.DRUID.value -> CharacterSheet.Class.DRUID
|
||||
CharacterSheet.Class.FIGHTER.value -> CharacterSheet.Class.FIGHTER
|
||||
CharacterSheet.Class.MONK.value -> CharacterSheet.Class.MONK
|
||||
CharacterSheet.Class.PALADIN.value -> CharacterSheet.Class.PALADIN
|
||||
CharacterSheet.Class.RANGER.value -> CharacterSheet.Class.RANGER
|
||||
CharacterSheet.Class.ROGUE.value -> CharacterSheet.Class.ROGUE
|
||||
CharacterSheet.Class.SORCERER.value -> CharacterSheet.Class.SORCERER
|
||||
CharacterSheet.Class.WARLOCK.value -> CharacterSheet.Class.WARLOCK
|
||||
CharacterSheet.Class.WIZARD.value -> CharacterSheet.Class.WIZARD
|
||||
CharacterSheet.Class.BARBARIAN.id -> CharacterSheet.Class.BARBARIAN
|
||||
CharacterSheet.Class.BARD.id -> CharacterSheet.Class.BARD
|
||||
CharacterSheet.Class.CLERIC.id -> CharacterSheet.Class.CLERIC
|
||||
CharacterSheet.Class.DRUID.id -> CharacterSheet.Class.DRUID
|
||||
CharacterSheet.Class.FIGHTER.id -> CharacterSheet.Class.FIGHTER
|
||||
CharacterSheet.Class.MONK.id -> CharacterSheet.Class.MONK
|
||||
CharacterSheet.Class.PALADIN.id -> CharacterSheet.Class.PALADIN
|
||||
CharacterSheet.Class.RANGER.id -> CharacterSheet.Class.RANGER
|
||||
CharacterSheet.Class.ROGUE.id -> CharacterSheet.Class.ROGUE
|
||||
CharacterSheet.Class.SORCERER.id -> CharacterSheet.Class.SORCERER
|
||||
CharacterSheet.Class.WARLOCK.id -> CharacterSheet.Class.WARLOCK
|
||||
CharacterSheet.Class.WIZARD.id -> CharacterSheet.Class.WIZARD
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ class CharacterSheetHeaderUioFactory @Inject constructor(
|
|||
sheetHeaderData: HeaderViewModel.SheetHeaderData?,
|
||||
fireHeaderData: HeaderViewModel.FireHeaderData?,
|
||||
): CharacterSheetHeaderUio {
|
||||
val classWithResource = sheetHeaderData?.characterClass?.firstOrNull { it.resource != null }
|
||||
val classWithResource = sheetHeaderData?.characterClass?.firstOrNull { it.resourceId != null }
|
||||
val favoriteSkill = skillRepository.find(
|
||||
character = character,
|
||||
skill = classWithResource?.resource
|
||||
skill = classWithResource?.resourceId
|
||||
)
|
||||
return CharacterSheetHeaderUio(
|
||||
initiative = LabelPointUio(
|
||||
|
|
@ -47,10 +47,10 @@ class CharacterSheetHeaderUioFactory @Inject constructor(
|
|||
value = "$it",
|
||||
)
|
||||
},
|
||||
resource = if (classWithResource?.label != null && favoriteSkill?.amount != null) {
|
||||
resource = if (classWithResource?.resourceLabel != null && favoriteSkill?.amount != null) {
|
||||
ResourcePointUio(
|
||||
id = favoriteSkill.name,
|
||||
label = classWithResource.label,
|
||||
label = classWithResource.resourceLabel,
|
||||
value = fireHeaderData?.resource ?: 0,
|
||||
max = favoriteSkill.amount,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.pixelized.rplexicon.ui.screens.landing
|
|||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.FloatRange
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
|
|
@ -42,7 +43,7 @@ import com.pixelized.rplexicon.utilitary.extentions.lexicon
|
|||
|
||||
@Stable
|
||||
data class LandingItemUio(
|
||||
@DrawableRes val icon: Int,
|
||||
@DrawableRes val icon: Int?,
|
||||
val title: String?,
|
||||
val subTitle: String?,
|
||||
)
|
||||
|
|
@ -54,6 +55,9 @@ fun LandingItem(
|
|||
paddings: PaddingValues = PaddingValues(),
|
||||
imagePadding: PaddingValues = PaddingValues(all = 16.dp),
|
||||
shape: Shape = remember { RoundedCornerShape(size = 8.dp) },
|
||||
backgroundFilter: ColorFilter? = ColorFilter.tint(color = MaterialTheme.colorScheme.onSurface),
|
||||
@FloatRange(from = 0.0, to = 1.0) backgroundGradientFrom: Float = 0.5f,
|
||||
@FloatRange(from = 0.0, to = 1.0) backgroundGradientTo: Float = 1f,
|
||||
rotation: Float = 0f,
|
||||
alpha: Float = 0.6f,
|
||||
onClick: () -> Unit,
|
||||
|
|
@ -66,23 +70,30 @@ fun LandingItem(
|
|||
.then(other = modifier),
|
||||
contentAlignment = Alignment.BottomCenter
|
||||
) {
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.matchParentSize()
|
||||
.padding(paddingValues = imagePadding)
|
||||
.rotate(degrees = rotation),
|
||||
painter = painterResource(id = item.icon),
|
||||
alpha = alpha,
|
||||
contentScale = ContentScale.FillHeight,
|
||||
alignment = Alignment.TopCenter,
|
||||
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.onSurface),
|
||||
contentDescription = null,
|
||||
)
|
||||
item.icon?.let {
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.matchParentSize()
|
||||
.padding(paddingValues = imagePadding)
|
||||
.rotate(degrees = rotation),
|
||||
painter = painterResource(id = it),
|
||||
alpha = alpha,
|
||||
contentScale = ContentScale.Fit,
|
||||
alignment = Alignment.TopCenter,
|
||||
colorFilter = backgroundFilter,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.matchParentSize()
|
||||
.background(brush = rememberBackgroundGradient())
|
||||
.background(
|
||||
brush = rememberBackgroundGradient(
|
||||
from = backgroundGradientFrom,
|
||||
to = backgroundGradientTo,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
Column(
|
||||
|
|
@ -118,13 +129,16 @@ fun LandingItem(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberBackgroundGradient(): Brush {
|
||||
private fun rememberBackgroundGradient(
|
||||
@FloatRange(from = 0.0, to = 1.0) from: Float = 0.5f,
|
||||
@FloatRange(from = 0.0, to = 1.0) to: Float = 1f,
|
||||
): Brush {
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
return remember {
|
||||
Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
colorScheme.surface.copy(alpha = 0.5f),
|
||||
colorScheme.surface.copy(alpha = 1.0f),
|
||||
colorScheme.surface.copy(alpha = from),
|
||||
colorScheme.surface.copy(alpha = to),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ import androidx.compose.material3.MaterialTheme
|
|||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.composed
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -44,6 +48,7 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
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.R
|
||||
import com.pixelized.rplexicon.ui.composable.rememberBackgroundGradient
|
||||
import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
|
||||
|
|
@ -59,7 +64,9 @@ import com.pixelized.rplexicon.utilitary.extentions.lexicon
|
|||
import com.pixelized.rplexicon.utilitary.extentions.modifier.scrollOffset
|
||||
|
||||
@Composable
|
||||
fun LandingScreen() {
|
||||
fun LandingScreen(
|
||||
viewModel: LandingViewModel = hiltViewModel(),
|
||||
) {
|
||||
val screen = LocalScreenNavHost.current
|
||||
|
||||
Surface(
|
||||
|
|
@ -75,7 +82,10 @@ fun LandingScreen() {
|
|||
end = 16.dp,
|
||||
bottom = 16.dp,
|
||||
),
|
||||
onCharacter = { screen.navigateToCharacterSheet(name = it) },
|
||||
characters = viewModel.landing,
|
||||
onCharacter = { character ->
|
||||
character.title?.let { screen.navigateToCharacterSheet(name = it) }
|
||||
},
|
||||
onSearch = {
|
||||
screen.navigateToSearch(
|
||||
enableLexicon = true,
|
||||
|
|
@ -103,13 +113,22 @@ private fun LandingContent(
|
|||
bottom = 16.dp,
|
||||
),
|
||||
sectionPadding: Dp = 32.dp,
|
||||
onCharacter: (String) -> Unit,
|
||||
characters: State<List<LandingItemUio>>,
|
||||
onCharacter: (LandingItemUio) -> Unit,
|
||||
onSearch: () -> Unit,
|
||||
onGameMaster: () -> Unit,
|
||||
onLexicon: () -> Unit,
|
||||
onQuest: () -> Unit,
|
||||
onMap: () -> Unit,
|
||||
) {
|
||||
val charactersSection = remember {
|
||||
derivedStateOf {
|
||||
characters.value
|
||||
.groupBy { characters.value.indexOf(it) / 3 }
|
||||
.values.toList()
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = modifier.verticalScroll(scrollState),
|
||||
) {
|
||||
|
|
@ -174,86 +193,28 @@ private fun LandingContent(
|
|||
text = stringResource(id = R.string.landing__caterogy__character),
|
||||
)
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||
) {
|
||||
stringResource(id = R.string.landing__character_brulkhai).let { character ->
|
||||
LandingItem(
|
||||
modifier = Modifier
|
||||
.height(128.dp)
|
||||
.weight(1f),
|
||||
imagePadding = PaddingValues(all = 8.dp),
|
||||
item = LandingItemUio(
|
||||
icon = R.drawable.ic_class_barbarian_24,
|
||||
title = character,
|
||||
subTitle = stringResource(id = R.string.class_barbarian),
|
||||
),
|
||||
onClick = { onCharacter(character) },
|
||||
)
|
||||
charactersSection.value.forEach { charactersGroup ->
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||
) {
|
||||
charactersGroup.forEach { character ->
|
||||
LandingItem(
|
||||
modifier = Modifier
|
||||
.aspectRatio(0.8f)
|
||||
.weight(1f),
|
||||
imagePadding = PaddingValues(bottom = 8.dp),
|
||||
item = character,
|
||||
backgroundFilter = null,
|
||||
backgroundGradientFrom = 0f,
|
||||
backgroundGradientTo = 0.5f,
|
||||
onClick = { onCharacter(character) },
|
||||
)
|
||||
}
|
||||
repeat(3 - charactersGroup.size) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
stringResource(id = R.string.landing__character_leandre).let { character ->
|
||||
LandingItem(
|
||||
modifier = Modifier
|
||||
.height(128.dp)
|
||||
.weight(1f),
|
||||
imagePadding = PaddingValues(all = 8.dp),
|
||||
item = LandingItemUio(
|
||||
icon = R.drawable.ic_class_cleric_24,
|
||||
title = character,
|
||||
subTitle = stringResource(id = R.string.class_cleric),
|
||||
),
|
||||
onClick = { onCharacter(character) },
|
||||
)
|
||||
}
|
||||
stringResource(id = R.string.landing__character_nelia).let { character ->
|
||||
LandingItem(
|
||||
modifier = Modifier
|
||||
.height(128.dp)
|
||||
.weight(1f),
|
||||
imagePadding = PaddingValues(all = 8.dp),
|
||||
item = LandingItemUio(
|
||||
icon = R.drawable.ic_class_ranger_24,
|
||||
title = character,
|
||||
subTitle = stringResource(id = R.string.class_ranger),
|
||||
),
|
||||
onClick = { onCharacter(character) },
|
||||
)
|
||||
}
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||
) {
|
||||
stringResource(id = R.string.landing__character_tigrane).let { character ->
|
||||
LandingItem(
|
||||
modifier = Modifier
|
||||
.height(128.dp)
|
||||
.weight(1f),
|
||||
imagePadding = PaddingValues(all = 8.dp),
|
||||
item = LandingItemUio(
|
||||
icon = R.drawable.ic_class_warlock_24,
|
||||
title = character,
|
||||
subTitle = stringResource(id = R.string.class_warlock),
|
||||
),
|
||||
onClick = { onCharacter(character) },
|
||||
)
|
||||
}
|
||||
stringResource(id = R.string.landing__character_unathana).let { character ->
|
||||
LandingItem(
|
||||
modifier = Modifier
|
||||
.height(128.dp)
|
||||
.weight(1f),
|
||||
imagePadding = PaddingValues(all = 8.dp),
|
||||
item = LandingItemUio(
|
||||
icon = R.drawable.ic_class_bard_24,
|
||||
title = character,
|
||||
subTitle = stringResource(id = R.string.class_bard),
|
||||
),
|
||||
onClick = { onCharacter(character) },
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
}
|
||||
|
||||
Text(
|
||||
|
|
@ -392,6 +353,37 @@ private fun LandingPreview() {
|
|||
Surface {
|
||||
LandingContent(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
characters = remember {
|
||||
mutableStateOf(
|
||||
listOf(
|
||||
LandingItemUio(
|
||||
icon = R.drawable.icbg_class_barbarian,
|
||||
title = "Brulkhai",
|
||||
subTitle = "Barbarian, Warrior",
|
||||
),
|
||||
LandingItemUio(
|
||||
icon = R.drawable.icbg_class_cleric,
|
||||
title = "Léandre",
|
||||
subTitle = "Cleric",
|
||||
),
|
||||
LandingItemUio(
|
||||
icon = R.drawable.icbg_class_ranger,
|
||||
title = "Nelia",
|
||||
subTitle = "Ranger, Druid",
|
||||
),
|
||||
LandingItemUio(
|
||||
icon = R.drawable.icbg_class_warlock,
|
||||
title = "Tigrane",
|
||||
subTitle = "Warlock",
|
||||
),
|
||||
LandingItemUio(
|
||||
icon = R.drawable.icbg_class_bard,
|
||||
title = "Unathana",
|
||||
subTitle = "Bard",
|
||||
),
|
||||
)
|
||||
)
|
||||
},
|
||||
onCharacter = { },
|
||||
onSearch = { },
|
||||
onGameMaster = { },
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
package com.pixelized.rplexicon.ui.screens.landing
|
||||
|
||||
import android.app.Application
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository
|
||||
import com.pixelized.rplexicon.utilitary.extentions.context
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class LandingViewModel @Inject constructor(
|
||||
private val sheetRepository: CharacterSheetRepository,
|
||||
application: Application,
|
||||
) : AndroidViewModel(application = application) {
|
||||
|
||||
private val _landing = mutableStateOf<List<LandingItemUio>>(emptyList())
|
||||
val landing: State<List<LandingItemUio>> = _landing
|
||||
|
||||
init {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
sheetRepository.data.collectLatest { sheets ->
|
||||
val landing = sheets.mapNotNull { entry ->
|
||||
val icon = entry.value.characterClass.firstOrNull()?.icon
|
||||
val title = entry.key
|
||||
val subTitle = entry.value.characterClass
|
||||
.map { context.getString(it.label) }
|
||||
.joinToString(separator = ", ") { it }
|
||||
|
||||
LandingItemUio(
|
||||
icon = icon,
|
||||
title = title,
|
||||
subTitle = subTitle,
|
||||
)
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
_landing.value = landing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -546,7 +546,7 @@ class SummaryFactory @Inject constructor(
|
|||
} ?: none()
|
||||
|
||||
// Update spells
|
||||
val skill = sheet.characterClass.firstOrNull()?.resource?.let { skill ->
|
||||
val skill = sheet.characterClass.firstOrNull()?.resourceId?.let { skill ->
|
||||
fire?.skills?.get(skill)
|
||||
}?.let { skill ->
|
||||
label(label = "$skill")
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ private object ResourcesCache {
|
|||
"Transe" to R.drawable.icbg_focused_conjuration,
|
||||
"Attaque supplémentaire" to R.drawable.icbg_extra_attack,
|
||||
"Apanage de la Noblesse" to R.drawable.icbg_natures_ward,
|
||||
"Druidique" to R.drawable.icbg_class_druid_badge,
|
||||
"Druidique" to R.drawable.icbg_class_druid,
|
||||
"Appel de familier" to R.drawable.icbg_find_familiar_cat,
|
||||
"Détection de la magie" to R.drawable.icbg_generic_psychic,
|
||||
"Vision dans le noir (Tieffelin)" to R.drawable.icbg_darkvision,
|
||||
|
|
|
|||
BIN
app/src/main/res/drawable/icbg_class_barbarian.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
app/src/main/res/drawable/icbg_class_bard.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
app/src/main/res/drawable/icbg_class_cleric.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
BIN
app/src/main/res/drawable/icbg_class_ranger.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
app/src/main/res/drawable/icbg_class_warlock.png
Normal file
|
After Width: | Height: | Size: 23 KiB |