Tighten TV home hero and bring-in-view offset

This commit is contained in:
2026-04-19 20:07:08 +02:00
parent 76eebc1139
commit 52a51b1b28
4 changed files with 108 additions and 52 deletions

View File

@@ -43,7 +43,7 @@ fun TvHomeScreen(
) { ) {
TvFocusedItemHero( TvFocusedItemHero(
item = focusedMediaUiModel.value, item = focusedMediaUiModel.value,
height = 250.dp height = 220.dp
) )
TvHomeContent( TvHomeContent(
libraries = libraries, libraries = libraries,

View File

@@ -6,7 +6,7 @@ import androidx.compose.foundation.gestures.BringIntoViewSpec
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import kotlin.math.abs import kotlin.math.abs
internal val TvHomeFocusedItemTopOffset = 56.dp internal val TvHomeFocusedItemTopOffset = 42.dp
internal val TvHomeBringIntoViewTrailingSpace = 120.dp internal val TvHomeBringIntoViewTrailingSpace = 120.dp
private const val TvHomeRowPivotParentFraction = 0.3f private const val TvHomeRowPivotParentFraction = 0.3f

View File

@@ -3,6 +3,7 @@
package hu.bbara.purefin.ui.screen.home.components package hu.bbara.purefin.ui.screen.home.components
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.LocalBringIntoViewSpec
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@@ -11,9 +12,11 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import hu.bbara.purefin.core.ui.model.MediaUiModel import hu.bbara.purefin.core.ui.model.MediaUiModel
@@ -37,12 +40,15 @@ fun TvHomeContent(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val scheme = MaterialTheme.colorScheme val scheme = MaterialTheme.colorScheme
val topOffsetPx = with(LocalDensity.current) { TvHomeFocusedItemTopOffset.toPx() }
val hasContinueWatching = continueWatching.isNotEmpty() val hasContinueWatching = continueWatching.isNotEmpty()
val hasNextUp = nextUp.isNotEmpty() val hasNextUp = nextUp.isNotEmpty()
val hasVisibleContent = hasContinueWatching || hasNextUp val hasVisibleContent = hasContinueWatching || hasNextUp
val initialFocusRequester = remember { FocusRequester() } val initialFocusRequester = remember { FocusRequester() }
CompositionLocalProvider(
LocalBringIntoViewSpec provides tvHomeColumnBringIntoViewSpec(topOffsetPx)
) {
LazyColumn( LazyColumn(
modifier = modifier modifier = modifier
.fillMaxSize() .fillMaxSize()
@@ -83,7 +89,7 @@ fun TvHomeContent(
itemsIndexed( itemsIndexed(
items = libraries, items = libraries,
key = { _, library -> library.id } key = { _, library -> library.id }
) { index, library -> ) { _, library ->
TvLibraryPosterSection( TvLibraryPosterSection(
title = library.name, title = library.name,
items = libraryContent[library.id].orEmpty(), items = libraryContent[library.id].orEmpty(),
@@ -102,3 +108,4 @@ fun TvHomeContent(
} }
} }
} }
}

View File

@@ -0,0 +1,49 @@
package hu.bbara.purefin.ui.screen.home.components
import org.junit.Assert.assertEquals
import org.junit.Test
class TvHomeBringIntoViewSpecTest {
private val topOffsetPx = 56f
private val spec = tvHomeColumnBringIntoViewSpec(topOffsetPx)
@Test
fun returnsZero_whenFocusedItemAlreadyAtTopOffset() {
assertEquals(
0f,
spec.calculateScrollDistance(
offset = topOffsetPx,
size = 52f,
containerSize = 240f
),
0.0001f
)
}
@Test
fun scrollsDownToTopOffset_whenFocusedItemIsBelowTarget() {
assertEquals(
64f,
spec.calculateScrollDistance(
offset = 120f,
size = 52f,
containerSize = 240f
),
0.0001f
)
}
@Test
fun scrollsUpToTopOffset_whenFocusedItemIsAboveTarget() {
assertEquals(
-32f,
spec.calculateScrollDistance(
offset = 24f,
size = 52f,
containerSize = 240f
),
0.0001f
)
}
}