feat(slint): per-context genre filter + favorites genre filtering

Make genre_filter.rs selection per-context (HashMap keyed by "discover" /
"favorites" + a current context the popup edits), so favorites filters
independently from Discover. Discover keeps its server-side path
unchanged (reads filter_ids("discover") explicitly; its genre buttons set
the "discover" context on open). Favorites get a genre button in both
toolbars that opens the shared popup in the "favorites" context, plus the
popup overlay; derive_tracks / derive_albums filter client-side by the
selected genre NAMES (selected_names expands parents to descendants).
on_toggle / on_clear branch on the current context to re-derive favorites
instead of re-fetching Discover. AlbumSummary gains an optional `genre`
(favorites track album objects carry it; TrackItem can't, so a track
id->genre map backs the tracks filter). Persisted per-context (legacy
flat selection migrates to "discover").

cc
This commit is contained in:
vicrodh committed 2026-05-27 08:03:56 -06:00
1 parent 9c273119a6
commit 4dddd36073
8 files changed
+327 -76

No files matched your search

@@ -10,7 +10,7 @@
import { Theme } from "../foundation/semantic-colors.slint";
import { Typography } from "../foundation/typography.slint";
import { DiscoverBrowseState, DiscoverBrowseActions, GenreFilterState } from "../state.slint";
import { DiscoverBrowseState, DiscoverBrowseActions, GenreFilterState, GenreFilterActions } from "../state.slint";
import { AlbumCollectionView } from "AlbumCollectionView.slint";
import { GenreFilterPopup } from "GenreFilterPopup.slint";
import { LoadingSpinner } from "../primitives/LoadingSpinner.slint";
@@ -209,6 +209,7 @@ export component DiscoverBrowseView inherits Rectangle {
alignment: center;
GenreButton {
clicked => {
GenreFilterActions.set-context("discover");
GenreFilterState.open = !GenreFilterState.open;
}
}
+2 -1
View File
@@ -8,7 +8,7 @@
import { Theme } from "../foundation/semantic-colors.slint";
import { Typography } from "../foundation/typography.slint";
import { HomeState, HomeActions, GenreFilterState, NavState, ContentView } from "../state.slint";
import { HomeState, HomeActions, GenreFilterState, GenreFilterActions, NavState, ContentView } from "../state.slint";
import { Carousel } from "Carousel.slint";
import { SlimCarousel } from "SlimCarousel.slint";
import { HomeSkeleton } from "HomeSkeleton.slint";
@@ -225,6 +225,7 @@ export component HomeView inherits Rectangle {
spacing: 6px;
GenreButton {
clicked => {
GenreFilterActions.set-context("discover");
GenreFilterState.open = !GenreFilterState.open;
}
}