From 8455922e8cb726656a9f2749d264a597d31767a7 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 27 May 2026 23:51:03 -0400 Subject: [PATCH] =?UTF-8?q?feat(android):=20QueueScreen=20rows=20show=20ar?= =?UTF-8?q?tist=20=C2=B7=20album=20+=20duration=20(audit=20v3=20=C2=A74.17?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Queue rows only showed title + artist. Now the subtitle reads "Artist · Album" (collapsing gracefully when either is empty) and a trailing m:ss duration appears when known — matches Flutter's queue row density so users can tell tracks apart by album + length. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../minstrel/player/ui/QueueScreen.kt | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/java/com/fabledsword/minstrel/player/ui/QueueScreen.kt b/android/app/src/main/java/com/fabledsword/minstrel/player/ui/QueueScreen.kt index 7e464f21..04ab26e3 100644 --- a/android/app/src/main/java/com/fabledsword/minstrel/player/ui/QueueScreen.kt +++ b/android/app/src/main/java/com/fabledsword/minstrel/player/ui/QueueScreen.kt @@ -123,9 +123,10 @@ private fun QueueRow(track: TrackRef, isCurrent: Boolean, onClick: () -> Unit) { maxLines = 1, overflow = TextOverflow.Ellipsis, ) - if (track.artistName.isNotEmpty()) { + val subtitle = queueSubtitle(track) + if (subtitle.isNotEmpty()) { Text( - text = track.artistName, + text = subtitle, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, maxLines = 1, @@ -133,7 +134,27 @@ private fun QueueRow(track: TrackRef, isCurrent: Boolean, onClick: () -> Unit) { ) } } + if (track.durationSec > 0) { + Text( + text = formatDuration(track.durationSec), + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } } } +/** "Artist · Album" — collapses gracefully when either is missing. */ +private fun queueSubtitle(track: TrackRef): String = listOf(track.artistName, track.albumTitle) + .filter { it.isNotEmpty() } + .joinToString(" · ") + +private const val SECONDS_PER_MINUTE = 60 + +private fun formatDuration(seconds: Int): String { + val mins = seconds / SECONDS_PER_MINUTE + val secs = seconds % SECONDS_PER_MINUTE + return "%d:%02d".format(mins, secs) +} + private const val HIGHLIGHT_ALPHA = 0.12f