Rework the detail system for object / skill / spell / alteration.
This commit is contained in:
parent
6481afb732
commit
244bed9ded
26 changed files with 672 additions and 357 deletions
|
|
@ -32,6 +32,7 @@ class SpellRepository @Inject constructor(
|
|||
) {
|
||||
private var _spellsBook = MutableStateFlow<List<Spell>>(emptyList())
|
||||
val spellsBook: StateFlow<List<Spell>> get() = _spellsBook
|
||||
|
||||
private val _spells = MutableStateFlow<Map<String, List<AssignedSpell>>>(emptyMap())
|
||||
val spells: StateFlow<Map<String, List<AssignedSpell>>> =
|
||||
combine(_spells, firebaseRepository.getAlterationStatus()) { spells, status ->
|
||||
|
|
|
|||
|
|
@ -82,8 +82,8 @@ import com.pixelized.rplexicon.ui.screens.character.pages.actions.SpellsViewMode
|
|||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationPage
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationPagePreview
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationViewModel
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.chooser.SpellLevelChooser
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.chooser.SpellLevelChooserPreview
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.chooser.SpellLevelChooser
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.chooser.SpellLevelChooserPreview
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.inventory.InventoryPage
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.inventory.InventoryPagePreview
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.inventory.InventoryViewModel
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ fun SpellLevelItem(
|
|||
text = stringResource(id = R.string.spell_level_chooser_available)
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
modifier = Modifier.alignByBaseline().padding(start = 4.dp),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
text = "${spell.remaining ?: 0}",
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
package com.pixelized.rplexicon.ui.screens.character.composable.alteration
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationDetail
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationDetailUio
|
||||
|
||||
@Composable
|
||||
fun AlterationDetailHandler(
|
||||
detail: State<AlterationDetailUio?>,
|
||||
onDismissRequest: () -> Unit,
|
||||
) {
|
||||
detail.value?.let {
|
||||
Dialog(
|
||||
properties = remember { DialogProperties(usePlatformDefaultWidth = false) },
|
||||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
AlterationDetail(
|
||||
detail = it,
|
||||
onClose = onDismissRequest,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
package com.pixelized.rplexicon.ui.screens.character.pages.chooser
|
||||
package com.pixelized.rplexicon.ui.screens.character.composable.chooser
|
||||
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
|
|
@ -1,44 +1,47 @@
|
|||
package com.pixelized.rplexicon.ui.screens.character.pages.alteration
|
||||
package com.pixelized.rplexicon.ui.screens.character.composable.dialogs
|
||||
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import android.net.Uri
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
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.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.composable.BackgroundImage
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.annotateWithDropCap
|
||||
import com.pixelized.rplexicon.utilitary.extentions.lexicon
|
||||
import com.pixelized.rplexicon.utilitary.extentions.modifier.ddBorder
|
||||
|
||||
@Stable
|
||||
data class AlterationDetailUio(
|
||||
data class AlterationDialogDetailUio(
|
||||
val icon: Uri?,
|
||||
val name: String,
|
||||
val original: String?,
|
||||
val source: String,
|
||||
|
|
@ -46,71 +49,81 @@ data class AlterationDetailUio(
|
|||
val description: String,
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
fun AlterationDetail(
|
||||
fun AlterationDetailDialog(
|
||||
paddingValues: PaddingValues = PaddingValues(horizontal = 16.dp, vertical = 128.dp),
|
||||
dialog: State<AlterationDialogDetailUio?>,
|
||||
onDismissRequest: () -> Unit,
|
||||
) {
|
||||
dialog.value?.let {
|
||||
Dialog(
|
||||
properties = remember { DialogProperties(usePlatformDefaultWidth = false) },
|
||||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
onClick = onDismissRequest,
|
||||
)
|
||||
.padding(paddingValues = paddingValues),
|
||||
) {
|
||||
AlterationDetailDialogContent(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
enabled = false,
|
||||
onClick = { },
|
||||
)
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
),
|
||||
detail = it,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AlterationDetailDialogContent(
|
||||
modifier: Modifier = Modifier,
|
||||
detail: AlterationDetailUio,
|
||||
onClose: () -> Unit,
|
||||
scrollState: ScrollState = rememberScrollState(),
|
||||
paddingValues: PaddingValues = PaddingValues(horizontal = 24.dp, vertical = 16.dp),
|
||||
detail: AlterationDialogDetailUio,
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.padding(all = 16.dp)
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
)
|
||||
.then(other = modifier),
|
||||
modifier = modifier,
|
||||
) {
|
||||
Column {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 24.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.Top,
|
||||
) {
|
||||
FlowRow(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = annotateWithDropCap(
|
||||
text = detail.name,
|
||||
style = MaterialTheme.lexicon.typography.dropCap.titleMedium,
|
||||
),
|
||||
)
|
||||
detail.original?.let {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
fontWeight = FontWeight.Light,
|
||||
fontStyle = FontStyle.Italic,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
text = it,
|
||||
)
|
||||
}
|
||||
}
|
||||
IconButton(onClick = onClose) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
Box {
|
||||
detail.icon?.let { uri ->
|
||||
BackgroundImage(
|
||||
modifier = Modifier
|
||||
.size(size = 144.dp)
|
||||
.align(alignment = Alignment.TopEnd),
|
||||
model = uri,
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(top = 8.dp)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = 24.dp),
|
||||
.verticalScroll(state = scrollState)
|
||||
.padding(paddingValues = paddingValues),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.lexicon.typography.base.headlineSmall,
|
||||
text = annotateWithDropCap(
|
||||
text = detail.name,
|
||||
style = MaterialTheme.lexicon.typography.dropCap.headlineSmall,
|
||||
),
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.offset(y = -(4.dp)),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontStyle = FontStyle.Italic,
|
||||
fontWeight = FontWeight.Light,
|
||||
text = detail.original ?: "",
|
||||
)
|
||||
Text(
|
||||
fontWeight = FontWeight.Light,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
|
|
@ -122,7 +135,7 @@ fun AlterationDetail(
|
|||
text = stringResource(id = R.string.alteration_target, detail.target),
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 8.dp, bottom = 24.dp),
|
||||
modifier = Modifier.padding(top = 12.dp),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = detail.description,
|
||||
)
|
||||
|
|
@ -136,8 +149,9 @@ fun AlterationDetail(
|
|||
@Preview(uiMode = UI_MODE_NIGHT_YES)
|
||||
private fun AlterationDetailPreview() {
|
||||
LexiconTheme {
|
||||
AlterationDetail(
|
||||
detail = AlterationDetailUio(
|
||||
AlterationDetailDialogContent(
|
||||
detail = AlterationDialogDetailUio(
|
||||
icon = null,
|
||||
name = "Rage",
|
||||
original = "Rage",
|
||||
source = "Barbare",
|
||||
|
|
@ -154,7 +168,6 @@ private fun AlterationDetailPreview() {
|
|||
"Condition \"\"Rage inhibée\"\" :\n" +
|
||||
"Votre rage vous demande des efforts de concentration ou se dissipe. Vous devez réussir un jet de sauvegarde de constitution dont la difficulté augmente à chaque tour (DC 6 + 2 par tour) sous peine de voir votre rage cesser. Sous certaines conditions, la difficulté pourra augmenter ou baisser au-delà des valeurs indiquées.\""
|
||||
),
|
||||
onClose = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
package com.pixelized.rplexicon.ui.screens.character.composable.dialogs
|
||||
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
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 com.pixelized.rplexicon.ui.composable.BackgroundImage
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.annotateWithDropCap
|
||||
import com.pixelized.rplexicon.utilitary.extentions.lexicon
|
||||
import com.pixelized.rplexicon.utilitary.extentions.modifier.ddBorder
|
||||
import com.pixelized.rplexicon.utilitary.extentions.string.skillIcon
|
||||
|
||||
@Stable
|
||||
data class SkillDialogDetailUio(
|
||||
val icon: Uri?,
|
||||
val name: String,
|
||||
val original: String?,
|
||||
val description: String,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun SkillDetailDialog(
|
||||
dialog: State<SkillDialogDetailUio?>,
|
||||
paddingValues: PaddingValues = PaddingValues(horizontal = 16.dp, vertical = 128.dp),
|
||||
onDismissRequest: () -> Unit,
|
||||
) {
|
||||
dialog.value?.let {
|
||||
Dialog(
|
||||
properties = remember { DialogProperties(usePlatformDefaultWidth = false) },
|
||||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
onClick = onDismissRequest,
|
||||
)
|
||||
.padding(paddingValues = paddingValues),
|
||||
) {
|
||||
SkillDetailDialogContent(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
enabled = false,
|
||||
onClick = { },
|
||||
)
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
),
|
||||
detail = it,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SkillDetailDialogContent(
|
||||
modifier: Modifier = Modifier,
|
||||
scrollState: ScrollState = rememberScrollState(),
|
||||
paddingValues: PaddingValues = PaddingValues(vertical = 16.dp, horizontal = 24.dp),
|
||||
detail: SkillDialogDetailUio,
|
||||
) {
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
) {
|
||||
Box {
|
||||
detail.icon?.let { uri ->
|
||||
BackgroundImage(
|
||||
modifier = Modifier
|
||||
.size(size = 144.dp)
|
||||
.align(alignment = Alignment.TopEnd),
|
||||
model = uri,
|
||||
)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(state = scrollState)
|
||||
.padding(paddingValues = paddingValues),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.lexicon.typography.base.headlineSmall,
|
||||
text = annotateWithDropCap(
|
||||
text = detail.name,
|
||||
style = MaterialTheme.lexicon.typography.dropCap.headlineSmall,
|
||||
),
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.offset(y = -(4.dp)),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontStyle = FontStyle.Italic,
|
||||
fontWeight = FontWeight.Light,
|
||||
text = detail.original ?: "",
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 12.dp),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = detail.description,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun AlterationDetailPreview() {
|
||||
LexiconTheme {
|
||||
SkillDetailDialogContent(
|
||||
detail = SkillDialogDetailUio(
|
||||
icon = "Endurance implacable".skillIcon(),
|
||||
name = "Endurance implacable",
|
||||
original = "Relentless Endurance",
|
||||
description = "Lorsque vous tombez à 0 point de vie, mais que vous n'êtes pas tué sur le coup, vous pouvez passer à 1 point de vie à la place. Vous devez terminer un repos long avant de pouvoir utiliser cette capacité de nouveau."
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,271 @@
|
|||
package com.pixelized.rplexicon.ui.screens.character.composable.dialogs
|
||||
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
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 com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.composable.BackgroundImage
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.annotateWithDropCap
|
||||
import com.pixelized.rplexicon.utilitary.extentions.lexicon
|
||||
import com.pixelized.rplexicon.utilitary.extentions.modifier.ddBorder
|
||||
|
||||
@Stable
|
||||
data class SpellDialogDetailUio(
|
||||
val icon: Uri?,
|
||||
val name: String,
|
||||
val translated: String,
|
||||
val level: String,
|
||||
@StringRes val school: Int,
|
||||
val castingTime: String,
|
||||
val range: String,
|
||||
val requirement: String,
|
||||
val duration: String,
|
||||
val description: String,
|
||||
val ritual: Boolean,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun SpellDetailDialog(
|
||||
dialog: State<SpellDialogDetailUio?>,
|
||||
paddingValues: PaddingValues = PaddingValues(horizontal = 16.dp, vertical = 128.dp),
|
||||
onDismissRequest: () -> Unit,
|
||||
) {
|
||||
dialog.value?.let {
|
||||
Dialog(
|
||||
properties = remember { DialogProperties(usePlatformDefaultWidth = false) },
|
||||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
onClick = onDismissRequest,
|
||||
)
|
||||
.padding(paddingValues = paddingValues),
|
||||
) {
|
||||
SpellDetailDialogContent(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
enabled = false,
|
||||
onClick = { },
|
||||
)
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
),
|
||||
detail = it,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
private fun SpellDetailDialogContent(
|
||||
modifier: Modifier = Modifier,
|
||||
scrollState: ScrollState = rememberScrollState(),
|
||||
paddingValues: PaddingValues = PaddingValues(vertical = 16.dp, horizontal = 24.dp),
|
||||
detail: SpellDialogDetailUio,
|
||||
) {
|
||||
val typography = MaterialTheme.lexicon.typography
|
||||
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
) {
|
||||
Box {
|
||||
detail.icon?.let { uri ->
|
||||
BackgroundImage(
|
||||
modifier = Modifier
|
||||
.size(size = 144.dp)
|
||||
.align(alignment = Alignment.TopEnd),
|
||||
model = uri,
|
||||
)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(state = scrollState)
|
||||
.padding(paddingValues = paddingValues),
|
||||
) {
|
||||
Text(
|
||||
style = typography.base.headlineSmall,
|
||||
text = annotateWithDropCap(
|
||||
text = detail.name,
|
||||
style = typography.dropCap.headlineSmall,
|
||||
),
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.offset(y = -(4.dp)),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontStyle = FontStyle.Italic,
|
||||
fontWeight = FontWeight.Light,
|
||||
text = detail.translated,
|
||||
)
|
||||
|
||||
FlowRow(
|
||||
modifier = Modifier.padding(top = 12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
text = stringResource(id = R.string.spell_detail_school),
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = stringResource(id = detail.school),
|
||||
)
|
||||
if (detail.ritual) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = "-",
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = stringResource(id = R.string.spell_detail_ritual),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
FlowRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
text = stringResource(id = R.string.spell_detail_level),
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = detail.level,
|
||||
)
|
||||
}
|
||||
|
||||
FlowRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
text = stringResource(id = R.string.spell_detail_casting_time),
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = detail.castingTime,
|
||||
)
|
||||
}
|
||||
FlowRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
text = stringResource(id = R.string.spell_detail_range),
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = detail.range,
|
||||
)
|
||||
}
|
||||
FlowRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
text = stringResource(id = R.string.spell_detail_components),
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = detail.requirement,
|
||||
)
|
||||
}
|
||||
FlowRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
text = stringResource(id = R.string.spell_detail_duration),
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = detail.duration,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
text = stringResource(id = R.string.spell_detail_description),
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = detail.description,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun SpellDetailDialogPreview() {
|
||||
LexiconTheme {
|
||||
SpellDetailDialogContent(
|
||||
detail = SpellDialogDetailUio(
|
||||
icon = null,
|
||||
name = "Représailles infernales",
|
||||
translated = "Hellish Rebuke",
|
||||
level = "1",
|
||||
school = R.string.spell_school_evocation,
|
||||
castingTime = "1 réaction, que vous prenez après avoir subi des dégâts par une créature située à 18 mètres maximum de vous et que vous pouvez voir.",
|
||||
range = "18 mètres",
|
||||
requirement = "V, S",
|
||||
duration = "Instantanée",
|
||||
description = "Vous pointez votre doigt, et la créature qui vous a infligé des dégâts est momentanément entourée de flammes infernales. La créature doit effectuer un jet de sauvegarde de Dextérité, subissant 2d10 dégâts de fue en cas d'échecn ou la moitié de ces dégâts en cas de réussite.\n\nAux niveaux supérieurs. Lorsque vous lancez ce sort en utilisant un emplacement de sort de niveau 2 ou supérieur, les dégâts sont augmentés de 1d10 pour chaque niveau d'emplacement au-dela du niveau 1.",
|
||||
ritual = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.remember
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.SpellLevelUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.chooser.SpellChooserUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.chooser.SpellChooserUio
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class CharacterSheetHeaderUioFactory @Inject constructor(
|
|||
),
|
||||
armorClass = LabelPointUio(
|
||||
label = R.string.character_sheet_title_ca,
|
||||
value = sheetHeaderData?.ca?.let { "$it" } ?: " ",
|
||||
value = sheetHeaderData?.ca?.let { "$it" } ?: "?",
|
||||
max = null,
|
||||
),
|
||||
hitPoint = LabelPointUio(
|
||||
|
|
@ -80,7 +80,7 @@ class CharacterSheetHeaderUioFactory @Inject constructor(
|
|||
}
|
||||
|
||||
else -> when {
|
||||
fireHeaderData?.wildShapeHp == null -> sheetHeaderData?.hpMax?.let { "$it" } ?: "?"
|
||||
fireHeaderData.wildShapeHp == null -> sheetHeaderData?.hpMax?.let { "$it" } ?: "?"
|
||||
fireHeaderData.extraHp == 0 -> "${fireHeaderData.wildShapeHp}"
|
||||
else -> "${fireHeaderData.wildShapeHp}+${fireHeaderData.extraHp}"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ import com.pixelized.rplexicon.LocalRollOverlay
|
|||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.composable.edit.HandleSkillEditDialog
|
||||
import com.pixelized.rplexicon.ui.composable.edit.HandleSpellEditDialog
|
||||
import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.navigateToSpellDetail
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.Attack
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AttackUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.GenericHeader
|
||||
|
|
@ -44,6 +42,8 @@ import com.pixelized.rplexicon.ui.screens.character.composable.actions.rememberS
|
|||
import com.pixelized.rplexicon.ui.screens.character.composable.preview.rememberAttackListStatePreview
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.preview.rememberObjectListStatePreview
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.preview.rememberSpellListStatePreview
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDetailDialog
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SpellDetailDialog
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
|
@ -56,7 +56,6 @@ fun ActionPage(
|
|||
spellsViewModel: SpellsViewModel = hiltViewModel(),
|
||||
skillViewModel: SkillsViewModel = hiltViewModel(),
|
||||
) {
|
||||
val screen = LocalScreenNavHost.current
|
||||
val overlay = LocalRollOverlay.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
|
|
@ -83,7 +82,7 @@ fun ActionPage(
|
|||
}
|
||||
},
|
||||
onObject = {
|
||||
skillViewModel.showSkillDetailDialog(item = it.name)
|
||||
objectsViewModel.showObjectDetailDialog(item = it.name)
|
||||
},
|
||||
onUseObject = {
|
||||
objectsViewModel.onUse(it.name)?.let { throws ->
|
||||
|
|
@ -103,13 +102,17 @@ fun ActionPage(
|
|||
}
|
||||
},
|
||||
onSkillInfo = {
|
||||
skillViewModel.showSkillDetailDialog(item = it.label)
|
||||
if (spellsViewModel.isSpell(name = it.label)) {
|
||||
spellsViewModel.showSpellDetailDialog(item = it.label)
|
||||
} else {
|
||||
skillViewModel.showSkillDetailDialog(item = it.label)
|
||||
}
|
||||
},
|
||||
onSpellLevel = { level: Int, value: Int, max: Int ->
|
||||
spellsViewModel.showSpellEditDialog(level = level, value = value, max = max)
|
||||
},
|
||||
onSpell = { spell ->
|
||||
screen.navigateToSpellDetail(spell = spell)
|
||||
spellsViewModel.showSpellDetailDialog(item = spell)
|
||||
},
|
||||
onSpellHit = { id ->
|
||||
scope.launch {
|
||||
|
|
@ -142,16 +145,26 @@ fun ActionPage(
|
|||
onConfirm = spellsViewModel::applySpellChange
|
||||
)
|
||||
|
||||
SpellDetailDialog(
|
||||
dialog = spellsViewModel.spellDetailDialog,
|
||||
onDismissRequest = spellsViewModel::hideSpellDetailDialog
|
||||
)
|
||||
|
||||
HandleSkillEditDialog(
|
||||
dialog = skillViewModel.skillEditDialog,
|
||||
onDismissRequest = skillViewModel::hideSkillEditDialog,
|
||||
onConfirm = skillViewModel::applySkillChange
|
||||
)
|
||||
|
||||
HandleSkillDetailDialog(
|
||||
SkillDetailDialog(
|
||||
dialog = skillViewModel.skillDetailDialog,
|
||||
onDismissRequest = skillViewModel::hideSkillDetailDialog
|
||||
)
|
||||
|
||||
SkillDetailDialog(
|
||||
dialog = objectsViewModel.objectDetailDialog,
|
||||
onDismissRequest = objectsViewModel::hideObjectDetailDialog
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
|
|||
import com.pixelized.rplexicon.data.repository.character.ObjectActionRepository
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.ObjectItemUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDialogDetailUio
|
||||
import com.pixelized.rplexicon.utilitary.extentions.string.objectIcon
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -28,8 +29,8 @@ class ObjectsViewModel @Inject constructor(
|
|||
private val _objects = mutableStateOf<List<ObjectItemUio>>(emptyList())
|
||||
val objects: State<List<ObjectItemUio>> get() = _objects
|
||||
|
||||
private val _dialog = mutableStateOf<SkillDetailUio?>(null)
|
||||
val dialog: State<SkillDetailUio?> get() = _dialog
|
||||
private val _objectDetailDialog = mutableStateOf<SkillDialogDetailUio?>(null)
|
||||
val objectDetailDialog: State<SkillDialogDetailUio?> get() = _objectDetailDialog
|
||||
|
||||
init {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
|
|
@ -60,4 +61,21 @@ class ObjectsViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun showObjectDetailDialog(item: String) {
|
||||
val description = descriptionRepository.getDescription(name = item)
|
||||
val item = objectsRepository.find(character = character, item = item)
|
||||
if (item != null && description != null) {
|
||||
_objectDetailDialog.value = SkillDialogDetailUio(
|
||||
icon = item.icon ?: item.name.objectIcon(),
|
||||
name = item.name,
|
||||
original = description.original,
|
||||
description = description.description
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun hideObjectDetailDialog() {
|
||||
_objectDetailDialog.value = null
|
||||
}
|
||||
}
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
package com.pixelized.rplexicon.ui.screens.character.pages.actions
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
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.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.lexicon
|
||||
import com.pixelized.rplexicon.utilitary.extentions.modifier.ddBorder
|
||||
|
||||
@Stable
|
||||
data class SkillDetailUio(
|
||||
val name: String,
|
||||
val original: String?,
|
||||
val description: String,
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
fun SkillDetail(
|
||||
modifier: Modifier = Modifier,
|
||||
detail: SkillDetailUio,
|
||||
onClose: () -> Unit,
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.padding(all = 16.dp)
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
)
|
||||
.then(other = modifier),
|
||||
) {
|
||||
Column {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 24.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.Top,
|
||||
) {
|
||||
FlowRow(
|
||||
modifier = Modifier
|
||||
.padding(top = 16.dp)
|
||||
.weight(weight = 1f),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
text = AnnotatedString(
|
||||
text = detail.name,
|
||||
spanStyles = listOf(
|
||||
AnnotatedString.Range(
|
||||
item = MaterialTheme.lexicon.typography.dropCap.titleMedium,
|
||||
start = 0,
|
||||
end = Integer.min(1, detail.name.length),
|
||||
)
|
||||
)
|
||||
),
|
||||
)
|
||||
detail.original?.let {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
fontWeight = FontWeight.Light,
|
||||
fontStyle = FontStyle.Italic,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
text = it,
|
||||
)
|
||||
}
|
||||
}
|
||||
IconButton(onClick = onClose) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(top = 8.dp)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = 24.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 8.dp, bottom = 24.dp),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = detail.description,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun HandleSkillDetailDialog(
|
||||
dialog: State<SkillDetailUio?>,
|
||||
onDismissRequest: () -> Unit,
|
||||
) {
|
||||
dialog.value?.let {
|
||||
Dialog(
|
||||
properties = remember { DialogProperties(usePlatformDefaultWidth = false) },
|
||||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
SkillDetail(
|
||||
detail = it,
|
||||
onClose = onDismissRequest,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun AlterationDetailPreview() {
|
||||
LexiconTheme {
|
||||
SkillDetail(
|
||||
detail = SkillDetailUio(
|
||||
name = "Endurance implacable",
|
||||
original = "Relentless Endurance",
|
||||
description = "Lorsque vous tombez à 0 point de vie, mais que vous n'êtes pas tué sur le coup, vous pouvez passer à 1 point de vie à la place. Vous devez terminer un repos long avant de pouvoir utiliser cette capacité de nouveau."
|
||||
),
|
||||
onClose = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,8 @@ import com.pixelized.rplexicon.ui.composable.edit.SkillEditDialogUio
|
|||
import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.SkillItemUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.factory.SkillFactoryUioFactory
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDialogDetailUio
|
||||
import com.pixelized.rplexicon.utilitary.extentions.string.skillIcon
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
|
|
@ -41,8 +43,8 @@ class SkillsViewModel @Inject constructor(
|
|||
private val _skillEditDialog = mutableStateOf<SkillEditDialogUio?>(null)
|
||||
val skillEditDialog: State<SkillEditDialogUio?> get() = _skillEditDialog
|
||||
|
||||
private val _skillDetailDialog = mutableStateOf<SkillDetailUio?>(null)
|
||||
val skillDetailDialog: State<SkillDetailUio?> get() = _skillDetailDialog
|
||||
private val _skillDetailDialog = mutableStateOf<SkillDialogDetailUio?>(null)
|
||||
val skillDetailDialog: State<SkillDialogDetailUio?> get() = _skillDetailDialog
|
||||
|
||||
private val _skills = mutableStateOf<List<SkillItemUio>>(emptyList())
|
||||
val skills: State<List<SkillItemUio>> get() = _skills
|
||||
|
|
@ -81,15 +83,16 @@ class SkillsViewModel @Inject constructor(
|
|||
)
|
||||
|
||||
fun showSkillDetailDialog(item: String) {
|
||||
_skillDetailDialog.value = descriptionRepository
|
||||
.getDescription(name = item)
|
||||
?.let { description ->
|
||||
SkillDetailUio(
|
||||
name = item,
|
||||
original = description.original,
|
||||
description = description.description
|
||||
)
|
||||
}
|
||||
val description = descriptionRepository.getDescription(name = item)
|
||||
val skill = skillRepository.find(character = character, skill = item)
|
||||
if (skill != null && description != null) {
|
||||
_skillDetailDialog.value = SkillDialogDetailUio(
|
||||
icon = skill.icon ?: skill.name.skillIcon(),
|
||||
name = skill.name,
|
||||
original = description.original,
|
||||
description = description.description
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun hideSkillDetailDialog() {
|
||||
|
|
|
|||
|
|
@ -16,19 +16,23 @@ import com.pixelized.rplexicon.data.model.roll.Throw
|
|||
import com.pixelized.rplexicon.data.network.CharacterSheetFire
|
||||
import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository
|
||||
import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository
|
||||
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
|
||||
import com.pixelized.rplexicon.data.repository.character.SpellRepository
|
||||
import com.pixelized.rplexicon.ui.composable.edit.SpellEditDialogUio
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.SpellHeaderUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.SpellLevelUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.SpellUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.chooser.SpellChooserUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SpellDialogDetailUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.chooser.SpellChooserUio
|
||||
import com.pixelized.rplexicon.utilitary.extentions.icon
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.firstSpellSlot
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.highestSpellLevel
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.label
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.spell
|
||||
import com.pixelized.rplexicon.utilitary.extentions.modifier
|
||||
import com.pixelized.rplexicon.utilitary.extentions.signLabel
|
||||
import com.pixelized.rplexicon.utilitary.extentions.string.spellIcon
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
|
|
@ -44,6 +48,7 @@ class SpellsViewModel @Inject constructor(
|
|||
private val characterRepository: CharacterSheetRepository,
|
||||
private val firebaseRepository: FirebaseRepository,
|
||||
private val spellRepository: SpellRepository,
|
||||
private val descriptionRepository: DescriptionRepository,
|
||||
application: Application,
|
||||
spellBookUseCase: SpellBookUseCase,
|
||||
savedStateHandle: SavedStateHandle,
|
||||
|
|
@ -52,6 +57,9 @@ class SpellsViewModel @Inject constructor(
|
|||
private var characterFire: CharacterSheetFire? = null
|
||||
private val characterName = savedStateHandle.characterSheetArgument.name
|
||||
|
||||
private val _spellDetailDialog = mutableStateOf<SpellDialogDetailUio?>(null)
|
||||
val spellDetailDialog: State<SpellDialogDetailUio?> get() = _spellDetailDialog
|
||||
|
||||
private val _editDialog = mutableStateOf<SpellEditDialogUio?>(null)
|
||||
val spellEditDialog: State<SpellEditDialogUio?> get() = _editDialog
|
||||
|
||||
|
|
@ -171,6 +179,34 @@ class SpellsViewModel @Inject constructor(
|
|||
hideSpellEditDialog()
|
||||
}
|
||||
|
||||
fun isSpell(name: String): Boolean {
|
||||
return spellRepository.findSpell(name = name) != null
|
||||
}
|
||||
|
||||
fun showSpellDetailDialog(item: String) {
|
||||
val description = descriptionRepository.getDescription(name = item)
|
||||
val spell = spellRepository.findSpell(name = item)
|
||||
if (spell != null && description != null) {
|
||||
_spellDetailDialog.value = SpellDialogDetailUio(
|
||||
icon = spell.icon ?: spell.name.spellIcon(),
|
||||
name = spell.name,
|
||||
translated = description.original,
|
||||
level = "${spell.level}",
|
||||
school = spell.school.label,
|
||||
castingTime = spell.castingTime,
|
||||
range = spell.range,
|
||||
requirement = spell.requirement,
|
||||
duration = spell.duration,
|
||||
description = description.description,
|
||||
ritual = spell.ritual,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun hideSpellDetailDialog() {
|
||||
_spellDetailDialog.value = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to build a readable String from a Throw.
|
||||
* Create a string following the format "amount 'd' faces '+' modifiers + amount * level 'd' faces"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||
import com.pixelized.rplexicon.ui.composable.CategoryHeader
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItem
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItemUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.alteration.AlterationDetailHandler
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.AlterationDetailDialog
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.preview.rememberRollAlterations
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -52,9 +52,9 @@ fun AlterationPage(
|
|||
},
|
||||
)
|
||||
|
||||
AlterationDetailHandler(
|
||||
detail = viewModel.alterationDetail,
|
||||
onDismissRequest = { viewModel.hideAlterationDetail() },
|
||||
AlterationDetailDialog(
|
||||
dialog = viewModel.alterationDetailDialog,
|
||||
onDismissRequest = viewModel::hideAlterationDetail,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,10 @@ import com.pixelized.rplexicon.data.repository.character.AlterationRepository
|
|||
import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository
|
||||
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.AlterationDialogDetailUio
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.factory.AlterationFactory
|
||||
import com.pixelized.rplexicon.utilitary.extentions.context
|
||||
import com.pixelized.rplexicon.utilitary.extentions.string.alterationIcon
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
|
|
@ -45,8 +47,8 @@ class AlterationViewModel @Inject constructor(
|
|||
private val _alterations = mutableStateOf<List<AlterationGroupUio>>(emptyList())
|
||||
val alterations: State<List<AlterationGroupUio>> get() = _alterations
|
||||
|
||||
private val _alterationDetail = mutableStateOf<AlterationDetailUio?>(null)
|
||||
val alterationDetail: State<AlterationDetailUio?> get() = _alterationDetail
|
||||
private val _alterationDetailDialog = mutableStateOf<AlterationDialogDetailUio?>(null)
|
||||
val alterationDetailDialog: State<AlterationDialogDetailUio?> get() = _alterationDetailDialog
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
|
|
@ -114,7 +116,8 @@ class AlterationViewModel @Inject constructor(
|
|||
val description = descriptionRepository.getDescription(
|
||||
name = alteration.name,
|
||||
)
|
||||
_alterationDetail.value = AlterationDetailUio(
|
||||
_alterationDetailDialog.value = AlterationDialogDetailUio(
|
||||
icon = alteration.icon ?: alteration.name.alterationIcon(),
|
||||
name = id,
|
||||
original = description?.original,
|
||||
source = alteration.source,
|
||||
|
|
@ -126,7 +129,7 @@ class AlterationViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun hideAlterationDetail() {
|
||||
_alterationDetail.value = null
|
||||
_alterationDetailDialog.value = null
|
||||
}
|
||||
|
||||
private data class AlterationStruct(
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import com.pixelized.rplexicon.ui.screens.character.composable.actions.Inventory
|
|||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.InventoryItemUio
|
||||
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.actions.HandleSkillDetailDialog
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDetailDialog
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -50,7 +50,7 @@ fun InventoryPage(
|
|||
},
|
||||
)
|
||||
|
||||
HandleSkillDetailDialog(
|
||||
SkillDetailDialog(
|
||||
dialog = viewModel.dialog,
|
||||
onDismissRequest = viewModel::hideSkillDetailDialog,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,8 +14,9 @@ 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.actions.InventoryItemUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.factory.ItemUioFactory
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.actions.SkillDetailUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDialogDetailUio
|
||||
import com.pixelized.rplexicon.utilitary.extentions.context
|
||||
import com.pixelized.rplexicon.utilitary.extentions.string.equipmentsIcon
|
||||
import com.pixelized.rplexicon.utilitary.extentions.uri
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -42,8 +43,8 @@ class InventoryViewModel @Inject constructor(
|
|||
private val _inventory = mutableStateOf<List<InventoryItemUio>>(emptyList())
|
||||
val inventory: State<List<InventoryItemUio>> get() = _inventory
|
||||
|
||||
private val _dialog = mutableStateOf<SkillDetailUio?>(null)
|
||||
val dialog: State<SkillDetailUio?> get() = _dialog
|
||||
private val _dialog = mutableStateOf<SkillDialogDetailUio?>(null)
|
||||
val dialog: State<SkillDialogDetailUio?> get() = _dialog
|
||||
|
||||
private val _snack = MutableSharedFlow<String?>()
|
||||
val snack: SharedFlow<String?> get() = _snack
|
||||
|
|
@ -86,12 +87,12 @@ class InventoryViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun showSkillDetailDialog(item: String) {
|
||||
val description = descriptionRepository.getDescription(name = item)
|
||||
|
||||
if (description != null) {
|
||||
_dialog.value = SkillDetailUio(
|
||||
_dialog.value = SkillDialogDetailUio(
|
||||
icon = item.equipmentsIcon(),
|
||||
name = item,
|
||||
original = description.original,
|
||||
description = description.description
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ import com.pixelized.rplexicon.ui.screens.character.composable.character.Profici
|
|||
import com.pixelized.rplexicon.ui.screens.character.composable.character.Stat
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.character.StatUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.preview.rememberCharacterSheetStatePreview
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.actions.HandleSkillDetailDialog
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDetailDialog
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.modifier.ddBorder
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -113,7 +113,7 @@ fun ProficiencyPage(
|
|||
onConfirm = viewModel::applySkillChange
|
||||
)
|
||||
|
||||
HandleSkillDetailDialog(
|
||||
SkillDetailDialog(
|
||||
dialog = viewModel.skillDetailDialog,
|
||||
onDismissRequest = viewModel::hideSkillDetailDialog
|
||||
)
|
||||
|
|
|
|||
|
|
@ -24,8 +24,9 @@ import com.pixelized.rplexicon.ui.screens.character.composable.character.Profici
|
|||
import com.pixelized.rplexicon.ui.screens.character.composable.character.StatUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.factory.CharacterSheetUioFactory
|
||||
import com.pixelized.rplexicon.ui.screens.character.factory.SkillFactoryUioFactory
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.actions.SkillDetailUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDialogDetailUio
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.toStatus
|
||||
import com.pixelized.rplexicon.utilitary.extentions.string.skillIcon
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.combine
|
||||
|
|
@ -53,8 +54,8 @@ class ProficiencyViewModel @Inject constructor(
|
|||
private val _skillEditDialog = mutableStateOf<SkillEditDialogUio?>(null)
|
||||
val skillEditDialog: State<SkillEditDialogUio?> get() = _skillEditDialog
|
||||
|
||||
private val _skillDetailDialog = mutableStateOf<SkillDetailUio?>(null)
|
||||
val skillDetailDialog: State<SkillDetailUio?> get() = _skillDetailDialog
|
||||
private val _skillDetailDialog = mutableStateOf<SkillDialogDetailUio?>(null)
|
||||
val skillDetailDialog: State<SkillDialogDetailUio?> get() = _skillDetailDialog
|
||||
|
||||
private val _skills = mutableStateOf<List<SkillItemUio>>(emptyList())
|
||||
val skills: State<List<SkillItemUio>> get() = _skills
|
||||
|
|
@ -154,15 +155,16 @@ class ProficiencyViewModel @Inject constructor(
|
|||
)
|
||||
|
||||
fun showSkillDetailDialog(item: String) {
|
||||
_skillDetailDialog.value = descriptionRepository
|
||||
.getDescription(name = item)
|
||||
?.let { description ->
|
||||
SkillDetailUio(
|
||||
name = item,
|
||||
original = description.original,
|
||||
description = description.description
|
||||
)
|
||||
}
|
||||
val description = descriptionRepository.getDescription(name = item)
|
||||
val skill = skillRepository.find(character = character, skill = item)
|
||||
if (skill != null && description != null) {
|
||||
_skillDetailDialog.value = SkillDialogDetailUio(
|
||||
icon = skill.icon ?: skill.name.skillIcon(),
|
||||
name = skill.name,
|
||||
original = description.original,
|
||||
description = description.description
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun hideSkillDetailDialog() {
|
||||
|
|
|
|||
|
|
@ -66,8 +66,6 @@ import androidx.compose.ui.unit.Density
|
|||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
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.LocalRollOverlay
|
||||
import com.pixelized.rplexicon.NO_WINDOW_INSETS
|
||||
|
|
@ -77,9 +75,8 @@ import com.pixelized.rplexicon.ui.composable.BlurredOverlayHostState
|
|||
import com.pixelized.rplexicon.ui.composable.CategoryHeader
|
||||
import com.pixelized.rplexicon.ui.composable.ModalNavigationDrawer
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItem
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationDetail
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationDetailUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationGroupUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.AlterationDetailDialog
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDice
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDiceUio
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCard
|
||||
|
|
@ -136,9 +133,9 @@ fun RollOverlay(
|
|||
onBack = { scope.launch { drawer.close() } },
|
||||
)
|
||||
|
||||
AlterationDetailHandler(
|
||||
detail = viewModel.alterationDetail,
|
||||
onDismissRequest = { viewModel.hideAlterationDetail() },
|
||||
AlterationDetailDialog(
|
||||
dialog = viewModel.alterationDetailDialog,
|
||||
onDismissRequest = viewModel::hideAlterationDetail,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -344,24 +341,6 @@ private fun Modifier.detailPaddingBottom(
|
|||
this.then(other = Modifier.padding(bottom = padding))
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AlterationDetailHandler(
|
||||
detail: State<AlterationDetailUio?>,
|
||||
onDismissRequest: () -> Unit,
|
||||
) {
|
||||
detail.value?.let {
|
||||
Dialog(
|
||||
properties = remember { DialogProperties(usePlatformDefaultWidth = false) },
|
||||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
AlterationDetail(
|
||||
detail = it,
|
||||
onClose = onDismissRequest,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = UI_MODE_NIGHT_YES)
|
||||
|
|
|
|||
|
|
@ -20,14 +20,15 @@ import com.pixelized.rplexicon.data.repository.character.AlterationRepository
|
|||
import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository
|
||||
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItemUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationDetailUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationGroupUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.AlterationDialogDetailUio
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDiceUio
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowCardFactory
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCardUio
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.factory.AlterationFactory
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.factory.DiceFactory
|
||||
import com.pixelized.rplexicon.utilitary.extentions.context
|
||||
import com.pixelized.rplexicon.utilitary.extentions.string.alterationIcon
|
||||
import com.pixelized.rplexicon.utilitary.extentions.switch
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -85,8 +86,8 @@ class RollOverlayViewModel @Inject constructor(
|
|||
private val _isThrowHidden = mutableStateOf(false)
|
||||
val isThrowHidden: State<Boolean> get() = _isThrowHidden
|
||||
|
||||
private val _alterationDetail = mutableStateOf<AlterationDetailUio?>(null)
|
||||
val alterationDetail: State<AlterationDetailUio?> get() = _alterationDetail
|
||||
private val _alterationDetailDialog = mutableStateOf<AlterationDialogDetailUio?>(null)
|
||||
val alterationDetailDialog: State<AlterationDialogDetailUio?> get() = _alterationDetailDialog
|
||||
|
||||
suspend fun prepareRoll(diceThrow: DiceThrow) {
|
||||
this.diceThrow = diceThrow
|
||||
|
|
@ -190,7 +191,8 @@ class RollOverlayViewModel @Inject constructor(
|
|||
name = alteration?.name,
|
||||
)
|
||||
if (alteration != null) {
|
||||
_alterationDetail.value = AlterationDetailUio(
|
||||
_alterationDetailDialog.value = AlterationDialogDetailUio(
|
||||
icon = alteration.icon ?: alteration.name.alterationIcon(),
|
||||
name = id,
|
||||
original = description?.original,
|
||||
source = alteration.source,
|
||||
|
|
@ -202,7 +204,7 @@ class RollOverlayViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun hideAlterationDetail() {
|
||||
_alterationDetail.value = null
|
||||
_alterationDetailDialog.value = null
|
||||
}
|
||||
|
||||
private data class AlterationStruct(
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ import com.pixelized.rplexicon.R
|
|||
import com.pixelized.rplexicon.ui.composable.KeepOnScreen
|
||||
import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.navigateToCharacterSheet
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.alteration.AlterationDetailHandler
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.AlterationDetailDialog
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCard
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCardUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.pages.statistic.StatisticSummary
|
||||
|
|
@ -124,8 +124,8 @@ fun SummaryScreen(
|
|||
onDetail = { statisticsViewModel.hideDetail() },
|
||||
)
|
||||
|
||||
AlterationDetailHandler(
|
||||
detail = statisticsViewModel.alterationDetail,
|
||||
AlterationDetailDialog(
|
||||
dialog = statisticsViewModel.alterationDetailDialog,
|
||||
onDismissRequest = { statisticsViewModel.hideAlterationDetail() },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@ import com.pixelized.rplexicon.R
|
|||
import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository
|
||||
import com.pixelized.rplexicon.data.repository.character.AlterationRepository
|
||||
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationDetailUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.AlterationDialogDetailUio
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowCardFactory
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCardUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.ClassHeaderSummaryUio
|
||||
import com.pixelized.rplexicon.utilitary.extentions.context
|
||||
import com.pixelized.rplexicon.utilitary.extentions.string.alterationIcon
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
|
|
@ -38,8 +39,8 @@ class StatisticViewModel @Inject constructor(
|
|||
private val _detail = mutableStateOf<ThrowsCardUio?>(null)
|
||||
val detail: State<ThrowsCardUio?> get() = _detail
|
||||
|
||||
private val _alterationDetail = mutableStateOf<AlterationDetailUio?>(null)
|
||||
val alterationDetail: State<AlterationDetailUio?> get() = _alterationDetail
|
||||
private val _alterationDetailDialog = mutableStateOf<AlterationDialogDetailUio?>(null)
|
||||
val alterationDetailDialog: State<AlterationDialogDetailUio?> get() = _alterationDetailDialog
|
||||
|
||||
fun showDetail(dice: ClassHeaderSummaryUio.Dice) {
|
||||
detailJob?.cancel()
|
||||
|
|
@ -70,7 +71,8 @@ class StatisticViewModel @Inject constructor(
|
|||
val description = descriptionRepository.getDescription(name = alteration?.name)
|
||||
|
||||
if (alteration != null) {
|
||||
_alterationDetail.value = AlterationDetailUio(
|
||||
_alterationDetailDialog.value = AlterationDialogDetailUio(
|
||||
icon = alteration.icon ?: alteration.name.alterationIcon(),
|
||||
name = name,
|
||||
original = description?.original,
|
||||
source = alteration.source,
|
||||
|
|
@ -82,6 +84,6 @@ class StatisticViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun hideAlterationDetail() {
|
||||
_alterationDetail.value = null
|
||||
_alterationDetailDialog.value = null
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,10 @@ fun String.objectIcon(): Uri? {
|
|||
return ResourcesCache.objects[this]?.uri?.toUriOrNull()
|
||||
}
|
||||
|
||||
fun String.equipmentsIcon(): Uri? {
|
||||
return ResourcesCache.equipments[this]?.uri?.toUriOrNull()
|
||||
}
|
||||
|
||||
fun String.alterationIcon(): Uri? {
|
||||
return ResourcesCache.alterations[this]?.uri?.toUriOrNull()
|
||||
}
|
||||
|
|
@ -112,6 +116,15 @@ private object ResourcesCache {
|
|||
"Baies nourricières" to R.drawable.icbg_food_goodberry_unfaded,
|
||||
)
|
||||
|
||||
val equipments = hashMapOf(
|
||||
"Dague" to R.drawable.icbg_dagger_unfaded,
|
||||
"Hache de guerre en argent" to R.drawable.icbg_battleaxe_plus_one_unfaded,
|
||||
"Bouclier" to R.drawable.icbg_studded_shield_unfaded,
|
||||
"Cape de protection" to R.drawable.icbg_cloak_of_protection_unfaded,
|
||||
"Armure d'écailles" to R.drawable.icbg_scale_mail_unfaded,
|
||||
"Armure de cuir" to R.drawable.icbg_leather_armour_rogue_unfaded,
|
||||
)
|
||||
|
||||
val skills = hashMapOf(
|
||||
"Dé de vie (Barbare)" to R.drawable.icbg_bolstering_magic_boon,
|
||||
"Dé de vie (Guerrier)" to R.drawable.icbg_bolstering_magic_boon,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue