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 225ff35c4c - Show all commits
@@ -203,27 +203,13 @@ private fun MiniRow(
}
}
LikeButton(liked = isLiked, onToggle = onToggleLike)
IconButton(onClick = onPrev) {
Icon(
imageVector = Lucide.SkipBack,
contentDescription = "Previous",
tint = MaterialTheme.colorScheme.onSurface,
)
}
IconButton(onClick = onPlayPause) {
Icon(
imageVector = if (isPlaying) Lucide.Pause else Lucide.Play,
contentDescription = if (isPlaying) "Pause" else "Play",
tint = MaterialTheme.colorScheme.onSurface,
)
}
IconButton(onClick = onNext) {
Icon(
imageVector = Lucide.SkipForward,
contentDescription = "Next",
tint = MaterialTheme.colorScheme.onSurface,
)
}
TransportButton(icon = Lucide.SkipBack, description = "Previous", onClick = onPrev)
TransportButton(
icon = if (isPlaying) Lucide.Pause else Lucide.Play,
description = if (isPlaying) "Pause" else "Play",
onClick = onPlayPause,
)
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(
@@ -234,3 +220,18 @@ private fun MiniRow(
)
}
}
@Composable
private fun TransportButton(
icon: androidx.compose.ui.graphics.vector.ImageVector,
description: String,
onClick: () -> Unit,
) {
IconButton(onClick = onClick) {
Icon(
imageVector = icon,
contentDescription = description,
tint = MaterialTheme.colorScheme.onSurface,
)
}
}