Commit Graph
100 Commits
Author SHA1 Message Date
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
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
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
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
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
vicrodh 8602493331 refactor(quality-badge): simplify to only detect MP3 format
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'
2026-01-25 06:06:10 -06:00
vicrodh fa8af9b1d9 fix(quality-badge): distinguish lossy formats from CD quality
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
2026-01-25 05:45:01 -06:00
vicrodh 5e5f85a86f fix(sidebar): fix collapsed folder button behavior and styling
- 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
2026-01-25 05:32:30 -06:00
vicrodh e95f487721 feat(local-library): add filter auto-close and album sorting
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.
2026-01-25 05:24:19 -06:00
vicrodh 2ea00c70d3 fix(ui): increase modal z-index to appear above sidebar and player
Updated z-index from 1000 to 10000 in all modal components to ensure
they are always displayed on top of the sidebar and player bar.
2026-01-25 05:24:13 -06:00
vicrodh 0ca97ee68d fix(local-library): add ALAC/APE format filters and fix last row cutoff
- Add ALAC and APE to format filter options
- Add 100px bottom padding to virtualized list for player bar
2026-01-25 05:08:09 -06:00
vicrodh f9115aa620 fix(ui): reduce left padding from 24px to 18px in all views 2026-01-25 05:06:01 -06:00
vicrodh 1407516b34 fix(ui): standardize AlbumCard size and grid layout across all views
- 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
2026-01-25 04:51:29 -06:00
vicrodh 75060305f3 Disable performer search links until MusicBrainz integration
Keep the onPerformerSearch infrastructure in TrackInfoModal and
AlbumCreditsModal but don't pass the prop. Performer names are
now plain text. Re-enable when MusicBrainz allows precise lookups.

Also fixes: sticky tabs in AlbumCreditsModal now work correctly.
2026-01-25 04:28:37 -06:00
vicrodh bb9d7d65ea Add clickable performer names to AlbumCreditsModal 2026-01-25 04:07:29 -06:00
vicrodh 3a898a3c3f Add clickable performer names and fix sticky tabs
Phase 7 quick wins (closes #17):
- Performer names in TrackInfoModal are now clickable
- Clicking a performer searches for their name in Qobuz
- SearchView auto-searches when opened with pre-filled query
- Credits/Review tabs in AlbumCreditsModal stay fixed when scrolling
2026-01-25 04:04:13 -06:00
vicrodh a3e8d47010 Revert album artwork size increase, keep at 200x200 2026-01-25 03:56:09 -06:00
vicrodh 01f75e098e Adjust AlbumCreditsModal layout and styling
- Increase modal width to 850px
- Increase album column to 260px (with larger artwork)
- Move tab switcher above track list/review content
- Reduce track row height by 2px (9px padding instead of 10px)
- Combine quality badges into single "24-Bit / 96 kHz" format
- Make scrollbar always visible and not overlay content
- Add padding to tracks list for scrollbar space
2026-01-25 03:56:01 -06:00
vicrodh 641ac30078 Add Credits button to tab switcher when review exists 2026-01-25 03:50:11 -06:00
vicrodh 25a49a1d68 Redesign AlbumCreditsModal with two-column layout
- Two columns: fixed album info (200px) + scrollable track list/review
- Remove track backgrounds, use thin divider lines between tracks
- Modal dimensions: 800px wide, reduced height by 5px
- Move tabs to bottom of album column (only show Review when available)
- Album info scroll area with overflow for long metadata
- Move album title and artist to modal header
- Remove "Credits" label since track list is always visible
2026-01-25 03:49:28 -06:00
vicrodh 1de77ec132 feat(credits): enable track info for all Qobuz tracks + add artist link
- Add onTrackShowInfo to HomeView (Continue Listening tracks)
- Add onShowInfo to VirtualizedTrackList (for FavoritesView)
- Add onTrackShowInfo to FavoritesView and wire to VirtualizedTrackList
- Pass showTrackInfo to HomeView and FavoritesView in +page.svelte
- Add clickable artist name to TrackInfoModal header
- Artist link navigates to artist page and closes modal
2026-01-25 03:38:35 -06:00
vicrodh f7161bafe1 feat(credits): redesign Single Track Modal per Figma specs (Phase 5)
- Glass effect modal (560px, blur(20px), rgba border)
- Header with track title + album subtitle
- 3-column metadata grid: Duration, Quality, ISRC
- 2-column credits grid grouped by role
- Role ordering: Composer/Lyricist first, MainArtist last
- CamelCase to UPPERCASE label conversion
- Multiple performers per role joined with comma
- Copyright section at bottom
- ESC key closes modal
- Animations: fade-in overlay, scale-up modal
2026-01-25 03:32:08 -06:00
vicrodh 9194164418 fix(credits): try alternate info icon (info-large.svg) 2026-01-25 03:19:48 -06:00
vicrodh 38427177f2 fix(credits): reduce info icon size to match heart glyph 2026-01-25 03:15:18 -06:00
vicrodh 6eff22632a feat(credits): complete Album Credits Modal with Review tab
- Use custom info SVG icon without circle outline
- All tracks collapsed by default (removed auto-expand)
- Add description field to Album model for editorial reviews
- Implement Review tab with album description content
- Tab switches between Credits (track list) and Review (description)
- Review tab disabled when no description available
2026-01-25 03:09:53 -06:00
vicrodh 3410774f32 feat(credits): add Album Credits Modal (Phase 4)
- Add get_album_credits Tauri command with TrackCredits, AlbumCredits,
  and AlbumInfo structs for consolidated album/track credits view
- Create AlbumCreditsModal component with two-column layout:
  album info (artwork, metadata, quality badges) and collapsible
  track list with performers and copyright
- Add Info button to AlbumDetailView header actions
- Integrate modal in +page.svelte with track play support
2026-01-25 02:53:46 -06:00
vicrodh 6601a3a5e6 feat(track-info): integrate TrackInfoModal with views
Phase 3 - Integration:
- Add onTrackShowInfo prop to TrackRow, AlbumDetailView,
  PlaylistDetailView, SearchView
- Add TrackInfoModal to +page.svelte with state management
- Pass showTrackInfo callback from main page to all views

cc
2026-01-25 02:28:52 -06:00
vicrodh e767809857 feat(track-info): add TrackInfoModal and context menu option
Phase 2 of track-info feature:
- Add performers, composer, copyright fields to Track model
- Add get_track_info command with parsed performers
- Create TrackInfoModal component to display track details and credits
- Add "Track info" option to TrackMenu context menu

cc
2026-01-25 02:23:42 -06:00
vicrodh eccadb6af9 feat(api): add performers string parser
Parse Qobuz performers field into structured data.
Format: "Name, Role1, Role2 - Name, Role1 - ..."

cc
2026-01-25 02:17:24 -06:00
vicrodh 825e9c290a Merge updates/uiux-1.1.7 into pre-release 2026-01-25 02:01:26 -06:00
vicrodh dcbe7e802a feat(playlist): track copied playlists and add attribution
- Hide "Copy to My Library" button after playlist has been copied
- Persist copied playlist IDs in localStorage for subsequent visits
- Add attribution note to description: "Originally curated by X on Qobuz"
2026-01-25 01:39:32 -06:00
vicrodh ee31c3e445 feat(playlist): add ability to copy Qobuz playlists to user library
When viewing a playlist not owned by the current user, a new "Copy to
My Library" button appears between the favorite and context menu buttons.
Clicking it creates a copy of the playlist with all its tracks in the
user's library.

- Add get_current_user_id command to check playlist ownership
- Add subscribe_playlist command to copy playlist with all tracks
- Add ListPlus button in PlaylistDetailView for non-owned playlists
- Button only shows for playlists owned by others (e.g., Qobuz curated)
2026-01-25 01:34:43 -06:00
vicrodh a276a30ff2 fix(playlist): show correct track count when creating playlist with tracks
When creating a new playlist from a track, the sidebar was showing 0 tracks
because the Qobuz API returns the playlist with tracks_count: 0 at creation
time (eventual consistency). The tracks are added after, but the sidebar
refresh might get stale data.

- Update newPlaylist.tracks_count after adding tracks in PlaylistModal
- Have handlePlaylistCreated update the sidebar with correct count
- Handle both Qobuz and local track cases
2026-01-25 01:15:42 -06:00
vicrodh 0655888f46 refactor(modals): remove color subtitles and fix button alignment
- Remove "Solid Colors", "Gradients", "Custom Gradient" subtitles
- Remove h4 styles no longer used
- Fix footer buttons: Delete left, Cancel/Save right-aligned
- Fix button size consistency with transparent border
2026-01-25 01:09:56 -06:00
vicrodh d98f4aa9ee refactor(modals): reduce icon sizes and remove help texts
- Add headphones icon to presets (7 icons total)
- Reduce icon size from 24px to 17px (70%)
- Reduce icon button size to 42x42px
- Update grid to 7 columns with smaller gap
- Remove section description texts
- Adjust modal width to 480px for FolderEditModal
2026-01-25 01:08:12 -06:00
vicrodh 83cbfc51c2 feat(sidebar): add adaptive search to context menu folder list
- Show search input when 8+ folders exist
- Scrollable folder list with max-height
- Filter folders as user types
- "No folders match" message when search has no results
- Search resets when context menu closes
2026-01-25 00:54:10 -06:00
vicrodh 2c907ea726 feat(sidebar): add context menu for moving playlists to folders
- Add oncontextmenu prop to NavigationItem component
- Right-click on playlist shows context menu with folder options
- "Move to folder" shows available folders
- "Move to root" appears if playlist is already in a folder
- Context menu closes on outside click
- Immediate UI update after moving playlist
2026-01-25 00:41:30 -06:00
vicrodh 8418a4005c feat(PlaylistManager): improve drag-drop, add absorption animation, and folder layouts
- Add absorption animation when dragging playlist to folder
- Playlist fades out and folder pulses on drop
- Update local state immediately after drop
- Add info icon with tooltip about custom sort requirement for drag & drop
- Make folder cards match playlist card width/spacing in grid view
- Add compact horizontal folder layout for list view
  - Smaller icon (36x36), name beside icon
  - Playlist count shown only on hover
2026-01-25 00:33:43 -06:00
vicrodh 9ae5aa2280 refactor(PlaylistModal): improve layout and move danger zone to footer
- Move delete button to footer (left-aligned, compact style)
- Make modal 50px wider (490px)
- Remove "(optional)" from Folder label
- Put "Make playlist public" and "Hide from sidebar" inline
- Add compact delete confirmation in footer
2026-01-25 00:28:31 -06:00
vicrodh 69f4de6d1a feat(folders): add icon and background customization to folders
- Create FolderEditModal component with icon presets and background colors
- Reuse same styling pattern as FavoritesEditModal
- Update folder cards in PlaylistManagerView to show custom icons/backgrounds
- Support preset icons (heart, star, music, folder, disc, library)
- Support solid colors and gradients for backgrounds
- Support custom image upload

This customization only affects PlaylistManagerView, not the sidebar.
2026-01-25 00:07:45 -06:00
vicrodh ca8b657413 fix(sidebar): match folder styling with playlist styling
- Change folder name to use --text-muted color (same as playlists)
- Change folder font-weight to 400 (same as playlists)
- Make folder icon inherit muted color from parent
- Hide playlist count by default, show on hover only
2026-01-25 00:04:46 -06:00
vicrodh 9c02da6303 fix(sidebar): move folder chevron to end for icon alignment
Move the expand/collapse chevron after the folder count so folder
icons align vertically with playlist icons.
2026-01-24 23:50:19 -06:00
vicrodh 664cf8d3f0 feat(playlists): add folder selector to playlist modal and simplify folder UI
- Add folder selector dropdown to PlaylistModal for create/edit modes
- Pass currentFolderId prop to PlaylistModal in detail and manager views
- Remove custom folder colors from Sidebar (consistent styling)
- Simplify folder creation - name only, no color picker
- Remove unused color-picker CSS from PlaylistManagerView

Phase 5 of playlist folders feature.
2026-01-24 23:49:25 -06:00
vicrodh df53c962f1 feat(playlist-manager): Add playlist folders Phase 4 - Manager View
- Add folder imports and state management
- Filter displayPlaylists by current folder
- Add breadcrumb navigation when inside a folder
- Add collapsible folders section with folder cards
- Add folder cards with icon, name, playlist count
- Add drag & drop support for moving playlists to folders
- Add folder edit/create modal with name and color picker
- Add delete folder functionality with confirmation
- Style folders grid, cards, modal, and breadcrumb
2026-01-24 23:42:36 -06:00
vicrodh 49a0a4223e fix(db): Move folder_id index creation to after migrations
The index was being created during schema execution, but for existing
databases the column doesn't exist until the migration runs. Now the
index is created after all migrations have completed.
2026-01-24 23:38:57 -06:00
vicrodh 916e4b9dc8 feat(sidebar): Add playlist folders Phase 3 - Sidebar integration
- Import and integrate playlistFoldersStore
- Add folder state management and expand/collapse tracking
- Add "New Folder" option to dropdown menu
- Render folders with collapsible playlist lists
- Add folder expand/collapse with chevron indicator
- Add folder name and playlist count display
- Add Create Folder modal with name input
- Add NavigationItem indented prop for nested playlists
- Style folder items, collapsed folder buttons, and modal
2026-01-24 23:35:29 -06:00
vicrodh c71350b5ae feat(frontend): Add playlist folders Phase 2 - stores and interfaces
- Create playlistFoldersStore.ts with full CRUD operations
- Add session-only expand/collapse state (not persisted per spec)
- Add folder_id to PlaylistSettings interface in all components:
  - Sidebar.svelte
  - PlaylistManagerView.svelte
  - PlaylistDetailView.svelte
2026-01-24 23:17:58 -06:00
vicrodh e5779ce6cf feat(backend): Add playlist folders Phase 1 - database and Tauri commands
- Add uuid crate dependency for folder ID generation
- Add PlaylistFolder struct and database schema
- Add folder_id field to PlaylistSettings
- Add database migration for existing installations
- Add CRUD methods for playlist folders:
  - create_playlist_folder
  - get_all_playlist_folders
  - get_playlist_folder
  - update_playlist_folder
  - delete_playlist_folder
  - reorder_playlist_folders
  - move_playlist_to_folder
  - get_playlists_in_folder
- Register Tauri commands for frontend integration
2026-01-24 23:15:48 -06:00
vicrodh 2fa42e9d8a feat(local-library): convert quality filter to multi-select checkboxes
- Replace dropdown with checkbox-based filter panel
- Quality section: Hi-Res, CD Quality, Lossy (OR within section)
- Format section: FLAC, WAV, MP3, AAC, Other (OR within section)
- AND logic between Quality and Format sections
- Add filter count badge on button
- Add "Clear all" button to reset filters
- Improved layout with 2-column grid for formats
2026-01-24 20:10:39 -06:00