Refactor the quest detail layout (spacing).
This commit is contained in:
parent
00267623ca
commit
8acb98ac27
1 changed files with 150 additions and 144 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue