fix(android): remove kebab from MiniPlayer to free space for artist line
android / Build + lint + test (push) Failing after 1m27s
android / Build signed release APK (push) Has been skipped

Cover + LikeButton + 3 transport buttons + kebab consumed almost all
of the 360-410dp viewport on typical phones, leaving the title /
artist column with only ~20-80dp - enough for a truncated title but
nothing for the artist line, which was rendering but effectively
unreadable.

Drops TrackActionsButton from MiniRow and the now-unused
onNavigateToAlbum / onNavigateToArtist callbacks from the MiniPlayer
signature + ShellScaffold call site. Full kebab surface still lives
on NowPlayingScreen (one screen swipe away).

Operator request 2026-06-01. Diverges from Flutter's player_bar
which still ships the kebab; parity-map row updated to reflect the
deliberate divergence. ShellScaffold's navController parameter is
kept on the signature for future shell-level navigation needs.
This commit is contained in:
2026-06-01 08:07:48 -04:00
parent ef8374753a
commit 5c2011e6f4
2 changed files with 15 additions and 31 deletions
@@ -46,7 +46,6 @@ import com.fabledsword.minstrel.nav.LocalAnimatedContentScope
import com.fabledsword.minstrel.nav.LocalSharedTransitionScope import com.fabledsword.minstrel.nav.LocalSharedTransitionScope
import com.fabledsword.minstrel.shared.widgets.LikeButton import com.fabledsword.minstrel.shared.widgets.LikeButton
import com.fabledsword.minstrel.shared.widgets.ServerImage import com.fabledsword.minstrel.shared.widgets.ServerImage
import com.fabledsword.minstrel.shared.widgets.trackactions.TrackActionsButton
import com.fabledsword.minstrel.shared.widgets.trackactions.TrackActionsViewModel import com.fabledsword.minstrel.shared.widgets.trackactions.TrackActionsViewModel
import com.fabledsword.minstrel.theme.FabledSwordFlatTokens import com.fabledsword.minstrel.theme.FabledSwordFlatTokens
@@ -110,18 +109,16 @@ private fun MiniCover(coverUrl: String, contentDescription: String) {
* *
* Layout (Column): * Layout (Column):
* - Slim seek slider at the top (4dp track) * - Slim seek slider at the top (4dp track)
* - Row: cover | title/artist column | like | prev | play/pause | next | kebab * - Row: cover | title/artist column | like | prev | play/pause | next
* *
* The slider participates in pointer-events so tap/scrub works * No kebab on the mini bar (operator 2026-06-01): the full kebab
* without the surface's onClick eating the gesture; the row's * surface lives on NowPlayingScreen, and dropping it from the mini
* surface-level clickable still expands to NowPlaying on tap of * gives the title/artist column the horizontal room it needs to
* the cover/title area. * actually display the artist name without truncation.
*/ */
@Composable @Composable
fun MiniPlayer( fun MiniPlayer(
onExpandClick: () -> Unit, onExpandClick: () -> Unit,
onNavigateToAlbum: (String) -> Unit,
onNavigateToArtist: (String) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
viewModel: PlayerViewModel = hiltViewModel(), viewModel: PlayerViewModel = hiltViewModel(),
trackActionsViewModel: TrackActionsViewModel = hiltViewModel(), trackActionsViewModel: TrackActionsViewModel = hiltViewModel(),
@@ -167,8 +164,6 @@ fun MiniPlayer(
onToggleLike = { onToggleLike = {
trackActionsViewModel.toggleLike(track.id, isLiked) trackActionsViewModel.toggleLike(track.id, isLiked)
}, },
onNavigateToAlbum = onNavigateToAlbum,
onNavigateToArtist = onNavigateToArtist,
) )
} }
} }
@@ -209,8 +204,6 @@ private fun MiniRow(
onPrev: () -> Unit, onPrev: () -> Unit,
onNext: () -> Unit, onNext: () -> Unit,
onToggleLike: () -> Unit, onToggleLike: () -> Unit,
onNavigateToAlbum: (String) -> Unit,
onNavigateToArtist: (String) -> Unit,
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier
@@ -219,9 +212,9 @@ private fun MiniRow(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
// Cover + title area expands to NowPlaying on tap, but the // Cover + title area expands to NowPlaying on tap, but the
// transport buttons + kebab don't (each IconButton handles // transport buttons don't (each IconButton handles its own
// its own clicks). Wrap only the cover-and-title region with // clicks). Wrap only the cover-and-title region with the
// the clickable modifier rather than the whole row. // clickable modifier rather than the whole row.
Row( Row(
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
@@ -255,14 +248,6 @@ private fun MiniRow(
onClick = onPlayPause, onClick = onPlayPause,
) )
TransportButton(icon = Lucide.SkipForward, description = "Next", onClick = onNext) TransportButton(icon = Lucide.SkipForward, description = "Next", onClick = onNext)
// hideQueueActions=true: the playing track is itself the
// queue entry, so Play next / Add to queue would be silly.
TrackActionsButton(
track = track,
hideQueueActions = true,
onNavigateToAlbum = onNavigateToAlbum,
onNavigateToArtist = onNavigateToArtist,
)
} }
} }
@@ -14,8 +14,6 @@ import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import com.fabledsword.minstrel.connectivity.ui.ConnectionErrorBanner import com.fabledsword.minstrel.connectivity.ui.ConnectionErrorBanner
import com.fabledsword.minstrel.nav.AlbumDetail
import com.fabledsword.minstrel.nav.ArtistDetail
import com.fabledsword.minstrel.player.ui.MiniPlayer import com.fabledsword.minstrel.player.ui.MiniPlayer
import com.fabledsword.minstrel.player.ui.PlaybackErrorViewModel import com.fabledsword.minstrel.player.ui.PlaybackErrorViewModel
import com.fabledsword.minstrel.update.ui.UpdateBanner import com.fabledsword.minstrel.update.ui.UpdateBanner
@@ -27,8 +25,9 @@ import com.fabledsword.minstrel.shared.widgets.trackactions.TrackActionsViewMode
* (conditional, none implemented yet), routed screen filling the * (conditional, none implemented yet), routed screen filling the
* middle, MiniPlayer pinned at the bottom (auto-hides when no track). * middle, MiniPlayer pinned at the bottom (auto-hides when no track).
* A shell-scoped SnackbarHost above the MiniPlayer surfaces transient * A shell-scoped SnackbarHost above the MiniPlayer surfaces transient
* messages emitted by the MiniPlayer's TrackActionsButton (snackbars * messages emitted by in-screen TrackActions kebabs (each screen owns
* for in-screen kebabs continue to live on each screen's own Scaffold). * its own Scaffold's snackbar host as well; this one is the shell-
* wide catch-all for events that outlive a single screen).
* *
* Mirrors the Flutter `_ShellWithPlayerBar` (lib/shared/routing.dart). * Mirrors the Flutter `_ShellWithPlayerBar` (lib/shared/routing.dart).
* *
@@ -39,8 +38,10 @@ import com.fabledsword.minstrel.shared.widgets.trackactions.TrackActionsViewMode
* back-only AppBar. * back-only AppBar.
* *
* [onExpandPlayer] is the navigate-to-NowPlaying callback passed * [onExpandPlayer] is the navigate-to-NowPlaying callback passed
* through to MiniPlayer's tap-handler. [navController] is needed by * through to MiniPlayer's tap-handler. [navController] is kept on
* the MiniPlayer kebab for go-to-album / go-to-artist nav. * the signature for future shell-level navigation needs (banner taps
* etc.); MiniPlayer itself no longer carries a kebab so doesn't need
* nav callbacks any more.
*/ */
@Composable @Composable
fun ShellScaffold( fun ShellScaffold(
@@ -82,8 +83,6 @@ fun ShellScaffold(
SnackbarHost(hostState = snackbarHostState) SnackbarHost(hostState = snackbarHostState)
MiniPlayer( MiniPlayer(
onExpandClick = onExpandPlayer, onExpandClick = onExpandPlayer,
onNavigateToAlbum = { id -> navController.navigate(AlbumDetail(id)) },
onNavigateToArtist = { id -> navController.navigate(ArtistDetail(id)) },
) )
} }
} }