Commit Graph
100 Commits
Author SHA1 Message Date
vicrodh 9621814555 Fix WhatsNewModal: reduce section headings to 14px, add extra padding top/bottom 2026-01-27 03:19:18 -06:00
vicrodh 5f78b7deb2 Reduce WhatsNewModal font sizes: main items 14px to 12px, nested 13px to 11px 2026-01-27 03:14:04 -06:00
vicrodh e7887d9d73 Fix WhatsNewModal: use whats-new-content class with !important overrides, adjust modal size 2026-01-27 03:11:44 -06:00
vicrodh 411cdaedaf Fix WhatsNewModal styling: darker secondary items and proper bullet indentation 2026-01-27 03:06:57 -06:00
vicrodh 54740ee225 feat(updates): add update checks and what's new modal
cx
2026-01-27 02:59:46 -06:00
vicrodh f84c27b5ee feat(ui): implement global FloatingMenu system for menu exclusivity
- 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.
2026-01-27 00:10:13 -06:00
vicrodh 19756092a4 fix(buttons): use text-primary for btn-primary foreground color 2026-01-26 23:43:20 -06:00
vicrodh 15c0258937 fix(modals): add missing btn base class and update acknowledgments
- Fix modal footer buttons missing 'btn' base class in:
  - PlaylistModal (New/Edit playlist, Add to playlist)
  - PlaylistImportModal (Import playlist)
  - FolderSettingsModal (Library folder settings)
  - Sidebar (New folder inline modal)
- Remove incorrect QobuzLegalNotice from PlaylistImportModal
- Add MusicBrainz and lyrics providers to AboutModal acknowledgments:
  - MusicBrainz (music metadata)
  - LRCLIB (synced lyrics)
  - lyrics.ovh (lyrics API)
2026-01-26 22:16:31 -06:00
vicrodh e1ea1671d2 fix(playlist): correct playing indicator and homologate reorder UI
- 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
2026-01-26 21:53:05 -06:00
vicrodh f918fd2b01 feat(playlist): add batch selection and move for custom order
- 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
2026-01-26 21:41:43 -06:00
vicrodh 5b80d639e0 feat(playlists): add arrow buttons for reordering in playlist manager
- 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
2026-01-26 21:36:00 -06:00
vicrodh 892d2e2b68 feat(playlist): add drag and drop for custom track reordering
- Add drag state tracking (draggedTrackIdx, dragOverIdx)
- Implement drag event handlers (start, over, leave, end, drop)
- Make track rows draggable in custom order mode
- Add visual feedback styles for dragging

cc
2026-01-26 21:33:40 -06:00
vicrodh 53b8605c3b feat(playlist): implement custom order UI with move controls
- 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
2026-01-26 21:28:24 -06:00
vicrodh 426584aa59 feat(backend): add custom track order persistence for playlists
- Create playlist_track_custom_order table for storing user-defined track positions
- Add database functions: get, init, set, move track, has, clear custom order
- Add Tauri commands for frontend access
- Migration-safe for existing databases

cc
2026-01-26 21:25:25 -06:00
vicrodh ee2fbedb6e feat(playlist): add Label, Added Recently, and Custom Order sort options
- 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
2026-01-26 21:22:26 -06:00
vicrodh 0f2c47ff92 feat(AlbumCard): add showGenre prop to hide genre overlay
- 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
2026-01-26 21:00:28 -06:00
vicrodh 65adf352b6 feat(TagEditor): show real-time progress when writing tags
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
2026-01-26 20:46:38 -06:00
vicrodh f1ff7d4698 feat(TagEditor): add spinner to Save button during file writes
- 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
2026-01-26 20:41:30 -06:00
vicrodh 186a249c45 fix(TagEditor): use selected result object instead of just ID
- 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
2026-01-26 20:31:59 -06:00
vicrodh e0d2439f56 fix: correct Discogs adapter to use extended search result
- 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
2026-01-26 20:30:11 -06:00
vicrodh fd08dc8f2c feat(TagEditor): add track count and descriptive result status
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
2026-01-26 20:14:33 -06:00
vicrodh 2c8efa64c7 feat(TagEditor): horizontal scroll cards for remote results
- 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
2026-01-26 20:04:35 -06:00
vicrodh 62defcffc0 feat(TagEditor): compact UI for smaller screens
- Reduce track row height (44px → 36px) and cell padding
- Input focus: underline indicator instead of pill style
- Remote section: inline header with provider/search/chevron
- Results: 2-column grid layout, max-height 140px
- Simplify result items (title, artist, year+country)
- Reduce overall gaps and spacing
- Show results count badge on chevron toggle
2026-01-26 19:58:45 -06:00
vicrodh b5698fbf88 fix: resolve 500 error from invalid JSX and wrong import
- 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
2026-01-26 19:40:25 -06:00
vicrodh 328fb77464 fix(TagEditor): remove stray indentation from style tag
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.
2026-01-26 19:29:41 -06:00
vicrodh dddb4d4fd1 fix: resolve type mismatches and add Phase 6 polish
- Fix RemoteTrackMetadata field types (disc_number, track_number as u8)
- Fix RemoteAlbumMetadata fields (genres, tracks as Vec, disc_count as u8)
- Fix cache method calls (async, proper signatures)
- Fix error variant construction (ProviderUnavailable, InvalidProviderId)
- Add track count mismatch warning in UI
- Add rate limit error message handling
- Add 'Open in browser' button for selected result
2026-01-26 18:55:05 -06:00
vicrodh 9dd63e106b feat(TagEditor): add remote metadata lookup UI
Phase 5 of service integration:
- Add MusicBrainz/Discogs provider selector
- Add search functionality with results display
- Add apply-to-form button to populate fields
- Include track-level metadata application
- Collapsible panel to keep UI clean
2026-01-26 18:48:46 -06:00
vicrodh 6d20baf914 feat: add remote metadata service and Tauri commands
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
2026-01-26 18:46:29 -06:00
vicrodh 25e877181a discogs: add search_releases and get_release_metadata methods
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
2026-01-26 18:42:41 -06:00
vicrodh b8340ad6c7 musicbrainz: add get_release_with_tracks with media/tracks support
- 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
2026-01-26 18:39:47 -06:00
vicrodh 70df504af3 library: add remote_metadata module structure and unified DTOs
- Add RemoteProvider enum (MusicBrainz, Discogs)
- Add RemoteAlbumSearchResult for lightweight search results
- Add RemoteAlbumMetadata for full metadata with tracks
- Add RemoteTrackMetadata for track info
- Add RemoteMetadataCache with TTL-based expiration
- Add adapter functions for MusicBrainz and Discogs
- Add Discogs position/duration parsing utilities
2026-01-26 18:37:45 -06:00
vicrodh 50d765509d fix(TagEditor): remove Tracklist label, tone down album path display 2026-01-26 18:27:25 -06:00
vicrodh d3e046d8ef fix(LocalLibrary): restore scroll in album detail view
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.
2026-01-26 18:24:31 -06:00
vicrodh 79ebd66856 refactor(PlaylistDetailView): use danger CSS variables for clear artwork button 2026-01-26 18:20:48 -06:00
vicrodh 590fea538c refactor: replace hardcoded colors with CSS variables
- 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
2026-01-26 18:20:06 -06:00
vicrodh 8ae4f62401 refactor(ExpandedPlayer): replace hardcoded colors with CSS variables 2026-01-26 18:16:23 -06:00
vicrodh fcda0ddf36 refactor: centralize button styles in app.css
- Add global .btn, .btn-primary, .btn-secondary, .btn-danger, .btn-ghost classes
- Add --danger color CSS variables for multi-theme support
- Add .btn-sm and .btn-lg size modifiers
- Refactor all modals and views to use global button classes
- Remove 260+ lines of duplicated button CSS across components

Files updated:
- FavoritesEditModal, FolderEditModal, FolderSettingsModal
- LocalLibraryTagEditorModal, MigrationModal, PlaylistImportModal
- PlaylistModal, Sidebar, LocalLibraryView, PlaylistManagerView
2026-01-26 18:02:58 -06:00
vicrodh 1751a83499 fix(ui): align metadata footer buttons with app style
cx
2026-01-26 17:45:08 -06:00
vicrodh c09a4233db fix(ui): align metadata editor footer buttons and spacing
cx
2026-01-26 17:42:34 -06:00
vicrodh 138f4388b7 fix(ui): ensure 5-row tracklist scroll and footer alignment
cx
2026-01-26 17:34:52 -06:00
vicrodh 6b107a8c57 fix(ui): stabilize metadata editor table and footer
cx
2026-01-26 17:19:51 -06:00
vicrodh be605dacf4 refactor(ui): polish metadata editor table and footer
cx
2026-01-26 17:05:51 -06:00
vicrodh 9889303a13 fix(ui): improve tracklist table and footer controls
cx
2026-01-26 16:55:01 -06:00
vicrodh 333c53002e fix(ui): tabular tracklist with vertical snap
cx
2026-01-26 16:49:13 -06:00
vicrodh 3ca9fe48af fix(ui): compute total discs without const tag
cx
2026-01-26 16:43:08 -06:00
vicrodh c63290b483 refactor(ui): update local metadata editor layout
cx
2026-01-26 16:40:32 -06:00
vicrodh cf41862c50 fix(ui): size local tag editor modal inputs
cx
2026-01-26 16:31:10 -06:00
vicrodh 13ee849604 fix(ui): ensure modals overlay sidebar and player
cx
2026-01-26 15:44:33 -06:00
vicrodh 4bc4bb0132 fix(ui): hide Discogs panel until fetch
cx
2026-01-26 15:36:39 -06:00
vicrodh 885b5f73b5 refactor(ui): align album artwork labels and grid
cx
2026-01-26 15:31:09 -06:00
vicrodh db45369b0a fix(ui): match Discogs cover size to preview
cx
2026-01-26 15:14:44 -06:00
vicrodh 8c99794fbf fix(ui): update album artwork button copy
cx
2026-01-26 15:13:26 -06:00
vicrodh 3ed0b19d16 fix(ui): adjust album settings modal artwork
cx
2026-01-26 15:12:56 -06:00
vicrodh 90d2bd94ae revert: album settings artwork panel polish
cx
2026-01-26 15:09:28 -06:00
vicrodh d0a0562885 fix(ui): polish album settings artwork panel
cx
2026-01-26 15:07:56 -06:00
vicrodh 4d139f78a0 refactor(ui): move Discogs results into artwork panel
cx
2026-01-26 14:47:55 -06:00
vicrodh 9dc0a87740 fix(ui): restore LocalLibrary album header layout
cx
2026-01-26 14:39:41 -06:00
vicrodh 6517cfc791 refactor(ui): align album settings actions layout
cx
2026-01-26 14:31:51 -06:00
vicrodh 249d49ab4f refactor(ui): adjust album settings header layout
cx
2026-01-26 13:45:54 -06:00
vicrodh 130f94ee43 refactor(ui): tighten album settings layout
cx
2026-01-26 13:35:56 -06:00
vicrodh 11efbd5a59 fix(ui): use alert for metadata errors
cx
2026-01-26 13:27:58 -06:00
vicrodh b8cc181974 fix(ui): refine album settings metadata entry
cx
2026-01-26 13:27:26 -06:00
vicrodh 92d601a35b feat(ui): add LocalLibrary metadata editor modal
cx
2026-01-26 13:25:00 -06:00
vicrodh 5d812f4966 feat(library): add LocalLibrary tag editor backend
cx
2026-01-26 13:24:51 -06:00
vicrodh 2f4b79f1bf fix(cast): cleanup Chromecast connection on app exit 2026-01-26 11:01:14 -06:00
vicrodh 1384a1d276 feat(cast): add position tracking and auto-advance for Chromecast
- Add cast_get_position command for Chromecast media position
- Add CastPositionInfo struct with position, duration, player_state, idle_reason
- Extend position polling to work with both DLNA and Chromecast
- Detect track end on Chromecast via IDLE state with FINISHED reason
- Unify polling logic for both protocols

cpvsc
2026-01-26 10:41:35 -06:00
vicrodh 5a2eba97d9 fix(cast): reset player state on cast disconnect
- Add onCastDisconnected callback to castStore
- Reset isPlaying state when cast disconnects
- Ensures play indicator stops in UI when DLNA disconnects

cpvsc
2026-01-26 10:20:32 -06:00
vicrodh 7ee12ea1b2 feat(cast): show cast badge and DLNA/Cast icon in AudioOutputBadges
- Add cast-aware badge that shows protocol name (DLNA/CAST/AIR)
- Show protocol-specific SVG icons in tooltip (dlna.svg, cast_audio.svg)
- Hide DAC passthrough and exclusive mode badges when casting
- Stop hardware polling when casting to avoid misleading info
- Add purple theme styling for cast badge consistent with cast UI

cpvsc
2026-01-26 10:16:39 -06:00
vicrodh 71ae2f92c1 feat(dlna): add position tracking and seekbar support
DLNA POSITION TRACKING:
- Added GetPositionInfo SOAP action to query current playback position
- Added GetTransportInfo SOAP action to get transport state (PLAYING/PAUSED/STOPPED)
- New dlna_get_position command returns position, duration, and transport state
- Added parse_time_string() helper for HH:MM:SS format

FRONTEND INTEGRATION:
- castStore: Added position polling (1s interval) when connected to DLNA
- castStore: New getCastPosition() for UI components
- castStore: Automatic polling start/stop on track play/disconnect
- playerStore: Subscribes to castStore for position updates
- playerStore: Updates currentTime from cast position when casting

This enables the seekbar to display accurate position during DLNA playback.
Seek functionality was already implemented (dlna_seek command).

Files modified:
- src-tauri/src/cast/dlna/device.rs
- src-tauri/src/cast/dlna/commands.rs
- src-tauri/src/cast/dlna/mod.rs
- src-tauri/src/lib.rs
- src/lib/stores/castStore.ts
- src/lib/stores/playerStore.ts
2026-01-26 09:41:11 -06:00
vicrodh 003468a28e fix(dlna): use fixed port 9876 and add extensive logging
CHANGES:
- MediaServer now uses fixed port 9876 (falls back to random if busy)
  This improves firewall compatibility for DLNA casting
- Added timeout (10s) for SOAP actions to prevent deadlocks
- Added extensive logging throughout DLNA flow:
  - Command entry point logging
  - MediaServer lifecycle (start, thread, requests)
  - SOAP action responses
  - Content-type and DIDL metadata details

VERIFIED WORKING:
- DLNA device discovery ✓
- Connection to gmediarender ✓
- SetAVTransportURI SOAP action ✓
- Play SOAP action ✓
- MediaServer serving audio to DLNA renderer ✓

Files modified:
- src-tauri/src/cast/dlna/device.rs
- src-tauri/src/cast/dlna/commands.rs
- src-tauri/src/cast/media_server.rs
2026-01-26 09:30:00 -06:00
vicrodh 892341b773 fix(dlna): use dynamic protocolInfo and add debug logging
PROBLEM:
- DLNA device detection and connection worked
- Audio playback on DLNA devices did not work

ROOT CAUSE:
- DIDL-Lite metadata had hardcoded protocolInfo='audio/flac'
- Many DLNA devices silently reject content when protocolInfo
  doesn't match the actual MIME type
- No debug logging to diagnose SOAP action failures

FIX:
- Pass actual content_type from Qobuz stream to DIDL builder
- Generate protocolInfo dynamically based on real MIME type
- Add extensive debug logging for:
  - MediaServer URL generated
  - Content-Type from Qobuz
  - Complete DIDL-Lite metadata
  - SOAP action responses (SetAVTransportURI, Play)
  - Error details when actions fail

Files modified:
- src-tauri/src/cast/dlna/device.rs
- src-tauri/src/cast/dlna/commands.rs
2026-01-26 07:56:08 -06:00
vicrodh 6044213919 Add slide-in animations to AlbumCard overlay
- Genre/date block: slides in from bottom (0.4s ease-out)
- Action buttons: slide in from top (0.4s ease-out)
2026-01-26 07:39:17 -06:00
vicrodh 01c21fffb1 Rename "Play later" to "Add to queue" in all menus
Changes the menu action label from "Play later" to "Add to queue"
for better clarity and consistency with standard music player UX.

Updated in:
- AlbumMenu.svelte
- TrackMenu.svelte
- ArtistDetailView.svelte (tracks context menu)

Relates to #21
2026-01-25 23:55:48 -06:00
vicrodh e9c7e4672c Add release date display to AlbumCard overlay
- Add releaseDate prop to AlbumCard component
- Display release date below genre in overlay (format: "Jan 25, 2026")
- Update all AlbumCard usages across views to pass releaseDate:
  - ArtistDetailView (all album sections)
  - HomeView (all featured album sections)
  - SearchView (search results)
  - FavoritesView (favorite albums)
  - LabelView (label albums)
  - AlbumDetailView ("By the same artist" section)
- Add releaseDate to types and adapters
- Skip local library view (VirtualizedAlbumList)
2026-01-25 23:47:33 -06:00
vicrodh e9e319aa46 style: improve genre overlay on AlbumCard
- Genre text: 14px, font-weight 600, padding 14px
- Simplified text-shadow (single subtle drop shadow)
- Darker overlay background (75% opacity)
- Increased blur effect (12px)
2026-01-25 23:38:20 -06:00
vicrodh 078f33085f fix: check studio albums count, not total albums
The previous logic checked total album count (< 10) to decide whether
to compare "X" vs "The X" variants. This failed for artists like
"Traveling Wilburys" (19 total albums, but 0 studio albums).

Now we:
1. Always count studio albums for the initial match
2. If studio albums < 10, search for "The X" variant
3. Compare studio album counts

Example fix:
- "Traveling Wilburys": 19 total, 0 studio albums
- "The Traveling Wilburys": 17 total, 6 studio albums
- Now correctly prefers "The Traveling Wilburys"
2026-01-25 23:14:59 -06:00
vicrodh fbc1938838 feat: compare studio albums only when matching artists
When comparing "X" vs "The X" variants, now fetches actual albums
and counts only studio albums (main discography) instead of total
album count. This filters out:
- Tributes (albums by other artists)
- Compilations (greatest hits, best of)
- Unofficial releases (bootlegs, broadcasts)
- Live albums
- EPs and singles

Uses the same categorization logic as the frontend (qobuzAdapters.ts).
This provides cleaner matching, e.g., "The Beatles" with 200+ studio
albums vs "Beatles" tribute compilation with 2 albums.
2026-01-25 23:08:46 -06:00
vicrodh c6c18460d0 fix: handle "The" prefix variations in artist matching
MusicBrainz often returns names without "The" prefix (e.g., "Beatles",
"Traveling Wilburys") but Qobuz has both variants, with the prefixed
version being the legitimate artist.

New matching logic:
1. Search for exact name match first
2. If no exact match, check for "The X" variant in results
3. If match has <5 albums, search for "The X" specifically and compare
4. Prefer the variant with more albums (likely the real artist)

This fixes navigation to "The Beatles", "The Traveling Wilburys", etc.
2026-01-25 22:37:37 -06:00
vicrodh fa3e070bce feat: add loading toast for musician resolution
Show "Looking up {name}..." toast when clicking on musician links
to provide feedback while the backend resolves the musician.
Also show error toast if lookup fails.
2026-01-25 22:30:47 -06:00
vicrodh 2c6cf6a56c feat: add musician resolution to Member Of section
Groups/bands in the sidebar now use the musician resolution flow.
Since bands typically have Qobuz artist pages, they resolve as
confidence=3 (Confirmed) and navigate directly to the artist page.
2026-01-25 22:29:26 -06:00
vicrodh 9b47a8bde2 feat: add musician click handlers to artist sidebar members
Wire up onMusicianClick for Members & Former and Collaborators
sections in ArtistDetailView sidebar. Clicking a member now triggers
the musician resolution flow (modal for weak confidence, musician
page for contextual, or artist page for confirmed).

Uses the first role from MusicBrainz relationships or defaults to
"Band Member" / "Collaborator" as the role parameter.
2026-01-25 22:26:04 -06:00
vicrodh 74d2059b8a fix: use correct fields from AlbumSummary in musician appearances
AlbumSummary only has id, title, image, and label fields.
The code was incorrectly trying to access artist and
release_date_original which only exist on the full Album struct.

- Use track.performer for artist_name instead of album.artist
- Set year to None since AlbumSummary doesn't have release_date
- Fix image access since ImageSet is direct field, not Option
- Fix title access since String is direct field, not Option
2026-01-25 22:18:15 -06:00
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
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