update poster in overview

This commit is contained in:
2026-07-27 21:49:23 +03:00
parent 32667ca9f3
commit 93a53967e3
@@ -13,7 +13,6 @@ import androiddev.apps.vbox.client.shared.generated.resources.star
import androiddev.apps.vbox.client.shared.generated.resources.star_unchecked
import androiddev.apps.vbox.client.shared.generated.resources.user_tags
import androiddev.apps.vbox.client.shared.generated.resources.watch
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.Spring
@@ -21,14 +20,21 @@ import androidx.compose.animation.core.spring
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
@@ -50,11 +56,13 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.withFrameNanos
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@@ -100,21 +108,19 @@ fun OverviewScreen(component: OverviewComponent) {
scrollBehavior = scrollBehavior,
snackbarState = snackbarState,
content = { padding ->
AnimatedContent(details) {
when {
when {
errorState != null -> ErrorAndRetry(
errorMsg = errorState!!
) { component.loadDetailsIfNeeded() }
errorState != null -> ErrorAndRetry(
errorMsg = errorState!!
) { component.loadDetailsIfNeeded() }
details != null -> DetailsInfo(
details = details!!,
paddingValues = padding,
onWatchClicked = { component.watch() }
)
details != null -> DetailsInfo(
details = details!!,
paddingValues = padding,
onWatchClicked = { component.watch() }
)
else -> Loading()
}
else -> Loading()
}
if (tagsBottomSheetVisible) {
@@ -261,7 +267,7 @@ fun DetailsInfo(
modifier = Modifier.applyBlurSource(blur),
contentPadding = paddingValues
) {
item { OverviewTitle(details) }
item { Poster(details.poster) }
item { OverviewDescription(details, showDetails) }
item {
Button(
@@ -274,8 +280,8 @@ fun DetailsInfo(
Text(stringResource(Res.string.watch))
}
// Чистый фокус без сдвига кадров через withFrameNanos
LaunchedEffect(Unit) {
withFrameNanos {}
requester.requestFocus()
}
}
@@ -291,7 +297,6 @@ private fun OverviewDescription(
modifier = Modifier
.fillMaxWidth()
.padding(4.dp)
// Самая важная магия: плавно анимирует высоту колонки при изменении maxLines текста
.animateContentSize(animationSpec = spring(stiffness = Spring.StiffnessMediumLow))
) {
Text(
@@ -307,7 +312,6 @@ private fun OverviewDescription(
overflow = TextOverflow.Ellipsis
)
// Вместо резкого 'if' плавно убираем кнопку разворачивания
AnimatedVisibility(
visible = !showDetails.value,
enter = fadeIn(),
@@ -319,7 +323,7 @@ private fun OverviewDescription(
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.primary,
modifier = Modifier
.padding(top = 8.dp) // Небольшой отступ сверху от основного текста
.padding(top = 8.dp)
.clickable { showDetails.value = true }
)
}
@@ -327,16 +331,49 @@ private fun OverviewDescription(
}
@Composable
private fun OverviewTitle(details: VideoDetails) {
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxWidth()) {
Image(
painter = rememberImagePainter(details.poster),
contentDescription = null,
modifier = Modifier
.padding(8.dp) // Добавим легкий отступ, чтобы картинка не липла к краям экрана
.clip(RoundedCornerShape(12.dp)), // На современных девайсах 12.dp выглядит аккуратнее, чем 8%
contentScale = ContentScale.Crop,
)
private fun Poster(posterUrl: String, modifier: Modifier = Modifier) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxWidth()
) {
Card(
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceContainerLow
),
elevation = CardDefaults.cardElevation(
defaultElevation = 4.dp
),
modifier = modifier.height(200.dp)
.aspectRatio(0.7f)
) {
Box(modifier = Modifier.fillMaxSize()) {
Image(
painter = rememberImagePainter(posterUrl),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
Box(
modifier = Modifier.fillMaxSize()
.background(
Brush.verticalGradient(
0.6f to Color.Transparent,
1.0f to Color.Black.copy(alpha = 0.6f)
)
)
)
Box(
modifier = Modifier.fillMaxSize()
.border(
width = 1.dp,
color = Color.White.copy(alpha = 0.15f),
shape = RoundedCornerShape(12.dp)
)
)
}
}
}
}