Commit Graph
874 Commits
Author SHA1 Message Date
vicrodh 53927b5c6f Add missing V2 commands and deprecate legacy integration commands
New V2 commands:
- v2_lastfm_set_session: Set session key for restored sessions
- v2_listenbrainz_queue_listen: Queue listen for offline (uses legacy cache)

Deprecated legacy commands (with #[deprecated] markers):
- ListenBrainz: get_status, is_enabled, set_enabled, connect, disconnect,
  now_playing, scrobble, queue_listen
- Last.fm: is_authenticated, get_auth_url, authenticate, set_session,
  disconnect, scrobble, now_playing
- MusicBrainz: is_enabled, set_enabled
- Audio: reinit_audio_device

All deprecated commands point to their V2 replacements in the note.
Frontend migration to V2 commands is next.
2026-02-15 15:29:59 -06:00
vicrodh 943f886637 Add V2 integration states to session lifecycle
Integrates ListenBrainzV2State, MusicBrainzV2State, and LastFmV2State
from qbz-integrations crate into the session activation/deactivation
lifecycle.

In activate_session:
- After legacy integrations init (which loads from SQLite), sync
  credentials to V2 states
- ListenBrainz V2: gets token, user_name, enabled from legacy client
- MusicBrainz V2: gets enabled state (use_proxy defaults to true)
- LastFm V2: initialized to clean state (no legacy equivalent)

In deactivate_session:
- Clear V2 state credentials to prevent cross-user leaks
- Reset states to defaults

This ensures V2 commands (using qbz-integrations crate) have access
to the same credentials as legacy commands, enabling a smooth
migration path.
2026-02-15 15:06:59 -06:00
vicrodh 856ceb796d Enforce ToS gate in backend for all login entrypoints
Add centralized require_tos_accepted() helper function that checks
ToS acceptance before any authentication attempt. This prevents
non-UI clients (TUI/CLI/tests) from bypassing the ToS gate.

Affected commands:
- v2_auto_login: Returns tos_not_accepted error code
- v2_manual_login: Returns tos_not_accepted error code
- v2_login: Returns RuntimeError::Internal

The ToS check was already in runtime_bootstrap, but these commands
could be called directly. Now the gate is enforced at the backend
level regardless of entry point.

Also updates obsolete comment about frontend handling ToS.
2026-02-15 15:02:15 -06:00
vicrodh d0fb30a5b1 fix(auth): enforce ToS gate and session activation severity parity
Fixes login consistency issues:

1. ToS gate enforcement:
   - LegalSettingsState now initialized GLOBALLY at app startup (not per-session)
   - runtime_bootstrap checks ToS BEFORE attempting auto-login
   - If ToS not accepted, skip auto-login and return to login screen

2. Session activation severity parity:
   - runtime_bootstrap now treats activate_session failure as FATAL
   - On failure: rollback auth state, set degraded, return error
   - Matches behavior of v2_auto_login/v2_manual_login

3. LegalSettings is now truly global:
   - Removed from session_lifecycle activate/deactivate
   - ToS acceptance persists across sessions
   - Can be checked before user is logged in

Acceptance criteria:
- ToS false + credentials -> no auto-login
- ToS true + credentials + activation OK -> session restored
- ToS true + credentials + activation fails -> error, no session
2026-02-15 14:55:14 -06:00
vicrodh 63994c0a20 refactor(cast): extract qbz-cast crate
Extract casting functionality (Chromecast, AirPlay, DLNA) to standalone
qbz-cast crate. This crate is Tauri-agnostic and can be used by TUI/CLI
clients.

- Move device connection, discovery, threading, and media server to crate
- Keep only Tauri commands in src-tauri/src/cast/
- Thin re-exports in src-tauri for backwards compatibility
- Remove duplicate dependencies from src-tauri Cargo.toml
2026-02-15 14:51:06 -06:00
vicrodh deece54bcb fix: eliminate double-brain session lifecycle (legacy vs V2)
Backend:
- v2_auto_login/v2_manual_login now FAIL if activate_session fails
  (was: log and continue with success:true, causing "logged in but not ready")
- Session activation is now REQUIRED, not optional

Frontend:
- Remove duplicate activate_user_session call from handleLoginSuccess
  (V2 login already activates session internally)
- Remove duplicate deactivate_user_session call from handleLogout
  (v2_logout already deactivates session internally)
- LoginView now uses runtime_bootstrap as SINGLE SOURCE OF TRUTH
  (was: v2_init_client + legacy is_logged_in/get_user_info checks)
- PlaylistDetailView uses runtime_get_status for user_id
  (was: legacy get_current_user_id)

This eliminates the "double-brain" where frontend used both legacy
and V2 paths, causing state divergence and intermittent failures.
2026-02-15 14:39:44 -06:00
vicrodh 59e3141aa6 fix: address 7 code review findings for V2 architecture
HIGH priority fixes:
- Enable WAL mode in qbz-integrations caches (ADR-002)
- v2_auto_login/v2_manual_login now call activate_session()
- RequiresUserSession allows offline sessions (only checks session_activated)

MEDIUM priority fixes:
- Consolidate lifecycle: legacy commands delegate to session_lifecycle
- ListenBrainz teardown now calls disconnect() to clear tokens
- Add SessionActivationFailed degraded reason and emit event on failure
2026-02-15 12:21:17 -06:00
vicrodh d6e4b3349b feat(qbz-library): extract local library management to standalone crate
Create qbz-library crate with:
- LibraryScanner: directory scanning for audio files
- MetadataExtractor: audio metadata extraction via lofty
- LibraryDatabase: SQLite persistence with WAL mode
- CueParser: CUE sheet parsing for single-file albums
- Thumbnails: artwork extraction and thumbnail generation
- Tag sidecar: album metadata override files

src-tauri re-exports from qbz-library for backwards compatibility.
Enables TUI/headless clients to manage local libraries without Tauri.
2026-02-15 12:12:52 -06:00
vicrodh 384459d4d7 feat(qbz-cache): extract audio caching to standalone crate
Create qbz-cache crate with:
- AudioCache: L1 in-memory LRU cache (~300MB)
- PlaybackCache: L2 disk-based cache (~500MB)
- LRU eviction with spillover from L1 to L2

src-tauri now re-exports from qbz-cache for backwards compatibility.
This enables TUI/headless clients to use caching without Tauri.
2026-02-15 11:27:38 -06:00
vicrodh a66d5a2af3 refactor(v2): use RuntimeError in remaining V2 commands
Convert all remaining V2 commands from Result<T, String> to Result<T, RuntimeError>:
- runtime_get_status, v2_is_logged_in
- v2_login, v2_logout, v2_activate_offline_session
- v2_play_track, v2_get_discover_albums
- Search commands: v2_search_albums, v2_search_tracks, v2_search_artists
- Catalog commands: v2_get_album, v2_get_track, v2_get_artist
- Favorites commands: v2_get_favorites, v2_add_favorite, v2_remove_favorite
- Playlist commands: full suite including CRUD operations
- Extended catalog: v2_get_tracks_batch, v2_get_genres, v2_get_discover_*
- Artist commands: v2_get_artist_page, v2_get_similar_artists, v2_get_artist_with_albums
- v2_get_label

Only v2_auto_login/v2_manual_login retain String (intentional - use V2LoginResponse error fields)
and download_audio (internal utility wrapped by callers).
2026-02-15 11:23:16 -06:00
vicrodh 8a6050f2f3 refactor(v2): use RuntimeError in queue and playback commands
Convert queue commands (16) and playback commands (10) from String
errors to typed RuntimeError:
- Queue: get_queue_state, set_repeat_mode, toggle_shuffle, etc.
- Playback: pause, resume, stop, seek, volume, get_state, etc.

Runtime checks now use direct ? propagation instead of map_err.
Bridge method errors wrapped with RuntimeError::Internal.
2026-02-15 11:15:13 -06:00
vicrodh 0c50c67a61 feat(v2): add integrations V2 commands using qbz-integrations crate
Wire qbz-integrations to Tauri via new V2 commands:

ListenBrainz V2:
- v2_listenbrainz_get_status, is_enabled, set_enabled
- v2_listenbrainz_connect, disconnect
- v2_listenbrainz_now_playing, scrobble

MusicBrainz V2:
- v2_musicbrainz_is_enabled, set_enabled
- v2_musicbrainz_resolve_track, resolve_artist

Last.fm V2:
- v2_lastfm_get_auth_url, complete_auth
- v2_lastfm_is_authenticated, disconnect
- v2_lastfm_now_playing, scrobble

New module integrations_v2.rs provides Tauri state wrappers for the
Tauri-independent clients from qbz-integrations crate.
2026-02-15 11:11:35 -06:00
vicrodh 6310e9b216 chore: add qbz-integrations crate dependency
Wire qbz-integrations to src-tauri Cargo.toml. The crate provides
Tauri-independent implementations of Last.fm, ListenBrainz, and
MusicBrainz integrations.

Next step: Create V2 commands that use the new crate, then gradually
deprecate the existing in-tree implementations.
2026-02-15 11:05:33 -06:00
vicrodh fbb7f3c226 refactor(v2): use RuntimeError in audio settings commands
Replace String errors with typed RuntimeError variants across all 17
audio settings V2 commands for consistent error handling:
- Lock errors: RuntimeError::Internal
- Session not active: RuntimeError::UserSessionNotActivated
- Store errors: RuntimeError::Internal

This aligns with the runtime contract (ADR_RUNTIME_SESSION_CONTRACT.md)
for typed errors that clients can pattern match.
2026-02-15 10:58:09 -06:00
vicrodh e70c577181 refactor: centralize session lifecycle, make runtime_bootstrap autocontenido
Addresses multiple review findings for V2 architecture:

1. Create session_lifecycle.rs module:
   - activate_session(): Full session activation callable from anywhere
   - deactivate_session(): Full teardown with proper runtime state cleanup
   - activate_offline_session(): Minimal session for offline/local-only use

2. Make runtime_bootstrap autocontenido:
   - Now activates session after successful auth (Step 4)
   - No longer delegates to frontend for session activation

3. Fix v2_login to be canonical:
   - Performs full flow: legacy auth -> corebridge auth -> session activation
   - Updates all runtime state flags

4. Fix v2_logout to be canonical:
   - Calls deactivate_session (teardown stores + clear runtime state)
   - Proper cleanup of legacy and corebridge auth

5. Fix deactivate_session:
   - Now clears session_activated flag (was missing)
   - Now clears corebridge_auth flag (was missing)
   - Emits UserSessionDeactivated event

6. Add v2_set_repeat_mode runtime check:
   - Now requires RequiresUserSession like other queue mutations

7. Fix LoginView early session activation:
   - Removed premature activate_user_session call before auto-login confirmed
   - ToS check uses localStorage fallback if no session

8. Fix offline mode:
   - Add v2_activate_offline_session command
   - Offline mode now activates minimal session so queue commands work
2026-02-15 10:53:49 -06:00
vicrodh cfe931e8ee fix: address critical login state and queue command issues
Issue 1 (HIGH): Fix UI/backend login state divergence
- Move setLoggedIn() AFTER successful activate_user_session
- Prevents UI entering logged-in state when backend fails

Issue 2 (HIGH): Fix userId fallback to 0
- Add validation in LoginView for both auto_login and manual_login
- Reject success responses with invalid user_id (0 or missing)

Issue 3 (HIGH): Add runtime requirement checks to queue commands
- All queue mutation commands now require authenticated user session
- CoreBridge-based commands require RequiresCoreBridgeAuth
- AppState-based commands require RequiresUserSession

Issue 6 (MEDIUM): Remove V1 auth surface
- Remove login, logout, auto_login from invoke_handler
- Frontend must use v2_login, v2_logout, v2_auto_login
2026-02-15 10:30:47 -06:00
vicrodh efb707d972 feat(v2): add v2_get_discover_albums command
Add get_discover_albums to qbz-core, CoreBridge, and commands_v2.
Supports endpoints: newReleases, idealDiscography, mostStreamed,
qobuzissimes, albumOfTheWeek, pressAward.

Migrate DiscoverBrowseView to use v2_get_discover_albums.
2026-02-15 05:32:33 -06:00
vicrodh 2f7cae58f4 feat(v2): add extended catalog and playlist V2 commands
Add missing API methods to QbzCore, CoreBridge, and V2 commands:
- Playlist management: create, delete, update, search
- Catalog: genres, discover index/playlists, playlist tags, featured albums
- Artists: artist page, similar artists, artist with albums pagination
- Labels: label details
- Tracks: batch fetch

All methods follow the V2 architecture with RuntimeManager requirements.
2026-02-15 04:25:31 -06:00
vicrodh ed80981852 feat(runtime): add requirement checks to catalog and playback commands
Add RuntimeManagerState and check_requirements to:
- v2_get_album/track/artist (RequiresCoreBridgeAuth)
- v2_pause/resume/stop_playback (RequiresClientInit)
- v2_seek, v2_set_volume (RequiresClientInit)

Playback commands use RequiresClientInit since they operate on
the local player and don't need API auth, just initialized state.
2026-02-15 04:08:06 -06:00
vicrodh 645cfe9194 feat(runtime): apply check_requirements to critical V2 commands
Add RuntimeManagerState parameter and CommandRequirement check to:
- v2_play_track (RequiresCoreBridgeAuth)
- v2_search_albums/tracks/artists (RequiresCoreBridgeAuth)
- v2_get_favorites/add_favorite/remove_favorite (RequiresCoreBridgeAuth)
- v2_get_user_playlists/get_playlist (RequiresCoreBridgeAuth)
- v2_add_tracks_to_playlist/remove_tracks_from_playlist (RequiresCoreBridgeAuth)

This enforces the ADR Runtime Session Contract at the command level.
V2 commands now fail with typed RuntimeError if auth state is invalid.
2026-02-15 04:05:38 -06:00
vicrodh 58f1957a05 feat(runtime): implement phased V2 login commands for runtime contract
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.
2026-02-15 04:02:34 -06:00
vicrodh 854088c3de fix(v2): make CoreBridge auth blocking per ADR
- auto_login now fails if V2 CoreBridge auth fails
- runtime_bootstrap now fails if V2 CoreBridge auth fails
- Add V2AuthFailed and V2NotInitialized runtime error variants
- Consistent with login command which was already blocking
2026-02-15 03:54:27 -06:00
vicrodh 8a844612ff feat(v2): migrate audio settings commands to V2
- Add V2 audio settings commands (output device, exclusive mode, DAC
  passthrough, sample rate, backend type, ALSA plugin, gapless,
  normalization, streaming only, quality limiting, etc.)
- Update frontend SettingsView to use V2 audio commands
- Update +page.svelte to use V2 normalization command
2026-02-15 03:52:48 -06:00
vicrodh 846da0270e feat(v2): migrate playlist commands to V2 architecture
- Add playlist methods to QbzCore (get_user_playlists, get_playlist,
  add_tracks_to_playlist, remove_tracks_from_playlist)
- Add playlist methods to CoreBridge
- Create V2 Tauri commands for all playlist operations
- Update frontend to use V2 playlist commands
- Support both playlistTrackIds and trackIds in remove command
  (with automatic resolution like legacy)
2026-02-15 00:41:48 -06:00
vicrodh 7a133e2915 Add V2 favorites commands using QbzCore
- Add get_favorites, add_favorite, remove_favorite to QbzCore
- Add favorites methods to CoreBridge
- Add v2_get_favorites, v2_add_favorite, v2_remove_favorite commands
- Migrate favoritesStore, artistFavoritesStore, albumFavoritesStore
- Migrate ArtistDetailView favorites toggle

Favorites operations now flow through V2 architecture.
2026-02-15 00:10:09 -06:00
vicrodh 7ef7ff1c7d Make V2 auth required and integrate RuntimeManager with auth
- Login now requires V2 CoreBridge auth to succeed (per ADR)
- V2 auth failure returns typed error, not silent non-blocking warning
- Update RuntimeManager state on login/logout for canonical tracking
- Add runtime_manager parameter to login and logout commands

This implements Phase 4 of the runtime contract: Login Semantics Hardening
2026-02-14 23:24:42 -06:00
vicrodh f34882ccc5 Integrate RuntimeManager with session lifecycle
- Add RuntimeManagerState to activate_user_session
- Add RuntimeManagerState to deactivate_user_session
- Update runtime state on session activation/deactivation
- Add v2_remove_upcoming_track command

This implements Phase 2 of the runtime contract by ensuring session
state changes are reflected in the canonical RuntimeManager.
2026-02-14 23:22:45 -06:00
vicrodh 6cea4149c0 Migrate all queue operations to V2 commands
- Add V2 queue commands: v2_set_shuffle, v2_move_queue_track,
  v2_add_tracks_to_queue, v2_add_tracks_to_queue_next,
  v2_remove_upcoming_track
- Migrate queueStore.ts to use all V2 queue commands
- Update all view components to use V2 queue commands:
  - HomeView, SearchView, ArtistDetailView, FavoritesView
  - LocalLibraryView, PlaylistDetailView
- Update +page.svelte to use V2 shuffle, repeat, and remove commands

No legacy queue commands are called from frontend anymore.
2026-02-14 23:21:19 -06:00
vicrodh 67ed397d02 feat(v2): add runtime contract and queue V2 commands
Runtime contract (ADR Phase 1+2):
- Add RuntimeManager with canonical state machine
- Add RuntimeStatus, RuntimeError (typed errors)
- Add RuntimeEvent for lifecycle events
- Add runtime_get_status and runtime_bootstrap commands

Queue V2 commands:
- v2_add_to_queue, v2_add_to_queue_next
- v2_set_queue, v2_remove_from_queue
- v2_next_track, v2_previous_track, v2_play_queue_index
- V2QueueTrack type with proper field mapping

All queue operations now have V2 equivalents.
Frontend migration to use these commands is next.
2026-02-14 23:13:21 -06:00
vicrodh d79e84fb9c fix(playback): emit events from V2 player when active
The event loop now checks both V2 (qbz-player) and legacy player states.
V2 player takes priority when it has an active track (track_id != 0).

This ensures the frontend receives correct playback position, duration,
sample rate, and bit depth when using v2_play_track commands.

Changes:
- Store V2 player SharedState after CoreBridge initializes
- Event loop checks V2 state first, falls back to legacy
- All playback event values now come from the active player
2026-02-14 23:04:17 -06:00
vicrodh c4b28e37ea fix(session): prevent false login state with userId=0
Addresses race condition and invalid state issues identified by Codex diagnostic:

1. CoreBridge: Add try_get() and is_initialized() methods to gracefully
   handle uninitialized state instead of panicking

2. auth.rs: Use try_get() for V2 auth in login/auto_login/logout to
   avoid panic if CoreBridge init is still in progress

3. LoginView.svelte: Reject userId=0 as fallback - if userInfo or userId
   is missing/invalid, don't call onLoginSuccess (require re-login)

4. +page.svelte:
   - Move get_audio_settings call to after sessionReady is set
   - Add explicit userId > 0 check before activate_user_session
   - Return early if activation fails to prevent sessionReady from
     being set in broken state

These are tactical fixes aligned with ADR_RUNTIME_SESSION_CONTRACT.md
invariants. Full runtime state machine implementation to follow.
2026-02-14 22:59:20 -06:00
vicrodh c3a14c1c87 feat(v2): add v2_reinit_audio_device command
- Added v2_reinit_audio_device for V2 player device reinitialization
- SettingsView now calls both legacy and V2 reinit commands
- Converts legacy AudioSettings to qbz_audio::AudioSettings for reload
2026-02-14 22:48:03 -06:00
vicrodh fbba4f25c1 feat(v2): add automatic prefetch to v2_play_track
- Added spawn_v2_prefetch helper function
- v2_play_track now prefetches next 2 Qobuz tracks after playback starts
- Respects streaming_only mode (skips prefetch when enabled)
- Uses semaphore to limit concurrent prefetch downloads to 1
- Prefetch works with cache (offline, memory, disk) paths
2026-02-14 22:45:29 -06:00
vicrodh 82a81e1ded feat(v2): add MPRIS, gapless, and prefetch V2 commands
V2 Playback Features:
- v2_set_media_metadata: Update MPRIS metadata
- v2_play_next_gapless: Queue next track for gapless playback
- v2_prefetch_track: Pre-download track into memory cache

V2 Command Updates:
- v2_pause/resume/stop: Now update MPRIS state
- v2_seek: Updates MPRIS progress
- v2_get_playback_state: Updates MPRIS progress on poll

Frontend Migration:
- playbackService: Use v2_set_media_metadata
- playerStore: Use v2_play_next_gapless
2026-02-14 22:42:03 -06:00
vicrodh 6778ef4ba6 fix(auth): sync V2 CoreBridge authentication with legacy login
- Modified login/auto_login commands to also authenticate CoreBridge
- Modified logout command to also logout from CoreBridge
- Removed redundant v2_login call from LoginView.svelte frontend

This ensures both legacy AppState.client and V2 CoreBridge.QbzCore.client
are authenticated in sync, allowing V2 commands to work after login.
2026-02-14 22:38:26 -06:00
vicrodh 41c8acce38 feat(tauri): register v2_play_track command 2026-02-14 22:11:05 -06:00
vicrodh af0d88283a feat(v2): implement v2_play_track command
Core playback now flows through V2 architecture:
- Added get_stream_url to QbzCore and CoreBridge
- Implemented v2_play_track with full cache support:
  - Offline cache (persistent disk)
  - Memory cache (L1)
  - Playback cache (L2 - disk)
- Downloads from Qobuz via CoreBridge.get_stream_url()
- Plays via CoreBridge.player() (qbz-player crate)
- Respects quality limits and streaming_only settings

Still uses AppState.audio_cache for caching (to be migrated later).
No dependency on legacy player module for playback.
2026-02-14 22:10:36 -06:00
vicrodh ac26f2079b chore: mark legacy player and queue modules as deprecated
Added DEPRECATED headers to src-tauri/src/player/mod.rs and
src-tauri/src/queue/mod.rs indicating these will be removed
after migration to qbz-player crate is complete.

New code should use:
- qbz_player::Player (via CoreBridge -> QbzCore)
- qbz_player::QueueManager (via CoreBridge -> QbzCore)
2026-02-14 22:07:30 -06:00
vicrodh 0e85285e90 feat(core): wire Player from qbz-player through QbzCore
- QbzCore now accepts Player in constructor and owns playback
- Added playback methods to QbzCore (pause, resume, stop, seek, volume)
- CoreBridge loads audio settings and creates Player from qbz-player
- V2 playback commands use CoreBridge instead of AppState

This closes the "operational playback core" gap identified by Codex.
V2 commands now flow: frontend -> commands_v2 -> CoreBridge -> QbzCore -> Player

Legacy player in src-tauri/src/player/ remains as emergency fallback.
2026-02-14 20:20:37 -06:00
vicrodh b12a06fff3 feat(v2): expand V2 commands with playback and dual event emission
V2 Commands expanded:
- Add searchType parameter to search commands
- Add blacklist filtering to V2 search commands
- Add V2 playback commands (pause, resume, stop, seek, volume, state)

TauriAdapter dual emission:
- Emit both "core-event" (new) and legacy events during migration
- Legacy events: queue:updated, queue:shuffle-changed, queue:repeat-changed
- Legacy events: auth:logged-in, auth:logged-out, error

Frontend migration (partial soft-delete test):
- SearchView, ArtistDetailView, LocalLibraryView use v2_search_*
- HomeView, +page.svelte use v2_get_album, v2_get_track
- TrackReplacementModal uses v2_search_tracks

Old commands remain registered but are no longer called by migrated
frontend code. This enables testing V2 architecture while keeping
fallback available.
2026-02-14 20:10:58 -06:00
vicrodh a8f56444ce feat(v2-commands): fix parameter names for frontend compatibility
- Use camelCase parameter names (albumId, trackId, artistId) to match
  frontend expectations
- Add #[allow(non_snake_case)] to suppress warnings

V2 commands are ready for testing. Full frontend migration pending:
- Search commands need searchType parameter
- Need to add get_user_info, login with full flow, etc.
2026-02-14 19:48:12 -06:00
vicrodh b930fa11ba fix(v2-commands): return SearchResultsPage for search commands
Update search commands to return full SearchResultsPage<T> with pagination
info instead of just Vec<T>. This makes V2 commands compatible with the
frontend's expected response format.
2026-02-14 19:46:16 -06:00
vicrodh 8ed8f02fcd Phase 7a: Replace src-tauri audio module with qbz-audio re-exports
- Remove duplicate audio module files from src-tauri
- Update audio/mod.rs to re-export from qbz_audio
- Single source of truth for audio types now in qbz-audio crate
- Compilation passes, types are aligned
2026-02-14 17:48:03 -06:00
vicrodh 0238b1c559 feat(qbz-nix): Phase 6.4 - add search and catalog V2 commands
Add search and catalog retrieval methods to QbzCore and V2 commands.

QbzCore methods added:
- search_albums, search_tracks, search_artists
- get_album, get_track, get_artist

V2 commands added:
- v2_search_albums, v2_search_tracks, v2_search_artists
- v2_get_album, v2_get_track, v2_get_artist

All commands registered in invoke_handler.
2026-02-14 15:16:31 -06:00
vicrodh 255dcf06fe feat(qbz-nix): Phase 6.3 - wire up CoreBridge in app setup
Initialize CoreBridge in Tauri setup hook and register V2 commands.

Changes:
- Add CoreBridgeState to managed Tauri state
- Initialize CoreBridge asynchronously in setup hook
- Register V2 commands in invoke_handler

The app now initializes the new multi-crate architecture alongside
the existing system. V2 commands are available for frontend testing.
2026-02-14 14:56:36 -06:00
vicrodh f59f0e1b87 feat(qbz-nix): Phase 6.2 - CoreBridge and V2 commands
Add bridge layer connecting QbzCore to Tauri and example V2 commands.

New files:
- core_bridge.rs: CoreBridge wraps QbzCore for Tauri integration
- commands_v2.rs: Example commands using new architecture

V2 commands implemented:
- v2_is_logged_in, v2_login, v2_logout (auth)
- v2_get_queue_state, v2_set_repeat_mode, v2_toggle_shuffle, v2_clear_queue

These coexist with old commands during migration. Frontend can
gradually switch to V2 commands as they're tested.
2026-02-14 14:54:20 -06:00
vicrodh d0e46aca05 feat(qbz-nix): Phase 6.1 - integrate extracted crates
Add dependencies on extracted crates and create TauriAdapter.

Changes:
- Add qbz-models, qbz-audio, qbz-player, qbz-qobuz, qbz-core as deps
- Add async-trait dependency for FrontendAdapter impl
- Create tauri_adapter.rs implementing FrontendAdapter
- TauriAdapter emits CoreEvents to frontend via Tauri event system

This is the first step of integration. The old modules still exist
but the new crates are now available for gradual migration.
2026-02-14 14:32:24 -06:00
vicrodh 1c9bb8dfdb Merge branch 'pr-79' into pre-release 2026-02-14 12:37:54 -06:00
Joel C 1ad22000ea Add unit tests 2026-02-14 17:57:26 +01:00
Joel C f29f95f6d2 Fix clear queue, preserve playing track if needed 2026-02-14 17:57:16 +01:00