Add background for quest screen.
This commit is contained in:
parent
2eff9f8e2f
commit
eaa4fcf8e9
2 changed files with 112 additions and 83 deletions
|
|
@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.BoxWithConstraints
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.heightIn
|
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.NestedScrollConnection
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
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.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.IntOffset
|
import androidx.compose.ui.unit.IntOffset
|
||||||
|
import androidx.compose.ui.unit.IntSize
|
||||||
import androidx.compose.ui.unit.Velocity
|
import androidx.compose.ui.unit.Velocity
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.min
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import com.pixelized.rplexicon.LocalSnack
|
import com.pixelized.rplexicon.LocalSnack
|
||||||
import com.pixelized.rplexicon.R
|
import com.pixelized.rplexicon.R
|
||||||
import com.pixelized.rplexicon.ui.composable.AsyncImage
|
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.FullScreenImageHandler
|
||||||
import com.pixelized.rplexicon.ui.composable.FullScreenImageViewModel
|
import com.pixelized.rplexicon.ui.composable.FullScreenImageViewModel
|
||||||
import com.pixelized.rplexicon.ui.composable.rememberBackgroundGradient
|
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.annotateWithDropCap
|
||||||
import com.pixelized.rplexicon.utilitary.dropCapRegex
|
import com.pixelized.rplexicon.utilitary.dropCapRegex
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.lexicon
|
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.extentions.searchCriterion
|
||||||
import com.pixelized.rplexicon.utilitary.highlightRegex
|
import com.pixelized.rplexicon.utilitary.highlightRegex
|
||||||
import com.pixelized.rplexicon.utilitary.styleWith
|
import com.pixelized.rplexicon.utilitary.styleWith
|
||||||
|
|
@ -233,17 +239,22 @@ private fun LocationContent(
|
||||||
val highlightRegex = remember(highlight) { highlightRegex(terms = highlight.searchCriterion()) }
|
val highlightRegex = remember(highlight) { highlightRegex(terms = highlight.searchCriterion()) }
|
||||||
val dropCapRegex = remember { dropCapRegex() }
|
val dropCapRegex = remember { dropCapRegex() }
|
||||||
|
|
||||||
|
val mapSize = remember { mutableStateOf<IntSize?>(null) }
|
||||||
val filledIconButtonColors = IconButtonDefaults.filledIconButtonColors(
|
val filledIconButtonColors = IconButtonDefaults.filledIconButtonColors(
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
contentColor = MaterialTheme.colorScheme.onSurface,
|
contentColor = MaterialTheme.colorScheme.onSurface,
|
||||||
)
|
)
|
||||||
|
|
||||||
val filledIconToggleButtonColors = IconButtonDefaults.filledIconToggleButtonColors(
|
val filledIconToggleButtonColors = IconButtonDefaults.filledIconToggleButtonColors(
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
contentColor = MaterialTheme.colorScheme.onSurface,
|
contentColor = MaterialTheme.colorScheme.onSurface,
|
||||||
checkedContainerColor = MaterialTheme.colorScheme.primary,
|
checkedContainerColor = MaterialTheme.colorScheme.primary,
|
||||||
checkedContentColor = MaterialTheme.colorScheme.onPrimary,
|
checkedContentColor = MaterialTheme.colorScheme.onPrimary,
|
||||||
)
|
)
|
||||||
|
val backgroundUri = remember(item) {
|
||||||
|
derivedStateOf {
|
||||||
|
item.value?.illustrations?.firstOrNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
|
@ -272,6 +283,7 @@ private fun LocationContent(
|
||||||
) {
|
) {
|
||||||
if (item.value?.map != null) {
|
if (item.value?.map != null) {
|
||||||
Surface(
|
Surface(
|
||||||
|
modifier = Modifier.onSizeChanged { mapSize.value = it },
|
||||||
tonalElevation = 2.dp,
|
tonalElevation = 2.dp,
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
|
|
@ -386,105 +398,121 @@ private fun LocationContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier.clip(RectangleShape),
|
||||||
.fillMaxWidth()
|
|
||||||
.heightIn(min = this@constraint.maxHeight)
|
|
||||||
.padding(vertical = 16.dp),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
verticalArrangement = Arrangement.spacedBy(space = 24.dp),
|
|
||||||
) {
|
) {
|
||||||
Text(
|
backgroundUri.value?.let { uri ->
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
BackgroundImage(
|
||||||
style = MaterialTheme.typography.headlineSmall,
|
|
||||||
text = annotate(
|
|
||||||
text = item.value?.name ?: "",
|
|
||||||
dropCapRegex styleWith typography.headlineSmallDropCap,
|
|
||||||
highlightRegex styleWith typography.detail.highlightStyle,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
item.value?.description?.let {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 16.dp),
|
.aspectRatio(ratio = 1f)
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
.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 = annotate(
|
||||||
text = it,
|
text = item.value?.name ?: "",
|
||||||
dropCapRegex styleWith typography.bodyMediumDropCap,
|
dropCapRegex styleWith typography.headlineSmallDropCap,
|
||||||
highlightRegex styleWith typography.detail.highlightStyle,
|
highlightRegex styleWith typography.detail.highlightStyle,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
item.value?.description?.let {
|
||||||
item.value?.illustrations?.takeIf { it.isNotEmpty() }?.let {
|
|
||||||
Column {
|
|
||||||
val maxSize = rememberMaxtWidth()
|
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(bottom = 8.dp)
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 16.dp),
|
.padding(horizontal = 16.dp),
|
||||||
style = MaterialTheme.typography.titleMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
text = annotateWithDropCap(
|
text = annotate(
|
||||||
text = stringResource(id = R.string.map_illustrations),
|
text = it,
|
||||||
style = MaterialTheme.lexicon.typography.titleMediumDropCap,
|
dropCapRegex styleWith typography.bodyMediumDropCap,
|
||||||
)
|
highlightRegex styleWith typography.detail.highlightStyle,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
LazyRow(
|
}
|
||||||
contentPadding = PaddingValues(horizontal = 16.dp),
|
if (item.value?.marquees?.isNotEmpty() == true) {
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
Column {
|
||||||
) {
|
Text(
|
||||||
items(items = it) {
|
modifier = Modifier
|
||||||
AsyncImage(
|
.padding(bottom = 8.dp)
|
||||||
modifier = Modifier
|
.padding(horizontal = 16.dp),
|
||||||
.clickable { onIllustration(it) }
|
style = MaterialTheme.typography.titleMedium,
|
||||||
.sizeIn(
|
text = annotateWithDropCap(
|
||||||
minWidth = maxSize / 2,
|
text = stringResource(id = R.string.map_destination),
|
||||||
maxWidth = maxSize,
|
style = MaterialTheme.lexicon.typography.titleMediumDropCap,
|
||||||
minHeight = maxSize,
|
|
||||||
maxHeight = maxSize,
|
|
||||||
),
|
|
||||||
contentScale = ContentScale.FillHeight,
|
|
||||||
model = it,
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
item.value?.illustrations?.takeIf { it.isNotEmpty() }?.let {
|
||||||
if (item.value?.marquees?.isNotEmpty() == true) {
|
Column {
|
||||||
Column {
|
val maxSize = rememberMaxtWidth()
|
||||||
Text(
|
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
|
modifier = Modifier
|
||||||
.clickable { onDestination(it) }
|
.padding(bottom = 8.dp)
|
||||||
.minimumInteractiveComponentSize()
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 16.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(
|
items(items = it) {
|
||||||
modifier = Modifier.alignByBaseline(),
|
AsyncImage(
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
modifier = Modifier
|
||||||
text = LOS_FULL
|
.clickable { onIllustration(it) }
|
||||||
)
|
.sizeIn(
|
||||||
Text(
|
minWidth = maxSize / 2,
|
||||||
modifier = Modifier.alignByBaseline(),
|
maxWidth = maxSize,
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
minHeight = maxSize,
|
||||||
text = annotate(
|
maxHeight = maxSize,
|
||||||
text = it.name,
|
),
|
||||||
dropCapRegex styleWith typography.bodyMediumDropCap,
|
contentScale = ContentScale.FillHeight,
|
||||||
highlightRegex styleWith typography.detail.highlightStyle,
|
model = it,
|
||||||
),
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ import androidx.compose.ui.graphics.TransformOrigin
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
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 androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.google.accompanist.placeholder.PlaceholderHighlight
|
import com.google.accompanist.placeholder.PlaceholderHighlight
|
||||||
|
|
@ -99,7 +100,7 @@ fun Modifier.cell() = composed {
|
||||||
@Stable
|
@Stable
|
||||||
fun Modifier.scrollOffset(
|
fun Modifier.scrollOffset(
|
||||||
scrollState: ScrollState,
|
scrollState: ScrollState,
|
||||||
block: (Dp) -> Dp
|
block: Density.(Dp) -> Dp
|
||||||
): Modifier = composed {
|
): Modifier = composed {
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
this.offset(y = with(density) { block(scrollState.value.toDp()) })
|
this.offset(y = with(density) { block(scrollState.value.toDp()) })
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue