feat(slint): Label landing page + All Releases sub-view
Port the Tauri LabelView module to native Slint, reusing existing components and extending where needed (no duplication). Landing (new LabelPageView): circular header + description read-more + Follow toggle, sticky JUMP TO bar, Popular Tracks (multi-select, 5->20->50 reveal, Play all), and Releases (+ See all) / Critics' Picks / Playlists / Artists / More Labels carousels. All Releases sub-view (LabelReleasesView): circular header + album count, toolbar (local search, group-by-artist, Hi-Res filter, sort) + grid/list toggle, load-more, states. TYPE column now populated. Split the label route: ContentView::label -> LabelPageView (landing), ContentView::label-releases -> LabelReleasesView; add NavEntry::LabelReleases. label.rs load_label_page parses /label/page + getAlbums + explore + the favorite-labels set; derive_releases re-derives the sub-view list. Reuse Carousel/PlaylistCarousel/ArtistCarousel/TrackRow/AlbumCard/ AlbumListRow/JumpNavBar/QbzSelect/ExpandableSearch; extend ArtistCard/ ArtistCarousel (follow-mode/follow-kind); promote CircleAction to a shared primitive; JumpNavBar gains show-search. Wire label media-actions: follow, play-top, open (more-labels), see-all. cc
This commit is contained in:
13 files changed
+1986
-152
No files matched your search
@@ -0,0 +1,41 @@
|
||||
// Ghost circular action button — translucent fill with a faint ring,
|
||||
// icon tinted on hover/active (never a solid accent fill, mirroring the
|
||||
// Tauri transport controls). Shared by the artist + label page headers
|
||||
// and their Popular Tracks clusters (Play all / Select / More).
|
||||
|
||||
import { Theme } from "../foundation/semantic-colors.slint";
|
||||
import { QbzIcon } from "QbzIcon.slint";
|
||||
|
||||
export component CircleAction inherits Rectangle {
|
||||
in property <image> icon;
|
||||
in property <bool> primary: false;
|
||||
// Stays "pressed" — same surface as hover, icon tinted accent.
|
||||
in property <bool> active: false;
|
||||
in property <length> diameter: 40px;
|
||||
callback clicked();
|
||||
|
||||
width: root.diameter;
|
||||
height: root.diameter;
|
||||
border-radius: root.diameter / 2;
|
||||
background: (ta.has-hover || root.active) ? Theme.surface-hover : transparent;
|
||||
border-width: 1px;
|
||||
border-color: (ta.has-hover || root.active) ? Theme.text-disabled : Theme.border-subtle;
|
||||
|
||||
QbzIcon {
|
||||
source: root.icon;
|
||||
width: root.primary ? 19px : 17px;
|
||||
height: root.primary ? 19px : 17px;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
tint: root.active
|
||||
? Theme.accent
|
||||
: (ta.has-hover ? Theme.text-primary : Theme.text-secondary);
|
||||
}
|
||||
|
||||
ta := TouchArea {
|
||||
mouse-cursor: pointer;
|
||||
clicked => {
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,10 @@ export struct JumpNavTab {
|
||||
export component JumpNavBar inherits Rectangle {
|
||||
in property <[JumpNavTab]> tabs;
|
||||
in property <string> active-tab-id;
|
||||
// Whether the inline page-search affordance is offered. Artist pages
|
||||
// have it; the label page does not (Tauri's label jump-nav has no
|
||||
// search), so the label view passes show-search: false.
|
||||
in property <bool> show-search: true;
|
||||
in-out property <bool> search-open: false;
|
||||
in-out property <string> search-text;
|
||||
|
||||
@@ -244,7 +248,7 @@ export component JumpNavBar inherits Rectangle {
|
||||
// expanded input run all the way to the bar's right padding
|
||||
// (right where the user just clicked the lupa). The inline
|
||||
// input carries its own X close button.
|
||||
if !root.search-open: VerticalLayout {
|
||||
if root.show-search && !root.search-open: VerticalLayout {
|
||||
alignment: center;
|
||||
horizontal-stretch: 0;
|
||||
Rectangle {
|
||||
|
||||
Reference in new issue
Block a user