Commit Graph
9 Commits
Author SHA1 Message Date
vicrodh a9dff18d25 fix(ui): make CircleAction buttons visible on light themes
CircleAction defaults to hardcoded light-on-dark colors, so every instance
sitting on the normal page background (not over artwork) vanished on light
themes. Set on-surface: true on those clusters — Popular Tracks (artist +
label), the PlaylistView hero row, LocalAlbumView, AwardView,
PurchaseDetailView, MixtapeDetailView, FavoritesView, LocalLibraryView — so
they use theme-appropriate colors. Buttons over artwork/dark headers keep the
light-on-dark defaults.

cc
2026-07-13 13:11:12 -06:00
vicrodh fa161be525 fix(header): gradient height = header container (ends at divider), artist-page parity, action buttons readable with gradient off
The album header gradient was a fixed px that overshot the header/track-list divider on tall (description-bearing) headers; bind its height to the divider's y so it ends exactly at the header container's bottom at any size. Apply the same readable-text + gradient-to-boundary treatment to the artist page. And CircleAction gains an on-surface variant (theme-colored fill/border/icon) driven by the gradient toggle, so when the header gradient is off the action buttons are visible on light themes instead of white-on-white. Below-divider content untouched. Extends #491/#519.

cc
2026-07-13 07:50:46 -06:00
vicrodh 0f88361427 fix(album): readable header text on light themes + gradient reaches the divider
The header sits on the always-dark art atmosphere, but its text used Theme.text-* which is dark on a light theme = unreadable. Route the header title/artist/meta/description through hdr-strong/hdr-body colors that go white over the gradient and fall back to the theme colors when the gradient is off; below-divider text is untouched. The atmosphere also faded out above the divider on description-bearing headers — raise its height to 440px and push the fade start to 74% so it reaches the header/track-list divider. Addresses #491/#519.

cc
2026-07-13 04:28:26 -06:00
vicrodh cf9d28b9e1 fix(i18n): say "Library" wherever the copy still said favorites
The nav tab already reads Library, but the surrounding communication
kept the old Qobuz term: the Home/Discovery section "Favorite Albums",
the Add/Remove-favorites menu entries on every card/row surface, the
playlist context-menu "Favorite" verb, and the Favorites view's
empty/error states. Align all of it with the Library terminology
(9 msgids renamed, translated in all 7 locales). Routes, ids and the
genre-filter context string are untouched — this is copy only.

cc
2026-07-05 15:03:47 -06:00
vicrodh 9b9bffbf64 feat(album): Last.fm similar-albums carousel under suggestions
Second album-page row sourced from Last.fm: the album's primary artist ->
artist.getSimilar -> one top album per similar artist, resolved to Qobuz and
deduped against the Qobuz /album/suggest row (by artist|title and by id).
Gated on Last.fm being connected; resolved row cached per album for 30 days
(re-opens make zero API calls; only non-empty results cached so a transient
failure re-fetches). New build_similar_albums_seeded in qbz-external-reco.
reset_album now also clears this row so the previous album's recommendations
don't linger while the next loads.

cc
2026-06-30 13:13:50 -06:00
vicrodh 8c18287577 fix(album): single-click album context menus
The album header (⋯) and cover-art PopupWindows used the default
close-on-click policy, which races the row's TouchArea — the popup can
dismiss on the press before the item's clicked fires, so some rows (e.g.
Share Qobuz link) needed a second open+click. Switch both to
close-on-click-outside and close explicitly per row, matching the existing
Sidebar/QueueSidebar fix.

cc
2026-06-30 13:13:39 -06:00
vicrodh 66889af421 feat(blacklist): album-block context menu + manager Albums tab; albumview polish
Phase 2 (Slint UI + wiring) for album-level blocking, plus the album-view
enhancements that share these files.

Album blacklist UI:
- "Block this album" in all three album menus: the page-header menu as a
  Block/Unblock toggle (gated to Qobuz via AlbumState), and the AlbumCard +
  AlbumListRow grid menus (one-way, drop-on-reload; local/Plex excluded).
  Menu heights bumped for the extra item.
- Blacklist Manager gains an Artists | Albums tab bar (segmented, ADR-008);
  an AlbumRow with a cover thumbnail (blind-eye fallback) + title + artist +
  "Added {date}"; tab-aware controls (shared enable toggle, per-tab search /
  Clear-All / count) and confirm modal. Settings row retitled "Blacklist",
  status shows both counts.
- state.slint: BlacklistedAlbumItem + album-items/album-count/active-tab on
  BlacklistState; set-tab/album-select/remove-album/clear-all-albums/
  block-album on BlacklistActions; AlbumState.is-album-blocked.
- main.rs: ("album","block"/"unblock") arm (header, resolves display fields
  from AlbumState); 5 album BlacklistActions callbacks; seed_blacklist_status
  pushes album_count.
- blacklist_manager.rs: album build/push + set_tab/block_album/remove_album/
  clear_all_albums; covers resolve async via a new ArtworkTarget::BlacklistAlbum
  through spawn_loads.

Album-view enhancements (same files):
- E1: full credited-artist header line with localized roles, each name a
  clickable artist link (Album.artists drove this; was interpreter-only).
- E3: classical work-header composer name is now a clickable artist link
  (work title + composer id/name split through TrackData/TrackItem).

i18n: es (Mexican) for all new strings; de/fr/pt/ru/ja fall back to English
pending a translator pass.

cargo check -p qbz green (Slint codegen + bin).

cc
2026-06-30 00:06:05 -06:00
vicrodh be487dca4c feat(slint): work grouping, ru/ja locales, About + What's New + Discover reco modal
- Album view: classical "work" section grouping (PR #536 port) — new
  Track.work model field + run-length per-work headers in AlbumView.
- i18n: add Russian + Japanese locales (1365 msgids each); extend plural.rs
  (ru 3-form one/few/many, ja single-form) + tests; fix the language-selector
  reseed (main.rs set_languages + ui_prefs index maps). Seven languages total.
- About modal: native port of the Tauri About (version, links, build info,
  one-paragraph acknowledgments, inline contributors with GitHub avatars,
  signature). Contributors credit hoyon (PR #536) and mxnix (PR #517, ru).
- What's New modal: renders the GitHub release-tag description (markdown
  sections + TOC); release fetch + build.rs emits build date/commit.
- Discover Recommendations: move Cache window + Refresh now into the Customize
  modal, gated to the reco tab; hide the section-config UI there; add an
  explainer paragraph. New strings translated to all six non-English locales.
- About modal width +120px; splash screen gains the legal disclaimer footer.

cc
2026-06-29 22:55:17 -06:00
vicrodh c8ef2a1b1d refactor(slint): split qbz-slint into qbz-ui lib + qbz bin; reclaim qbz binary
Slint cannot split the .slint compilation across crates, but a Slint LIBRARY
crate exposes its generated Rust types to dependent crates (verified with a
minimal proof). So:

- NEW crate `qbz-ui` (lib): owns the whole .slint tree + build.rs + bundled
  translations; `slint::include_modules!()` + the generated types (AppWindow,
  MiniPlayerWindow, all globals/structs) are re-exported. Translation domain is
  now `qbz-ui` (the .po files renamed accordingly).
- `qbz-slint` (bin) -> renamed to `qbz` (package + `[[bin]] name = "qbz"`),
  reclaiming the binary name from the retired Tauri app. It depends on `qbz-ui`
  and does `pub use qbz_ui::*;` so existing `crate::AppWindow` / `crate::*State`
  references resolve unchanged.

This splits the single ~20 GB rustc into two crates (UI/codegen vs the 75k LOC
of logic) — the foundation for lower build peak, incremental caching, and the
upcoming per-feature crate extraction.

Also fixed for the move: qbz-i18n bundled-.po include paths, the font/WGSL
`include_bytes!`/`include_str!` paths (-> ../../qbz-ui/ui/), workspace members,
dev scripts (`-p qbz`), and the CI workflows. `cargo check -p qbz` is green.

cc
2026-06-25 17:51:09 -06:00