Modal PDF viewer for album booklets with page navigation,
zoom controls, and keyboard shortcuts. Uses pdfjs-dist to
render PDF pages from URL in canvas.
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.
- Increase pool sizes (INITIAL_POOL 18->30, EXPANDED_POOL 60->100, MAX_POOL 120->200)
- Add auto-refresh when available tracks fall below threshold (MIN_AVAILABLE_THRESHOLD=12)
- Add artist identity validation to filter incompatible genres (prevents merengue in metal playlists)
- Log when artists are skipped due to incompatible disambiguation
- Increase backend defaults (max_artists 20->30, tracks_per_artist 5->6, max_pool_size 100->150)
- Update version to 1.1.6-rc for release candidate testing
- Add Linux ARM64/aarch64 build workflow
- Uses ubuntu-24.04-arm GitHub runner (free for public repos)
- Builds .deb, .rpm, .AppImage, and AUR tarball for ARM64
- Workflow isolated with continue-on-error to not block x86_64 builds
Backend:
- Add add_tracks_to_pending_playlist method to OfflineStore
- Reads current track lists, appends new tracks, updates DB
- Add corresponding Tauri command and register in lib.rs
Frontend:
- Detect pending playlists by negative ID in handleAddToPlaylist
- Call add_tracks_to_pending_playlist for pending playlists
- Properly separate Qobuz and local tracks before adding
- Fixes error trying to call playlist_add_local_track with negative ID
- Backend now emits playback:state events every 250ms when state changes
- PlayerStore uses listen() instead of setInterval for real-time updates
- Added Vitest testing framework with mocked Tauri APIs
- Added 53 unit tests for playerStore and queueStore
Import Chromecast, AirPlay, and DLNA casting scaffolding from separate
branches. The module is currently disabled due to:
- Thread safety issues: rust_cast uses Rc internally (not Send)
- API compatibility: rupnp methods have changed
The scaffolding includes:
- Chromecast: mDNS discovery, device connection, media server
- AirPlay: Discovery scaffolding (RAOP playback pending)
- DLNA/UPnP: SSDP discovery scaffolding (playback pending)
To enable casting in the future:
1. Fix rust_cast thread safety (or use spawn_blocking)
2. Update rupnp API calls for current version
3. Add Deserialize derive to metadata types
4. Uncomment cast module in lib.rs
5. Wire up commands in invoke_handler
- Add svelte-i18n dependency
- Create i18n configuration with locale persistence
- Add complete translation files for EN and ES
- Create root layout with theme CSS variables
- Support 4 themes: dark (default), light, oled, warm
- Add global styles and spacing system