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 85af93c63f - Show all commits
@@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
@@ -61,7 +62,12 @@ fun ShellScaffold(
snackbarHostState.showSnackbar(msg)
}
}
Column(modifier = modifier.fillMaxSize()) {
// Consume the status-bar inset once here so the banner stack sits
// below the status bar (mirrors Flutter's SafeArea(bottom:false)).
// statusBarsPadding consumes the inset for descendants, so the in-
// shell screens' app bars no longer re-pad for the status bar —
// avoiding a double inset while fixing banners drawing under it.
Column(modifier = modifier.fillMaxSize().statusBarsPadding()) {
// Banner slot. VersionTooOldBanner appears when the server's
// min_client_version exceeds our build; UpdateBanner softly
// nudges an available (newer-than-installed) APK; and