Commit Graph
2332 Commits
Author SHA1 Message Date
vicrodh 9a0bdc33cb fix(qconnect): register renderer role during connect bootstrap
cx
2026-02-21 14:22:09 -06:00
vicrodh 4dc60c7bb6 fix(qconnect): bootstrap renderer visibility on connect
cx
2026-02-21 14:16:55 -06:00
vicrodh 0dad07a50d fix(qconnect): auto-resolve websocket endpoint via qws createToken
cx
2026-02-21 14:07:22 -06:00
vicrodh b89c9eb5f0 feat(qconnect-ui): isolate local session persistence and route batch queue ops via admission
cx
2026-02-21 13:49:58 -06:00
vicrodh 9764b4d39a feat(qconnect-ui): apply admission-aware queue actions and i18n messages
cx
2026-02-21 13:49:55 -06:00
vicrodh ec4a9e41eb feat(ui): add Qobuz Connect panel with runtime diagnostics
cx
2026-02-21 13:38:23 -06:00
vicrodh a85f7ca324 feat(qconnect-tauri): add admission middleware commands and blocked events
cx
2026-02-21 13:38:17 -06:00
vicrodh 95f916c6d4 feat(ui): add Qobuz Connect toggle button beside cast
cx
2026-02-21 13:23:20 -06:00
vicrodh 4152d740c9 feat(qconnect-tauri): add controller command API and snapshots
cx
2026-02-21 13:10:42 -06:00
vicrodh 3e91c2f8b0 feat(qconnect-protocol): add Android controller websocket messages
cx
2026-02-21 13:04:17 -06:00
vicrodh a0790f9a1d feat(qconnect-tauri): add runtime service bridging renderer commands to CoreBridge
cx
2026-02-21 12:54:06 -06:00
vicrodh e9619b1b43 feat(qconnect-app): emit renderer command events and outbound reports
cx
2026-02-21 12:54:01 -06:00
vicrodh c6bcf6296e feat(qconnect-protocol): encode renderer->server RNDR_SRVR reports
cx
2026-02-21 12:53:55 -06:00
vicrodh fc0135246a feat(qconnect-app): apply renderer commands from WS transport events
-cx
2026-02-21 12:35:20 -06:00
vicrodh 0124728aa9 feat(qconnect-protocol): decode SRVR_RNDR command contracts from protobuf
-cx
2026-02-21 12:35:16 -06:00
vicrodh 5659bf794a feat(qconnect-core): add renderer domain state and reducer
-cx
2026-02-21 12:35:13 -06:00
vicrodh 9959117439 feat(qconnect-app): add app adapter with pending timeout, resync and concurrency policy
-cx
2026-02-21 12:17:55 -06:00
vicrodh c4ffbf4f57 feat(qconnect-transport): add native websocket transport with qcloud framing
-cx
2026-02-21 12:17:47 -06:00
vicrodh d1b01bbd5e feat(qconnect-protocol): implement protobuf queue command and server event contracts
-cx
2026-02-21 12:17:42 -06:00
vicrodh 18b1bd76e0 feat(qconnect-core): add queue domain model, reducer and pending lifecycle
-cx
2026-02-21 12:17:36 -06:00
vicrodh 373220c379 chore(qconnect): register workspace crates and tauri adapter dependency
-cx
2026-02-21 12:17:30 -06:00
vicrodh 221a66c675 fix(audio): reload settings before first play to prevent 48kHz lock
On first play after app start, the audio thread held stale settings from
Player::new() — if the user had configured PipeWire/ALSA backend, the
thread might not use the correct backend/device, defaulting to 48kHz.

Now v2_play_track reloads settings from the DB before every play_data()
call, matching what v2_reinit_audio_device already does. This is why
re-selecting the device fixed the issue: it called reload_settings first.

Also extracts convert_to_qbz_audio_settings() helper to deduplicate the
settings conversion between v2_play_track and v2_reinit_audio_device.

Fixes #69
2026-02-21 08:54:57 -06:00
vicrodh 06c6b3457b feat(radio): add track radio submenu to playlist and favorites views
Thread onCreateQbzRadio/onCreateQobuzRadio through TrackRow,
VirtualizedTrackList, PlaylistDetailView, and FavoritesView so
track context menus in playlists and favorites show the radio
submenu with QBZ Radio and Qobuz Radio options.
2026-02-21 07:34:58 -06:00
vicrodh 209cacb569 feat(mixes): add FavQ and TopQ to Your Mixes section
FavQ shuffles up to 50 tracks from the user's Qobuz favorites.
TopQ seeds the Qobuz suggest API from the user's most-played playlists.
Both have same-day cache, refresh button, red/blue gradient artwork,
and a "qbz" badge (vs "qobuz" on DailyQ/WeeklyQ).
2026-02-20 22:45:55 -06:00
vicrodh f4113a9622 feat(ui): add right-click context menu to track rows
Add context menu support (right-click) to the inline track rows in
ArtistDetailView and LabelView popular tracks sections. Right-clicking
a track opens the TrackMenu at the cursor position with all available
actions. Also wires up TrackRow component with contextMenuPosition
prop for the same functionality in reusable track rows.
2026-02-20 22:12:35 -06:00
vicrodh 2dcaa76027 feat(radio): add Qobuz artist/track radio with submenu selection
Add /radio/artist and /radio/track Qobuz API endpoints alongside the
existing /radio/album. TrackMenu now shows a radio submenu with QBZ
Radio (RadioPoolBuilder) and Qobuz Radio options when both are
available. Artist header radio button opens a dropdown to choose
between the two engines.

Backend: get_radio_artist(), get_radio_track() in client.rs,
v2_create_qobuz_artist_radio and v2_create_qobuz_track_radio commands.
Frontend: TrackMenu radio submenu with mutual exclusion against
share/download submenus, ArtistDetailView dropdown, LabelView support.
i18n keys added to all four locale files.
2026-02-20 22:10:44 -06:00
vicrodh f8a56d7f4b fix(radio): fetch full track data for album radio
The /radio/album endpoint returns partial track objects without the
performer field, causing all tracks to show as "Unknown Artist".
Extract track IDs from the response and fetch each via get_track()
to get complete data, matching the pattern used by artist/track radio.
2026-02-20 21:38:56 -06:00
vicrodh 557414ce4e feat(radio): add album radio button to UI
Add Radio button to album detail header (next to favorite button)
that calls v2_create_album_radio, populates the queue with Qobuz
API recommended tracks, and starts playback of the first track.

Add i18n keys for album radio in all 4 locale files (en/es/de/fr).
2026-02-20 21:35:15 -06:00
vicrodh d47f89c6b2 feat(radio): add RadioResponse model, API method, and v2_create_album_radio command
Add /radio/album Qobuz API endpoint support:
- RadioResponse struct in models.rs with lenient deserialization
- get_radio_album() client method
- v2_create_album_radio command that calls the API directly (no
  RadioPoolBuilder/RadioDb), filters blacklisted artists, populates
  queue, and sets Radio playback context
- Register command in lib.rs invoke handler
2026-02-20 21:32:23 -06:00
vicrodh 06c0e9735c fix(session): use struct return type and proactive saves
Two fixes for session not persisting:

1. Changed v2_get_all_queue_tracks to return a struct instead of a
   tuple — Tauri IPC serialization of tuples is unreliable.

2. Added proactive session saves instead of relying on async
   beforeunload (which races with window close):
   - Debounced full save on track change (2s after new track starts)
   - Debounced full save on pause
   - Reduced periodic save from 60s to 15s during playback
   - Close handler remains as best-effort backup
2026-02-20 20:43:35 -06:00
vicrodh aa1aa32f7a fix(session): save full queue with all tracks and metadata
The save was broken in two ways:
1. Only current_track + upcoming (capped at 20) were saved, dropping
   all history tracks. Queue was reconstructed incomplete on restore.
2. Track metadata (hires, bit_depth, sample_rate, source, etc.) was
   not being persisted, only the basic 6 fields.

Add v2_get_all_queue_tracks command that returns the full uncapped
track list with correct current_index. Use it in saveSessionBeforeClose
instead of the capped v2_get_queue_state. Map all metadata fields.
2026-02-20 20:33:39 -06:00
vicrodh 5a0d4c50a1 feat(session): re-enable session restore and add startup page setting
Re-enable queue/track restore on startup (visual only, paused at 0:00).
Update saveSessionBeforeClose to persist current view with context IDs.
Add "Startup page" dropdown in Settings > Appearance (Home / Where you
left off) that controls whether the last view is restored on launch.
i18n keys added to all 4 locale files.
2026-02-20 20:02:26 -06:00
vicrodh 07d5d95cea feat(session): extend frontend service and add restoreView helpers
Update PersistedSession interface with last_view fields. Add lastView,
viewContextId, viewContextType params to saveSessionState(). Add
restoreView(), setRestoredPlaylistId(), setRestoredLocalAlbumId() to
navigationStore for session restore without triggering data fetches.
2026-02-20 19:58:54 -06:00
vicrodh cda07f97c5 feat(session): extend schema with last_view columns and V2 params
Add last_view, view_context_id, view_context_type to player_state
table via migration. Update PersistedSession struct, save/load/clear,
and v2_save_session_state with 3 new optional parameters.
2026-02-20 19:58:17 -06:00
vicrodh 6a04f13174 fix(keybindings): resolve 4 keyboard shortcut bugs (#95)
- Strip Shift modifier for symbol keys in eventToShortcut() so ? maps correctly
- Remove duplicate Space handler in ImmersivePlayer that caused double-fire
- Add bindingsVersion dependency to KeybindingsSettings for instant visual updates
- Add missing uiOpenLink i18n key and use getActionLabel() fallback in modal
- Add full keybindings translations to de.json and fr.json
2026-02-20 19:33:40 -06:00
vicrodh cd57d37e7a feat(settings): add font family selector in Appearance
- Add 4 bundled fonts: Montserrat, Noto Sans, Source Sans 3, plus
  existing LINE Seed JP (default) and System fallback
- Font selector dropdown in Settings > Appearance, after Language
- Persisted in localStorage, applied on app bootstrap via data-font
  attribute on <html> which overrides --font-sans CSS variable
- @font-face declarations for variable font files in static/fonts/
- i18n key "fontFamily" added to all 4 locales
2026-02-20 18:13:57 -06:00
vicrodh e82940810b feat(immersive): make window draggable and rename to Immersive Mode
- Add persistent drag region (32px strip) at top of immersive overlay
  that remains active even when the header auto-hides after 4 seconds
- Add app-region: drag CSS to ImmersiveHeader's left spacer for proper
  drag support when header is visible
- Add app-region: no-drag to tabs and window controls to keep them
  clickable
- Double-click on drag strip toggles maximize
- Rename "Full Screen" to "Immersive Mode" in all 4 locales (en/es/de/fr)
2026-02-20 18:03:41 -06:00
vicrodh fec3db17fa feat(link-resolver): direct platform APIs + smart Qobuz search
- Deezer/Spotify/Tidal: fetch metadata directly from platform APIs
  (bypasses Odesli ~300ms vs ~2-3s) with Odesli as fallback
- Smart Qobuz search with 3 progressive attempts:
  1. Full "title artist" query
  2. Cleaned title (strip parenthetical/bracket suffixes like Remastered)
  3. Artist-only search with fuzzy title matching
- Fixes albums not found when platform titles differ (e.g. Iron Maiden
  "Senjutsu (2021 Remaster)" vs Qobuz "Senjutsu")
2026-02-20 16:46:20 -06:00
vicrodh 97e319f2d9 fix(link-resolver): add retry for transient Odesli API errors
The Odesli API can fail with connection errors on rapid successive
requests (connection pool staleness). Add a single retry with 500ms
delay to handle transient network failures gracefully.

Also improve song.link URL handling to hint track vs album detection.
2026-02-20 16:37:58 -06:00
vicrodh 9ba09ff37b fix(share): handle Odesli entities with numeric IDs (Bandcamp)
Odesli's API returns entity IDs as integers for some platforms (e.g.
Bandcamp) while others return strings. The Entity.id field was typed as
String which caused serde deserialization to fail on numeric values.

Add a custom deserializer that accepts both strings and numbers.
Also show actual backend error in LinkResolverModal for easier debugging.
2026-02-20 16:31:02 -06:00
vicrodh e581508946 fix(link-resolver): search Qobuz catalog instead of relying on Odesli platform map
Odesli does NOT include Qobuz in its linksByPlatform response, so the
previous approach of extracting platforms["qobuz"] would always fail.

New strategy: use Odesli to identify the content (title/artist), then
search the Qobuz catalog via CoreBridge to find the matching album or
track. Falls back from track search to album search if needed.
2026-02-20 15:54:33 -06:00
vicrodh b78b67fa8c feat(link-resolver): cross-platform music link resolution via Odesli
Ctrl+L now accepts URLs from Spotify, Apple Music, Tidal, Deezer, and
song.link/album.link in addition to Qobuz. Non-Qobuz track/album URLs
are resolved to their Qobuz equivalent via the existing Odesli API
integration. Playlist URLs redirect to the Playlist Importer.

- Add MusicResource/MusicProvider enums and detect_music_resource()
- Add detect_resource() to each provider (spotify, apple, tidal, deezer)
- Add v2_resolve_music_link command with Odesli-based cross-resolution
- Upgrade LinkResolverModal with platform icon detection and playlist redirect
- Update i18n keys in all 4 locales (en, es, de, fr)
2026-02-20 15:27:49 -06:00
vicrodh 45a1a6471b fix(player): album art hover preview renders above sidebar
NowPlayingBar z-index raised from 100 to 2001 (above sidebar's 2000)
so the artwork preview floats over the sidebar instead of behind it.
Safe because the bar and sidebar occupy non-overlapping vertical space.

Fixes #96
2026-02-20 14:57:37 -06:00
vicrodh 417ece2fb9 fix(library): clean up deleted files during scan refresh
Library scan now automatically removes tracks whose files no longer
exist on disk, both for full scans and single-folder scans. Previously,
deleted files would remain in the library until the user manually ran
"Cleanup missing files" from Settings.

Fixes #93
2026-02-20 14:54:00 -06:00
vicrodh 3f17c83847 fix(purchases): persist verbose log toggle, fix dropdown stacking, wire Add to Library button
- Verbose capture toggle now persists to localStorage across sessions
- PurchasesView dropdown menus now have mutual exclusion (opening one closes others)
- Add to Library button wired to v2_library_add_folder with download destination tracking
- Added i18n keys for add-to-library success/error toasts (all 4 locales)
2026-02-20 14:46:03 -06:00
vicrodh 8051f1745b feat(about): two-column build info, show git commit hash
- Build Info grid now uses 2-column layout (Version|License, Platform|Build)
- Build field shows date + short commit hash (6 chars) injected at
  build time via VITE_BUILD_COMMIT
2026-02-20 14:36:54 -06:00
vicrodh 321a165285 Merge remote-tracking branch 'origin/dependabot/npm_and_yarn/sveltejs/kit-2.52.2' into pre-release
# Conflicts:
#	package-lock.json
2026-02-20 14:34:45 -06:00
vicrodh 7b4cccad7b Merge remote-tracking branch 'origin/dependabot/npm_and_yarn/devalue-5.6.3' into pre-release
# Conflicts:
#	package-lock.json
2026-02-20 14:34:35 -06:00
vicrodh dfa6ae3d04 style(about): wider modal, two-column acknowledgments, author as pill
- Increase modal max-width by 110px (672 -> 782)
- Acknowledgments section now uses 2-column grid layout
- Replace plain author name with GitHub avatar pill (slightly larger
  than contributor pills)
2026-02-20 14:32:48 -06:00
vicrodh 384952a500 feat(about): add contributors section with GitHub links
Add horizontal list of code contributors (vorce, boxdot) below the
author section, with avatars and links to their GitHub profiles.
2026-02-20 14:29:49 -06:00