release v2026.05.11.3: caching, perf, playlist polish #41

Merged
bvandeusen merged 262 commits from dev into main 2026-05-11 20:35:49 -04:00
bvandeusen commented 2026-05-11 20:35:38 -04:00 (Migrated from git.fabledsword.com)

Significant batch since v2026.05.11.2. Server perf wins + Flutter caching/UX polish.

Server (perf):

  • /api/albums/{id}: GetAlbumWithArtist join — 3 round trips → 2.
  • /api/artists/{id}: ListAlbumsByArtistWithTrackCount correlated subquery — 1+N round trips → 2 (32 collapsed to 2 on a 30-album artist).
  • /api/home: aggregate-first rewrites of ListLastPlayedArtistsForUser (was scanning all artists) and ListMostPlayedTracksForUser (was joining tracks×albums×artists across every play_event before grouping).

Flutter (caching strategy reset):

  • Stale playlist reconcile in playlistsListProvider — system-playlist UUIDs rotate on rebuild and were piling up in drift; deleteWhere any owned row not in fresh response, then upsert.
  • 404 on playlist detail evicts the stale row from drift.
  • playlistDetailProvider now writes cachedTracks rows from PlaylistTrack fields (was missing them — detail screens showed empty rows for system playlists).
  • Stream-cached audio files register in audio_cache_index via just_audio bufferedPositionStream listener — eviction can now reclaim them.
  • Cache-usage display in Settings walks the actual cache directory.
  • Metadata prefetcher (one-shot per session per id) warms artistProvider for top-N items in home sections + library Artists tab. Album warming intentionally dropped — was creating a feedback loop with playback contention.
  • Dropped alwaysRefresh on album/artist providers (kept on playlistsListProvider where rotation matters). Pull-to-refresh remains the explicit invalidation path.

Flutter (player):

  • /queue moved to top level — fixes duplicate-page-key crash when tapping Queue from /now-playing.
  • Full player layout: shuffle/repeat/queue + like + kebab combined into one row above the seek bar; title centered without competition.
  • Player ErrorListener + state/processingState diagnostics — silent stops will surface in logs next time.

Flutter (UX):

  • Playlist cover art via deterministic /api/playlists/{id}/cover — drift round-trip no longer drops it.
  • 1px album-card overflow silenced (cellH slack 4→8).
Significant batch since v2026.05.11.2. Server perf wins + Flutter caching/UX polish. Server (perf): - /api/albums/{id}: GetAlbumWithArtist join — 3 round trips → 2. - /api/artists/{id}: ListAlbumsByArtistWithTrackCount correlated subquery — 1+N round trips → 2 (32 collapsed to 2 on a 30-album artist). - /api/home: aggregate-first rewrites of ListLastPlayedArtistsForUser (was scanning all artists) and ListMostPlayedTracksForUser (was joining tracks×albums×artists across every play_event before grouping). Flutter (caching strategy reset): - Stale playlist reconcile in playlistsListProvider — system-playlist UUIDs rotate on rebuild and were piling up in drift; deleteWhere any owned row not in fresh response, then upsert. - 404 on playlist detail evicts the stale row from drift. - playlistDetailProvider now writes cachedTracks rows from PlaylistTrack fields (was missing them — detail screens showed empty rows for system playlists). - Stream-cached audio files register in audio_cache_index via just_audio bufferedPositionStream listener — eviction can now reclaim them. - Cache-usage display in Settings walks the actual cache directory. - Metadata prefetcher (one-shot per session per id) warms artistProvider for top-N items in home sections + library Artists tab. Album warming intentionally dropped — was creating a feedback loop with playback contention. - Dropped alwaysRefresh on album/artist providers (kept on playlistsListProvider where rotation matters). Pull-to-refresh remains the explicit invalidation path. Flutter (player): - /queue moved to top level — fixes duplicate-page-key crash when tapping Queue from /now-playing. - Full player layout: shuffle/repeat/queue + like + kebab combined into one row above the seek bar; title centered without competition. - Player ErrorListener + state/processingState diagnostics — silent stops will surface in logs next time. Flutter (UX): - Playlist cover art via deterministic /api/playlists/{id}/cover — drift round-trip no longer drops it. - 1px album-card overflow silenced (cellH slack 4→8).
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bvandeusen/minstrel#41