Add background for quest screen.

This commit is contained in:
Thomas Andres Gomez 2023-11-21 15:28:18 +01:00
parent 2eff9f8e2f
commit eaa4fcf8e9
2 changed files with 112 additions and 83 deletions

View file

@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
@ -57,6 +58,7 @@ import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
@ -67,12 +69,15 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.min
import androidx.hilt.navigation.compose.hiltViewModel
import com.pixelized.rplexicon.LocalSnack
import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.ui.composable.AsyncImage
import com.pixelized.rplexicon.ui.composable.BackgroundImage
import com.pixelized.rplexicon.ui.composable.FullScreenImageHandler
import com.pixelized.rplexicon.ui.composable.FullScreenImageViewModel
import com.pixelized.rplexicon.ui.composable.rememberBackgroundGradient
@ -84,6 +89,7 @@ import com.pixelized.rplexicon.utilitary.annotate
import com.pixelized.rplexicon.utilitary.annotateWithDropCap
import com.pixelized.rplexicon.utilitary.dropCapRegex
import com.pixelized.rplexicon.utilitary.extentions.lexicon
import com.pixelized.rplexicon.utilitary.extentions.scrollOffset
import com.pixelized.rplexicon.utilitary.extentions.searchCriterion
import com.pixelized.rplexicon.utilitary.highlightRegex
import com.pixelized.rplexicon.utilitary.styleWith
@ -233,17 +239,22 @@ private fun LocationContent(
val highlightRegex = remember(highlight) { highlightRegex(terms = highlight.searchCriterion()) }
val dropCapRegex = remember { dropCapRegex() }
val mapSize = remember { mutableStateOf<IntSize?>(null) }
val filledIconButtonColors = IconButtonDefaults.filledIconButtonColors(
containerColor = MaterialTheme.colorScheme.surface,
contentColor = MaterialTheme.colorScheme.onSurface,
)
val filledIconToggleButtonColors = IconButtonDefaults.filledIconToggleButtonColors(
containerColor = MaterialTheme.colorScheme.surface,
contentColor = MaterialTheme.colorScheme.onSurface,
checkedContainerColor = MaterialTheme.colorScheme.primary,
checkedContentColor = MaterialTheme.colorScheme.onPrimary,
)
val backgroundUri = remember(item) {
derivedStateOf {
item.value?.illustrations?.firstOrNull()
}
}
Scaffold(
modifier = modifier,
@ -272,6 +283,7 @@ private fun LocationContent(
) {
if (item.value?.map != null) {
Surface(
modifier = Modifier.onSizeChanged { mapSize.value = it },
tonalElevation = 2.dp,
) {
Box(
@ -386,105 +398,121 @@ private fun LocationContent(
}
}
Column(
modifier = Modifier
.fillMaxWidth()
.heightIn(min = this@constraint.maxHeight)
.padding(vertical = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(space = 24.dp),
Box(
modifier = Modifier.clip(RectangleShape),
) {
Text(
modifier = Modifier.padding(horizontal = 16.dp),
style = MaterialTheme.typography.headlineSmall,
text = annotate(
text = item.value?.name ?: "",
dropCapRegex styleWith typography.headlineSmallDropCap,
highlightRegex styleWith typography.detail.highlightStyle,
),
)
item.value?.description?.let {
Text(
backgroundUri.value?.let { uri ->
BackgroundImage(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
style = MaterialTheme.typography.bodyMedium,
.aspectRatio(ratio = 1f)
.scrollOffset(scrollState = scrollState) {
val mapHeight = (mapSize.value?.height ?: 0).toDp()
min((mapHeight - it) / 2, 0.dp)
},
model = uri,
)
}
Column(
modifier = Modifier
.fillMaxWidth()
.heightIn(min = this@constraint.maxHeight)
.padding(vertical = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(space = 24.dp),
) {
Text(
modifier = Modifier.padding(horizontal = 16.dp),
style = MaterialTheme.typography.headlineSmall,
text = annotate(
text = it,
dropCapRegex styleWith typography.bodyMediumDropCap,
text = item.value?.name ?: "",
dropCapRegex styleWith typography.headlineSmallDropCap,
highlightRegex styleWith typography.detail.highlightStyle,
),
)
}
item.value?.illustrations?.takeIf { it.isNotEmpty() }?.let {
Column {
val maxSize = rememberMaxtWidth()
item.value?.description?.let {
Text(
modifier = Modifier
.padding(bottom = 8.dp)
.fillMaxWidth()
.padding(horizontal = 16.dp),
style = MaterialTheme.typography.titleMedium,
text = annotateWithDropCap(
text = stringResource(id = R.string.map_illustrations),
style = MaterialTheme.lexicon.typography.titleMediumDropCap,
)
style = MaterialTheme.typography.bodyMedium,
text = annotate(
text = it,
dropCapRegex styleWith typography.bodyMediumDropCap,
highlightRegex styleWith typography.detail.highlightStyle,
),
)
LazyRow(
contentPadding = PaddingValues(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
items(items = it) {
AsyncImage(
modifier = Modifier
.clickable { onIllustration(it) }
.sizeIn(
minWidth = maxSize / 2,
maxWidth = maxSize,
minHeight = maxSize,
maxHeight = maxSize,
),
contentScale = ContentScale.FillHeight,
model = it,
}
if (item.value?.marquees?.isNotEmpty() == true) {
Column {
Text(
modifier = Modifier
.padding(bottom = 8.dp)
.padding(horizontal = 16.dp),
style = MaterialTheme.typography.titleMedium,
text = annotateWithDropCap(
text = stringResource(id = R.string.map_destination),
style = MaterialTheme.lexicon.typography.titleMediumDropCap,
)
)
item.value?.marquees?.forEach {
Row(
modifier = Modifier
.clickable { onDestination(it) }
.minimumInteractiveComponentSize()
.fillMaxWidth()
.padding(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
) {
Text(
modifier = Modifier.alignByBaseline(),
style = MaterialTheme.typography.bodyMedium,
text = LOS_FULL
)
Text(
modifier = Modifier.alignByBaseline(),
style = MaterialTheme.typography.bodyMedium,
text = annotate(
text = it.name,
dropCapRegex styleWith typography.bodyMediumDropCap,
highlightRegex styleWith typography.detail.highlightStyle,
),
)
}
}
}
}
}
if (item.value?.marquees?.isNotEmpty() == true) {
Column {
Text(
modifier = Modifier
.padding(bottom = 8.dp)
.padding(horizontal = 16.dp),
style = MaterialTheme.typography.titleMedium,
text = annotateWithDropCap(
text = stringResource(id = R.string.map_destination),
style = MaterialTheme.lexicon.typography.titleMediumDropCap,
)
)
item.value?.marquees?.forEach {
Row(
item.value?.illustrations?.takeIf { it.isNotEmpty() }?.let {
Column {
val maxSize = rememberMaxtWidth()
Text(
modifier = Modifier
.clickable { onDestination(it) }
.minimumInteractiveComponentSize()
.fillMaxWidth()
.padding(bottom = 8.dp)
.padding(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
style = MaterialTheme.typography.titleMedium,
text = annotateWithDropCap(
text = stringResource(id = R.string.map_illustrations),
style = MaterialTheme.lexicon.typography.titleMediumDropCap,
)
)
LazyRow(
contentPadding = PaddingValues(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
Text(
modifier = Modifier.alignByBaseline(),
style = MaterialTheme.typography.bodyMedium,
text = LOS_FULL
)
Text(
modifier = Modifier.alignByBaseline(),
style = MaterialTheme.typography.bodyMedium,
text = annotate(
text = it.name,
dropCapRegex styleWith typography.bodyMediumDropCap,
highlightRegex styleWith typography.detail.highlightStyle,
),
)
items(items = it) {
AsyncImage(
modifier = Modifier
.clickable { onIllustration(it) }
.sizeIn(
minWidth = maxSize / 2,
maxWidth = maxSize,
minHeight = maxSize,
maxHeight = maxSize,
),
contentScale = ContentScale.FillHeight,
model = it,
)
}
}
}
}

View file

@ -38,6 +38,7 @@ import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.google.accompanist.placeholder.PlaceholderHighlight
@ -99,7 +100,7 @@ fun Modifier.cell() = composed {
@Stable
fun Modifier.scrollOffset(
scrollState: ScrollState,
block: (Dp) -> Dp
block: Density.(Dp) -> Dp
): Modifier = composed {
val density = LocalDensity.current
this.offset(y = with(density) { block(scrollState.value.toDp()) })