feat(slint): favorites tabs as history pages + homologated nav-bar/title

Each favorites tab is now its own history entry (NavEntry::Favorites{tab},
mirroring Discover) recorded from both the header nav and the in-view tab
bar, so back/forward moves between tabs instead of exiting Favorites. Add
the back/forward NavButtons at the same position as every other page
(11px top padding + 22px gap) — FavoritesView was the only view missing
it — and shrink the "Favorites" heading to Typography.section (the album
name size in AlbumView).

cc
This commit is contained in:
vicrodh committed 2026-05-25 17:41:35 -06:00
1 parent abff875a0e
commit 21af0f63f8
3 files changed
+44 -3

No files matched your search

+24 -1
View File
@@ -465,6 +465,18 @@ fn apply_entry(
ensure_for_you_loaded(runtime, weak, handle, image_cache); ensure_for_you_loaded(runtime, weak, handle, image_cache);
} }
} }
nav::NavEntry::Favorites { tab } => {
if let Some(fav_tab) = favorites::FavTab::from_tab_id(&tab) {
navigate_favorites(
runtime.clone(),
weak.clone(),
handle,
image_cache.clone(),
fav_tab,
&tab,
);
}
}
nav::NavEntry::Settings => { nav::NavEntry::Settings => {
let _ = weak.upgrade_in_event_loop(|w| { let _ = weak.upgrade_in_event_loop(|w| {
w.global::<NavState>().set_view(ContentView::Settings); w.global::<NavState>().set_view(ContentView::Settings);
@@ -2476,7 +2488,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
if let Some(tab) = favorites::FavTab::from_route(route.as_str()) { if let Some(tab) = favorites::FavTab::from_route(route.as_str()) {
let tab_id = route.strip_prefix("favorites-").unwrap_or("tracks"); let tab_id = route.strip_prefix("favorites-").unwrap_or("tracks");
nav::record(nav::NavEntry::Home); // favorites is not yet a history entry nav::record(nav::NavEntry::Favorites {
tab: tab_id.to_string(),
});
if let Some(w) = weak.upgrade() {
update_nav_flags(&w);
}
navigate_favorites( navigate_favorites(
runtime.clone(), runtime.clone(),
weak.clone(), weak.clone(),
@@ -2948,6 +2965,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
return; return;
}; };
// Each favorites tab is its own history page (mirrors the
// Discover tabs) so back/forward moves between them.
nav::record(nav::NavEntry::Favorites { tab: id.to_string() });
if let Some(w) = weak.upgrade() {
update_nav_flags(&w);
}
navigate_favorites( navigate_favorites(
runtime.clone(), runtime.clone(),
weak.clone(), weak.clone(),
+6
View File
@@ -19,6 +19,12 @@ pub enum NavEntry {
Discover { Discover {
tab: String, tab: String,
}, },
/// A Library > Favorites tab page ("tracks" | "albums" | "artists" |
/// "playlists" | "labels"). Each tab is its own history entry so
/// back/forward moves between the favorites pages, mirroring Discover.
Favorites {
tab: String,
},
/// A Qobuz mix detail page ("daily" | "weekly" | "fav" | "top"). /// A Qobuz mix detail page ("daily" | "weekly" | "fav" | "top").
Mix { Mix {
kind: String, kind: String,
@@ -22,6 +22,7 @@ import { AlbumCard } from "../discover/AlbumCard.slint";
import { TrackRow } from "../primitives/TrackRow.slint"; import { TrackRow } from "../primitives/TrackRow.slint";
import { QbzIcon } from "../primitives/QbzIcon.slint"; import { QbzIcon } from "../primitives/QbzIcon.slint";
import { LoadingSpinner } from "../primitives/LoadingSpinner.slint"; import { LoadingSpinner } from "../primitives/LoadingSpinner.slint";
import { NavButtons } from "../shell/NavButtons.slint";
// One tab in the favorites tab bar. // One tab in the favorites tab bar.
component FavTab inherits Rectangle { component FavTab inherits Rectangle {
@@ -256,15 +257,26 @@ export component FavoritesView inherits Rectangle {
width: parent.width; width: parent.width;
padding-left: 32px; padding-left: 32px;
padding-right: 32px; padding-right: 32px;
padding-top: 20px; padding-top: 11px;
padding-bottom: 100px; padding-bottom: 100px;
spacing: 0px; spacing: 0px;
alignment: start; alignment: start;
// Back / forward nav buttons — same position as every other
// page (11px top padding, then a 22px gap to the header).
HorizontalLayout {
alignment: start;
NavButtons { }
}
Rectangle { height: 22px; }
// Page title — same size as the album name in AlbumView
// (Typography.section), not the larger Typography.title.
Text { Text {
text: @tr("Favorites"); text: @tr("Favorites");
color: Theme.text-primary; color: Theme.text-primary;
font-size: Typography.title; font-size: Typography.section;
font-weight: Typography.bold; font-weight: Typography.bold;
} }