mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-28 03:43:02 +00:00
meta hero layout changes
This commit is contained in:
parent
3a54098907
commit
b8f7ebdc4b
3 changed files with 417 additions and 359 deletions
|
|
@ -9,6 +9,7 @@ import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
|
@ -18,6 +19,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.layout.statusBars
|
import androidx.compose.foundation.layout.statusBars
|
||||||
|
|
@ -46,6 +48,7 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.nuvio.app.core.ui.NuvioBackButton
|
import com.nuvio.app.core.ui.NuvioBackButton
|
||||||
|
|
@ -306,6 +309,11 @@ fun MetaDetailsScreen(
|
||||||
label = "detail_floating_header_progress",
|
label = "detail_floating_header_progress",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
BoxWithConstraints(modifier = Modifier.fillMaxSize()) {
|
||||||
|
val isTablet = maxWidth >= 720.dp
|
||||||
|
val contentHorizontalPadding = if (isTablet) 32.dp else 18.dp
|
||||||
|
val contentMaxWidth = detailTabletContentMaxWidth(maxWidth, isTablet)
|
||||||
|
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
@ -314,6 +322,8 @@ fun MetaDetailsScreen(
|
||||||
) {
|
) {
|
||||||
DetailHero(
|
DetailHero(
|
||||||
meta = meta,
|
meta = meta,
|
||||||
|
isTablet = isTablet,
|
||||||
|
contentMaxWidth = contentMaxWidth,
|
||||||
scrollOffset = scrollState.value,
|
scrollOffset = scrollState.value,
|
||||||
onHeightChanged = { heroHeightPx = it },
|
onHeightChanged = { heroHeightPx = it },
|
||||||
)
|
)
|
||||||
|
|
@ -321,13 +331,16 @@ fun MetaDetailsScreen(
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 18.dp),
|
.padding(horizontal = contentHorizontalPadding)
|
||||||
|
.widthIn(max = if (isTablet) contentMaxWidth else Dp.Unspecified),
|
||||||
verticalArrangement = Arrangement.spacedBy(20.dp),
|
verticalArrangement = Arrangement.spacedBy(20.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
DetailActionButtons(
|
DetailActionButtons(
|
||||||
playLabel = playButtonLabel,
|
playLabel = playButtonLabel,
|
||||||
saveLabel = if (isSaved) "Saved" else "Save",
|
saveLabel = if (isSaved) "Saved" else "Save",
|
||||||
isSaved = isSaved,
|
isSaved = isSaved,
|
||||||
|
isTablet = isTablet,
|
||||||
onPlayClick = {
|
onPlayClick = {
|
||||||
when {
|
when {
|
||||||
(meta.type == "series" || hasEpisodes) && seriesAction != null -> {
|
(meta.type == "series" || hasEpisodes) && seriesAction != null -> {
|
||||||
|
|
@ -600,12 +613,12 @@ fun MetaDetailsScreen(
|
||||||
}
|
}
|
||||||
pickerPending = false
|
pickerPending = false
|
||||||
}
|
}
|
||||||
Unit
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (requestedMeta == null) {
|
if (requestedMeta == null) {
|
||||||
NuvioBackButton(
|
NuvioBackButton(
|
||||||
|
|
@ -621,6 +634,13 @@ fun MetaDetailsScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun detailTabletContentMaxWidth(maxWidth: Dp, isTablet: Boolean): Dp =
|
||||||
|
if (!isTablet) {
|
||||||
|
maxWidth
|
||||||
|
} else {
|
||||||
|
(maxWidth * 0.6f).coerceIn(520.dp, 680.dp)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
private fun TraktListPickerDialog(
|
private fun TraktListPickerDialog(
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedButton
|
import androidx.compose.material3.OutlinedButton
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
@ -30,6 +31,7 @@ fun DetailActionButtons(
|
||||||
playLabel: String = "Play",
|
playLabel: String = "Play",
|
||||||
saveLabel: String = "Save",
|
saveLabel: String = "Save",
|
||||||
isSaved: Boolean = false,
|
isSaved: Boolean = false,
|
||||||
|
isTablet: Boolean = false,
|
||||||
onPlayClick: () -> Unit = {},
|
onPlayClick: () -> Unit = {},
|
||||||
onSaveClick: () -> Unit = {},
|
onSaveClick: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
|
|
@ -38,12 +40,22 @@ fun DetailActionButtons(
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = modifier.fillMaxWidth(),
|
modifier = modifier.fillMaxWidth(),
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
horizontalArrangement = if (isTablet) {
|
||||||
|
Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally)
|
||||||
|
} else {
|
||||||
|
Arrangement.spacedBy(12.dp)
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
Button(
|
Button(
|
||||||
onClick = onPlayClick,
|
onClick = onPlayClick,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.then(
|
||||||
|
if (isTablet) {
|
||||||
|
Modifier.width(220.dp)
|
||||||
|
} else {
|
||||||
|
Modifier.weight(1f)
|
||||||
|
}
|
||||||
|
)
|
||||||
.height(50.dp),
|
.height(50.dp),
|
||||||
shape = RoundedCornerShape(40.dp),
|
shape = RoundedCornerShape(40.dp),
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
|
@ -68,7 +80,13 @@ fun DetailActionButtons(
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onClick = onSaveClick,
|
onClick = onSaveClick,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.then(
|
||||||
|
if (isTablet) {
|
||||||
|
Modifier.width(220.dp)
|
||||||
|
} else {
|
||||||
|
Modifier.weight(1f)
|
||||||
|
}
|
||||||
|
)
|
||||||
.height(50.dp),
|
.height(50.dp),
|
||||||
shape = RoundedCornerShape(40.dp),
|
shape = RoundedCornerShape(40.dp),
|
||||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline),
|
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline),
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,14 @@ package com.nuvio.app.features.details.components
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
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.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
|
@ -19,6 +20,7 @@ import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.layout.onSizeChanged
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import coil3.compose.AsyncImage
|
import coil3.compose.AsyncImage
|
||||||
|
|
@ -27,14 +29,21 @@ import com.nuvio.app.features.details.MetaDetails
|
||||||
@Composable
|
@Composable
|
||||||
fun DetailHero(
|
fun DetailHero(
|
||||||
meta: MetaDetails,
|
meta: MetaDetails,
|
||||||
|
isTablet: Boolean = false,
|
||||||
scrollOffset: Int = 0,
|
scrollOffset: Int = 0,
|
||||||
|
contentMaxWidth: Dp = 560.dp,
|
||||||
onHeightChanged: (Int) -> Unit = {},
|
onHeightChanged: (Int) -> Unit = {},
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
BoxWithConstraints(
|
||||||
|
modifier = modifier.fillMaxWidth(),
|
||||||
|
) {
|
||||||
|
val heroHeight = detailHeroHeight(maxWidth, isTablet)
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.aspectRatio(0.75f)
|
.height(heroHeight)
|
||||||
.onSizeChanged { onHeightChanged(it.height) }
|
.onSizeChanged { onHeightChanged(it.height) }
|
||||||
.graphicsLayer {
|
.graphicsLayer {
|
||||||
clip = true
|
clip = true
|
||||||
|
|
@ -57,6 +66,7 @@ fun DetailHero(
|
||||||
scaleX = 1.08f
|
scaleX = 1.08f
|
||||||
scaleY = 1.08f
|
scaleY = 1.08f
|
||||||
},
|
},
|
||||||
|
alignment = if (isTablet) Alignment.TopCenter else Alignment.Center,
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -86,7 +96,7 @@ fun DetailHero(
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 18.dp)
|
.padding(horizontal = if (isTablet) 32.dp else 18.dp)
|
||||||
.padding(bottom = 8.dp),
|
.padding(bottom = 8.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
|
|
@ -95,14 +105,16 @@ fun DetailHero(
|
||||||
model = meta.logo,
|
model = meta.logo,
|
||||||
contentDescription = "${meta.name} logo",
|
contentDescription = "${meta.name} logo",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth(0.6f)
|
.fillMaxWidth(if (isTablet) 0.56f else 0.6f)
|
||||||
.height(80.dp),
|
.widthIn(max = contentMaxWidth)
|
||||||
|
.height(if (isTablet) 72.dp else 80.dp),
|
||||||
|
alignment = Alignment.Center,
|
||||||
contentScale = ContentScale.Fit,
|
contentScale = ContentScale.Fit,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Text(
|
Text(
|
||||||
text = meta.name,
|
text = meta.name,
|
||||||
style = MaterialTheme.typography.displayLarge,
|
style = if (isTablet) MaterialTheme.typography.displaySmall else MaterialTheme.typography.displayLarge,
|
||||||
color = MaterialTheme.colorScheme.onBackground,
|
color = MaterialTheme.colorScheme.onBackground,
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
)
|
)
|
||||||
|
|
@ -121,3 +133,11 @@ fun DetailHero(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun detailHeroHeight(maxWidth: Dp, isTablet: Boolean): Dp =
|
||||||
|
if (!isTablet) {
|
||||||
|
(maxWidth * 1.33f).coerceIn(420.dp, 760.dp)
|
||||||
|
} else {
|
||||||
|
(maxWidth * 0.42f).coerceIn(300.dp, 420.dp)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue