Commit Graph
1345 Commits
Author SHA1 Message Date
vicrodh e9f67ed1cf feat: make performer names clickable in credits modals
AlbumCreditsModal:
- Add onMusicianClick prop
- Update handlePerformerClick to pass name and role
- Falls back to onPerformerSearch if onMusicianClick not provided

TrackInfoModal:
- Add onMusicianClick prop
- Add handlePerformerClick function
- Pass role from groupedCredits to handler

+page.svelte:
- Pass handleMusicianClick to both modals
2026-01-25 22:13:55 -06:00
vicrodh e9fde31ecf feat: integrate Musician Page and Modal in main app
Navigation integration:
- Add 'musician' to ViewType
- Add selectedMusician and musicianModalData state
- Add handleMusicianClick handler with confidence-based routing:
  - Confirmed (3): Navigate to Artist Page
  - Contextual (2): Navigate to Musician Page
  - Weak/None (0-1): Show Informational Modal

View rendering:
- Add MusicianPageView in main content area
- Add MusicianModal overlay

Imports:
- MusicianPageView, MusicianModal components
- ResolvedMusician type
2026-01-25 22:11:30 -06:00
vicrodh 48045b0316 feat(ui): add MusicianPageView component
Full page view for musicians with confidence level 2 (Contextual):
- Header with musician name, role, and avatar
- Bands & Projects section (from MusicBrainz)
- Appears On section with album grid (Qobuz only)
- Pagination with Load More button
- Album cards with artwork, title, artist, year, and role badge
- Click album to navigate to album detail
2026-01-25 22:08:35 -06:00
vicrodh bb7ef733d0 feat(ui): add MusicianModal component
Informational modal for musicians with confidence level 0-1:
- Shows musician name and primary role
- Lists known bands/projects (from MusicBrainz)
- Displays explanatory copy based on confidence
- Provides CTA to Artist Page if applicable
- Does NOT show albums, tracks, or deep navigation
- Closes on Escape key or backdrop click
2026-01-25 22:07:46 -06:00
vicrodh 46fc26dd12 feat(frontend): add musician TypeScript types
- MusicianConfidence type (confirmed/contextual/weak/none)
- ResolvedMusician interface
- AlbumAppearance interface for 'Appears On' section
- MusicianAppearances response interface
2026-01-25 22:06:38 -06:00
vicrodh fc138d801c feat(backend): add musician resolution types and commands
Phase 1 of Musician Page implementation:

Types (musicbrainz/models.rs):
- MusicianConfidence enum (Confirmed/Contextual/Weak/None)
- ResolvedMusician struct with confidence assessment
- AlbumAppearance and MusicianAppearances for 'Appears On'

Commands (commands/musician.rs):
- resolve_musician: Determines confidence level and destination
- get_musician_appearances: Returns deduplicated album appearances

Confidence logic:
- Level 3 (Confirmed): Has Qobuz artist page with albums
- Level 2 (Contextual): Appears in 3+ album credits
- Level 1 (Weak): Sparse Qobuz results
- Level 0 (None): No safe match
2026-01-25 22:06:16 -06:00
Victor RH 596f8ab524 Merge branch 'feature/artist-enrichment' into pre-release 2026-01-25 21:53:28 -06:00
vicrodh f92db3d675 feat: hide MusicBrainz Relationships section when disabled or unavailable
- Add mbAvailable state to track MusicBrainz availability
- Set mbAvailable=false when MB is disabled or API fails
- Wrap entire Relationships section with {#if mbAvailable}
2026-01-25 21:48:42 -06:00
vicrodh 6651ba84b4 fix: filter labels to only include main Discography albums
- 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)
2026-01-25 21:14:49 -06:00
vicrodh 9f104433f3 feat: implement Labels section in Artist Network sidebar
- 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
2026-01-25 21:10:18 -06:00
vicrodh e9eff7403d fix(sidebar): remove top gap, align with title bar (top: 32px)
cc
2026-01-25 20:59:52 -06:00
vicrodh a881ea993e feat(sidebar): bidirectional mutual exclusion complete
Network sidebar now closes lyrics and queue when opened

cc
2026-01-25 20:55:34 -06:00
vicrodh 919641e7ed feat(sidebar): complete mutual exclusion (lyrics/queue close network)
cc
2026-01-25 20:54:15 -06:00
vicrodh 562c770cf9 feat(sidebar): add content sidebar store for mutual exclusion
- Add ContentSidebarType to sidebarStore
- Network sidebar uses store for open/close
- Prepared for lyrics/queue integration

cc
2026-01-25 20:53:05 -06:00
vicrodh 8236f3683a refactor(sidebar): match Lyrics sidebar style, use element-connect icon
- 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
2026-01-25 20:51:07 -06:00
vicrodh 5429c7d504 fix(sidebar): rename Members to 'Members & Former' for clarity
cc
2026-01-25 20:41:17 -06:00
vicrodh 8271cb2436 fix(musicbrainz): don't separate members by ended status
- 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
2026-01-25 20:38:44 -06:00
vicrodh 77d3d21882 feat(settings): show MusicBrainz cache stats (artists, relations, recordings)
- Display cache entry counts
- Disable clear button when cache is empty

cc
2026-01-25 20:19:46 -06:00
vicrodh a1e0e7c606 feat(sidebar): group members by MBID, show roles in tooltip
- 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
2026-01-25 20:18:31 -06:00
vicrodh 1cdf15ecf0 feat(settings): add MusicBrainz cache clear button in Storage section
cc
2026-01-25 20:17:14 -06:00
vicrodh dfbf64b1a4 fix(musicbrainz): correct member/group relationship logic
When viewing a BAND: direction=backward means related is a MEMBER
When viewing a PERSON: direction=forward means related is a GROUP

cc
2026-01-25 20:11:44 -06:00
vicrodh 53dbff219e feat(sidebar): restructure relationships section
- Members: current band members
- Former Members: past members (with muted style)
- Member Of: groups artist belongs to
- Collaborators: collaboration relationships

cc
2026-01-25 20:06:46 -06:00
vicrodh e9039f9909 style(sidebar): homogenize item styles, more compact
- Add User icon to Similar Artists items
- Reduce padding and gap for denser layout
- Smaller font size (12px)

cc
2026-01-25 19:54:45 -06:00
vicrodh bcb6b88713 feat(artist): add Artist Network sidebar with sections
- Fixed position sidebar that slides in from right
- Labels section (placeholder)
- Similar Artists section (functional)
- MusicBrainz Relationships section (functional)

cc
2026-01-25 19:52:38 -06:00
vicrodh c4426d19ea feat(artist): add Artist Network toggle button next to Radio
cc
2026-01-25 19:45:47 -06:00
vicrodh 513b6ef210 wip: temporarily hide similar artists and MB relationships for sidebar experiments
cc
2026-01-25 19:26:32 -06:00
vicrodh 0a632d4c04 feat(artist): reduce bio preview from 3 to 2 lines
cc
2026-01-25 19:23:47 -06:00
Victor RH 3218c6c3ec Merge branch 'pre-release' into feature/artist-enrichment 2026-01-25 19:15:19 -06:00
Victor RH e31c14657b Merge branch 'bugfix/alsa-direct-play-pause-resume' into pre-release 2026-01-25 19:14:42 -06:00
vicrodh 4fdb61978c fix(alsa-direct): implement proper pause/resume support
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.
2026-01-25 18:28:39 -06:00
Victor RH 009fa8d4c5 Merge branch 'feature/stream-first-feature-flag' into pre-release 2026-01-25 18:14:46 -06:00
vicrodh 008c5623cb feat(streaming): add seekbar progress and dynamic buffer sizing
- 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.
2026-01-25 18:06:41 -06:00
vicrodh 7d0aa215a5 feat(streaming): implement incremental decoding for true streaming playback
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
2026-01-25 13:50:24 -06:00
vicrodh 4b9d819a98 Fix genre prop propagation for album cards
- 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
2026-01-25 13:02:24 -06:00
vicrodh 36b3a4da56 refactor(streaming): remove unused writer field from PlayStreaming command
The download task is spawned before the command is sent, so the writer
doesn't need to be included in the command payload.

cpvsc
2026-01-25 12:41:08 -06:00
vicrodh 39dd249f98 feat(streaming): integrate streaming playback in play_track command
- 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
2026-01-25 12:39:43 -06:00
vicrodh 2a89b025a6 Merge PR #22: Add genre display on album hover
Resolved merge conflicts with size="large" changes from pre-release.
Both genre and size="large" props now included in AlbumCard components.
2026-01-25 12:35:27 -06:00
vicrodh 5519fc7b25 feat(streaming): add BufferedMediaSource for streaming playback
- 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
2026-01-25 12:25:41 -06:00
vicrodh 6e82fc380d feat(ui): add stream first track toggle in settings
Add UI controls in SettingsView for streaming configuration:
- Toggle for enabling stream-first mode for uncached tracks
- Slider for initial buffer size (1-10 seconds)
- Settings load/save handlers connected to Tauri commands
- CSS styling for buffer slider

cpvsc
2026-01-25 12:23:22 -06:00
vicrodh 1d0e069be1 feat(config): add stream_first_track setting to AudioSettings
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
2026-01-25 12:20:47 -06:00
vicrodh 0b40b59e75 fix(search): add MainArtist filter and reserve clear button space 2026-01-25 12:07:17 -06:00
vicrodh 2136a2a0e7 feat(search): add search type filters for refined results
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)
2026-01-25 12:04:49 -06:00
vicrodh 6467ca038e feat: add LabelView to browse albums by record label
- 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
2026-01-25 11:28:51 -06:00
vicrodh 04197b98f0 feat(musicbrainz): add smart playlist generation backend (Stage 4)
- 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
2026-01-25 09:51:47 -06:00
Joel C 22f0aa5a0e Display genre on AlbumCard when mouse over it 2026-01-25 16:08:46 +01:00
vicrodh c97d62393d feat(musicbrainz): add artist page enrichment (Stage 3)
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
2026-01-25 06:56:37 -06:00
vicrodh ba09024b17 feat(listenbrainz): integrate scrobbling with playback service
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
2026-01-25 06:52:13 -06:00
vicrodh 23d208b3d0 feat: implement ListenBrainz integration (Stage 2)
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
2026-01-25 06:49:40 -06:00
vicrodh d264b4b994 feat(settings): add MusicBrainz enable/disable toggle
- Add toggle in Integrations section
- Load and save state via Tauri commands

cc
2026-01-25 06:37:33 -06:00
vicrodh 55693e66ba feat(musicbrainz): add MusicBrainz integration engine (Stage 1)
- 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
2026-01-25 06:33:35 -06:00