meta hero layout changes

This commit is contained in:
tapframe 2026-04-01 18:31:41 +05:30
parent 3a54098907
commit b8f7ebdc4b
3 changed files with 417 additions and 359 deletions

View file

@ -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(

View file

@ -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),

View file

@ -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)
}