The ribbon feature relied on album.awards arriving on the frontend, but
the DiscoverAlbum Rust struct in both qbz-models and src-tauri/api was
missing the 'awards' field, so serde silently dropped it during
deserialization of /discover/index. Result: frontend always saw an
empty awards array and pickAlbumRibbon returned undefined.
Also bumps the home sessionStorage cache to schemaVersion 2 so pre-fix
caches (which persisted AlbumCardData without ribbon) are discarded on
next launch instead of rehydrating with missing fields.
cc
When download fails after retry at the same quality (e.g. HiRes),
automatically try the next lower quality (e.g. Lossless). This handles
CDN edges that consistently serve broken responses for specific tracks
at certain quality levels. Applied to all three download paths: standard
download, streaming probe fallback, and prefetch. Also fixes prefetch
retry using wrong quality variable.
Display parental_warning badge (E icon) next to track titles in all
views: TrackRow, QueuePanel, NowPlayingBar, ImmersivePlayer with all
13 visualizer panels, MiniPlayer surfaces, and AlbumDetailView.
Propagate parental_warning field through the full data chain from
Rust backend (qbz-models, queue, commands_v2, session_store, API
server) to frontend stores, adapters, and UI components. Badge uses
CSS mask technique with explicit.svg for theme compatibility.
Replace the flat album grid LabelView with a rich detail page featuring:
- Header with label image, name, description, and play button
- Popular Tracks section (5/10/all expand, same UX as ArtistDetailView)
- Releases horizontal scroll row with "See all" → LabelReleasesView
- Critics' Picks section from second releases container
- Playlists, Artists, and More Labels sections
Backend: add /label/page and /label/explore API endpoints with V2
commands (v2_get_label_page, v2_get_label_explore). Models use
serde_json::Value for flexible section parsing.
Old LabelView renamed to LabelReleasesView for the "See all" flow.
i18n keys added to all 4 locales (en, es, de, fr).
Tier 0 crate with no dependencies on other qbz-* crates:
- types.rs: Core API types (Track, Album, Artist, Playlist, Quality, etc.)
- playback.rs: Playback types (QueueTrack, RepeatMode, PlaybackState, etc.)
- events.rs: CoreEvent enum for frontend communication
- traits.rs: FrontendAdapter trait enabling multiple frontends
- error.rs: QbzError enum with error codes and recovery flags
All types extracted from qbz-nix/src-tauri/src/api/models.rs and
queue/mod.rs. Ready for use by Tier 1 crates (qbz-audio, qbz-qobuz).
Create the foundational workspace structure for the multi-crate
architecture refactor. This phase establishes placeholder crates
that will be populated in subsequent phases.
Crates created:
- qbz-models: Shared types, events, and traits (Tier 0)
- qbz-audio: Audio backend system (Tier 1)
- qbz-player: Playback engine and queue (Tier 1)
- qbz-qobuz: Qobuz API client (Tier 1)
- qbz-core: Orchestrator (Tier 3)
All crates compile successfully with placeholder implementations.
The workspace uses shared dependencies via workspace.dependencies.
cc