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