Commit Graph
1622 Commits
Author SHA1 Message Date
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
vicrodh bec6907dbe feat(blacklist): integrate filtering into search and radio commands
Phase 2 (part 1) - Read-only integration:
- Filter blacklisted artists from search_tracks, search_artists, search_all
- Filter blacklisted artists from get_similar_artists
- Filter most_popular item if blacklisted
- Add blacklist filtering to all radio commands (artist/track/infinite/refill)
- Use output-layer filtering for radio (engine internals unchanged)

cc
2026-02-02 13:09:35 -06:00
vicrodh 26c5a1b0a3 feat(blacklist): add artist blacklist module with O(1) lookups
Phase 1 of artist blacklist implementation:
- Add artist_blacklist module with HashSet-based service for O(1) lookups
- Add SQLite persistence with WAL mode
- Add global enable/disable feature flag
- Add Tauri commands for CRUD operations
- Register BlacklistState in app state

cc
2026-02-02 13:05:50 -06:00
vicrodh a742c22c8f fix(prefetch): limit concurrent prefetches to prevent memory corruption
Add semaphore to limit concurrent prefetch operations to 1 at a time.
This helps prevent potential race conditions in native audio libraries
(CPAL/PipeWire/ALSA) that can cause malloc corruption.

Also:
- Reduce QOBUZ_PREFETCH_COUNT from 3 to 2
- Reduce PREFETCH_LOOKAHEAD from 15 to 10
- Add 50ms delay before cache insertion

Addresses #38 - random crashes during prefetch
2026-02-02 12:20:10 -06:00
vicrodh aa04a26b6c fix(offline): use hybrid strategy to reduce false positives
Implement 9/10 check strategy:
- 9 out of 10 connectivity checks go to 1.1.1.1 (Cloudflare DNS)
- 1 out of 10 checks go to Qobuz to verify service availability

This prevents false offline detections when the app is making many
concurrent API calls (e.g., loading genre hierarchies), which could
trigger Qobuz rate limiting and cause timeout-based false positives.

Also reduced timeout from 15s to 10s and retry wait from 2s to 1s
since 1.1.1.1 responds much faster than Qobuz.
2026-02-02 11:29:26 -06:00
vicrodh e86ceb827c fix(genre-filter): hide carets for genres without children
Only show expand carets in the advanced view for genres that actually
have children loaded, or where children haven't been loaded yet.
Applies to all levels (parent, child, grandchild).
2026-02-02 11:14:03 -06:00
vicrodh 1dcf2ac29a feat(genre): eager load all 3 levels on first load for complete search 2026-02-02 11:10:12 -06:00
vicrodh e599a7b803 feat(genre): add 30-day localStorage cache for genres 2026-02-02 11:06:32 -06:00
vicrodh 586dfb5754 fix(genre): stop propagation on expand buttons to prevent dropdown close 2026-02-02 10:59:15 -06:00
vicrodh df85bc9fba fix(genre): single notification when loading descendants
- Add silent parameter to loadChildren to skip notification
- loadAllDescendants now loads children and grandchildren in parallel
- Only one notification after all loads complete (no triple reload)
2026-02-02 10:56:26 -06:00
vicrodh 023d88cce1 fix(genre): lazy loading, positioning, and eager descendant loading
- Lazy load children only when tree node is expanded (faster startup)
- Fix popup positioning to grow left when toggling advanced view
- Eagerly load all descendants when selecting a parent for filtering
- This ensures basic mode also filters by Genre > Children > Grandchildren
- Show loading spinner while fetching children
2026-02-02 10:53:29 -06:00
vicrodh 62e8ba7892 feat(genre): 3-level hierarchy with collapsible tree and search
Store changes:
- Load all 3 levels of genres (parent → child → grandchild)
- Add genreTree for hierarchical structure
- getAllDescendantIds() for cascade selection
- setGenresSelected() for batch operations

Popup changes:
- Advanced view with collapsible tree structure
- Search box filters and auto-expands matching nodes
- Click parent checkbox selects/deselects all descendants
- Partial selection shows indeterminate state
- Expanded size: 630px wide, 700px tall
- Descendant count badges on expandable nodes
2026-02-02 10:50:02 -06:00
vicrodh 3155627669 feat(genre): hierarchical view for granular genre selection
- Parent genres shown as headers with checkbox
- Children displayed in grid below each parent
- Clicking parent toggles all its children
- Partial selection shows indeterminate state on parent
- Popup expands 150px taller when in advanced view
2026-02-02 10:37:48 -06:00
vicrodh 589e6071c4 feat(genre): show parent genres by default with sub-genre toggle
- Default view shows only parent genres (less cluttered like Qobuz)
- When selecting a parent, filtering includes all its sub-genres
- Added "Show all sub-genres" toggle for granular control
- Store now tracks parent/child relationships for proper filtering
- getFilterGenreNames() returns selected + children for filtering
2026-02-02 10:26:21 -06:00
vicrodh d2544dceb9 fix(genre): load all genres including sub-genres
Fetch parent genres first, then fetch sub-genres for each parent in
parallel. Combine into a flat list sorted alphabetically. This fixes
the issue where albums with sub-genres (like Alternative & Indie,
Opera, Concertos) were filtered out even when all genres were selected.
2026-02-02 10:18:57 -06:00
vicrodh df7a7e2cb5 feat(favorites): add playlist overlay with action buttons
Add FavoritePlaylistCard component with hover overlay containing:
- Heart button (remove from favorites)
- Play button (start playlist playback)
- More menu (play next, add to queue, share, remove)

Card click navigates to playlist page. Updates FavoritesView to use
the new component with all action handlers wired through +page.svelte.
2026-02-02 10:15:02 -06:00
vicrodh befe36ce30 style(ui): genre button variants and dropdown alignment
- Add 'control' variant for Favorites style matching other dropdowns
- Add 'align' prop: 'left' (Home) or 'right' (Favorites)
- FavoritesView uses control variant with right alignment
- Control variant shows "Genre: X" with chevron icon
2026-02-02 10:03:55 -06:00
vicrodh 2c886fae7a feat(genre): separate persistence for Home and Favorites contexts
- Refactor genreFilterStore to support multiple contexts
- Each context (home, favorites) has independent selection state
- Separate localStorage keys: qbz_genre_filter_home, qbz_genre_filter_favorites
- GenreFilterButton/Popup accept context prop
- FavoritesView uses 'favorites' context
2026-02-02 09:55:08 -06:00
vicrodh 65b42295e9 feat(favorites): add genre filter to Albums tab
- Add GenreFilterButton to Favorites > Albums toolbar
- Filter albums by genre name (multi-select supported)
- Use genreFilterVersion for reactivity tracking

Note: Artists tab doesn't have genre filter since artist
objects don't contain genre info directly.
2026-02-02 09:49:06 -06:00