Commit Graph
6 Commits
Author SHA1 Message Date
vicrodh eea336fd49 feat(slint): lyrics controls flyout, per-user prefs, cache settings row
Sidebar header gains the controls flyout (auto-follow, font size on the
280px-adapted scale, dimming, active color, uppercase, copy lyrics,
reset). Every setting persists per user via the new lyrics_prefs store
(loaded on all session activation paths, applied into LyricsState,
Tauri defaults). Settings gains the lyrics cache row with honest per-user
stats and clear (the F1 fix shipped in qbz-lyrics). Parity and @tr sweep
over the sidebar surfaces per the review inventory.

Closes the S1-S5 implementation run of the Lyrics epic: Qobuz-first
word-synced lyrics (real per-word timestamps - richer than Tauri's
line-level estimation), LRCLIB/lyrics.ovh fallback, shared per-user cache
with additive wsync column, 30Hz sync engine with word-anchored karaoke
fill, auto-center scroll, and QConnect peer-following.

cc
2026-06-10 18:00:29 -06:00
vicrodh 5a4dbd87f6 feat(slint): lyrics wiring + static sidebar rendering
S3 of the Lyrics epic: the qbz-lyrics engine reaches the Slint shell —
per-user cache binding, the track-edge fetch rider, the LyricsState
global, and the real sidebar body replacing the placeholder.

- Glue (src/lyrics.rs, offline_mode/fav_cache template): process-global
  LyricsService over the core client lock (read at call time, never
  cached); init_for_user on ALL session activation paths (browser login,
  saved-session restore, offline entry) binding the SAME per-user
  lyrics/lyrics.db Tauri uses; teardown on logout.
- Fetch rider on the NOTIFY_LAST_TRACK dedupe edge in
  refresh_now_playing_meta, next to scrobble/notify — prefetch on every
  track change regardless of panel visibility (Tauri parity,
  lyricsStore.ts:545-565) and deliberately NO skip-if-remote (Q7: lyrics
  follow the QConnect peer). Track->null resets the state. Request
  carries source kind (qobuz_download counts as Qobuz, real catalog id)
  + the offline engine verdict; raw title to the engine (F4).
- Stale guard (F2): responses echo the request identity and are dropped
  unless they still match the latest requested track. Duplicate-fetch
  guard mirrors Tauri's lastFetchedTrackId (skip only while loaded).
  Parsed doc (native wsync words) held Rust-side for the S4 engine.
- LyricsState global: line model (text, time-ms, end-ms, has-words),
  status (idle/loading/ready/no-lyrics/error/offline), synced, provider
  + attribution label, header meta, active-index placeholder (-1), and
  panel-opened (fetch-on-open via conditional-mount init).
- LyricsLinesView (shared, miniplayer-ready): 280px-adapted typography
  per the owner Q3 spec - 13/15px reduced scale, 0.2px letter-spacing,
  6px side padding, full-width wrapped text; dimming ladder on the INNER
  Text (never a root opacity binding); centering spacers from the
  Flickable's own height; plain mode = static top-aligned at 0.85;
  fallback-provider attribution line (Qobuz first-party = none).
- Sidebar 1:1 header (mic tile 36px, LYRICS overline 11px/1.5px per the
  alignment standard, title-artist meta, sliders trigger for the S5
  flyout, close kept) + state bodies incl. the typed NotAvailableOffline
  as a translated string (F3). All new strings @tr()-wrapped.

Sync engine (position, active line, auto-center, karaoke fill) is S4.

cc
2026-06-10 16:46:13 -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 14e3e3689c feat(qbz-slint): Queue+Lyrics stacking, NowPlayingBar polish, shell fill fix
NowPlayingBar / SongCard:
- Audio stamp homologated New<->Classic + vertically centred (alignment:center
  on the stamp column; New had a binding-loop card height, now explicit).
- Dot-LED output indicators (circle-dot/circle) in both modes; render-target
  badge moved into the LED row when a peer/cast device owns playback.
- Right-cluster buttons made square (32x32); context glyph -> disc-album,
  flush-left; classic stamp right margin; quality tooltip = the quality text;
  heart tooltip = Add to library; Qobuz Connect tooltip always shows On/Off.

Qobuz Connect:
- Clear the session topology on disconnect so a late event cannot resurrect
  the golden render badge (badge-persists-after-disconnect fix).

Queue / Lyrics right panel:
- Queue and Lyrics can both be open at once, stacked vertically in one column
  (independent queue-open/lyrics-open flags replace the exclusive right-panel
  int); each closable from its bar button and its own X.
- Panel width 280; compact rows (zebra), now-playing card homologated with a
  row, flexible footer search, Lyrics title sized like the Queue tabs.

Shell layout:
- Pin AppShell to the window and size the content area arithmetically
  (window - header - player-bar - padding). A Slint VerticalLayout ignores an
  explicit height and does not auto-fill its parent Rectangle, so the content
  row collapsed once the right panels became conditionally mounted; a Rectangle
  takes the explicit height and it cascades up. Bar height references the single
  Layout.player-bar-height source (note left for the future Small/Large bars).

cc
2026-06-04 11:49:24 -06:00
vicrodh 1f6159f3ba feat(slint): split sidebar toggle from nav buttons, animate side panels
NavButtons now renders the collapse toggle and history buttons as two
spaced pills instead of separating them with a bar. Queue and Lyrics
sidebars animate their own width open/closed (160ms ease-in-out) so
they slide in like the main sidebar instead of appearing abruptly.

cc
2026-05-18 22:43:13 -06:00
vicrodh 33df7bce76 feat(slint): collapsible sidebar, Queue/Lyrics panels, nav menus
Shell chrome (steps 1-3):
- Left sidebar is collapsible — a toggle in the nav cluster (left of the
  [<] [>] pair) and a draggable right edge that resizes 200-420px and
  collapses below 160px. ShellState global drives it.
- Queue and Lyrics right sidebars: 320px panels rendered as layout
  siblings, so opening one pushes the content area narrower rather than
  overlaying it. The header captions/queue buttons toggle them
  (mutually exclusive) and light up when active.
- The four nav tabs (Discover/Library/Local Library/My QBZ) open
  dropdown menus listing their sub-sections; Discover -> Home is wired.

Detail views (steps 4-5):
- Track rows: the even-row tint is now clearly fainter than the hover
  tint so the two states no longer look identical.
- The favorite and offline-cache glyphs in album track rows are real
  buttons (hover state, emit media-action).
- Album header artist link uses the metadata text color, bold, instead
  of the accent blue.
- Album description and artist biography span the full content width
  below the header block.

cc
2026-05-18 21:54:31 -06:00