feat: M3 weighted shuffle v1 — real /api/radio with scoring #21

Merged
bvandeusen merged 262 commits from dev into main 2026-04-27 11:00:29 -04:00
Showing only changes of commit 8455922e8c - Show all commits
@@ -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