- Use top/bottom positioning instead of calculated height
- top: 32px (below title bar), bottom: 104px (above player)
- Add adjustment for when title bar is hidden (top: 0)
- Sidebar now always fits within visible content area
- Make "Adding n tracks" inline with "Choose playlist" label
- Add min-height 400px for addTrack mode modal
- Fix dropdown being clipped by modal: overflow visible + z-index 10001
- Dropdown can now extend outside modal boundaries
PlaylistModal changes:
- Replace native select with custom searchable dropdown
- Show max 8 playlists at a time with scroll indicator
- Add search/autocomplete functionality
- Support keyboard navigation (arrows, enter, escape)
Button contrast fix:
- Add --btn-primary-text CSS variable per theme
- Use dark text on light accent colors (Warm, Nord, Dracula, etc.)
- Use light text on dark accent colors (Adwaita, default)
- Add FlatpakWelcomeModal component shown once for Flatpak users
- Add persistence for Flatpak welcome shown state (updates.db)
- Implement sequential modal priority: Flatpak > What's new > Update available
- Add Flatpak section to Settings navigation (only when running in Flatpak)
- Clean up duplicate Flatpak section and invalid style block in SettingsView
- Add copyable command styling for Flatpak section
- Add floatingMenuStore.ts with global menu state management
- Only one floating menu can be open at a time across the entire app
- Standardize inactivity timeout to 2 seconds for all menus
Updated components:
- TrackMenu: integrate with global store, reduce timeout from 5s to 2s
- AlbumMenu: integrate with global store, add inactivity timeout
- Sidebar: integrate dropdown, context menu, and folder popover
- PlaylistManagerView: integrate filter and sort dropdowns
- Dropdown.svelte: integrate generic dropdown component
The global store ensures that opening any menu (context menu,
dropdown, popover) automatically closes all other open menus.
- Fix playing indicator to consider isPlaybackActive (not just activeTrackId)
- Track now shows as playing only when actually playing, not when paused
- Change reorder controls from vertical to horizontal layout
- Homologate UI with PlaylistManagerView (buttons beside drag handle)
cc
- Add checkbox selection for tracks in custom order mode
- Add batch controls bar with Select All, Clear, Move Up/Down
- Implement moveSelectedUp/Down to move multiple tracks as group
- Refactor PlaylistManagerView to use savePlaylistOrder helper
- Add CSS styles for batch controls and checkboxes
cc
- Add ChevronUp/ChevronDown buttons alongside drag handle in custom mode
- Implement movePlaylistUp/movePlaylistDown functions
- Extract savePlaylistOrder helper for code reuse
- Support both grid and list view layouts
- Add CSS styles for reorder controls
cc
- Add custom order state management in PlaylistDetailView
- Load custom order when entering custom sort mode
- Initialize custom order from current tracks if not exists
- Add move up/down buttons for track reordering
- Update sorting logic to use customOrderMap
- Add CSS styles for reorder controls
cc
- Extend DisplayTrack interface with label, addedIndex, customPosition fields
- Add PlaylistTrack.album.label type for record label data
- Add three new sort options: Added Recently, Label, Custom Order
- Implement sorting logic for new options
- Label sorting places tracks without label (local) at the end
- Added Recently uses original index as proxy for date added
cc
- Add showGenre prop (default true) to AlbumCard
- Make genre prop optional
- Hide genre and favorite button in LocalLibrary albums
- VirtualizedAlbumList passes showGenre={false}, showFavorite={false}
- Add spacer to keep Play button centered when favorite is hidden
Backend:
- Emit 'library:tag_write_progress' events with current/total count
- Progress updates as each file is written
Frontend:
- Listen for progress events during direct write mode
- Save button shows "Writing X of Y..." dynamically
- Cleanup listener on completion or error
- Show spinner-inline animation on Save button while saving
- Different text: "Writing tags..." for direct mode, "Saving..." for sidecar
- Provides visual feedback during potentially slow file operations
- Store full RemoteAlbumSearchResult instead of provider_id only
- Apply uses provider from selected result, not from dropdown
- Prevents mismatch when user changes provider after searching
- Remove duplicate discogs_release_to_search_result function
- Use existing discogs_extended_to_search_result which properly maps:
year, country, label, catno, format
- MusicBrainz already maps label_info with catalog_number
Backend:
- Add media/track-count fields to MusicBrainz ReleaseResult model
- Extract track_count and format from search results
Frontend:
- Show "{n} results" or "No results, try different search"
- Auto-expand results panel when search returns data
- Track hasSearched state for proper status display
- Results now scroll horizontally with snap behavior
- Each card is 50% width (min 200px) showing:
- Title (up to 2 lines)
- Artist
- Details pills: year, track count, country, format
- Label + catalog number at bottom
- Cards have better visual hierarchy with background
- More metadata visible to identify editions/re-releases
- Remove invalid React/JSX component (CopyableCommand) from SettingsView
- Replace JSX usage with proper Svelte 5 markup
- Fix import: use openUrl instead of open from plugin-opener
The style tag was indented with 2 spaces, causing PostCSS to fail
parsing (it saw JavaScript as CSS). Svelte requires the style tag
to be at root level with no indentation.
Phase 4 of service integration:
- Add provider adapters (MusicBrainz, Discogs to unified DTOs)
- Add RemoteMetadataState with search_albums and get_album_metadata
- Create remote_metadata commands module with Tauri handlers
- Wire up state and commands in lib.rs
Available commands:
- remote_metadata_search: Search albums on MusicBrainz or Discogs
- remote_metadata_get_album: Get full album metadata with tracks
- remote_metadata_cache_stats: Get cache statistics
- remote_metadata_clear_cache: Clear the in-memory cache
Phase 3 of service integration:
- Add DiscogsReleaseMetadata struct with full album info
- Add DiscogsArtist, DiscogsLabel, DiscogsTrack structs
- Add DiscogsSearchResultExtended for detailed search results
- Add search_releases() for release search with extended metadata
- Add get_release_metadata() for full release with tracklist
- Add ReleaseFullResponse model with media, tracks, and tags
- Add Medium, MediumTrack, TrackRecording, Tag models
- Add get_release_with_tracks() for fetching full release details
- Add search_releases_extended() with configurable limit and catalog number
- Export new types from module
The virtualized-active class was being applied even when viewing album
detail, causing overflow:hidden to block scrolling. Added !selectedAlbum
check to only apply virtualized mode for list views.
- FocusMode: replace #000, white with theme variables
- miniplayer: replace #6366f1, #fff, #818cf8 with accent/text variables
- AlbumDetailView: replace #666666 with --text-muted
- LoginView: use --danger and --warning variables for error/timeout boxes
- PlaylistModal: use .icon-inline utility class
Add to app.css:
- Warning color variables (--warning, --warning-bg, --warning-border)
- .icon-inline and .badge-warning utility classes