feat(slint): Favorites Playlists + Labels tabs

Completes the five Favorites tabs. Both lazy-load like the others.

Playlists:
  - Sourced from QbzCore::get_user_playlists (the getUserFavorites
    envelope has no playlists branch; Tauri splits owned-vs-following
    locally — the MVP shows the full user playlist list for now).
  - FavoritePlaylistItem card: cover (images300 > images150 >
    images, first entry), name, "N tracks". Cover streams via the
    artwork pipeline (new ArtworkTarget::FavoritePlaylist). Click is
    logged — no playlist detail view in the Slint MVP yet.

Labels:
  - Parsed from get_favorites("labels"); the qbz-models Label is
    just {id,name}, so a local FavLabel shape picks up the
    albums_count. FavLabelRow (icon + name + "N releases") routes
    the click into the existing LabelReleasesView via
    FavoritesActions::open-label -> navigate_label.

FavTab gains Playlists + Labels; from_route/from_tab_id now resolve
them so the header dropdown and tab bar both lazy-load. Tab bar
shows live counts for all five tabs.

Still deferred (per "finish then polish one by one"): the richer
Tauri options (sort, group-by-artist, owned/following split,
per-row context menus, bulk select, download status).

cc
This commit is contained in:
vicrodh committed 2026-05-20 21:20:53 -06:00
1 parent a40c6ce569
commit 93edce305c
5 files changed
+356 -15

No files matched your search

+23
View File
@@ -649,6 +649,23 @@ export struct FavoriteArtistItem {
image: image,
}
// One playlist tile in the Favorites > Playlists grid.
export struct FavoritePlaylistItem {
id: string,
name: string,
owner: string,
tracks-line: string, // "N tracks"
cover-url: string,
cover: image,
}
// One label row in the Favorites > Labels list.
export struct FavoriteLabelItem {
id: string,
name: string,
albums-line: string, // "N releases"
}
// Library > Favorites state. The active tab decides which model is
// shown; all are populated lazily by `crate::favorites` the first
// time their tab is opened. Albums reuse AlbumCardItem, tracks reuse
@@ -661,9 +678,13 @@ export global FavoritesState {
in property <[SearchTrackItem]> tracks: [];
in property <[AlbumCardItem]> albums: [];
in property <[FavoriteArtistItem]> artists: [];
in property <[FavoritePlaylistItem]> playlists: [];
in property <[FavoriteLabelItem]> labels: [];
in property <int> tracks-total: 0;
in property <int> albums-total: 0;
in property <int> artists-total: 0;
in property <int> playlists-total: 0;
in property <int> labels-total: 0;
in property <bool> loading: false;
}
@@ -673,6 +694,8 @@ export global FavoritesActions {
callback select-tab(string);
callback open-album(string);
callback open-artist(string);
callback open-label(string /* label id */, string /* name */);
callback open-playlist(string /* playlist id */);
callback play-track(string /* track id */);
callback track-action(string /* track id */, string /* action */);
}