remove debug isTv hardcode, update ui
This commit is contained in:
+8
-23
@@ -150,18 +150,14 @@ fun VideosInfo(
|
|||||||
val requester = remember { FocusRequester() }
|
val requester = remember { FocusRequester() }
|
||||||
val blur = LocalBlurState.current
|
val blur = LocalBlurState.current
|
||||||
val gridState = rememberLazyGridState()
|
val gridState = rememberLazyGridState()
|
||||||
|
Box(modifier = Modifier.fillMaxSize().padding(4.dp)) {
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
|
||||||
if (items.isNotEmpty()) {
|
if (items.isNotEmpty()) {
|
||||||
LazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
columns = GridCells.Adaptive(minSize = 130.dp),
|
columns = GridCells.Adaptive(minSize = 130.dp),
|
||||||
modifier = Modifier
|
modifier = Modifier.fillMaxSize().applyBlurSource(blur),
|
||||||
.fillMaxSize()
|
|
||||||
.padding(8.dp)
|
|
||||||
.applyBlurSource(blur),
|
|
||||||
contentPadding = paddingValues,
|
contentPadding = paddingValues,
|
||||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
state = gridState
|
state = gridState
|
||||||
) {
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
@@ -181,8 +177,6 @@ fun VideosInfo(
|
|||||||
VideosNotFound(emptyResource)
|
VideosNotFound(emptyResource)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Мягкий фокус без withFrameNanos, реагирующий на появление данных
|
|
||||||
LaunchedEffect(items.isNotEmpty()) {
|
LaunchedEffect(items.isNotEmpty()) {
|
||||||
if (items.isNotEmpty()) {
|
if (items.isNotEmpty()) {
|
||||||
requester.requestFocus()
|
requester.requestFocus()
|
||||||
@@ -199,21 +193,18 @@ fun Poster(
|
|||||||
) {
|
) {
|
||||||
var isFocused by remember { mutableStateOf(false) }
|
var isFocused by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
// Анимируем увеличение карточки при фокусе (эффект для ТВ)
|
|
||||||
val scale by animateFloatAsState(
|
val scale by animateFloatAsState(
|
||||||
targetValue = if (isFocused) 1.08f else 1.0f,
|
targetValue = if (isFocused) 1.0f else 0.92f,
|
||||||
animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
|
animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
|
||||||
label = "scale"
|
label = "scale"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Плавная анимация цвета обводки
|
|
||||||
val borderColor by animateColorAsState(
|
val borderColor by animateColorAsState(
|
||||||
targetValue = if (isFocused) MaterialTheme.colorScheme.primary else Color.Transparent,
|
targetValue = if (isFocused) MaterialTheme.colorScheme.primary else Color.Transparent,
|
||||||
animationSpec = tween(200),
|
animationSpec = tween(200),
|
||||||
label = "borderColor"
|
label = "borderColor"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Плавная анимация толщины обводки
|
|
||||||
val borderWidth by animateDpAsState(
|
val borderWidth by animateDpAsState(
|
||||||
targetValue = if (isFocused) 3.dp else 0.dp,
|
targetValue = if (isFocused) 3.dp else 0.dp,
|
||||||
animationSpec = tween(200),
|
animationSpec = tween(200),
|
||||||
@@ -222,9 +213,8 @@ fun Poster(
|
|||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.aspectRatio(0.7f) // Стандартное кинематографическое соотношение для постеров
|
.aspectRatio(0.7f)
|
||||||
.graphicsLayer {
|
.graphicsLayer {
|
||||||
// Применяем масштаб и скругление на уровне слоя (работает максимально быстро)
|
|
||||||
scaleX = scale
|
scaleX = scale
|
||||||
scaleY = scale
|
scaleY = scale
|
||||||
clip = true
|
clip = true
|
||||||
@@ -238,27 +228,22 @@ fun Poster(
|
|||||||
)
|
)
|
||||||
.clickable(onClick = onClick)
|
.clickable(onClick = onClick)
|
||||||
) {
|
) {
|
||||||
// Картинка постера
|
|
||||||
Image(
|
Image(
|
||||||
painter = rememberImagePainter(imageUrl),
|
painter = rememberImagePainter(imageUrl),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Оптимизированный затемняющий градиент (снизу вверх)
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(
|
.background(
|
||||||
Brush.verticalGradient(
|
Brush.verticalGradient(
|
||||||
0.4f to Color.Transparent, // До 40% высоты прозрачно
|
0.4f to Color.Transparent,
|
||||||
1.0f to Color.Black.copy(alpha = 0.85f) // К низу плотное затемнение
|
1.0f to Color.Black.copy(alpha = 0.85f)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Текст названия фильма/сериала
|
|
||||||
Text(
|
Text(
|
||||||
text = label,
|
text = label,
|
||||||
style = MaterialTheme.typography.bodyMedium.copy(
|
style = MaterialTheme.typography.bodyMedium.copy(
|
||||||
|
|||||||
+5
-2
@@ -4,11 +4,14 @@ import android.app.UiModeManager
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
actual fun isTv(): Boolean {
|
actual fun isTv(): Boolean {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val uiModeManager = context.getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
|
return remember(context) {
|
||||||
return uiModeManager.currentModeType == Configuration.UI_MODE_TYPE_TELEVISION
|
val uiModeManager = context.getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
|
||||||
|
uiModeManager.currentModeType == Configuration.UI_MODE_TYPE_TELEVISION
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
|||||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialExpressiveTheme
|
import androidx.compose.material3.MaterialExpressiveTheme
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.NavigationBar
|
import androidx.compose.material3.NavigationBar
|
||||||
import androidx.compose.material3.NavigationBarItem
|
import androidx.compose.material3.NavigationBarItem
|
||||||
import androidx.compose.material3.NavigationRail
|
import androidx.compose.material3.NavigationRail
|
||||||
@@ -161,10 +160,7 @@ private fun <T : Route> ExpandedContent(
|
|||||||
val bottomPadding = values.calculateBottomPadding()
|
val bottomPadding = values.calculateBottomPadding()
|
||||||
val endPadding = values.calculateEndPadding(LayoutDirection.Ltr)
|
val endPadding = values.calculateEndPadding(LayoutDirection.Ltr)
|
||||||
Row(modifier = Modifier.fillMaxSize()) {
|
Row(modifier = Modifier.fillMaxSize()) {
|
||||||
NavigationRail(
|
NavigationRail(modifier = Modifier.padding(start = 4.dp, end = 4.dp, top = topPadding)) {
|
||||||
modifier = Modifier.padding(start = 4.dp, end = 4.dp, top = topPadding),
|
|
||||||
containerColor = MaterialTheme.colorScheme.surfaceContainerLow
|
|
||||||
) {
|
|
||||||
navigationEntries.forEach { entry ->
|
navigationEntries.forEach { entry ->
|
||||||
NavigationRailItem(
|
NavigationRailItem(
|
||||||
selected = currentRoute == entry.route,
|
selected = currentRoute == entry.route,
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ fun AlertContent(
|
|||||||
@Composable
|
@Composable
|
||||||
fun BaseDialogLayout() {
|
fun BaseDialogLayout() {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.padding(8.dp),
|
modifier = Modifier.padding(16.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(6.dp)
|
verticalArrangement = Arrangement.spacedBy(6.dp)
|
||||||
) {
|
) {
|
||||||
title?.let {
|
title?.let {
|
||||||
@@ -51,9 +51,10 @@ fun AlertContent(
|
|||||||
) {
|
) {
|
||||||
Surface(
|
Surface(
|
||||||
shape = MaterialTheme.shapes.extraLarge,
|
shape = MaterialTheme.shapes.extraLarge,
|
||||||
color = MaterialTheme.colorScheme.surface,
|
color = MaterialTheme.colorScheme.surface
|
||||||
tonalElevation = 6.dp
|
) {
|
||||||
) { BaseDialogLayout() }
|
BaseDialogLayout()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ModalBottomSheet(
|
ModalBottomSheet(
|
||||||
|
|||||||
Reference in New Issue
Block a user