Commit Graph
117 Commits
Author SHA1 Message Date
vicrodh 12ed5a7c4a feat(slint): browser-like back/forward navigation history
Add a navigation history so pages can be walked back and forward.

- nav.rs: a back/forward stack of NavEntry (home, album, artist,
  settings); record() on fresh navigation, go_back/go_forward to walk it
- NavButtons: a [<] [>] pair styled like the Discover tab group; inline
  beside the Discover tabs and in place of the per-page Back button on
  album, artist and settings views
- All navigation routes through Rust (open-album/-artist record entries;
  the gear and header menu use NavState.request-settings) so the history
  stays accurate; back/forward re-apply entries, re-loading entity pages
- AppShell listens for the mouse back/forward buttons
- can-back / can-forward drive the buttons' enabled state

Also in this round:

- Album header description: render a pre-truncated short string so it
  wraps to a couple of lines instead of overflowing the header; the full
  text stays in the Read-more modal
- Header queue button uses an ordered-list icon (the previous one read
  as a playlist)

cc
2026-05-18 20:17:54 -06:00
vicrodh 9bd8692518 fix(slint): album view layout and a working track search
Four album-view corrections from review:

- Explicit badge: the title row now uses `alignment: start`, so the E
  badge sits right after the track name instead of being stretched out
  to a fake column position.
- Label/awards sidebar: dropped `alignment: start` on the track/sidebar
  row — it had defeated the track list's stretch and left the sidebar
  floating mid-row with dead space. The list now stretches and the
  254px sidebar is flush right; it rides the content region inward when
  a main sidebar opens.
- Track search: now a real client-side filter — a TextInput drives the
  AlbumActions.search global callback; album.rs keeps the unfiltered
  list and filter_tracks() matches title/artist case-insensitively.
- Description modal: the Flickable is vertical-stretch bounded so long
  text scrolls, and strip_html keeps paragraph breaks as newlines.

cc
2026-05-18 19:51:47 -06:00
vicrodh 9af170db66 feat(slint): recently-played albums section on Discover Home
Discover Home now has both recently-played modules: a carousel of
album cards and the slim track grid (renamed "Recently Played
Tracks").

- recently.rs records track plays with their album metadata;
  load_albums() derives the distinct recent albums from that history
- home.rs threads a recent_albums list into HomeData; HomeView renders
  it as a carousel; the artwork pipeline gains ArtworkTarget::RecentAlbum

Also raises the header-gradient contrast: the artwork color is now
saturation-boosted off its average and normalized to a fixed peak
brightness instead of just darkened, so the tint is actually visible.

cc
2026-05-18 19:25:33 -06:00
vicrodh d132636caa feat(slint): recently-played store and Discover Home section
Close the Recently Played Tracks tech debt: a JSON-backed play-history
store at the shared QBZ data path, surfaced as a slim-card section on
Discover Home (it hides while empty).

- recently.rs: load() reads the store newest-first; record() prepends a
  track, dedupes by id and caps the list — the playback session calls
  record() when a track starts
- home.rs threads a `recent` list into HomeData; HomeView renders a
  "Recently Played" GridSection; artwork pipeline gains an
  ArtworkTarget::Recent

The data path is complete end to end; only record() awaits the
playback session.

cc
2026-05-18 18:47:24 -06:00
vicrodh 49cd8f6a87 feat(slint): album and artist detail view parity pass
Bring the album and artist pages closer to the Tauri originals.

Shared:
- Artwork-tinted gradient header — header_tint() derives an average,
  darkened color from the decoded cover; the page header renders a
  linear-gradient from it. Both pages scroll on a Flickable (no
  scrollbar gutter).

Album view:
- Full header action row: play, shuffle, favorite, radio, credits,
  booklet, mixtape, multi-select, more (visual where playback/feature
  wiring is pending; play and favorite emit media-action)
- Right sidebar with the record label and editorial awards, each a
  round-avatar card; AlbumData now carries id, label and awards

Artist view:
- Gradient header, fuller action row, and an "ARTIST" eyebrow
- Discography split into titled release sections (Albums, EPs &
  Singles, Live Albums, Compilations, ...) instead of one flat list
- Artist track rows gained the more-button context menu

cc
2026-05-18 18:23:50 -06:00
vicrodh 644fd88dc5 feat(slint): hamburger user row with subscription tier
The header user element is now just the hamburger icon. The menu it
opens leads with a user row showing the display name and the Qobuz
subscription tier, carried through from the login/restore session.

cc
2026-05-18 18:07:48 -06:00
vicrodh 7eb9627eab feat(slint): context menus for album cards and track rows
Add a first cut of context menus, opened from the "more" (ellipsis)
button on Discover album cards and on album track rows.

- ContextMenu / ContextMenuItem primitives (PopupWindow-hosted panel)
- AlbumCard: the overlay action buttons are now interactive (they gate
  their pointer handling so non-hovered cards still open on click); the
  more button opens a menu — Open album, Play, Add to queue, Add to
  favorites
- TrackRow: a hover-revealed more button opens a menu — Play, Add to
  queue, Add to favorites; AlbumTrackItem and TrackData carry the
  track id
- Menu actions bubble up as a single media-action(kind, id, action)
  callback through the shell; main.rs logs it for now — playback and
  favorites wiring lands with the playback session
- user and list-plus icons

cc
2026-05-18 17:32:56 -06:00
vicrodh 1fd3cfcb2b fix(slint): album card overlay, award ribbon, and quality tooltip
Three corrections to the Discover album card:

- Overlay meta: the genre is one point larger and bold, and the year
  now sits a single line below it (conditional `if` rows with explicit
  heights, instead of `visible` toggles that left a phantom gap)
- Award ribbon: width hugs its label (capped at 200px, below the card
  width) instead of spanning the full card — it reads as a ribbon again
- Quality badge: extracted to a QualityBadge primitive that reveals
  the exact quality ("Hi-Res: 24-bit / 96 kHz") on hover, mirroring the
  Tauri QualityBadge; home.rs derives the label from the discover
  audio info

cc
2026-05-18 17:22:43 -06:00
vicrodh 5d78fb0a09 feat(slint): add Settings page with Audio and Playback panels
Introduce the Settings page, reachable from the Discover gear and the
header menu. Two sub-sections backed by the existing UI-agnostic stores.

- Audio panel: backend, output device and sample-rate dropdowns;
  toggles for exclusive mode, DAC passthrough, PipeWire force
  bit-perfect, gapless, normalization and quality fallback
- Playback panel: autoplay mode, show context icon, remember session
  and resume position
- settings.rs controller owns AudioSettingsStore + PlaybackPreferencesStore
  at the shared global path; persists changes and applies audio ones to
  the live Player (reload_settings, plus reinit_device for routing-
  critical changes); a backend switch re-enumerates output devices
- QbzToggle (switch) and QbzSelect (PopupWindow dropdown) primitives,
  SettingRow layout helper, chevron-down icon
- SettingsState global, ContentView::settings, settings-bool /
  settings-select callbacks wired through the shell

cc
2026-05-18 17:08:24 -06:00
vicrodh 1662b3824e feat(slint): add slim-card grid for Popular albums
Add a compact "slim" card variant and a 4-column grid section that
renders it, used for the Popular albums row on Discover Home.

- SlimCard: 60px row with optional rank, 44px thumbnail, title/subtitle
- GridSection: 4-column grid; cards absolutely positioned since Slint
  GridLayout cannot host a `for`
- state.slint: SlimItem struct and HomeState.popular model
- home.rs: load_home now returns HomeData { sections, popular };
  map_slim maps the discover most-streamed container
- artwork pipeline: ArtworkTarget enum routes decoded covers to either
  a section card or a popular card

cc
2026-05-18 16:08:42 -06:00
vicrodh 4e143bbcd5 feat(qbz-slint): artist detail page
Clicking an artist (from the album page's artist line) opens the
artist detail view: a circular portrait, name, biography, action
buttons, a Popular Tracks list, and a Discography carousel.

- artist.rs: fetches the artist page via QbzCore::get_artist_page and
  maps name, biography (HTML-stripped), portrait URL, top tracks and
  releases; the portrait loads through the shared image cache.
- ArtistPageView.slint reuses AlbumCard for the discography (through
  the Carousel) and AlbumTrackItem for the track list.
- NavState becomes a three-way ContentView (home / album / artist) and
  AppShell routes the content region accordingly. The album page's
  artist line and the artist page's release cards are navigable.

cc
2026-05-18 15:59:47 -06:00
vicrodh 8c27de5651 feat(qbz-slint): header redesign, Lucide icons, scrollbar fixes
- Replace every Unicode glyph placeholder with Lucide icons via QbzIcon
  (player transport, carousel nav, album-card overlay, album-page
  actions, gear, search, checkbox, sidebar).
- Header: the search field is centered to the window width and gets a
  search icon; the header and player bar now use the elevated surface,
  so all chrome (header, sidebar, player bar) shares one color over the
  darker content area.
- The sidebar user card moves to the header as a user element (name +
  QBZ logo) that opens a dropdown — Settings, Keyboard Shortcuts,
  Documentation, Report an Issue, About, plus Log Out and Close. Log Out
  clears the session and returns to login; Close quits the app.
- Content ScrollViews disable the horizontal scrollbar — no view scrolls
  horizontally, so the phantom reserved lane is gone.

cc
2026-05-18 14:58:58 -06:00
vicrodh 6b772b41b0 feat(qbz-slint): album detail page
Clicking an album card opens the album detail view: a back button,
the album header (224px artwork, title, artist, and info line — year,
label, genre, track count, duration — plus play / shuffle / favorite /
more action buttons), and the track list with a column header (#,
title, artist, duration, quality).

- album.rs: fetches the album via QbzCore::get_album, maps it (info
  line, per-track quality tier, durations) onto the AlbumState global,
  and loads the header artwork through the shared image cache.
- AlbumPageView.slint, with NavState driving the shell content region
  between Home and the album page.
- Album clicks bubble AlbumCard -> Carousel -> HomeView -> AppShell ->
  AppWindow -> main; the back button returns to Home.

cc
2026-05-18 14:38:45 -06:00
vicrodh 2a7147a008 feat(qbz-slint): album card hover overlay
Album cards gain the AlbumCardLite-style hover overlay: a dark scrim,
genre/year meta in the top-left, and circular favorite / play / more
action buttons (play primary, white). The action buttons are visual
for now; one TouchArea over the artwork drives the hover state and
emits a clicked(album_id) callback for navigation.

AlbumCardItem carries genre and year; home.rs maps them from the
discover album (genre name, year from the release dates).

cc
2026-05-18 14:29:45 -06:00
vicrodh 7801478819 fix(qbz-slint): match current QBZ Discover Home
Corrections from testing feedback:
- Remove the greeting — the current QBZ discovery view has no greeting,
  only the tab selector. Drops HomeState.greeting and the chrono dep.
- Quality badge is now the icon-only badge (hi-res.svg, or cd.svg in a
  framed square), not a numeric text pill. AlbumCardItem carries a
  quality tier instead of a quality string.
- Tighten the album card: deterministic 274px height, title and artist
  in a 2px-spaced stack — removes the large gap between them.
- SectionRow no longer scrolls vertically (vertical-scrollbar-policy
  always-off, height pinned to the card height).
- Artwork is downscaled to 264px on decode instead of holding ~600px
  source textures.

cc
2026-05-18 13:20:52 -06:00
vicrodh e2e409cf93 feat(qbz-slint): album artwork pipeline
Discover cards now show real Qobuz cover art. Artwork is fetched and
decoded off the UI thread, capped at 16 concurrent downloads, and each
result is applied to its own card row on the Slint event loop — so a
cover arriving never resets a section.

- artwork.rs: download + decode worker and per-row apply.
- AlbumCardItem gains an `artwork` image field; AlbumCard overlays the
  cover, falling back to the elevated placeholder until it resolves.
- main.rs: after the discover sections render, artwork jobs are spawned
  for every card with an image URL.

qbz-slint now depends on reqwest and image.

cc
2026-05-18 13:05:12 -06:00
vicrodh 8246ad5dd6 feat(qbz-slint): real Discover Home view
After sign-in the app loads the real Qobuz discover index and renders
the Home view: a time-based greeting with the user's name, the tab
pill (Home / Editor's Picks / For You), and discover sections — New
Releases, Press Accolades, Ideal Discography, Qobuzissimes, Albums of
the Week — each a horizontally scrolling row of album cards.

- state.slint: AlbumCardItem / DiscoverSection structs, HomeState global.
- discover/: AlbumCard (artwork area, award ribbon, title, artist,
  quality badge), SectionRow, HomeView.
- home.rs: discover-index fetch and mapping (award-ribbon priority,
  quality string), greeting, and event-loop model application. Unit
  tests for ribbon, quality, and greeting logic.
- AppShell content region is now the HomeView.

Album artwork images load in the next increment (artwork pipeline);
cards currently show the elevated placeholder. No fixtures — all data
is the live discover index.

cc
2026-05-18 13:01:45 -06:00