Commit Graph
100 Commits
Author SHA1 Message Date
vicrodh 94c867c934 chore: bump version to 1.1.8-rc-6 for workflow testing 2026-02-04 18:46:58 -06:00
vicrodh 31df685e08 fix: lower jump-nav z-index to prevent overlap with dropdown menus
Reduced z-index from 4 to 1 to ensure dropdown menus appear above
the sticky navigation bar.

cc
2026-02-04 17:25:16 -06:00
vicrodh 4dec2df315 chore: temporarily disable remote control setup guide button
Content not ready for release.

cc
2026-02-04 16:51:50 -06:00
vicrodh eaed5b3c9e refactor(artist): improve hide artist button
- Hide button only shows when content filtering is enabled
- Use custom blind-eye.svg icon
- Remove border for cleaner look
- Banner also conditional on filtering being enabled

cc
2026-02-04 14:58:06 -06:00
vicrodh 7e8e79c025 refactor(artist): replace blacklist button with hide dropdown
- Replaced prominent blacklist button with smaller tertiary button
- Button now opens dropdown with descriptive help text:
  "Hide this artist - Don't show in searches, playlists, discover, etc."
- Updated terminology from "blacklist" to "hide/show"
- Updated banner and toast messages for consistency
- Uses EyeOff icon instead of Ban for softer visual

cc
2026-02-04 14:35:21 -06:00
vicrodh 0877213625 feat: add warning toast type
The 'warning' type was being used but not defined in ToastType.

cc
2026-02-04 14:20:07 -06:00
vicrodh a044017c3b fix: more $t() and store access issues in $derived() blocks
- PlaylistModal: convert $derived with get(t) to regular function
- LocalLibraryTagEditorModal: rename 't' to 'track' in map to avoid
  shadowing the t store

cc
2026-02-04 14:18:36 -06:00
vicrodh 73e7d799df i18n: add download.* keys to French and German locales
cc
2026-02-04 14:05:45 -06:00
vicrodh c9b26eb4db fix: remove $t() calls from $derived() blocks to fix PostCSS errors
vite-plugin-svelte CSS extraction fails when $t() is used inside $derived().
This causes "[postcss] Unknown word <script" errors that appear to be cache
issues but are actually a known Svelte 5 / vite-plugin-svelte incompatibility.

Files fixed:
- DownloadButton.svelte: use titleKey pattern with function resolver
- DACSetupWizard.svelte: use labelKey pattern resolved in WizardStepper
- RemoteControlSetupGuide.svelte: use labelKey pattern
- WizardStepper.svelte: support optional labelKey with $t() in template

Also added download.* translation keys to en.json and es.json.

cc
2026-02-04 14:05:18 -06:00
vicrodh 4cfde680aa chore: remove debug logging from HomeView
cc
2026-02-04 08:14:45 -06:00
vicrodh deaffa183d feat(home): add Qobuz discover playlists section with tag filter
- Add backend endpoint for /discover/playlists API
- Add PlaylistTagFilter dropdown component for filtering by genre
- Add QobuzPlaylistCard with CSS blur background effect (color-thief style)
- Add HorizontalScrollRow header snippet for custom headers with scroll controls
- Add session cache store for caching API responses
- Add i18n keys for playlist filter and discover section

cc
2026-02-03 21:37:26 -06:00
vicrodh 9341e9ee19 fix: migrate cached_artists table to include locale column
Old database schemas created before locale support was added
caused "no such column: locale" errors when fetching artists.
The migration detects this and drops the old table so it gets
recreated with the correct schema.

Fixes Top Artists section not appearing in Home view.
2026-02-03 17:11:38 -06:00
vicrodh 2818ac4d29 security: improve credential encryption and CORS configurability
Security improvements based on code review:

1. Credential Encryption (Critical)
   - Replace XOR obfuscation with AES-256-GCM encryption
   - Derive key from machine ID (tied to specific machine)
   - Add migration support for legacy XOR format
   - Automatic re-encryption on first load of legacy credentials

2. HTTPS Default (Medium)
   - Change default `secure` setting to `true` for new installs
   - Existing users keep their current setting

3. Configurable CORS Origins (High)
   - Replace hardcoded domain whitelist with SQLite-backed storage
   - Default origins: vicrodh.github.io, control.qbz.lol
   - Add commands: get/add/remove origins, restore defaults
   - Origins can be customized for third-party clients
   - Server restarts automatically when origins change

New dependencies:
   - aes-gcm: AES-256-GCM authenticated encryption
   - sha2: SHA-256 for key derivation
2026-02-03 12:36:18 -06:00
vicrodh 8e7d9de754 docs: add OpenAPI specification for Remote Control API
Add comprehensive OpenAPI 3.1 documentation covering all REST endpoints:
- Connection/auth endpoints (ping, cert)
- Playback control (play, pause, seek, volume, next, previous)
- Queue management (add, shuffle, repeat, play index)
- Search (tracks, albums, artists)
- Favorites management
- Library (album/artist details)
- Real-time updates (SSE and WebSocket)

Also add /api/docs endpoint to serve the spec when Remote Control is active.
This enables developers to build custom clients (web, CLI, mobile).
2026-02-03 11:34:04 -06:00
vicrodh 001cadcbe7 refactor(settings): move Remote Control to end, make collapsible
- Move Remote Control section to end of Settings (after Updates)
- Make section collapsible, closed by default
- Keep Experimental badge visible when collapsed
- Update nav sidebar order to reflect new position
- Remove unused .section-title-row CSS selectors
2026-02-03 11:17:40 -06:00
vicrodh 1039241d28 feat(api): add SSE endpoint for real-time playback updates
Add /api/events endpoint using Server-Sent Events (SSE) as a more
efficient alternative to WebSocket for pushing playback state updates
to PWA clients. SSE provides automatic reconnection and is simpler
to implement on the client side.

- Add tokio-stream dependency with sync feature for BroadcastStream
- Implement sse_handler with 15s keep-alive ping
- Keep /api/ws for backwards compatibility
2026-02-03 10:57:16 -06:00
vicrodh 596efc05ce feat(api): add add-to-queue-next endpoint 2026-02-03 09:31:20 -06:00
vicrodh 477258d94a feat(remote): sync shuffle/repeat between desktop and PWA
- Add shuffle/repeat fields to PlaybackEvent struct
- Emit queue:state event when shuffle/repeat changes via API
- Add queue event listener in desktop frontend
- Include shuffle/repeat in WebSocket broadcasts
- PWA updates shuffle/repeat from WebSocket messages

This enables bidirectional sync: changes from PWA update desktop UI,
and changes from desktop update PWA via WebSocket.
2026-02-03 09:22:55 -06:00
vicrodh 6b85086b0a fix(player): sync volume from backend playback events
Update the local volume state when receiving playback events from the
backend. This ensures the volume slider reflects changes made via
remote control or other external sources.
2026-02-03 09:14:52 -06:00
vicrodh b0ddf2d020 fix(player): always keep event listener active for remote control
The playback event listener was only started when currentTrack existed,
creating a chicken-and-egg problem: external playback (from PWA) couldn't
set currentTrack because the listener wasn't active to receive the event.

Now the listener is always active, allowing remote control to update the
player state even when nothing is playing locally.
2026-02-03 09:00:09 -06:00
vicrodh 21054b9f22 fix(player): update player state immediately on external track change
Call notifyListeners() right after setting currentTrack when track
changes from remote control. Also update isPlaying and currentTime
from the event to ensure player UI reflects correct state.

Added debug logging for queue track mismatches.
2026-02-03 08:39:09 -06:00
vicrodh d1347bc425 fix(player): sync queue when track changes from remote control
When a track change is detected from an external source (e.g., PWA
remote control), also sync the full queue state. This fixes the issue
where desktop UI showed empty queue after PWA started playback.
2026-02-03 08:28:39 -06:00
vicrodh 651d0b0792 chore: bump version to 1.1.8-rc-5 2026-02-03 08:28:34 -06:00
vicrodh 027d5d74d2 fix(api): emit playback events immediately to update desktop UI
Add emit_playback_update() to notify both desktop UI (Tauri event) and
PWA (WebSocket) when playback state changes from remote commands.

Previously, desktop UI would only update on the next polling cycle (up
to 5 seconds), making the remote control feel unresponsive.
2026-02-03 08:17:46 -06:00
vicrodh 0651acf1db Add playback preferences API endpoint for remote control
- GET /api/playback/preferences - get current autoplay mode
- POST /api/playback/autoplay - set autoplay mode (continue/track_only/infinite)
2026-02-03 07:54:39 -06:00
vicrodh 8e4d39684a feat(api): add album and artist detail endpoints 2026-02-03 05:52:12 -06:00
vicrodh 22834822df feat(api): add favorites and album playback endpoints
- GET /api/favorites - Get user favorites (albums, tracks, artists)
- POST /api/favorites/add - Add item to favorites
- POST /api/favorites/remove - Remove item from favorites
- POST /api/album/play - Play album (clears queue and adds all tracks)
2026-02-03 05:49:53 -06:00
vicrodh da93c746cf feat(remote-control): add setup guide wizard and experimental badge
- Add RemoteControlSetupGuide component with step-by-step instructions
- Include certificate installation guides for iOS, macOS, Windows, Android
- Mark remote control section as "Experimental" with red badge
- Add Setup Guide button to open the wizard
- Add translations for wizard (en/es)
2026-02-03 05:38:20 -06:00
vicrodh 4972c76746 feat(api): add search_all endpoint for combined search
- GET /api/search/all returns albums, tracks, and artists
- Parallel search queries for better performance
- Respects artist blacklist filtering
2026-02-03 05:31:38 -06:00
vicrodh a775dda14d feat(api): add shuffle and repeat endpoints
- POST /api/queue/shuffle - set shuffle mode
- POST /api/queue/repeat - set repeat mode (off/all/one)
- Return current shuffle/repeat state in response
2026-02-03 05:30:10 -06:00
vicrodh fd4445c8ce feat(api): add queue management endpoints
- GET /api/queue - get full queue state
- POST /api/queue/add - add track to queue
- POST /api/queue/play - play specific track by index
2026-02-03 05:18:17 -06:00
vicrodh 53b9031c36 fix(player): sync track changes from remote control
When tracks are changed externally (via PWA remote control), the desktop
player now detects the track_id mismatch and fetches the new track info
from the backend queue. This fixes bidirectional sync where skipping
tracks on the PWA wasn't reflected in the QBZ desktop UI.
2026-02-03 05:16:17 -06:00
vicrodh 4d2227cb5b fix(remote-control): initialize rustls provider
cx
2026-02-03 04:55:22 -06:00
vicrodh 229d24f891 feat(remote-control): add HTTPS mode and cert flow
cx
2026-02-03 04:48:23 -06:00
vicrodh b906f747fa Merge feature/internal/qbz-control: Remote Control API
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
2026-02-03 03:52:06 -06:00
vicrodh 0fc6494332 Merge fix/general-debug-1.1.7: DAC Setup Wizard improvements
Features:
- Redesigned welcome step with comprehensive disclaimer
- Added DAC info extension to all wizard steps
- Fixed stepper navigation when going backwards
- Added custom gandalf tooltip with nerdy text
- Applied ChatGPT micro-adjustments (warnings, hints)
- Full i18n support (EN/ES/FR/DE)
2026-02-03 03:51:11 -06:00
vicrodh 363ca4c264 feat(remote-control): add LAN API server, settings UI, and QR pairing\n\n- add axum API server with LAN-only + token auth + CORS allowlist\n- expose playback and search endpoints plus WS updates\n- persist remote control settings (enabled/port/token)\n- add settings UI with QR/token controls and i18n\n\ncx 2026-02-03 03:47:48 -06:00
vicrodh 2f85129547 feat(dac-wizard): apply ChatGPT micro-adjustments
Step 1 (Precheck):
- Add inactive warning: "If any service is inactive, stop here..."

Step 2 (Other distro):
- Change to "Ensure these packages (or equivalents) are installed"

Step 3 (Detect DAC):
- Add input warning: "This must match exactly..."

Step 4 (Backup):
- Update hint about user responsibility for keeping backup

Step 6 (Pulse):
- Change "browsers" to "browsers and apps"

Step 7 (WirePlumber):
- Add rules note: "These rules apply only to the detected DAC"

All translations updated for EN/ES/FR/DE
2026-02-03 03:15:59 -06:00
vicrodh dbe70e774c style(dac-wizard): make tooltip text friendlier and nerdier
- Reference "The Hi-Fi Wizard/Mage" for the gandalf icon
- Add "if you haven't already" to acknowledge power users
- Keep it playful without being patronizing
2026-02-03 03:07:15 -06:00
vicrodh d99611ef46 feat(dac-wizard): improve button size and add custom tooltip
- Match button height to dropdown (40px)
- Increase gandalf icon size (24px) for better visibility
- Add custom hover tooltip with larger gandalf icon
- Tooltip shows title and description explaining the wizard
- Add tooltip translations for EN/ES/FR/DE
2026-02-03 03:04:11 -06:00
vicrodh 8ef38c67e0 feat(dac-wizard): redesign welcome step and fix stepper navigation
Welcome step changes:
- Add comprehensive disclaimer with bullet points
- Add system requirements caveats (custom configs, manual mods, etc.)
- Add recovery information
- Update translations for EN/ES/FR/DE

Bug fixes:
- Fix stepper not updating when navigating backwards
  (current step now always shows as 'active')

UI changes:
- Replace Wand2 icon with gandalf.svg for DAC wizard button
2026-02-03 02:59:34 -06:00
vicrodh e6d5c1ae7d feat(dac-wizard): extend DAC info to all steps and done summary
- Add DAC short name to pulse config filename for multi-DAC support
- Add getCreatedConfigPaths() for dynamic file path generation
- Show configured DAC name/description in done step
- Add configuredFor translation to all locales (EN/ES/FR/DE)
2026-02-03 02:38:49 -06:00
vicrodh c3ae0a2e6a fix(dac-wizard): use DAC name in PipeWire config filename 2026-02-03 02:31:57 -06:00
vicrodh fb85ee2de4 feat(dac-wizard): add sample rate checkboxes and DAC-specific config files
Step 5 (PipeWire config):
- Add sample rate checkboxes (44.1, 48, 88.2, 96, 176.4, 192 kHz)
- Pre-fill from DAC query if available, otherwise empty for manual selection
- Show "detected" badge for rates found by query
- Dynamic command updates based on selection

Step 7 (WirePlumber config):
- Use DAC short name in filename: 99-qbz-dac-{name}.conf
- Extract name from node.name or description
- Include DAC description in config file comment
- Use selected sample rates instead of hardcoded values

This enables proper multi-DAC separation - each DAC gets its own config file.
2026-02-03 02:25:12 -06:00
vicrodh 02d79b13b5 fix(dac-wizard): fix step label translation for kebab-case names 2026-02-03 02:16:29 -06:00
vicrodh a5a2100a2a feat(dac-wizard): add mandatory checkboxes for steps 1 and 4
- Welcome step: checkbox to confirm understanding of system changes
- Backup step: checkbox to confirm backup was created
- Start/Next buttons disabled until checkboxes are checked
- Add translations for checkboxes (EN/ES/FR/DE)
2026-02-03 02:07:05 -06:00
vicrodh b20934b7c7 fix(dac-wizard): query ALSA hardware for real sample rates
- Clear default input value (use empty string)
- Add ALSA hardware capabilities query via:
  - /proc/asound/cardX/stream0 for USB devices
  - aplay --dump-hw-params for detailed hw params
- Parse rate ranges [min max] and expand to common rates
- Now shows actual DAC capabilities, not just current config
2026-02-03 02:00:15 -06:00
vicrodh 278136762d feat(dac-wizard): add DAC capabilities query from PipeWire/PulseAudio
Backend (Rust):
- Add query_dac_capabilities command that queries pw-cli and pactl
- Returns supported sample rates, formats, channels, and device description
- Parses both PipeWire and PulseAudio outputs for maximum compatibility

Frontend (Svelte):
- Add "Query DAC Capabilities" button in detect-dac step
- Display detected sample rates, formats, channels
- Show disclaimer about checking manufacturer docs if values don't match
- Add translations for query UI (EN/ES/FR/DE)
2026-02-03 01:47:42 -06:00
vicrodh 5ce5a57d5b feat(dac-wizard): add node name validation and DAC type detection
- Validate node.name format (alsa_output.* or alsa_input.*)
- Detect DAC type: USB, PCI, Bluetooth, Virtual
- Show visual feedback with color-coded status:
  - USB DAC: green (bit-perfect supported)
  - PCI: yellow (depends on hardware)
  - Bluetooth/Virtual: red (not possible)
- Add translations for validation messages (EN/ES/FR/DE)
2026-02-03 01:41:40 -06:00
vicrodh 8e74689226 fix: settings menu expands upward in collapsed sidebar
- Remove redundant subtitle text from DAC wizard welcome (all languages)
- Fix collapsed sidebar settings menu to expand upward instead of down
- Menu now opens to the right and grows upward, avoiding player overlap
2026-02-03 01:27:59 -06:00
vicrodh e11f943bbb chore: move qobuz-player to end of app list 2026-02-03 01:21:08 -06:00
vicrodh afc61b3660 feat(i18n): add FR/DE translations for DAC wizard, add qobuz-player app
- Add complete French (FR) translations for dacWizard section
- Add complete German (DE) translations for dacWizard section
- Add qobuz-player (TUI) to bit-perfect app selector in all 4 languages
2026-02-03 01:18:57 -06:00
vicrodh d8f72ff318 feat: add DAC Setup Wizard for PipeWire bit-perfect configuration
- Add guided 10-step wizard for manual PipeWire/WirePlumber configuration
- Steps: welcome, precheck, detect-dac, backup, pipewire-config,
  pulse-config, wireplumber-config, restart, verify, done
- Users manually copy and run commands (no automatic execution)
- Include rollback instructions with documentation links on error
- Add wizard trigger button in Settings (visible when PipeWire selected)
- Support multiple distros: Debian, Fedora, Arch, openSUSE
- Add bit-perfect app selector for QBZ, VLC, DeaDBeeF, etc.
- Full i18n support (EN/ES translations)
2026-02-03 01:12:56 -06:00
vicrodh 6104bbf09d feat: add Ctrl+F keybinding for search focus
- Add 'nav.search' action with Ctrl+F default shortcut
- Add focusSearch() export to Sidebar that clears and focuses search
- Add translations for en/es (Search / Buscar)
- Register action handler in +page.svelte
2026-02-02 23:47:41 -06:00
vicrodh 18537f9899 feat: add dropdown menu to UserCard with settings, keybindings, bug report, about
- Replace single settings button with dropdown menu in UserCard
- Menu opens upward in expanded mode, to the right in collapsed mode
- Use openUrl from Tauri plugin for external links (bug report)
- Make dropdown compact (similar to context menu) and wider
- Pass onKeybindingsClick prop through Sidebar to +page.svelte
- Support collapsed prop in UserCard for sidebar collapsed mode
2026-02-02 23:43:45 -06:00
vicrodh d2913f0c0c feat(keybindings): add shortcut configuration UI (Phase 4)
- Create ShortcutInput.svelte with recording mode and conflict detection
- Create KeybindingsSettings.svelte modal for customizing shortcuts
- Integrate settings modal accessible from shortcuts modal
- Add i18n translations for configuration UI (en/es)
- Visual indicators for modified shortcuts
- Reset individual or all shortcuts to defaults
2026-02-02 23:24:08 -06:00
vicrodh fdab331c5c feat(keybindings): add keyboard shortcuts modal (Phase 3)
- Create KeyboardShortcutsModal.svelte with categorized shortcuts display
- Add ? shortcut to open modal (ui.showShortcuts action)
- Integrate modal in +page.svelte with Settings navigation
- Use i18n for all UI text
- Add animations and accessibility attributes
2026-02-02 23:21:22 -06:00
vicrodh 6db319b67a fix(keybindings): use regular variables instead of runes at module level
$state and $derived at module level cause "Cannot access uninitialized
variable" error during SSR. Changed to lazy initialization with getter
functions.
2026-02-02 23:14:46 -06:00
vicrodh fa6538df2c feat(keybindings): implement centralized keybindings system
Phase 1: Core infrastructure
- Add keyboard.ts with event-to-shortcut conversion, display formatting
- Add keybindingsStore.ts with action registry, conflict detection, persistence

Phase 2: Migration
- Migrate +page.svelte shortcuts to use keybinding manager
- Register global actions: playback, navigation, UI controls
- Integrate FocusMode with contextual seek actions
- Simplify ExpandedPlayer to use keybinding handler
- Add i18n translations for keybinding labels (en/es)
2026-02-02 23:02:33 -06:00
vicrodh cec4c32bcc chore: remove unused CSS selectors from Svelte components
Clean up dead CSS that remained after HTML refactors:
- NowPlayingBar, Sidebar, PlaylistManagerView, FavoritesView
- PlaylistModal, LocalLibraryView, PlaylistDetailView
- Dropdown, MigrationModal, AlbumCard, QualityBadge
- SearchPlaylistCard, LocalLibraryTagEditorModal
- TrackReplacementModal, ImmersiveHeader, SuggestionsPanel
- LyricsFocusPanel, ExpandedPlayer, FocusMode
- ArtistDetailView, SearchView, SettingsView
2026-02-02 22:51:42 -06:00
vicrodh 678693d0c4 fix: resolve all Rust warnings in qbz-nix crate
- Remove unused import TagExt in library/commands.rs
- Remove unnecessary unsafe block in alsa_direct.rs
- Fix value-never-read warnings in search.rs blacklist filtering
- Handle unused Result from chromecast.disconnect() in lib.rs
- Add #[allow(dead_code)] to unused but intentional API:
  - VECTOR_TTL_SECS constant (future use)
  - PipeWireBackend host field (stored for future use)
  - AlsaDirectStream is_playing field (future use)
  - CacheEntry track_id field (debug purposes)
  - CastSession app_id field (deserialized but unused)
  - ItunesAlbumResult struct (deserialized response)
  - ReleaseDetails struct (Discogs API response)
  - simple_hash function (utility for future use)
  - LrclibItem struct (lyrics API response)
  - AudioSpecs/AudioMetadata structs (future use)
  - Player visualizer_tap field (future feature)
  - Retry constants (future retry logic)
  - PlaybackEngine position/duration/is_alsa_direct methods

Remaining warnings are in vendor/rodio (external code).
2026-02-02 22:09:41 -06:00
vicrodh 1540146df6 chore: move suggestions engine logs to debug level
Keep only start/result summary at INFO for user issue reports.
Move all intermediate steps (MBID resolution, config, engine steps) to DEBUG.

Also moved to debug:
- playlist_get_settings, playlist_get_stats
- playlist_get_local_tracks_with_position
- All [SuggestionsEngine] step logs
2026-02-02 21:55:11 -06:00
vicrodh 4e80dcf731 chore: reduce log noise by changing frequent commands to debug level
Move high-frequency API read commands from log::info! to log::debug!:
- get_artist, get_artist_detail, get_artist_tracks, get_artist_albums
- get_featured_albums, get_genres
- get_user_playlists, get_playlist, search_playlists
- get_favorites, get_tracks_by_ids, get_track_info, get_current_user_id
- playlist_get_all_settings, playlist_get_all_stats
- playlist_get_all_local_track_counts, get_playlist_folders

User action commands (create, delete, add, remove) remain at info level.
2026-02-02 21:50:01 -06:00
vicrodh 9b12f761b5 feat(alsa): use stable device IDs for persistent device selection
Convert hw:X,0 to front:CARD=name,DEV=0 format when saving device selection.
This makes device IDs stable across reboots and USB reconnections since they
use the card name (e.g., C20) instead of the card number which can change.

- Add normalize_device_id_to_stable() to convert hw:X,0 to front:CARD=name,DEV=0
- Add resolve_stable_to_current_hw() for reverse lookup when needed
- Apply normalization automatically in set_audio_output_device command
- Export functions from audio module for use across codebase
2026-02-02 21:41:34 -06:00
vicrodh 67895aaa9b fix(audio): validate saved device exists in current enumeration
- Clear stale device IDs from DB when they don't exist in enumeration
- Add warning when device lookup fails in handleBackendDeviceChange
- Add logging to set_audio_output_device command for debugging

ALSA card numbers (hw:X,0) can change between boots when USB devices
are connected/disconnected. This fix prevents using invalid device IDs
that cause playback failures.

cc
2026-02-02 21:32:01 -06:00
vicrodh 1e3aa7b0df fix(i18n): add French and German to language selector
- Add Français and Deutsch to available languages in settings
- Update language mappings and Auto detection
2026-02-02 20:09:15 -06:00
vicrodh bdeb436fb8 i18n: add French and German translations
- Add fr.json with complete French translations
- Add de.json with complete German translations
- Register new locales in i18n/index.ts
- Add missing keys (playlist, metadata, genreFilter sections)
- All 869 translation keys present in both files
2026-02-02 20:07:16 -06:00
vicrodh 739c29b2c9 i18n: translate GenreFilter module to Spanish
- Add genreFilter section to en.json and es.json with all filter UI strings
- Translate GenreFilterButton: genre prefix, genre count, filter title
- Translate GenreFilterPopup: title, options, expand/collapse, clear
- Use get(t) pattern for translations inside functions
2026-02-02 18:32:01 -06:00
vicrodh 3919b59eb2 i18n: translate LocalLibraryTagEditorModal to Spanish
- Translated modal title and form labels
- Translated search buttons and results text
- Translated table headers (track, title, disc)
- Translated persistence options (sidecar vs direct)
- Translated progress states (writing tags, saving)
- Added placeholder translations for year and genre examples
2026-02-02 18:19:49 -06:00
vicrodh 059dce3114 i18n: translate PlaylistModal to Spanish
- Translated modal titles (new/edit/add to playlist)
- Translated form labels and placeholders
- Translated buttons (create, save, cancel, delete)
- Translated track count and playlist count labels
- Added missing translation keys for actions (add, create, deleteConfirm)
- Used get(t) in $derived() to avoid PostCSS extraction issues
2026-02-02 18:14:32 -06:00
vicrodh e2c3c9447d fix(i18n): avoid $t() inside $derived() to fix PostCSS error
Using $t() store subscriptions inside $derived() was causing
vite-plugin-svelte CSS extraction to fail, resulting in PostCSS
receiving the entire file content instead of just the style block.

Changed networkFsOptions to use labelKey pattern with $t() called
directly in the template instead.
2026-02-02 18:11:28 -06:00
vicrodh a489b2e875 i18n(search): translate context menus and empty states
- Update play menu items (Play now, Play next, Add to queue)
- Update navigation items (Go to artist, Go to album)
- Translate View more buttons
- Add noPlaylistsFor translation key

cc
2026-02-02 17:21:08 -06:00
vicrodh 5900e0bb83 i18n(settings): translate integrations section labels and placeholders
- Update Last.fm API key and shared secret labels
- Update Last.fm authorize button text
- Update ListenBrainz labels and token hint
- Add translations for connecting/opening states
- Add apiKey, sharedSecret, userToken translation keys

cc
2026-02-02 17:19:16 -06:00
vicrodh ef99d5f0ce i18n(components): translate dropdown placeholders and modal labels
- Update Dropdown.svelte with search placeholder translation
- Update DeviceDropdown.svelte with searchDevices placeholder
- Update GenreFilterPopup.svelte with searchGenres placeholder
- Update PlaylistModal.svelte with name and description labels
- Add playlist.name and playlist.descriptionOptional keys

cc
2026-02-02 17:17:40 -06:00
vicrodh 5b35851f41 i18n(library): translate empty states and headers
- Add translations for loading/error states
- Translate empty states for albums, artists, tracks views
- Translate header titles and subtitle
- Update button titles (Scan, Settings, Play All, Shuffle)
- Translate offline mode notice
- Translate filter panel labels
- Add editAlbumMetadataTitle key for tooltips

cc
2026-02-02 17:15:29 -06:00
vicrodh 1e2d074065 i18n(favorites): translate empty states, loading, and headers
- Add t import and use translations for all empty state messages
- Translate loading states (favorites, playlists, albums)
- Translate section headers (Discography, EPs & Singles, Live Albums)
- Translate button titles (Play All, Shuffle, More, Search, Clear)
- Add hint translations for liking items to favorites
- Update getSortLabel to use sort.* translation keys
- Update getTabLabel to use favorites.tabLabels.* keys

cc
2026-02-02 17:10:52 -06:00
vicrodh 9a053c9219 docs(i18n): add internationalization guidelines to CONTRIBUTING.md
Document i18n requirements for contributors:
- No hardcoded strings policy
- svelte-i18n interpolation format ({ values: {} })
- Translation key naming conventions
- Checklist for PRs with UI text
2026-02-02 16:51:06 -06:00
vicrodh ca11c43a4b merge: fix/general-debug-1.1.7 into pre-release (resolve i18n conflicts) 2026-02-02 16:41:38 -06:00
vicrodh 0c5c0ce1a8 i18n: add LocalLibraryView translations for empty states and UI 2026-02-02 16:38:53 -06:00
vicrodh 1d2a9f6636 i18n: add Settings, Storage, and Blacklist Manager translations
- MusicBrainz integration labels
- Storage section summary
- Complete BlacklistManagerView translations (title, description,
  search, empty states, confirm modal)
2026-02-02 16:38:02 -06:00
vicrodh a63bc1cbcd merge: integrate pre-release blacklist feature with i18n fixes 2026-02-02 16:34:52 -06:00
vicrodh 805fec1529 i18n: add Settings audio, offline library, and updates translations
Complete Spanish translations for:
- Audio settings (backend, ALSA plugin, hardware volume, streaming)
- Offline library section (repair, manage, clear)
- Updates section (check on launch, show changelog)
- Flatpak warning messages
2026-02-02 16:29:04 -06:00
vicrodh 55d383c431 fix(i18n): correct svelte-i18n interpolation format
svelte-i18n requires { values: { key: value } } format for variable
interpolation, not { key: value } directly. Fixed across all toast
and greeting calls.
2026-02-02 16:24:52 -06:00
vicrodh 764e55d1e8 fix: use $derived for networkFsOptions to support i18n reactivity 2026-02-02 16:17:18 -06:00
vicrodh aa98b4d411 i18n: Update toast messages in remaining components
- Update LocalLibraryTagEditorModal to use toast translations
- Update PlaylistImportModal to use toast translations
- Update PlaylistModal to use toast translations
- Update LocalLibraryView to use toast translations
- Update SettingsView to use toast translations for error messages
2026-02-02 15:48:05 -06:00
vicrodh 2dc9989d22 i18n: Add greeting and toast translations
- Add time-based greeting translations (goodMorning, goodAfternoon,
  goodEvening, goodNight) to homeSettings section
- Update homeSettingsStore to export getGreetingInfo for i18n support
- Update HomeView.svelte to use translated greetings
- Add comprehensive toast translations (~60 keys) for all user-facing
  notifications including queue, playback, offline, favorites, etc.
- Update +page.svelte to use $t() for all showToast calls
- Complete Spanish translations for all new keys
2026-02-02 15:45:35 -06:00
vicrodh e09c7e4a94 i18n: add missing Spanish translations for settings, audio, library and metadata 2026-02-02 15:35:04 -06:00
vicrodh 0fc5c4bb6f feat(blacklist): filter tracks in backend queue commands
Add second level of protection by filtering blacklisted artists
in Rust queue commands: set_queue, add_to_queue, add_to_queue_next,
and add_tracks_to_queue. This ensures blacklisted tracks are never
added to the queue regardless of frontend implementation.
2026-02-02 15:00:46 -06:00
vicrodh 4a1b2d6ad1 fix(blacklist): filter tracks per-artist in compilations and album queue 2026-02-02 14:42:28 -06:00
vicrodh 6ecd40b703 fix(blacklist): filter blacklisted tracks from queue operations 2026-02-02 14:32:17 -06:00
vicrodh f87e0bfe70 fix(blacklist): move @const declarations inside {#each} blocks 2026-02-02 14:22:43 -06:00
vicrodh 8480ad13da fix(blacklist): correct import path for artistBlacklistStore 2026-02-02 14:20:54 -06:00
vicrodh 6ff6269f74 feat(blacklist): add grayout styling for blacklisted artist tracks
- TrackRow: Add isBlacklisted prop with grayout styling and ban icon
- VirtualizedTrackList: Check blacklist status for each track
- PlaylistDetailView: Gray out and restrict actions for blacklisted tracks
- AlbumDetailView: Apply album-level blacklist check to all tracks
- HomeView: Gray out blacklisted tracks in Continue Listening section
- ArtistDetailView: Banner shown when viewing blacklisted artist page

Blacklisted tracks show reduced opacity, ban icon instead of track
number, and restricted menu actions (navigation only, no playback).
2026-02-02 14:17:01 -06:00
vicrodh bdffe6c709 feat(blacklist): add toast notifications for blacklist operations
- Show success/error toasts when adding/removing artists
- Show feedback when enabling/disabling blacklist
- Show confirmation toast when clearing all artists
2026-02-02 14:06:10 -06:00
vicrodh 6257f76484 fix(blacklist): use correct handleArtistClick function in BlacklistManagerView 2026-02-02 14:02:23 -06:00
vicrodh 958f0d7dca fix(blacklist): use callback prop for navigation to blacklist manager
- Replace direct navigateTo import with onBlacklistManagerClick callback
- Pass navigation callback from +page.svelte to SettingsView
- Follows same pattern as other view navigation (playlist-manager, etc)
2026-02-02 13:51:21 -06:00
vicrodh f95348bb1e feat(blacklist): add Blacklist Manager View
- Create BlacklistManagerView component with list of blocked artists
- Add enable/disable toggle, search filter, and clear all function
- Integrate navigation to blacklist manager from Settings
- Add Content Filtering section in Settings with artist count
- Add i18n translations for English and Spanish
- Wire up view routing in +page.svelte
2026-02-02 13:46:27 -06:00
vicrodh c18dfe641d fix(blacklist): filter albums and iterate most_popular for first valid item
- most_popular now iterates through all items to find first non-blacklisted
- Added album filtering to search_all by album.artist.id
- Added BlacklistState to search_albums with filtering
- Fixes edge case where most_popular was empty when first item was blacklisted
2026-02-02 13:26:23 -06:00
vicrodh e1849f0bb3 feat(blacklist): add frontend store and artist page UI
Phase 3 (minimal) - UI for testing:
- Add artistBlacklistStore.ts with O(1) local checks
- Initialize store on app startup
- Add blacklist toggle button to ArtistDetailView
- Button shows red when artist is blacklisted

cc
2026-02-02 13:18:38 -06:00
vicrodh bd4c9b7792 feat(blacklist): filter playlist suggestions by artist
Phase 2 (part 2) - Suggestions integration:
- Filter SuggestedTrack results by artist_id
- Log filtered count for debugging

cc
2026-02-02 13:10:36 -06:00