Commit Graph
9 Commits
Author SHA1 Message Date
vicrodh 46673b2077 feat(slint): extend scroll-position restore to all views
Wire the per-history-entry scroll memory (added for Local Library) into
every top-level view: Home/Discover, Album, Local Album, Artist, Musician,
Label, Label Releases, Location, Favorites, Mix, Playlist, Playlist Manager,
Offline Manager, Search, Settings.

Each view's primary scroll container reports its viewport-y and restores it
on back/forward via NavState.restore-scope (scope_for in main.rs maps each
entry to a stable id; tab views carry the tab, e.g. "fav:albums"). The
container restores once per arm, only after content lays out, then clears
the scope. A `changed sr-armed` trigger covers views that persist across
sub-tab navigation (Home's Discover tabs, Favorites' shared list, Playlist
A->B->A) where no fresh mount occurs.

ScrollView-based views (Offline Manager, Settings) use visible-height for
the overflow check; ListView/Flickable views use height. Favorites' shared
albums/artists/playlists/labels Flickable matches the active tab's scope
dynamically.

cc
2026-06-08 15:53:40 -06:00
vicrodh 82129cff35 feat(slint): LocalLibrary ephemeral folders + Folders tree 1:1 port
Ephemeral folders: open / browse / play a folder without indexing it —
album-grouped pane, CUE seek fast-path (no full re-decode per virtual track),
folder-path persistence + rehydrate, "already playing" add-vs-replace choice
dialog (ephemeral-only), and now-playing / queue / menu gating so an ephemeral
track exposes no persistence actions.

Folders tree brought 1:1 with Tauri:
- Rail header: select-mode, collapse-all, open-ephemeral, tree search.
- Resizable rail (default ~20% narrower; drag handle, min 50% default /
  max 50% of the content area).
- Subfolder cover grid + grid/list toggle, recursive track count, name search;
  compact icon bulk bar (folder-check / play-next / queue / playlist / clear).
- Tree is the default mode; circular checkboxes homologated with TrackRow;
  compact rows (smaller type + icon, no ambiguous trailing count).
- Flat/Tree icon toggle (disc-album / folder-tree), floated right.

Per-source TrackRow context menu (logic, not a blanket trim): Qobuz/offline =
full; local = play/next/queue + add-to-playlist; plex/ephemeral = play/next/
queue only.

App-wide standard: Math.round pixel-snap on icon centering across the UI to
kill sub-pixel blur (CircleAction, header back/forward/collapse, and the rest).
NowPlayingBar context icon -> turntable (frees disc-album for the Folders
toggle). New assets: folder-check, folder-tree, turntable.

cc
2026-06-07 10:12:59 -06:00
vicrodh 321d3ba116 fix(slint): track drag no longer stays glued after release
The drag-end relied on the row TouchArea's pointer-up, which only arrives
if the row still holds the grab. Inside a ListView (or a Flickable that
stays interactive) the scroll gesture can steal the grab mid-drag, so the
up never reached the row and the ghost stayed glued to the cursor. Add a
`changed pressed` safety net that ends the drag on any release or grab
cancel (both paths guard on ta.dragging, so end() runs once). Also give
LabelPageView's Flickable the interactive: !DragState.active flag the
other track views already have.

cc
2026-05-30 20:18:11 -06:00
vicrodh 610c6c1f79 refactor(slint): share album grid/list/grouped renderer
DiscoverBrowseView and LabelReleasesView each carried their own album
grid column math, flat-list (AlbumListHeader + AlbumListRow loop), and
LabelReleasesView additionally the group-by-section rendering. Extract
all of it into a shared AlbumCollectionView (with an inner AlbumGrid),
driven by albums / grouped / is-grouped / view-mode / show-source props.
Both views now mount the one renderer; behavior is preserved (the empty
length>0 guards mirror the previous per-block guards). Readies the same
renderer for the Favorites albums tab.

cc
2026-05-26 21:25:13 -06:00
vicrodh 1c9c9de40b refactor(slint): promote ToggleButton to a shared primitive
LabelReleasesView and DiscoverBrowseView each carried a verbatim copy of
the 34px segmented/toolbar toggle. Move it to primitives/ToggleButton and
import it in both. No visual change — same surface, one definition.

cc
2026-05-26 21:18:35 -06:00
vicrodh 12048bcee0 fix(slint): label albums missing artist/quality/date + favorite + load-more
/label/getAlbums returns the V2 nested album shape (DiscographyAlbumDto:
artists[], audio_info, dates, track_count) — confirmed against the Android
decompiled sources — but it was deserialized into the flat Album model,
which dropped artist, quality and release date (Unknown Artist in
group-by-artist, no quality badge, no date, empty list-row columns).

qbz-models Album: capture the nested V2 fields (audio_info, dates,
track_count, release_type) as optional serde(default) — backward
compatible with the flat-shape endpoints.
label.rs map_album: read nested-first (quality from audio_info, date from
dates, count from track_count, artist from artists[] main-artist, explicit
release_type) with flat fallback. Fixes the releases grid + list columns,
the landing Releases carousel, and Critics' Picks.
Wire ("album","favorite") -> add_favorite + toast (works on every album
card via the shared component).
LabelReleases load-more now driven by has_more (the endpoint caps each
page well below the catalog, so total was an unreliable gate).

cc
2026-05-26 20:10:09 -06:00
vicrodh 56c924d8ea 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
2026-05-26 18:35:42 -06:00
vicrodh b2004e6867 feat(slint): TrackRow favorites + artist/album links, PlaylistView, LabelView, scrollbar
CHECKPOINT — this batch is NOT yet acceptable; substantial feedback is pending. Committed so the work is preserved for rework next session, after a max-effort Tauri code review. Areas: TrackRow favorite toggle/state + clickable artist/album (TrackItem gains is-favorite/artist-id/album-id + fav_cache, populated across all builders); PlaylistView header buttons + cover-art hover overlay; LabelView full AlbumCard + grid/list toggle; vertical scrollbar moved to the right gutter across ~12 views.

cc
2026-05-26 16:36:02 -06:00
vicrodh 302f708694 feat(slint): LabelReleasesView (Port 3, second of three click targets)
Wires the artist network sidebar's Labels section to a real
destination. Mirrors Tauri's LabelReleasesView.svelte core: a label
header (image + name + release count) over a wrapping album grid
with load-more pagination. (Sort / filter Hi-Res / group-by-artist
from the Tauri view are deferred — the core browse experience is in.)

Slint:
  - ContentView gains `label`; NavEntry mirrors with
    `Label { id, name }`.
  - LabelState / LabelActions globals carry the header (id, name,
    image-url + decoded image) and the AlbumCardItem grid + total.
  - New `ui/label/LabelReleasesView.slint`: label header card,
    then the same absolute-position album grid + load-more pattern
    the artist/musician views use. Reuses the Discover AlbumCard
    (artist-as-subtitle is correct here — a label's catalog is
    various artists).
  - AppShell routes ContentView.label and forwards open-album +
    media-action.

Rust:
  - `crate::label` controller — load_label (parallel-ish
    get_label_page + get_label_albums), load_more_albums,
    apply_label, append_albums, apply_image (label header), and
    artwork_jobs. extract_label_image handles the flexible
    /label/page image value (string or mega/extralarge/.../small
    object), same precedence as the Svelte.
  - artwork::ArtworkTarget gains LabelAlbum { index }.
  - main.rs: navigate_label + apply_entry route + on_label_clicked
    (sidebar) + LabelActions::on_load_more.
  - No new qbz-core methods — get_label_page / get_label_albums
    already existed.

cc
2026-05-20 20:09:09 -06:00