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 942d7e88cc - Show all commits
+11 -4
View File
@@ -13,10 +13,17 @@ exists in Flutter:
opened the Flutter file in this session, you have not earned the right to
write the Android version.
2. **Replicate it exactly.** Match the behavior, the layout structure, the
section order, the empty/loading/error states, the copy strings, the data
sources, and the edge cases. Same number of rows, same fields per row, same
tap targets.
2. **Replicate the user-visible behavior exactly; implement it idiomatically.**
Match what the user sees and feels: layout structure, section order, empty/
loading/error states, copy strings, edge cases, and — critically — the
**responsiveness** (the app caches to make the UI feel instant; preserve
that). But you do NOT have to copy Flutter's *implementation*. Flutter uses
drift `watch()` + Riverpod `invalidate`; the well-supported Android idioms
are Room + Flow, Compose state, WorkManager, Media3. **Prefer the native
mechanism that delivers the same or better UX** over a literal transliteration
of the Dart. Exact on behavior + feel; idiomatic on structure. If a more
native approach genuinely improves the experience, do that (and note it in
the parity map as an intentional, better-supported divergence).
3. **Never silently substitute a different design.** If the faithful port seems
hard, blocked, or impossible, STOP and verify by reading more of the Flutter