merge: Most Played Albums (feature/most-played-albums)

Play-count album history store (album_play_history, WAL per ADR-002) hooked
into record_recent, Most Played Albums carousel on Home + For You (default
off), View-all page with search + per-card play count, i18n in all 8
locales.

Conflicts resolved against pre-release: kept the Slint-era Pinned section
alongside the new MostPlayedAlbums everywhere (DiscoverySectionId, prefs,
render kinds, nav, ContentView, HomeActions); AlbumCardItem carries both
is_pinned and plays (populated via card_to_item); .po files union-merged,
msgfmt clean; discover_prefs tests updated (home 15/8 ON, forYou 14/13 ON)
— 10/10 green. Release build green.

km
This commit is contained in:
vicrodh committed 2026-07-22 17:46:09 -06:00
commit 6c6eaf2b36
29 files changed
+950 -18

No files matched your search

+27 -1
View File
@@ -35,6 +35,8 @@ export struct AlbumCardItem {
quality-detail: string,// "24-bit / 96 kHz" — bare detail for QualityBadgeFull
track-count: string, // "12" — TRACKS column
plain-year: string, // "1973" — bare year for the list-row YEAR column
plays: int, // play count — shown ONLY in the Most Played Albums
// View-all (0 elsewhere, so no count is drawn).
}
// One entry in an A-Z jump strip (favorites tracks name-group / albums
@@ -223,6 +225,9 @@ export global HomeState {
// reorders HomeState.favorite-albums in place when this changes.
in-out property <int> library-albums-sort: 0;
in property <DiscoverSection> release-watch;
// Most Played Albums rail — top albums by local play count (title set by
// Rust from `album_play_history::top_albums`). Self-hides while empty.
in property <DiscoverSection> most-played-albums;
in property <[SlimItem]> top-artists: [];
// Qobuz Playlists row (Home + Editor's Picks). Single-cover cards; the
// active tab's set is swapped in by crate::home::select_tab.
@@ -254,6 +259,9 @@ export global HomeActions {
// "View all" on the Qobuz Playlists rail -> the full-page playlist
// browse (PlaylistBrowseView); a fresh open resets its tag to All.
callback open-playlist-browse();
// Opens the full "Most Played Albums" page (MostPlayedAlbumsView), fed
// from the local play-count store.
callback open-most-played-albums();
// Fired by HomeView's init on every (re)mount. Rust re-reads the LOCAL
// recently-played store into the two rails IF a play was recorded while
// Home was off-screen (dirty-flag gated in Rust — a no-op otherwise, so
@@ -276,6 +284,21 @@ export global RecentAlbumsState {
in property <bool> loading: false;
}
// MostPlayedAlbumsView — the full "Most Played Albums" page opened from the
// rail's "View all". Ranked by local play count; each item carries its
// `plays`. `search` filters title/artist client-side (visibility only).
export global MostPlayedAlbumsState {
in property <[AlbumCardItem]> albums: [];
in property <bool> loading: false;
in-out property <string> search: "";
}
export global MostPlayedAlbumsActions {
// Filter the loaded page by title/artist. Rust re-sets `albums` to the
// matches and re-fires their artwork (mirrors the Qobuz-playlists filter).
callback filter(string);
}
// ---------------------------------------------------------------------------
// Discover section configurator (Slice 5) — prefs-driven render loop + modal.
// ---------------------------------------------------------------------------
@@ -430,6 +453,9 @@ export global ForYouState {
in property <DiscoverSection> recent-albums;
// Favorite Albums — the user's favorited albums (For You #6).
in property <DiscoverSection> favorite-albums;
// Most Played Albums — top albums by local play count (same data as
// HomeState.most-played-albums; local, not tab-specific).
in property <DiscoverSection> most-played-albums;
in property <[SlimItem]> recent-tracks: [];
in property <[SlimItem]> top-artists: [];
in property <[SlimItem]> artists-to-follow: [];
@@ -1083,7 +1109,7 @@ export global DragActions {
}
// Which content view the shell shows.
export enum ContentView { home, album, artist, artist-releases, settings, search, musician, label, label-releases, award, award-albums, location, favorites, mix, playlist, discover-browse, playlist-browse, recent-albums, playlist-manager, offline-manager, blacklist-manager, local-library, local-album, mixtapes, collections, mixtape-detail, discography-builder, purchases, purchase-album, now-playing }
export enum ContentView { home, album, artist, artist-releases, settings, search, musician, label, label-releases, award, award-albums, location, favorites, mix, playlist, discover-browse, playlist-browse, recent-albums, most-played-albums, playlist-manager, offline-manager, blacklist-manager, local-library, local-album, mixtapes, collections, mixtape-detail, discography-builder, purchases, purchase-album, now-playing }
// In-app toast (transient notification). Mirrors Tauri's toastStore:
// a single toast at a time (a new one replaces the current), auto-hidden