diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 818b6f0..4d342f5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -64,7 +64,7 @@ val projectNoticeText = // A release workflow can derive the app version from its Git tag without editing the // source tree. Local builds keep using the checked-in default. -val defaultVersionName = "0.2.87" +val defaultVersionName = "0.2.88" val membyVersionName: String = (project.findProperty("memby.versionName") as String?) ?.trim() diff --git a/app/src/main/java/com/ponzischeme89/memby/ui/HomeComponents.kt b/app/src/main/java/com/ponzischeme89/memby/ui/HomeComponents.kt index 0baee24..6b75c21 100644 --- a/app/src/main/java/com/ponzischeme89/memby/ui/HomeComponents.kt +++ b/app/src/main/java/com/ponzischeme89/memby/ui/HomeComponents.kt @@ -1124,9 +1124,9 @@ internal fun MetadataHero( .clipToBounds() .background( Brush.verticalGradient( - 0f to MembySurface.copy(alpha = 0.52f), - 0.72f to MembySurface.copy(alpha = 0.30f), - 1f to Color.Transparent, + 0f to MembySurface.copy(alpha = 0.68f), + 0.72f to MembySurface.copy(alpha = 0.46f), + 1f to MembySurface.copy(alpha = 0.16f), ), ), ) { diff --git a/app/src/main/java/com/ponzischeme89/memby/ui/HomeScreen.kt b/app/src/main/java/com/ponzischeme89/memby/ui/HomeScreen.kt index 06b240e..9963e4c 100644 --- a/app/src/main/java/com/ponzischeme89/memby/ui/HomeScreen.kt +++ b/app/src/main/java/com/ponzischeme89/memby/ui/HomeScreen.kt @@ -166,9 +166,9 @@ internal fun homeHeaderHeight(viewportHeight: Dp, showHero: Boolean): Dp = (viewportHeight * 0.46f).coerceIn(232.dp, 300.dp) } else { // The focused metadata surface is also the clean upper boundary for shelves as - // they move vertically. About 20dp more coverage at common TV heights keeps a - // departing card's last text line from being exposed without costing another row. - (viewportHeight * 0.46f).coerceIn(240.dp, 320.dp) + // they move vertically. Give it a little more room than the cinematic hero so the + // title, ratings and overview read as one persistent browse panel. + (viewportHeight * 0.48f).coerceIn(250.dp, 330.dp) } private val LazyListStateMapSaver: Saver, Any> = listSaver( diff --git a/app/src/test/java/com/ponzischeme89/memby/ui/HomeMovieHeroScreenshotTest.kt b/app/src/test/java/com/ponzischeme89/memby/ui/HomeMovieHeroScreenshotTest.kt index 5d4d979..fb219f5 100644 --- a/app/src/test/java/com/ponzischeme89/memby/ui/HomeMovieHeroScreenshotTest.kt +++ b/app/src/test/java/com/ponzischeme89/memby/ui/HomeMovieHeroScreenshotTest.kt @@ -12,8 +12,10 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -33,6 +35,7 @@ import androidx.tv.material3.Text import com.github.takahirom.roborazzi.captureRoboImage import com.ponzischeme89.memby.ServiceLocator import com.ponzischeme89.memby.data.model.BaseItem +import com.ponzischeme89.memby.data.model.MediaRating import org.junit.Before import org.junit.Assert.assertTrue import org.junit.Rule @@ -154,6 +157,11 @@ class HomeMovieHeroScreenshotTest { 2026, "Beyond the mapped worlds, one explorer finds an ocean that remembers every visitor.", 8.7, + ).copy( + membyRatings = listOf( + MediaRating(source = "imdb", name = "IMDb", score = "8.7", scale = "/10"), + MediaRating(source = "tomatoes", name = "Rotten Tomatoes", score = "93", scale = "%"), + ), ) compose.setContent { @@ -165,46 +173,58 @@ class HomeMovieHeroScreenshotTest { contentScale = ContentScale.Crop, modifier = Modifier.fillMaxSize(), ) - Column(Modifier.fillMaxSize()) { - MetadataHero( - item = item, - loading = false, - sectionLabel = "Movies", - modifier = Modifier - .height(homeHeaderHeight(540.dp, showHero = false)) - .zIndex(1f), + Row(Modifier.fillMaxSize()) { + TvNavigationRail( + selected = BrowseDestination.MOVIES, + expanded = true, + navigationFocusRequester = remember { FocusRequester() }, + onRailFocusChanged = {}, + onDestinationSelected = {}, + activeUsername = "Matt", + calendarEnabled = true, + genresEnabled = true, ) - Text( - "Matt's Favourites", - color = Color(0xFFF1F3F4), - fontSize = 18.sp, - modifier = Modifier.padding(start = 36.dp, top = 8.dp, bottom = 10.dp), - ) - Row( - modifier = Modifier.fillMaxWidth().padding(horizontal = 36.dp), - horizontalArrangement = Arrangement.spacedBy(12.dp), - ) { - repeat(5) { index -> - Column(Modifier.weight(1f)) { - Box( - Modifier - .fillMaxWidth() - .aspectRatio(16f / 9f) - .clip(RoundedCornerShape(7.dp)) - .background(Color(0xFF27343D)), - ) - Text( - "Favourite ${index + 1}", - color = Color.White, - fontSize = 13.sp, - modifier = Modifier.padding(top = 6.dp), - ) - Text( - "2026 • 1h 47m", - color = Color(0xFF8F9AA3), - fontSize = 11.sp, - modifier = Modifier.padding(top = 2.dp), - ) + Column(Modifier.weight(1f).offset(x = 112.dp)) { + MetadataHero( + item = item, + loading = false, + sectionLabel = "Movies", + modifier = Modifier + .height(homeHeaderHeight(540.dp, showHero = false)) + .zIndex(1f), + ) + Text( + "Matt's Favourites", + color = Color(0xFFF1F3F4), + fontSize = 18.sp, + modifier = Modifier.padding(start = 36.dp, top = 8.dp, bottom = 10.dp), + ) + Row( + modifier = Modifier.fillMaxWidth().padding(horizontal = 36.dp), + horizontalArrangement = Arrangement.spacedBy(12.dp), + ) { + repeat(5) { index -> + Column(Modifier.weight(1f)) { + Box( + Modifier + .fillMaxWidth() + .aspectRatio(16f / 9f) + .clip(RoundedCornerShape(7.dp)) + .background(Color(0xFF27343D)), + ) + Text( + "Favourite ${index + 1}", + color = Color.White, + fontSize = 13.sp, + modifier = Modifier.padding(top = 6.dp), + ) + Text( + "2026 • 1h 47m", + color = Color(0xFF8F9AA3), + fontSize = 11.sp, + modifier = Modifier.padding(top = 2.dp), + ) + } } } } diff --git a/app/src/test/java/com/ponzischeme89/memby/ui/HomeMovieHeroTest.kt b/app/src/test/java/com/ponzischeme89/memby/ui/HomeMovieHeroTest.kt index e3a34af..d94afda 100644 --- a/app/src/test/java/com/ponzischeme89/memby/ui/HomeMovieHeroTest.kt +++ b/app/src/test/java/com/ponzischeme89/memby/ui/HomeMovieHeroTest.kt @@ -43,12 +43,13 @@ class HomeMovieHeroTest { } @Test - fun `metadata hero adds a modest scalable row boundary`() { + fun `metadata hero is slightly taller than the cinematic hero`() { val compactTvHeight = homeHeaderHeight(540.dp, showHero = false) - assertEquals(248.4f, compactTvHeight.value, 0.01f) - assertTrue(540.dp - compactTvHeight >= 288.dp) - assertEquals(320f, homeHeaderHeight(720.dp, showHero = false).value, 0.01f) + assertEquals(259.2f, compactTvHeight.value, 0.01f) + assertTrue(compactTvHeight > homeHeaderHeight(540.dp, showHero = true)) + assertTrue(540.dp - compactTvHeight >= 280.dp) + assertEquals(330f, homeHeaderHeight(720.dp, showHero = false).value, 0.01f) } @Test