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
2 changed files with 11 additions and 12 deletions
Showing only changes of commit 2b17a4ed69 - Show all commits
@@ -60,22 +60,19 @@ fun AddToPlaylistSheet(
modifier = Modifier.fillMaxWidth().padding(24.dp),
contentAlignment = Alignment.Center,
) { CircularProgressIndicator(color = MaterialTheme.colorScheme.primary) }
UiState.Empty -> Text(
text = "You haven't created any playlists yet.",
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(horizontal = 20.dp, vertical = 12.dp),
)
is UiState.Error -> Text(
text = s.message,
color = MaterialTheme.colorScheme.error,
modifier = Modifier.padding(horizontal = 20.dp, vertical = 12.dp),
)
is UiState.Success -> if (s.data.isEmpty()) {
Text(
text = "You haven't created any playlists yet.",
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(horizontal = 20.dp, vertical = 12.dp),
)
} else {
LazyColumn(modifier = Modifier.fillMaxWidth()) {
items(items = s.data, key = { it.id }) { p ->
PlaylistPickRow(playlist = p, onClick = { onPick(p.id) })
}
is UiState.Success -> LazyColumn(modifier = Modifier.fillMaxWidth()) {
items(items = s.data, key = { it.id }) { p ->
PlaylistPickRow(playlist = p, onClick = { onPick(p.id) })
}
}
}
@@ -30,7 +30,9 @@ class AddToPlaylistViewModel @Inject constructor(
val uiState: StateFlow<UiState<List<PlaylistRef>>> = repository
.observeUserPlaylists()
.map { list -> UiState.Success(list) as UiState<List<PlaylistRef>> }
.map { list ->
if (list.isEmpty()) UiState.Empty else UiState.Success(list)
}
.onStart {
// Best-effort refresh so the sheet reflects newly-created
// playlists from another device. Cached list shows first;