- Added core:window:allow-set-min-size permission
- Call setMinSize(300x140) before setSize to allow smaller window
- Restore original minSize (800x600) when exiting miniplayer
- Added more console logs for debugging
- Use localStorage to persist original window state across navigation
- Add 4px margin frame around the player with rounded corners
- Darker background (#0f0f12) visible in the margin
- Box shadow for depth effect
- Removed isMiniplayerMode guards that prevented restore
- Added startPolling/stopPolling for seekbar to update properly
- Removed border-radius to fix white corners issue
- Added queue button with track count badge
- Simplified CSS to solid background color
- MiniPlayer now resizes the main window instead of creating a separate floating window
- Cider-inspired UI with large album art, track info, full playback controls
- Progress bar with current/remaining time display
- Shuffle, repeat, volume controls integrated
- Pin/restore buttons to control always-on-top and return to main view
- Fixed tray icon to use transparent PNG from static/icons
- Create miniplayerService.ts for window management
- Add /miniplayer route with compact player UI
- Sync playback state from main window via events
- MiniPlayer features:
- Draggable window (decorations disabled)
- Always-on-top toggle (pin button)
- Album art, track title, artist
- Play/Pause, Next, Previous controls
- Progress bar
- Close button (hides window)
- Add PictureInPicture2 button to NowPlayingBar
- State synced via emitTo('miniplayer', ...) events
- Enable debouncedSavePosition() during playback state updates
(saves position every 5 seconds while playing)
- Flush position save immediately when pausing
- Add periodic full session save every 30 seconds during playback
- Persist volume changes to session immediately
- Persist shuffle/repeat mode changes to session immediately
This fixes the race condition where async saves in beforeunload
wouldn't complete before app close. Now we save frequently enough
that the worst case is losing only 5-30 seconds of progress.
- Add conditional compilation for get_pipewire_sinks():
- Linux: Uses pactl to get PipeWire/PulseAudio sinks with volume info
- macOS/Windows: Uses cpal to enumerate audio devices (no volume)
- AboutModal: Detect platform and show macOS or Linux label
- Easter egg: Tux penguin is 64px on Mac (asserts dominance)
- Remove suggested tracks feature (no similarity algorithm)
- Fix collage to show 3-4 covers properly in square format
- Covers now fill full height, cropped on sides as needed
- Fixed grid card layout with header row (drag handle left, edit right)
- Fixed 180px card width with 160px artwork
- Added playlist search bar for both list and grid views
- Replaced hide/show button with edit button (opens PlaylistModal)
- Clean separation of clickable content area
- Reset customArtworkPath when switching playlists (prevents wrong image)
- Fixed asset:// URL for custom playlist artwork display
- Updated ROADMAP.md with current implementation status
- Created hi-res-gray.svg: grayscale filter on original logo
- Created hi-res-blue.svg: metallic blue version matching app accent
- Created hi-res-mono.svg: simplified black/white version
- QualityBadge now uses grayscale version for cleaner look
- Add consistent scrollbar styling to all view components
- Scrollbar is visible (subtle) by default, brighter on hover
- Position scrollbar 8px from right edge
- Each view now handles its own scroll container
- Set min-height for import modal to prevent layout shift
- Fix Qobuz logo color to match text (white)
- Invert Tidal logo when active for visibility on dark background
- Reduce spacing between platform icons
- Refresh sidebar on playlist edit/delete from detail view
- Custom scrollbar: closer to edge, hidden until hover/scroll
- Upscale Qobuz image URLs to 600x600 for better quality
- Change import icon from Download to Import for clarity
- Move hidden badge to bottom-right of artwork
- Reduce playlist name font size in grid view
- Use large album art instead of thumbnail for collage quality
- Move edit button to navigation row (same level as back button)
- Replace glass effect with solid background in PlaylistModal
- New view for managing playlists with full features
- Filter by All/Visible/Hidden
- Sort by Name/Recent/Play Count/Custom
- Toggle between grid and list view
- Drag reorder when in Custom sort mode
- Display play count stats
- Toggle visibility per playlist
- Uses PlaylistCollage for artwork
- Persists preferences in localStorage
- Remove filter, sort, view toggle from sidebar (will be in manager page)
- Remove grid view and collage from sidebar
- Add Settings button for playlist manager
- Show only visible playlists in sidebar
- Add onPlaylistManagerClick prop for navigation
- Clean up unused CSS
- Replace artwork section with PlaylistCollage component
- Add play count display in header info (with BarChart2 icon)
- Increment play count when "Play All" is clicked
- Add edit button that opens PlaylistModal
- Add handleEditSuccess and handleDelete callbacks
- Add onPlaylistUpdated and onPlaylistDeleted props
- Update Sidebar to use NavigationItem in list view (icons only)
- Keep PlaylistCollage in grid view only per user request
- Add badge and class props to NavigationItem component
- Add hidden checkbox to toggle sidebar visibility in edit mode
- Add danger zone with delete button and confirmation
- Update handleUpdate to save hidden status locally
- Add handleDelete function with proper error handling
- Style danger zone with red theme for visibility
Root cause: Queue tracks were being built without quality fields (hires,
bit_depth, sample_rate) in multiple views. When auto-advancing or skipping
tracks, the playerStore would have undefined quality data, causing
QualityBadge to default to CD tier.
Fixed by:
- Adding quality fields to queue track builders in PlaylistDetailView,
FavoritesView, ArtistDetailView, and LocalLibraryView
- Replacing all 'CD Quality' fallbacks with '-' placeholder in +page.svelte
- Adding bitDepth/samplingRate fields to ArtistDetailView DisplayTrack
The GlassSurface's .glass-content wrapper wasn't set up for flex layout,
preventing the inner .content div from scrolling properly.
Added global styles for .queue-panel .glass-content:
- display: flex; flex-direction: column
- flex: 1; min-height: 0
- overflow: hidden (so child .content can scroll)
- PlaylistDetailView: Show '-' when quality data is unavailable
- handleDisplayTrackPlay: Use '-' fallback, added TODO for streaming update
- handleDisplayTrackDownload: Consistent quality fallback logic
- TrackRow: Always render quality column (previous commit)
This prevents showing potentially incorrect 'CD Quality' labels.
Quality should be updated when actual streaming info is available.
- TrackRow: Always render quality column to maintain consistent layout
- PlaylistDetailView: Show exact quality (24bit/96kHz) when available
- PlaylistDetailView: Fall back to 'Hi-Res' or 'CD Quality' label
- Prevents column shift when quality data is missing