- Only extract labels from albums categorized as 'albums' (Discography)
- Excludes EPs, live albums, compilations, tributes, and others
- Change icon from Tag to Disc (record label, not tag)
- Add labels field to ArtistDetail type
- Extract unique labels from artist albums in convertQobuzArtist
- Update appendArtistAlbums to merge new labels
- Display labels in sidebar with click navigation to label view
- Use Tag icon from lucide-svelte
- Remove ended visual distinction (all members same style)
- Match Lyrics sidebar dimensions (340px, same height)
- Update header structure to match Lyrics
- Use element-connect.svg icon
- Equal spacing between items in all sections
cc
- All band members go to single 'Members' list
- Show ended status with muted color
- Tooltip shows roles + period (e.g. 'guitar (1981 - 2003)')
- Remove separate 'Former Members' section
cc
- Deduplicate members that appear multiple times with different roles
- Combine roles and show in mouseover tooltip
- Apply to Members, Former Members, Member Of, Collaborators
cc
- Members: current band members
- Former Members: past members (with muted style)
- Member Of: groups artist belongs to
- Collaborators: collaboration relationships
cc
- Fixed position sidebar that slides in from right
- Labels section (placeholder)
- Similar Artists section (functional)
- MusicBrainz Relationships section (functional)
cc
The playback thread was terminating on pause instead of waiting.
Now uses two separate flags:
- is_playing: controls pause/resume (thread waits when false)
- should_stop: controls full termination (thread exits when true)
This allows the ALSA Direct playback thread to pause and resume
without losing its position or requiring a full restart.
Bit-perfect audio path remains unchanged - only control flow modified.
- Pass track duration from frontend to streaming playback for seekbar
- Add StreamInfo struct with speed measurement during probe
- Implement StreamingConfig::from_speed_mbps() for adaptive buffer sizing
- Add play_streaming_dynamic() method using speed-based buffer config
- Enhanced download logging with progress %, speed (current/avg), and ETA
- Auto-cache streamed tracks for instant replay
The seekbar now shows playback progress during streaming by using
the track's known duration from metadata rather than detecting it
from incomplete audio data.
BREAKING CHANGE: Replace blocking decode_streaming_source with IncrementalStreamingSource
Key improvements:
- IncrementalStreamingSource implements rodio::Source and decodes packets on-demand
- Playback starts immediately after initial buffer (512KB default) fills
- Audio is decoded incrementally while download continues in background
- Reduced initial buffer from 2MB to 512KB for faster startup
- Added fast_start() config option for minimal 256KB buffer
The previous implementation blocked until the ENTIRE file was downloaded
and decoded, making streaming slower than traditional download-first.
Now playback truly starts within ~1 second of initial buffer filling.
Signed-off-by: cpvsc
- Add genre field to QobuzTrack.album type
- Add genre to compilation albums in qobuzAdapters
- Add getGenreLabel function to LabelView
- Add genre prop to AlbumDetailView artist albums
- Update +page.svelte artist albums mapping to include genre
- Add PlayStreaming variant to AudioCommand enum
- Add play_streaming() method to Player for starting stream-first playback
- Modify play_track command to check stream_first_track setting
- Add get_stream_info() for HEAD request to get content-length
- Add extract_audio_format_from_header() to probe audio format from initial bytes
- Add download_and_stream() for async chunked download with buffer push
- Update BufferedMediaSource with create_reader() for independent read positions
- Add has_min_buffer() method for playback readiness check
- Implement Clone for BufferWriter
Phases 3-4/7: Conditional streaming path with async download integration
cpvsc
- Create streaming_source.rs with BufferedMediaSource implementation
- Implements Read + Seek + MediaSource traits for symphonia compatibility
- BufferWriter allows async chunk pushing from HTTP downloads
- StreamingConfig with configurable min_buffer and max_buffer sizes
- Supports seeking within buffered range and EOF detection
- Thread-safe with Arc<Mutex<>> interior for shared state
- Includes comprehensive unit test suite
Phase 2/7: Core streaming infrastructure for first-track playback
cpvsc
Add two new fields to AudioSettings struct:
- stream_first_track: bool flag to enable streaming for uncached tracks
- stream_buffer_seconds: u8 for initial buffer size (1-10 seconds)
Includes:
- Database schema migration for existing users
- Getter/setter methods in AudioSettingsStore
- Tauri commands for frontend integration
- Registration in lib.rs invoke_handler
cpvsc
Backend:
- Add search_type parameter to search_albums, search_tracks, search_artists
- Pass optional type filter to Qobuz API (Performer, Composer, Label, ReleaseName)
Frontend:
- Add SearchFilterType to search state management
- Add filter radio buttons in SearchView (visible when results exist)
- Remove redundant counts from tabs
- Add Clear filter button independent from Clear search
- Filters reset automatically when starting new search or clearing
Filters allow finding performers, composers, and labels that default
search misses (e.g., searching "Nicko McBrain" with Performer filter
shows Iron Maiden tracks)
- Add get_label API endpoint and Tauri command
- Create LabelView component with album grid, search, and infinite scroll
- Add clickable label links in AlbumDetailView, AlbumCreditsModal, and TrackInfoModal
- Add label_id to AlbumInfo and AlbumDetail types
- Add label to QobuzTrack album summary for track info display
- Add PlaylistRule enum with BandMembers, ArtistGroups, CollaboratorNetwork variants
- Add GeneratedPlaylist struct for playlist preview results
- Add PlaylistGenerationConfig for customizing track limits
- Implement smart_playlist_preview command to generate playlists from MusicBrainz relationships
- Implement smart_playlist_resolve_artist helper to find artist MBID by name
- Implement smart_playlist_get_available_types to check what playlist types are available
- Search Qobuz for member/collaborator tracks and return matching track IDs
Display MusicBrainz artist relationships on artist detail page:
- Band Members section with role info (for groups)
- Past Members section (former members)
- Member Of section (groups this artist belongs to)
Features:
- Automatic MusicBrainz artist resolution on page load
- Click to navigate to related artist's Qobuz page
- Graceful degradation when data unavailable
- Respects MusicBrainz enabled setting
Uses Stage 1 MusicBrainz infrastructure for data fetching.
cc
Add automatic ListenBrainz scrobbling when tracks play:
- Now-playing submission on track start
- Scrobble after 50% or 4min (whichever is shorter)
- MusicBrainz data enrichment for enhanced scrobbles
- Offline queue support (flush when back online)
- ISRC field added to PlayingTrack interface
Scrobbling uses Stage 1 MusicBrainz resolution to include:
- Recording MBID
- Release MBID
- Artist MBIDs
cc
Add ListenBrainz scrobbling support with:
- Client module for ListenBrainz API
- Token-based authentication (user provides token from listenbrainz.org)
- Now-playing submission support
- Scrobble submission with MusicBrainz enrichment
- SQLite-based offline queue with TTL
- Credential persistence across sessions
- Settings UI for connection management
API integration uses Stage 1 MusicBrainz data to enrich scrobbles with
recording MBID, release MBID, and artist MBIDs when available.
cc
- Add MusicBrainz client with rate limiting (1 req/sec)
- Add SQLite cache with TTL for recordings, artists, releases
- Add Tauri commands for entity resolution
- Support ISRC, UPC/barcode, and name-based lookups
- Include artist relationship extraction (Stage 3 prep)
cc
Simplified the lossy format detection since only MP3 is clearly lossy
among supported library formats (flac, m4a, wav, aiff, ape, mp3).
m4a can be either ALAC (lossless) or AAC (lossy) so it's not reliable.
- Removed LOSSY_FORMATS array, now only checks for 'mp3'
- Use /mp3.svg icon (text-only, more readable than mp3-cd.svg)
- Simplified tier to just 'mp3' instead of 'mp3-cd' and 'lossy'
MP3 and other lossy formats (aac, m4a, ogg, opus, wma) at CD-like
sample rates (44.1-48kHz) were incorrectly shown as "CD" quality
because bitDepth check came before format check.
Changes:
- Add format prop to QualityBadge, NowPlayingBar, ExpandedPlayer
- Add format field to PlayingTrack interface
- Check for lossy formats BEFORE checking bitDepth/samplingRate
- New 'mp3-cd' tier for lossy formats at CD sample rates
- Uses /mp3-cd.svg icon for this tier
- Add folder popover for collapsed sidebar mode - clicking a folder
button now shows a menu with the playlists inside instead of silently
toggling the expansion state
- Fix folder button color to match other nav items (--text-muted)
- Fix folder button size to match nav items (32px height instead of 40px)
- Add overflow-x: hidden to playlists-scroll to prevent horizontal scroll
Filter panel now auto-closes after 3 seconds of inactivity and when
clicking outside. Added album sorting with three options:
- Album Name (A-Z, Z-A)
- Release Year (ascending, descending)
- Artist Name (A-Z, Z-A)
Sort selection persists within the session and secondary sort by
title is applied when primary sort values match.
- Use size="large" (180px) for all AlbumCard instances
- Change album grids from CSS grid with 1fr to flexbox
- Fix LocalLibrary gap issue by using consistent spacing
- Align VirtualizedAlbumList, ArtistDetailView, SearchView,
FavoritesView, HomeView, and AlbumDetailView