Commit Graph
171 Commits
Author SHA1 Message Date
vicrodh 35ff1818f6 feat(qt): say "not yet available" on pre-release tracks
/album/get sends streamable_at and release_date_stream per track: a future
value marks a pre-release, null a pulled track. Track carries both fields
and Track::is_upcoming applies the one rule (future streamable_at wins,
then a future release date); the album, playlist, search and label rows
publish qobuzUpcoming and the unavailable glyph reads "This track is not
yet available" instead of "no longer". Artist page rows carry no dates and
keep the generic copy. New msgid in the seven translated catalogs.

cc
2026-09-02 20:34:58 -06:00
vicrodh bef2a8847a fix(discover): honor blacklist and prune stale pins
cx
2026-09-02 16:03:26 -06:00
vicrodh db1d36537b feat(purchases): genre filter, zebra rows, and a list that no longer overlaps
The list view's quality column was 110 px for a badge that is 136 px
wide, so the badge ran into the release-date column; it is 150 now, the
album list's width. Both list rows and track rows draw the odd-row
zebra every other list in the app draws. The filter panel gains a Genre
section built from the catalog genre on each purchased album (albums
tab only, transient like group and sort), counted and summarised with
the other filters.

cc
2026-09-02 07:11:03 -06:00
vicrodh 29a6528ec1 feat(quality): DSD wears its mark in the Local Library and MyQBZ too
The local rows, the source-side quality hint and the MyQBZ badge still
tiered a 1-bit file as "hires"; they now say `dsd`, so the same DSD mark
the purchases show reaches every local surface, and the Local Library's
hi-res filter keeps counting DSD as hi-res.

cc
2026-09-02 07:11:03 -06:00
vicrodh 07e683f5ef feat(purchases): detail polish and a Downloads section in the nav flyout
The purchase detail badges what was bought on every row (DSD128 on a
DSD purchase, not the catalog's 24/352.8), marks the formats already on
disk with a check in the dropdown, offers a track filter, links to the
album in the Local Library once its folder is indexed, and gives the
download the accent while Play drops to a plain control of the same
size — on this screen the download is the point.

Downloads are process-wide and survive leaving the page; the nav flyout
now lists the purchases with a download in flight under "Downloads · N"
so the user can find them again, each row reopening its detail.

cc
2026-09-02 01:30:12 -06:00
vicrodh 554d43cfdf feat(playback): play the purchased copy of a Qobuz track when it is on disk
A downloaded purchase played nothing: Play on the purchase detail (and
every other Qobuz entry) streamed the catalog, so a DSD64 album bought
and saved to disk still came out of the CD stream with a "downgrade"
badge. Resolve the download registry at the audible step instead: the
best registered copy of the track that answers the bounded reachability
probe plays under the SAME Qobuz id (`play_id` = catalog id, so
now-playing, history, scrobbling and QConnect see the track they always
did), `.dsf`/`.dff` through the player's additive DSD ticket and PCM
through the file ticket. The gapless successor takes the same route, so
an album bought as DSD stays DSD across the track edge. A play that asks
for a start offset keeps the stream for a DSD copy (DSD cannot seek), and
anything the copy cannot do falls through to the tier walk unchanged.

Contract: qt-frontend/2026-09-01-purchases-local-playback §6, first
slice (implicit preference: the copy wins; no per-album select yet).

cc
2026-09-02 00:08:46 -06:00
vicrodh e41235f791 feat(purchases): readable dates, a release-date column and sort, column labels
The list printed the purchase date as "9/1/26" and nothing else, so a
row said neither when the record came out nor, at a glance, what the
number meant. Rows now carry the catalog's original release date next to
the purchase date, both as "Sep 1, 2026", under a column-label strip
like the album list's, and the toolbar sorts by release date (`released`)
beside the four existing keys.

cc
2026-09-01 23:59:36 -06:00
vicrodh 0756e96940 fix(purchases): draw the shared quality badge instead of the raw tier word
The purchase card and list row printed `qualityTier` as text ("hires")
under the artist, the one surface in the app that did. Use the same
icon-only QualityMini on the card and QualityBadgeFull on the row that
every other album card and list row draws, with the exact quality
(DSD64/DSD128, 24-bit / 96 kHz) in the badge's tooltip and detail line.

cc
2026-09-01 23:44:43 -06:00
vicrodh 3c8ab80be5 refactor(purchases): drop the blind-mode disclaimer modal
Purchases is now exercised against an account with real purchases, so
the one-time "built in blind mode" notice no longer describes the
feature. Remove the modal, its controller state, the bridge invokable,
the persisted pref and the three strings from the seven catalogs that
carried them.

cc
2026-09-01 23:40:33 -06:00
vicrodh 1cb988954e fix(qt): rename on-prefixed QML properties and gate the pattern
A property named `on<Upper>` is filed as a signal handler as soon as a
sibling member `<upper>` exists: its initializer never binds, it sits at
the type default, and nothing warns. `PurchasesView.qml` declared
`onAlbums` next to `albums`, so the Albums tab bound `[]` once and never
re-evaluated, which blanked Purchases for every account with real
purchases. Reproduced standalone with the `qml` runtime: the identical
expression under another name reads `true`.

Rename it to `albumsTab` and the four other `on<Upper>` properties
(`collectionsTab`, `surfaceTint`, `accentFloor`, `litColor`) so the rule
can be exact, and add `qml_on_prefixed_property_audit.py` to the four
QML audit sites (qt-run, cargo-test, test-crates, qt-gate-windows).

cc
2026-09-01 23:40:33 -06:00
vicrodh e41ec15e0e feat(qt): Add to playlist for local albums everywhere
Playlists can be fully local or mixed, so hiding the row on local albums
was wrong — the resolution logic already existed end to end. The quick
view drops its !localAlbum gates (album and track menus) and a new
'playlist' arm hands the overlay's row snapshot to the picker in LOCAL
MODE, fired before close so the generation guard cannot refuse it. The
local album cards and list rows reuse the existing bulk 'album' scope
(group key -> rows -> picker). My QBZ's heterogeneous cells stay out via
an explicit opt-in, since their local ids are container items the bulk
seam cannot resolve.

cc
2026-08-31 16:00:11 -06:00
vicrodh 69e5066d07 fix(qt): wheel-lock sweep across plain-Item modal overlays
Plain-Item overlays get no modal grab, so a MouseArea that swallows
presses still lets the wheel scroll the page underneath (the rule and
its wording live in DiscoverConfigModal.qml). Every scrim and panel
swallow across the modal set now accepts the wheel; the modal Popups
(TrackInfo, CastPicker, AlbumInfo, QconnectDev, LocalMediaInfo) already
had the Overlay grab, and CoverLightbox — a non-modal Popup — gets its
own.

cc
2026-08-31 11:50:32 -06:00
vicrodh ad4d48eeef feat(qt): one-time blind-mode disclaimer on Purchases
The WindowsDisclaimerModal mechanism on the purchases pref seam: a
purchases_disclaimer_seen key seeded on entry, a disclaimerVisible field
in the list document, and an OK that persists the dismissal for good. The
overlay uses the DiscoverConfigModal wheel-lock shape; the scrim does not
dismiss, so a stray click can never acknowledge it. Body ships as msgids
in all locales with the Star Wars line kept in English everywhere.

cc
2026-08-31 11:35:45 -06:00
vicrodh 6cdbd12bd0 feat(qt): Play all later in the Popular Tracks group menu
The section-level menu offered Play all next and Add all to queue with no
block-tail option; enqueue_track_list_mode already carries the "later"
arm, so only the entry was missing. New msgid translated in the seven
non-English locales.

cc
2026-08-31 11:09:53 -06:00
vicrodh c2d5a30bfa feat(qt): Play later in the album overflow and quick-view menus
AlbumView's album menu gains the row and stops mapping its append action
to mode "later" (that aliasing only worked while the backend collapsed
the two). AlbumQuickView drops the local-only gate on Play later now that
catalog albums own a real block-tail insert.

cc
2026-08-31 11:09:48 -06:00
vicrodh bbe8b6a0f2 feat(qt): album card quality badges reveal the exact quality on hover
QualityBadge has always owned a hover tooltip, but every AlbumCard host
passed only the tier, so the tip had nothing to say. The card gains a
qualityDetail input feeding the badge's label, and all fifteen mounts
now pass their model's detail (HomeCard rides its qualityLabel twin).
Un-hydrated Plex/remote rows surface their bare filetype — the known
honest fallback; an empty detail still shows no tooltip at all. The
Scene panel's own card already wired this and is untouched.

cc
2026-08-30 19:55:48 -06:00
vicrodh 0c28f9e64b fix(qt): artist Popular Tracks quality cell mounts the real badge
The PopularTrackRow fork rendered a lone tier word (HI-RES/CD) in a
plain Text while the document has carried qualityDetail all along; it
now mounts the same bare QualityBadgeFull as the shared TrackRow's
quality cell — tier label over the exact bit-depth/rate line. Audit:
every other popular/track list already goes through rows/TrackRow.qml,
so this fork was the only divergent quality cell.

cc
2026-08-30 19:55:48 -06:00
vicrodh e9fa3fb57b feat(qt): local rows drag to the sidebar and the queue
The shared drag gains a LOCAL payload arm: a Local Library / Explorer
row enters via dragStartLocal carrying its ROW ID, resolved to
source-aware refs at drop time — a library row id can never be read as
a catalog id, the same invariant the picker's Payload enum enforces.
TrackRow's localDragSource reuses every existing guardrail (horizontal
arming, select-mode/dead-row/playBlocked gates, preventStealing,
cancel teardown) without touching catalogRow's meaning. Drops route
through the picker's own add matrix: refs onto a local playlist or the
Qobuz sidecar, and Qobuz ids onto a local playlist (previously a
documented POC gap); queue drops land at the exact slot through the
same insert path as Qobuz drags. Native-catalog tracks rows keep the
gesture off until their identity can ride it.

cc
2026-08-30 18:58:32 -06:00
vicrodh 9486346130 feat(qt): explorer collapse caret tooltip and collapsed filter strip
The Library Explorer caret now says what it does on hover (Show/Hide
filter panels, all eight locales). While the panels are collapsed with
filters applied, a single-line strip of removable chips stays visible
next to the caret (top of the results area for the left/right rail
layouts), so hiding the panels never hides what is filtering the
results. The chip is the empty-state delegate extracted into a shared
component; removal reuses clearFilterChip verbatim.

cc
2026-08-30 16:17:29 -06:00
vicrodh 3dbc1fc9d0 fix(qt): restore playlist header menu
cx
2026-08-29 14:55:30 -06:00
vicrodh c7a3012955 feat(local-library): complete catalog and metadata workflows
Add bounded native library models, complete grouping rails and scan progress. Bring source-aware metadata editing, media information and collection offline preflight to Qt, and repair inherited Plex album artwork without overriding healthy tokens.

cx
2026-08-28 18:50:05 -06:00
vicrodh 5ba49a7390 fix(qt): hide the Windows rows nothing can honour
Three settings and menu entries offered Windows something no code behind them
could do.

DSD playback was opened to WASAPI in fc0d35e29, written before the phase B
spike. The spike then measured this DAC refusing 176400, the DSD64 DoP
carrier, so DoP over exclusive mode lost its target; and both non-convert
modes are cfg(target_os = "linux") in the audio thread and answer "DoP
playback is Linux-only" with a stream error. The row could only offer two ways
to fail. Back to ALSA-only. DSD still plays on Windows, converted to PCM.

Exclusive mode became visible the moment phase B published backendIsWasapi,
but the selection arm keys on backend_type == WasapiExclusive and never reads
exclusive_mode. A live toggle that changes nothing, directly under the
BIT-PERFECT header and directly above the thing being measured.

Open audio CD is dropped on Windows: the CDDA backend is mod unsupported there
and answers NoDrive to everything. Open SACD image stays on every platform --
it opens a file, not a drive, and hiding it would have been a bug.

cc
2026-08-27 12:44:20 -06:00
vicrodh d555b8fde4 feat(qt): add album quick view and queue focus controls
cx
2026-08-26 16:29:16 -06:00
vicrodh aa66c58ea4 fix(playlists): restore cover editing
cx
2026-08-26 16:29:04 -06:00
vicrodh 4630c40222 feat(queue): make history occurrences reorderable
cx
2026-08-26 12:31:48 -06:00
vicrodh edcb12b8a1 feat(qt): close migration parity gaps
cx
2026-08-26 11:11:50 -06:00
vicrodh fb6c38cbfd fix(qbz-qt): preserve collection builder viewport
cx
2026-08-26 02:29:30 -06:00
vicrodh fc7fe4f094 fix(qbz-qt): align collection controls with theme
cx
2026-08-26 02:28:52 -06:00
vicrodh 272d85fcd6 fix(qbz-qt): make listen list reordering tangible
cx
2026-08-26 02:12:49 -06:00
vicrodh cdc5eb99e7 feat(qbz-qt): add atmosphere to local album headers
cx
2026-08-26 00:11:00 -06:00
vicrodh bae1523abf fix(qbz-qt): finish compact album header layout
cx
2026-08-25 23:58:45 -06:00
vicrodh ae175f3403 fix(qbz-qt): retry queue artwork misses
cx
2026-08-25 22:56:10 -06:00
vicrodh 2d31244a7a fix(qbz-qt): refine compact album header layout
cx
2026-08-25 22:04:35 -06:00
vicrodh 1517b4c567 feat(qbz-qt): add global compact album headers
cx
2026-08-25 20:50:39 -06:00
vicrodh 1f15f988cd fix(qbz-qt): preserve artist sidebar choice when resized
cx
2026-08-25 20:36:57 -06:00
vicrodh 908fdf13b4 fix(qbz-qt): collapse album sidebar when constrained
cx
2026-08-25 20:26:40 -06:00
vicrodh 10869f76a7 fix(qbz-qt): darken ambient artist jump bar
cx
2026-08-25 19:53:12 -06:00
vicrodh 8c31fd4ab0 fix(qbz-qt): keep library toolbar responsive
cx
2026-08-25 19:53:07 -06:00
vicrodh 40180fca9a fix(qbz-qt): reconcile local favorite album lifecycle
Real-library smoke pending: the original orphaned favorite fixture was removed before verification.

cx
2026-08-25 19:53:02 -06:00
vicrodh d244213a64 fix(library): harden cross-source catalog data
Preserve per-disc and collection artwork, multi-value genres and remote metadata across Local, Plex, Jellyfin and Subsonic.

Apply source, format and quality filters before pagination, reject invalid CUE rows, and keep Qt library surfaces aligned with the selected physical version.

cx
2026-08-25 18:26:06 -06:00
vicrodh e0dc288659 perf(library): virtualize large album details
Render only the visible track slice for expanded box sets and share physical version caches without cloning every source row.

cx
2026-08-25 18:22:32 -06:00
vicrodh 9c22a909d6 feat(library): add Library Explorer
Add the chained genre, artist, and album browser with persistent layout and tab ordering. Reuse the shared album semantics for grouped versions and disc-aware details, enforce active source filters, and bound foreground detail work so chained searches stay responsive.

cx
2026-08-25 17:21:07 -06:00
vicrodh dcf4509aa0 refactor(ui): rename the queue view
Present the expanded queue surface as Listen list across its header, launcher, and supported translations.\n\ncx
2026-08-25 02:52:11 -06:00
vicrodh 5a14eef258 fix(metadata): complete local editor sessions
Consume preflight data when loading clears so the modal cannot spin indefinitely.

Reuse the editor for ephemeral folders and bind sidecar or direct writes to the exact active session.

cx
2026-08-24 17:28:54 -06:00
vicrodh 2c6bd510a9 fix(library): make explicit server resync authoritative
Treat Local Library resync actions as complete source reconciliations so provider IDs removed or reminted by Jellyfin are pruned only after a successful sweep.

Add regressions for a fully remapped Jellyfin identity set and for the QML resync contract.

cx
2026-08-24 15:36:32 -06:00
vicrodh d627560f4f fix(library): unify album versions across sources
Associate physical copies only when normalized album identity and strong track-title/duration overlap agree. Keep every source visible on one card and resolve each authoritative album id into the existing version cache.

Order versions by delivered quality and then track count, expose inferred edition labels and full format metadata, and keep source filters aware of every represented copy.

cx
2026-08-23 21:56:38 -06:00
vicrodh 63ca21abaf fix(library): paginate grouped Tracks globally
Order every source by the active grouping key before the bounded merge so later pages preserve the visible prefix. Remove the accumulated QML reorder that moved the viewport when new rows sorted ahead.

cx
2026-08-23 19:30:24 -06:00
vicrodh fcb9851736 fix(library): append Tracks pages without model reset
Keep one compatibility ListModel mounted and publish stable page prefixes through rowsInserted notifications. Preserve semantic anchor restoration only for grouped reorders so ordinary lazy pagination cannot move the viewport.

cx
2026-08-23 18:44:13 -06:00
vicrodh f8092db81a fix(library): retain Tracks anchor through model publish
Capture the visible semantic anchor before requesting the next compatibility page and retain it across bridge signal ordering and the ListView polish pass. This prevents the loading latch from dropping early and avoids recursive page requests during viewport restoration.

cx
2026-08-23 17:50:09 -06:00
vicrodh 4a2f4bdc02 fix(library): canonicalize fallback artist families
Collapse repeated collection-and-contributor credits in the legacy Artists reader while retaining isolated collaborations. Preserve Unicode artist identities, resolve the collapsed row back to every family album, and use lexical QML timer ids so query coalescing remains live.

cx
2026-08-23 17:49:50 -06:00