From 8acb98ac278ae61f356715c512c9901e5c01bc32 Mon Sep 17 00:00:00 2001 From: Thomas Andres Gomez Date: Sun, 17 Dec 2023 14:36:00 +0100 Subject: [PATCH] Refactor the quest detail layout (spacing). --- .../screens/quest/detail/QuestDetailScreen.kt | 294 +++++++++--------- 1 file changed, 150 insertions(+), 144 deletions(-) diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/quest/detail/QuestDetailScreen.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/quest/detail/QuestDetailScreen.kt index 352d0e0..8051e25 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/quest/detail/QuestDetailScreen.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/quest/detail/QuestDetailScreen.kt @@ -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