Add V2 commands that implement the ADR Runtime Session Contract:
- v2_init_client: Phase 1 - init client only (bundle tokens)
- v2_auto_login: Phase 2 - auto-login with blocking V2 auth
- v2_manual_login: Manual login with blocking V2 auth
This allows frontend to control ToS check between init and auth:
1. v2_init_client() -> InitializedNoAuth
2. activate_user_session() -> restore session
3. loadTosAcceptance() -> check ToS
4. v2_auto_login() or v2_manual_login() -> Ready
V2 CoreBridge auth is now REQUIRED per ADR - login fails if V2 fails.
Migrate LoginView.svelte to use new V2 commands:
- Replace init_client with v2_init_client
- Replace auto_login with v2_auto_login
- Replace login with v2_manual_login
Add i18n keys for V2 auth errors in all 4 locales.
- Add refresh button next to device dropdown to re-enumerate devices
without app restart (fixes#69)
- Re-enable quality limiting with per-device sample rate storage
- User can manually set max sample rate per DAC (44.1k to 384k)
- Quality limiting is opt-in (disabled by default)
- Streaming Quality dropdown always takes priority (fixes#72)
Backend: HashMap<device_id, max_rate> stored as JSON in SQLite
Frontend: Conditional UI shows rate dropdown when limit is enabled
Adds a help text showing which device is the current system default.
This helps users understand what "System Default" will actually use.
Backend:
- New command `get_default_device_name` that uses pactl for PipeWire/Pulse
and CPAL for ALSA to get the current default device
Frontend:
- Shows "(System Default is: <device name>)" under the output device setting
- Styled as secondary description text (italic, muted)
Translations added for en, es, de, fr.
- Add +/- buttons to volume control for 5% increments
- Reduce SongCard min-width from 508px to 436px
- Add playlist search in sidebar header with expandable input
- Add translations for new features in all 4 locales
cc
- Add Hardware Acceleration toggle to Composition section
- Move Force DMA-BUF toggle from Developer Mode to Composition
- Add i18n keys for new composition toggles (en, es, de, fr)
These settings logically belong together since they both control
GPU rendering behavior. Hardware Acceleration is the broad switch
that enables GPU; Force DMA-BUF controls the specific buffer-sharing
mechanism with the compositor.
Only capture log/info levels in dev builds or when verbose mode is
explicitly enabled in Developer Mode. Always capture error/warn for
bug tracking. Reduces GC/CPU overhead in production builds.
Adds toggle in Settings > Developer Mode to enable verbose capture
when debugging production issues.
QueuePanel:
- Add vertical ... icon to the right of track duration
- Context menu with 3 options:
- Remove from Queue (calls backend remove_from_queue)
- Add to Playlist (reuses existing playlist modal)
- Show Track Info (reuses existing track info modal)
- Menu shows on button click, closes on click outside
+page.svelte:
- Add handlers: handleRemoveFromQueue, handleQueueTrackAddToPlaylist,
handleQueueTrackInfo
- Wire up new QueuePanel props
i18n: Add toast messages for remove from queue (all 4 locales)
Backend:
- Add static atomics to track graphics startup state
- Add set_startup_graphics_state() called from main.rs
- Add get_graphics_startup_status command for frontend
Frontend (SettingsView):
- Query graphics startup status on mount
- Show prominent red warning in Composition section when
using fallback graphics settings
- Display recovery command (qbz --reset-graphics)
i18n: Add fallbackWarning/fallbackDesc to all 4 locales
This helps users understand when graphics settings failed to
load and may be causing performance degradation.
Replace the misleading Hardware Acceleration toggle (which was a no-op
since v1.1.12 reverted to env-var-only control) and the standalone
Force X11 toggle with a collapsible "Composition" subsection that:
- Groups all GPU/rendering settings in one place
- Shows help text explaining what the section controls
- Includes a crash recovery warning with terminal command
- Keeps Force X11 toggle (functional, writes to DB)
- Adds GDK_SCALE and GDK_DPI_SCALE inputs (shown when Force X11 on)
- Lists all env var overrides with descriptions
- Translated in all 4 locales (en, es, de, fr)
Add a toggle in Settings > Appearance to force X11 (XWayland) backend
on Wayland sessions. Persisted in graphics_settings.db, env var
QBZ_FORCE_X11=1|0 overrides for crash recovery. Also fixes the
display server log to report effective GDK backend instead of
session type.
- Add 3 new Rust endpoint constants and command mappings for
/discover/qobuzissims, /discover/albumOfTheWeek, /discover/pressAward
- Add 3 new navigation ViewType values and genre filter contexts
- Extend DiscoverBrowseView to handle the 3 new endpoint types
- Add See All links with chevron caret and pipe separator to all 6
discover sections in HomeView (newReleases, mostStreamed,
essentialDiscography, qobuzissimes, editorPicks, pressAwards)
- Wire up 3 new views in +page.svelte with full album action callbacks
- Rename Editor's Picks to Albums of the Week, Press Awards to Press
Accolades across all 4 locale files (en, es, de, fr)
- Fix rank badge: top-right position, Impact font, 35px size
- See All styling: inline-flex with ChevronRight icon, pipe divider,
15px gap before nav buttons, #666666 color matching nav buttons
Add full-page browsing views for the three discover sections that were
previously only shown as limited carousels on the Home page.
Backend: add get_discover_albums Tauri command with endpoints for
newReleases, idealDiscography, and mostStreamed. Uses paginated API
calls with genre_ids filtering.
Frontend: new DiscoverBrowseView component with virtualized grid/list,
genre filter dropdown, client-side search, and infinite scroll.
VirtualizedFavoritesAlbumGrid gains ranking support (showRanking),
infinite scroll (onLoadMore), and loading indicator.
HomeView sections now show "See All" links that navigate to the
dedicated browse pages. i18n keys added to all 4 locales.
Qobuz limits playlists to 2000 tracks. When matched tracks exceed
this limit, the importer now automatically splits into multiple
playlists named "Playlist (Part 1)", "Playlist (Part 2)", etc.
- models.rs: qobuz_playlist_id -> qobuz_playlist_ids Vec, add parts_created
- importer.rs: chunk matched tracks by 2000, create playlist per chunk
- Frontend: show parts count in summary, move all parts to folder
- i18n: add partsCreated key in en/es/de/fr
Replace sequential track matching with buffer_unordered(8) for 8
concurrent Qobuz API calls, reducing import time ~8x. Add real-time
progress events (import:progress, import:phase) emitted from Rust
backend and consumed by frontend via Tauri event listeners.
Frontend shows progress bar, matching status text, and current track
name during import. Individual search failures are now logged and
skipped instead of aborting the entire import.
Replace 5 hardcoded validation messages ('Please enter a playlist
name', 'Please select a playlist') with i18n keys playlist.enterName
and playlist.selectPlaylist across all 4 locales.
Migrate PlaylistDuplicateConfirmModal from Svelte 4 (export let,
createEventDispatcher, on:click) to Svelte 5 ($props, callback
props, onclick). Replace hardcoded English strings with i18n keys
under playlist.duplicates for all 4 locales (en, es, de, fr).
Runtime decoration toggling doesn't work reliably in either direction
on Linux/Wayland. Always restart the app so the window is recreated
with the correct decoration state.
Disabling system titlebar works at runtime (decorations:true -> false
is fine on Linux/Wayland). Only enabling requires a restart because
the window must be born with decorations:true for WM buttons to work.
When disabling: remove OS decorations via setDecorations(false) and
restore the custom title bar immediately via notifyListeners().
Since the window must be created with the correct decoration state
(runtime toggling doesn't work on Linux/Wayland), persist the setting
to the Rust backend and restart the app immediately.
Add restart_app Tauri command using AppHandle::restart(). Update i18n
descriptions to inform the user the app will restart.
Add option to use OS native window decorations instead of the custom
QBZ title bar. Uses Tauri setDecorations() API to toggle at runtime.
Disables "Hide title bar" toggle when system bar is active.
GPU rendering is opt-in via a toggle with restart-required toast.
Recovery from crash: QBZ_HARDWARE_ACCEL=0 qbz (env var always
overrides the stored setting). i18n keys added to all 4 locales.
Replace single degradedTooltip string with quality.tooltip.*
keys (source, output, resampled, fix) for the new custom tooltip
in QualityBadge. Updated all 4 locales (en, es, de, fr).
Upload is now per-tab (Terminal/Console separately). Each tab shows a
checkmark after upload. URL displayed inline with copy button. Help text
appears after first upload encouraging users to share both URLs.
Moves streamUncached, initialBuffer, streamingOnly and related keys
from settings.audio to settings.playback in all 4 locale files.
Adds reset audio/playback keys to settings.audio section.
Adds factory reset keys to settings.storage section.
Remove gapless button from NowPlayingBar and place it in
SettingsView under Playback section. The toggle is now sensitive to
blocking settings: auto-disables when ALSA Direct backend or
streaming-only mode is activated. Gapless itself never blocks other
settings. Added inline experimental label and descriptive tooltips
with proper i18n for all 4 locales.
Add a toggleable gapless button next to the repeat button in the
NowPlayingBar. The setting persists in audio_settings.db and controls
whether the audio thread pre-queues the next track for gapless
transitions. Includes i18n keys for all 4 locales.
Adds 3-state normalization icon between fullscreen and volume controls.
Uses mask-image SVGs for theme-compatible coloring. Reduces song card
min-width by 72px to accommodate the new control.
DAC badge tooltip now says "Active" instead of "Bit-perfect" since
PipeWire passthrough is best-effort, not guaranteed bit-perfect like
ALSA Direct hw:X,Y. Added a brief note in Settings when DAC Passthrough
is enabled clarifying the distinction. Also i18n'd the hardcoded
dacPassthroughTooltipOverride string in SettingsView.
Moved all hardcoded English/Spanish tooltip text to i18n keys
under audioBadges section in all 4 locale files.
Removed dead dacTooltip derived property (unused in template).
The button previously failed silently when version was unavailable or
the GitHub API request failed. Now shows loading state while fetching
and a toast notification on failure.
Features:
- Axum REST API server for remote control
- WebSocket real-time playback updates
- Token-based authentication with QR pairing
- LAN-only security middleware
- Settings UI for enabling/configuring remote control