Refactor the quest detail layout (spacing).

This commit is contained in:
Thomas Andres Gomez 2023-12-17 14:36:00 +01:00
parent 00267623ca
commit 8acb98ac27

View file

@ -18,6 +18,7 @@ import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.minimumInteractiveComponentSize
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@ -41,6 +42,7 @@ import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
@ -59,6 +61,7 @@ import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
import com.pixelized.rplexicon.ui.navigation.screens.navigateToLexiconDetail
import com.pixelized.rplexicon.ui.navigation.screens.navigateToLocationDetail
import com.pixelized.rplexicon.ui.theme.LexiconTheme
import com.pixelized.rplexicon.ui.theme.typography.LexiconTypography
import com.pixelized.rplexicon.utilitary.LOS_FULL
import com.pixelized.rplexicon.utilitary.LOS_HOLLOW
import com.pixelized.rplexicon.utilitary.annotate
@ -153,7 +156,7 @@ private fun QuestDetailContent(
},
content = { padding ->
Surface(
modifier = Modifier.padding(padding),
modifier = Modifier.padding(paddingValues = padding),
) {
Box(
modifier = Modifier
@ -177,6 +180,7 @@ private fun QuestDetailContent(
)
}
}
Column(
modifier = Modifier
.verticalScroll(state)
@ -188,13 +192,13 @@ private fun QuestDetailContent(
},
bottom = 16.dp,
),
verticalArrangement = Arrangement.spacedBy(space = 16.dp),
verticalArrangement = Arrangement.spacedBy(space = 24.dp),
) {
Text(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
.padding(bottom = 16.dp),
.padding(bottom = 24.dp),
textAlign = TextAlign.Center,
style = typography.base.headlineLarge,
text = annotate(
@ -205,148 +209,15 @@ private fun QuestDetailContent(
)
quest?.steps?.forEach { quest ->
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
quest.subtitle?.let {
Text(
modifier = Modifier
.padding(horizontal = 16.dp)
.padding(top = 16.dp),
style = MaterialTheme.typography.titleLarge,
textAlign = TextAlign.Center,
overflow = TextOverflow.Ellipsis,
maxLines = 3,
text = annotate(
text = it,
dropCapRegex styleWith typography.titleLargeDropCap,
highlightRegex styleWith typography.detail.highlightStyle,
),
)
}
quest.giver?.let {
Column(
modifier = Modifier
.fillMaxWidth()
.clickable(
enabled = quest.giverId != null,
onClick = { quest.giverId?.let { onGiver(it) } }
)
.padding(horizontal = 16.dp)
) {
Text(
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
text = stringResource(id = R.string.quest_detail_giver),
)
Text(
style = MaterialTheme.typography.bodyMedium,
text = annotate(
text = when (quest.giverId) {
null -> "$LOS_HOLLOW $it"
else -> "$LOS_FULL $it"
},
highlightRegex styleWith typography.detail.highlightStyle,
)
)
}
}
}
quest.place?.let {
Column(
modifier = Modifier
.fillMaxWidth()
.clickable(
enabled = quest.placeId != null,
onClick = { quest.placeId?.let { onLocation(it) } }
)
.padding(horizontal = 16.dp),
) {
Text(
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
text = stringResource(id = R.string.quest_detail_area),
)
Text(
style = MaterialTheme.typography.bodyMedium,
text = annotate(
text = when (quest.placeId) {
null -> "$LOS_HOLLOW $it"
else -> "$LOS_FULL $it"
},
highlightRegex styleWith typography.detail.highlightStyle
),
)
}
}
quest.globalReward?.let {
Column(
modifier = Modifier.padding(horizontal = 16.dp),
) {
Text(
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
text = stringResource(id = R.string.quest_detail_group_reward),
)
Text(
style = MaterialTheme.typography.bodyMedium,
text = annotate(
text = "$LOS_HOLLOW $it",
highlightRegex styleWith typography.detail.highlightStyle,
),
)
}
}
quest.individualReward?.let {
Column(
modifier = Modifier.padding(horizontal = 16.dp),
) {
Text(
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
text = stringResource(id = R.string.quest_detail_individual_reward),
)
Text(
style = MaterialTheme.typography.bodyMedium,
text = annotate(
text = "$LOS_HOLLOW $it",
highlightRegex styleWith typography.detail.highlightStyle,
),
)
}
}
Text(
modifier = Modifier.padding(horizontal = 16.dp),
style = MaterialTheme.typography.bodyMedium,
text = annotate(
text = quest.description,
dropCapRegex styleWith typography.bodyMediumDropCap,
highlightRegex styleWith typography.detail.highlightStyle,
),
QuestStep(
quest = quest,
typography = typography,
highlightRegex = highlightRegex,
dropCapRegex = dropCapRegex,
onGiver = onGiver,
onLocation = onLocation,
onImage = onImage,
)
if (quest.images.isNotEmpty()) {
LazyRow(
contentPadding = PaddingValues(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
items(items = quest.images) {
AsyncImage(
modifier = Modifier
.clickable { onImage(it) }
.sizeIn(maxWidth = rememberMaxWidth())
.height(height = 160.dp),
contentScale = ContentScale.FillHeight,
model = it,
)
}
}
}
}
}
}
@ -354,6 +225,141 @@ private fun QuestDetailContent(
)
}
@Composable
private fun QuestStep(
modifier: Modifier = Modifier,
quest: QuestDetailUio.QuestStep,
typography: LexiconTypography,
highlightRegex: Regex,
dropCapRegex: Regex,
onGiver: (String) -> Unit,
onLocation: (String) -> Unit,
onImage: (Uri) -> Unit,
) {
Column(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(space = 8.dp)
) {
quest.subtitle?.let {
Text(
modifier = Modifier
.padding(horizontal = 16.dp)
.padding(top = 16.dp),
style = MaterialTheme.typography.titleLarge,
textAlign = TextAlign.Center,
overflow = TextOverflow.Ellipsis,
maxLines = 3,
text = annotate(
text = it,
dropCapRegex styleWith typography.titleLargeDropCap,
highlightRegex styleWith typography.detail.highlightStyle,
),
)
}
quest.giver?.let {
SubTitle(
title = stringResource(id = R.string.quest_detail_giver),
label = annotate(
text = when (quest.giverId) {
null -> "$LOS_HOLLOW $it"
else -> "$LOS_FULL $it"
},
highlightRegex styleWith typography.detail.highlightStyle,
),
onClick = { quest.giverId?.let { id -> onGiver(id) } },
)
}
quest.place?.let {
SubTitle(
title = stringResource(id = R.string.quest_detail_area),
label = annotate(
text = when (quest.placeId) {
null -> "$LOS_HOLLOW $it"
else -> "$LOS_FULL $it"
},
highlightRegex styleWith typography.detail.highlightStyle
),
onClick = { quest.placeId?.let { id -> onLocation(id) } },
)
}
quest.globalReward?.let {
SubTitle(
title = stringResource(id = R.string.quest_detail_group_reward),
label = annotate(
text = "$LOS_HOLLOW $it",
highlightRegex styleWith typography.detail.highlightStyle,
),
)
}
quest.individualReward?.let {
SubTitle(
title = stringResource(id = R.string.quest_detail_individual_reward),
label = annotate(
text = "$LOS_HOLLOW $it",
highlightRegex styleWith typography.detail.highlightStyle,
),
)
}
Text(
modifier = Modifier.padding(horizontal = 16.dp),
style = MaterialTheme.typography.bodyMedium,
text = annotate(
text = quest.description,
dropCapRegex styleWith typography.bodyMediumDropCap,
highlightRegex styleWith typography.detail.highlightStyle,
),
)
if (quest.images.isNotEmpty()) {
LazyRow(
contentPadding = PaddingValues(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
items(items = quest.images) {
AsyncImage(
modifier = Modifier
.clickable { onImage(it) }
.sizeIn(maxWidth = rememberMaxWidth())
.height(height = 160.dp),
contentScale = ContentScale.FillHeight,
model = it,
)
}
}
}
}
}
@Composable
private fun SubTitle(
modifier: Modifier = Modifier,
title: String,
label: AnnotatedString,
onClick: (() -> Unit)? = null,
) {
Column(
modifier = Modifier
.clickable(
enabled = onClick != null,
onClick = { onClick?.invoke() }
)
.minimumInteractiveComponentSize()
.fillMaxWidth()
.padding(horizontal = 16.dp)
.then(other = modifier),
verticalArrangement = Arrangement.Center,
) {
Text(
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
text = title,
)
Text(
style = MaterialTheme.typography.bodyMedium,
text = label,
)
}
}
@Composable
private fun rememberMaxWidth(): Dp {
val configuration = LocalConfiguration.current