From e1948a823ff065f22e60433281f06ef97b1c94c6 Mon Sep 17 00:00:00 2001 From: Seb3thehacker Date: Mon, 26 Oct 2026 20:28:47 -0700 Subject: [PATCH] media: the tabs fill the header again, and the nav bar goes see-through over the player so the cover's glow runs behind it --- .../seb3thehacker/gearslip/car/CarNavBar.kt | 9 +++++-- .../app/seb3thehacker/gearslip/car/CarUi.kt | 9 ++++--- .../seb3thehacker/gearslip/car/MediaScreen.kt | 27 +++++++++---------- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/CarNavBar.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/CarNavBar.kt index 4ba38b3..462e777 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/CarNavBar.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/CarNavBar.kt @@ -167,8 +167,13 @@ internal fun CarNavBar(navigator: CarNavigator) { val running = rememberRunningApps() // A full-width strip along the bottom, casting the theme's panel shadow up onto the map so the - // bar sits above it rather than beside it. - Surface(Modifier.gsBarShadow(), color = MaterialTheme.colorScheme.surfaceContainer) { + // bar sits above it rather than beside it. Over the player it's see-through instead, so the + // player's background and the cover's glow carry on behind it. + val overPlayer = navigator.current == CarScreen.Media + Surface( + if (overPlayer) Modifier else Modifier.gsBarShadow(), + color = if (overPlayer) androidx.compose.ui.graphics.Color.Transparent else MaterialTheme.colorScheme.surfaceContainer, + ) { BoxWithConstraints(Modifier.fillMaxWidth().height(NAV_BAR_HEIGHT).padding(horizontal = 10.dp)) { Row(Modifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically) { // Home and Apps are two different places now, not a toggle on one button - the diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/CarUi.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/CarUi.kt index 1d86e4d..59d60f4 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/CarUi.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/CarUi.kt @@ -294,8 +294,9 @@ fun CarUi() { .fillMaxSize() .graphicsLayer { if (fromHome) alpha = enter.value } .background(MaterialTheme.colorScheme.background) - // The bar never hides here, so keep the screen clear of it. - .padding(bottom = if (!keyboardVisible && !fullscreen) NAV_BAR_HEIGHT else 0.dp) + // The bar never hides here, so keep the screen clear of it. The + // player runs on under the see-through bar and keeps clear itself. + .padding(bottom = if (!keyboardVisible && !fullscreen && screen != CarScreen.Media) NAV_BAR_HEIGHT else 0.dp) // Keeps touches that miss this screen's controls off the map. .pointerInput(Unit) { detectTapGestures { } }, ) { @@ -308,7 +309,9 @@ fun CarUi() { when (screen) { CarScreen.Home -> Unit CarScreen.Apps -> CarLauncher() - CarScreen.Media -> mediaApp?.let { MediaScreen(it) { navigator.back() } } + CarScreen.Media -> CompositionLocalProvider( + LocalNavBarInset provides if (!keyboardVisible && !fullscreen) NAV_BAR_HEIGHT else 0.dp, + ) { mediaApp?.let { MediaScreen(it) { navigator.back() } } } CarScreen.Browse -> BrowseAppScreen(navigator) CarScreen.Settings -> CarSettingsScreen() CarScreen.Dashboard -> CarDashboardScreen() diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/MediaScreen.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/MediaScreen.kt index 28c691a..f362eec 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/MediaScreen.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/MediaScreen.kt @@ -110,7 +110,7 @@ fun MediaScreen(app: MediaApp, onExit: () -> Unit) { Surface(Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { if (phase == CarMedia.Phase.READY && !searching) AlbumGlow(art, Modifier.fillMaxSize(), wide = true) if (phase != CarMedia.Phase.READY) { - Column(Modifier.fillMaxSize()) { + Column(Modifier.fillMaxSize().padding(bottom = LocalNavBarInset.current)) { AppIdentity(app, onExit, Modifier.padding(horizontal = 16.dp, vertical = 10.dp)) when (phase) { CarMedia.Phase.REJECTED -> when (rejection) { @@ -143,7 +143,7 @@ fun MediaScreen(app: MediaApp, onExit: () -> Unit) { } if (searching) { - SearchPanel( + Box(Modifier.padding(bottom = LocalNavBarInset.current)) { SearchPanel( appLabel = app.label, media = media, canPickForYou = now.canSearch, @@ -161,7 +161,7 @@ fun MediaScreen(app: MediaApp, onExit: () -> Unit) { tab = Tab.NOW_PLAYING }, onClose = { searching = false }, - ) + ) } return@Surface } @@ -194,7 +194,9 @@ fun MediaScreen(app: MediaApp, onExit: () -> Unit) { } } - BoxWithConstraints(Modifier.fillMaxSize().padding(start = 16.dp, end = 16.dp, top = 10.dp, bottom = 8.dp)) { + BoxWithConstraints( + Modifier.fillMaxSize().padding(start = 16.dp, end = 16.dp, top = 10.dp, bottom = 8.dp + LocalNavBarInset.current), + ) { // A small screen, or a big one at Extra large size, has no room for two columns: the // app and the tabs share one bar, and a list takes the whole width. The nav bar keeps // the controls, so nothing is lost. @@ -233,15 +235,10 @@ fun MediaScreen(app: MediaApp, onExit: () -> Unit) { } } Column(Modifier.weight(1.2f).fillMaxHeight()) { - // Each tab takes a share of the row, but a long word (a translation, a big - // text size) can still scroll the row rather than be cut off. - Row( - Modifier.fillMaxWidth().horizontalScroll(rememberScrollState()), - horizontalArrangement = Arrangement.spacedBy(8.dp), - ) { - Row(Modifier.weight(1f, fill = false), horizontalArrangement = Arrangement.spacedBy(8.dp)) { - tabs(Modifier.widthIn(min = 96.dp)) - } + // The tabs share the row evenly; a long word (a translation, a big text size) + // shrinks to fit its tab instead. + Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) { + tabs(Modifier.weight(1f)) searchButton() } search?.let { SearchStatus(it, app.label, media::dismissSearch) } @@ -424,8 +421,8 @@ private fun MediaTab(label: String, selected: Boolean, modifier: Modifier, onCli style = MaterialTheme.typography.titleSmall, fontWeight = if (selected) FontWeight.Bold else FontWeight.Normal, maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.padding(horizontal = 12.dp), + autoSize = TextAutoSize.StepBased(minFontSize = 11.sp, maxFontSize = MaterialTheme.typography.titleSmall.fontSize), + modifier = Modifier.padding(horizontal = 8.dp), ) } }