Commit Graph
239 Commits
Author SHA1 Message Date
vicrodh f4fe4b01c9 fix(ui): Standardize scrollbar across all views
- Add consistent scrollbar styling to all view components
- Scrollbar is visible (subtle) by default, brighter on hover
- Position scrollbar 8px from right edge
- Each view now handles its own scroll container
2026-01-11 22:08:57 -06:00
vicrodh 8f60a42d7f fix(ui): Import modal and scrollbar improvements
- Set min-height for import modal to prevent layout shift
- Fix Qobuz logo color to match text (white)
- Invert Tidal logo when active for visibility on dark background
- Reduce spacing between platform icons
- Refresh sidebar on playlist edit/delete from detail view
- Custom scrollbar: closer to edge, hidden until hover/scroll
2026-01-11 22:01:14 -06:00
vicrodh b18bd2eac2 feat(playlists): Wire PlaylistManagerView to main page
Add 'playlist-manager' to ViewType and connect it to Sidebar navigation
2026-01-11 20:53:31 -06:00
vicrodh 3fb9ee1381 feat(playlists): Add playlist management - filter, sort, view modes, collage artwork
- Add PlaylistCollage component with Qobuz-style overlapping covers
- Add playlist_settings columns (hidden, position) with migration
- Add playlist_stats table for play count tracking
- Add backend commands for playlist management:
  - playlist_get_all_settings, playlist_set_hidden
  - playlist_set_position, playlist_reorder
  - playlist_get_stats, playlist_get_all_stats
  - playlist_increment_play_count
- Update Sidebar with filter dropdown (All/Visible/Hidden)
- Add sort dropdown (Name/Recent/Custom)
- Add view toggle between list and grid modes
- Fix TypeScript errors in +page.svelte and TitleBar.svelte
2026-01-11 20:37:23 -06:00
vicrodh 7affd2bf13 Fix Hi-Res quality badge showing as CD when playing from playlists
Root cause: Queue tracks were being built without quality fields (hires,
bit_depth, sample_rate) in multiple views. When auto-advancing or skipping
tracks, the playerStore would have undefined quality data, causing
QualityBadge to default to CD tier.

Fixed by:
- Adding quality fields to queue track builders in PlaylistDetailView,
  FavoritesView, ArtistDetailView, and LocalLibraryView
- Replacing all 'CD Quality' fallbacks with '-' placeholder in +page.svelte
- Adding bitDepth/samplingRate fields to ArtistDetailView DisplayTrack
2026-01-11 19:57:40 -06:00
vicrodh 1ae0073dff fix: use '-' placeholder for unknown quality instead of 'CD Quality'
- PlaylistDetailView: Show '-' when quality data is unavailable
- handleDisplayTrackPlay: Use '-' fallback, added TODO for streaming update
- handleDisplayTrackDownload: Consistent quality fallback logic
- TrackRow: Always render quality column (previous commit)

This prevents showing potentially incorrect 'CD Quality' labels.
Quality should be updated when actual streaming info is available.
2026-01-11 19:49:17 -06:00
vicrodh 70f03a1003 fix: quality badge accuracy and queue drag-to-reorder
Quality Badge Fix:
- Extended BackendQueueTrack with hires, bit_depth, sample_rate fields
- Updated all queue track builder functions to pass quality data
- Fixed quality badge showing CD instead of Hi-Res for playlist tracks
- Extended session persistence to save/restore quality info

Queue Drag-to-Reorder:
- Added move_track function to Rust QueueManager
- Added move_queue_track Tauri command
- Implemented HTML5 drag-and-drop in QueuePanel
- Visual feedback with drag-over indicator and dragging opacity
- Disabled drag when search filter is active
- Prevented text selection during drag operations
2026-01-11 19:28:34 -06:00
vicrodh 22cf6d9051 feat(playlist-import): integrate Codex playlist import feature
Cherry-pick and integrate playlist import from playlist-import-impl branch:
- Add playlist_import Rust module with providers (Spotify, Apple, Tidal, Deezer)
- Add track matching algorithm (ISRC first, then fuzzy matching)
- Add PlaylistImportModal.svelte with progress log UI
- Wire up import button in Sidebar
- Add modal state management in uiStore
- Register Tauri commands for preview and execute

Original implementation by Codex, integrated manually due to branch divergence.
2026-01-11 17:42:52 -06:00
vicrodh f9baecfbdb Pass bitDepth and samplingRate to playTrack in all handlers 2026-01-11 12:41:50 -06:00
vicrodh dd758d3523 Fix session restore and audio badges visibility
Session restore:
- Add pendingSessionRestore state to playerStore
- When restored track is played, load from Qobuz first
- Seek to saved position after track loads

Audio badges:
- Always show DAC/EXC badges (very muted when off)
- Adjust margins and sizing for better alignment
2026-01-11 11:19:34 -06:00
vicrodh ddc9497286 Implement session persistence between app restarts
Backend (Rust):
- Create session_store module with SQLite database
- Store queue tracks, current index, position, volume, shuffle/repeat
- Add Tauri commands: save_session_state, load_session_state, etc.
- Use WAL mode for better concurrent access

Frontend (TypeScript):
- Create sessionService.ts with save/load functions
- Restore session after login (queue, track info, volume, modes)
- Save session on beforeunload and visibility change
- Clear session on logout
- Debounced position saving during playback

Users can now close the app and resume where they left off.
2026-01-11 03:37:49 -06:00
vicrodh 3f114e11da Improve TitleBar: fix drag/controls and modernize design
- Use startDragging() API for reliable window dragging
- Create dedicated drag-region div for consistent drag behavior
- Double-click to maximize/restore
- Cleaner Discord/Spotify-inspired minimal design
- Reduce height to 32px for more content space
- Use Maximize2/Minimize2 icons for clearer visual feedback
- Fix button event handlers with proper async/await
2026-01-11 02:59:27 -06:00
vicrodh 96dc524c92 Implement Client-Side Decorations (CSD) with custom title bar
- Disable native window decorations in tauri.conf.json
- Create TitleBar component with minimize/maximize/close controls
- Add drag region for window movement
- Integrate TitleBar into main layout and LoginView
- Adjust content heights to account for 36px title bar
- Prepare for future mini player implementation
2026-01-11 02:56:17 -06:00
vicrodh 5926bd6fd5 feat(about): replace user avatar with app logo and add About modal
- Replace avatar with app logo (72x72 icon)
- Add hover glow effect on logo without layout shift
- Click logo opens About modal with:
  - App description and links (GitHub, website)
  - Version, license, build info
  - Library/API attributions (Qobuz, Tauri, Svelte, etc.)
  - Author credit and signature message
2026-01-11 02:37:56 -06:00
vicrodh 1b90a45212 refactor(favorites): centralize track favorites in favoritesStore
- Create favoritesStore.ts for centralized favorites state management
- Refactor TrackRow to be self-sufficient with internal favorites handling
- TrackRow now subscribes to store and toggles favorites internally
- Remove redundant favoriteTrackIds state from AlbumDetailView and PlaylistDetailView
- Remove manual onAddFavorite prop drilling from all views
- Add trackId prop to TrackRow for store lookup (optional for local tracks)
- Add hideFavorite prop for local tracks that don't have Qobuz IDs
- Load favorites once on app init in +page.svelte
2026-01-11 02:08:14 -06:00
vicrodh d86db5745e feat: add Home customization with greeting and section ordering
- Add homeSettingsStore for persistent settings (localStorage)
- Create reusable Modal component with overlay
- Create HomeSettingsModal for customizing home layout
- Add time-based greeting (Good morning/afternoon/evening/night)
- Support custom greeting text with {name} placeholder
- Allow reordering and toggling visibility of sections
- Show Qobuz badge for editorial sections (New Releases, Press Awards)
- Add settings icon in home header using home-gear.svg
2026-01-11 00:40:23 -06:00
vicrodh bb996a4002 feat: improve HomeView with multiple fixes
- Reduce album card size by 10% (180px -> 162px)
- Move quality badge below artist name with subtle styling
- Fix Spanish texts to English for consistency
- Add missing onTrackPlay and onArtistClick handlers
- Implement progressive loading for faster home render
- Use fast reco_get_home query instead of ML-based one
2026-01-11 00:20:52 -06:00
vicrodh 8b46660c99 fix: handle song-card links for local tracks
When playing a local track:
- Album link navigates to local library view
- Artist link shows toast (no Qobuz artist ID available)
2026-01-10 23:56:40 -06:00
vicrodh 73ef1f91db feat: album/playlist header menu and UI consistency
Album/Playlist Menu:
- Remove + and Download buttons from headers
- Add AlbumMenu component with: Play Next, Play Later, Share (Qobuz/song.link), Download
- Implement queue handlers (handleAddAlbumToQueueNext, handleAddAlbumToQueueLater)
- Implement share handlers (shareAlbumQobuzLink, shareAlbumSonglink)
- Apply same menu to PlaylistDetailView

Button consistency (no more pills):
- AlbumDetailView: border-radius 20px → 8px
- PlaylistDetailView: border-radius 24px → 8px
- ArtistDetailView: border-radius 20px → 8px
- FavoritesView: border-radius 20px → 8px
- LocalLibraryView: border-radius 24px/20px → 8px

UserCard simplified (previous commit)
2026-01-10 23:54:25 -06:00
vicrodh 266b5e2029 fix: add proper bottom margin to NowPlayingBar
- Increase height to 104px (+8px)
- Increase bottom padding to 26px
- Remove divider separators
- Update all viewport height calculations
2026-01-10 23:31:59 -06:00
vicrodh 16c5336898 fix: increase NowPlayingBar height to 96px
- More bottom margin for controls row (padding 10px top, 14px bottom)
- Update all viewport height calculations to match
2026-01-10 23:24:50 -06:00
vicrodh c66fe100b5 fix: NowPlayingBar song-card improvements
- Add album prop and click handlers (onArtistClick, onAlbumClick)
- Fix controls-row padding (equal top/bottom: 8px)
- QualityBadge: use gray colors instead of white with alpha
2026-01-10 23:24:17 -06:00
vicrodh 609d88719e feat: redesign NowPlayingBar (88px) and update QualityBadge opacity
- Redesign NowPlayingBar with new layout: seekbar at top, controls/song card/volume below
- Increase NowPlayingBar height from 80px to 88px
- Update all height calculations to match (Sidebar, LyricsSidebar, main-content)
- Set QualityBadge text opacity to 85%
- Add static icons for quality badges (cd.svg, mp3.svg, logo-hires.png)
2026-01-10 23:18:24 -06:00
vicrodh 8f77e01578 Rename FullScreenNowPlaying to ExpandedPlayer + add lyrics
ExpandedPlayer:
- Renamed from FullScreenNowPlaying for clearer nomenclature
- Added lyrics panel on right side (Cider-style blend)
- Blurred album art background with gradient overlay
- All buttons now have tooltips
- Horizontal layout: artwork+controls left, lyrics right
- Responsive breakpoints for smaller screens

FocusMode:
- Centered main layout (max-width: 1400px)
- Fixed empty space on right side

Nomenclature:
- NowPlayingBar: Bottom bar (always visible)
- ExpandedPlayer: Expanded view (click artwork)
- FocusMode: Immersive lyrics view (from ExpandedPlayer)
2026-01-10 11:26:41 -06:00
vicrodh c75a19f98f feat(reco): train scores automatically after login 2026-01-10 08:16:09 -06:00
vicrodh f4e8d68538 feat(home): add recommendation store and data-driven home
Backend:
- Add reco_store module with SQLite-backed event storage
- Add reco_log_event, reco_get_home commands
- Add ML-lite scoring: reco_train_scores, reco_get_home_ml
- Score decay based on event age (configurable half-life)

Frontend:
- Add recoService.ts for event logging
- Log play/favorite/playlist_add events
- Add albumId/artistId to PlayingTrack for tracking
- Rework HomeView to fetch recommendations from reco_store
- Display recently played, continue listening, top artists, favorites

Integrated from home-reco and home-reco-ml branches
2026-01-10 08:10:34 -06:00
vicrodh 340fb2a72a feat(lyrics): smoother transitions and static lyrics at top
- Reduced transition durations from 300-400ms to 120-150ms
- Changed easing to ease-out for snappier feel
- Added will-change for GPU acceleration
- Non-synced lyrics now display at container top (no spacers)
- Added isSynced prop to all lyrics components
2026-01-10 07:37:04 -06:00
vicrodh 0676989c71 feat(lyrics): add auto-scroll, karaoke effects, and FocusMode integration
- LyricsLines: improved auto-scroll with prevActiveIndex tracking
- LyricsLines: added immersive mode for larger text in FocusMode
- LyricsLines: enhanced opacity fading and text-shadow for active line
- FocusMode: redesigned with blurred artwork background like Cider
- FocusMode: integrated lyrics panel on right side with proper styling
- FocusMode: added bottom bar with track info, controls, and progress
- +page.svelte: wire lyrics props to FocusMode component
- +page.svelte: start lyrics updates when either sidebar or FocusMode open
2026-01-10 07:02:22 -06:00
vicrodh c32f25ab5e fix: restore explicit height on .main-content to fix rendering 2026-01-10 06:55:32 -06:00
vicrodh 78522b99ac fix: improve lyrics display with theme colors and karaoke effect
- Use theme CSS variables instead of hardcoded Cider colors
- Add distance-based opacity fading for non-active lines
- Fix scroll to center active line with proper reactivity
- Add spacers to allow first/last lines to scroll to center
- Add karaoke progress gradient on active line
- Prefetch lyrics on track start instead of button click
- Remove provider badge (will add to About modal later)
- Add loading spinner animation
2026-01-10 06:43:15 -06:00
vicrodh 80ff8afa3a feat: integrate lyrics module with UI
- Add lyricsStore for frontend state management with LRC parsing
- Wire LyricsSidebar to main layout with toggle button in NowPlayingBar
- Fix Rust compile errors (add Clone to LrclibItem, remove unused import)
- Add lyrics active line tracking with binary search
- Auto-start/stop lyrics updates based on playback state
2026-01-10 06:31:12 -06:00
vicrodh 6dfcc8adaa refactor: extract app bootstrap to $lib/app/bootstrap.ts
Create bootstrap module with:
- loadSavedTheme() - theme initialization
- restoreLastfmSession() - Last.fm session restore
- setupMouseNavigation() - mouse back/forward handlers
- bootstrapApp() - combined init with cleanup

+page.svelte: 1,229 → 1,194 lines (-35 lines)
2026-01-10 05:56:33 -06:00
vicrodh 7580948e8c refactor: remove unnecessary navigation wrappers
- Remove goBack(), goForward(), handlePlaylistSelect() wrappers
- Use navGoBack, navGoForward, selectPlaylist directly from store
- Keep navigateTo() wrapper (has debug logging)

+page.svelte: 1,241 → 1,229 lines (-12 lines)
2026-01-10 05:54:36 -06:00
vicrodh 58db1bedc1 refactor: consolidate playback handlers to use playTrack service
- Simplify handleTrackPlay: 55 → 20 lines
- Simplify handleAlbumTrackPlay: 82 → 36 lines
- Simplify playQueueTrack: 58 → 18 lines

All playback handlers now use the unified playTrack() service which
handles MPRIS, notifications, Last.fm, and favorites automatically.

+page.svelte: 1,361 → 1,241 lines (-120 lines, -9%)
2026-01-10 05:53:22 -06:00
vicrodh 5be437dd4e refactor: extract Qobuz adapters and unify DisplayTrack type
- Create $lib/adapters/qobuzAdapters.ts with:
  - formatDuration/formatDurationMinutes (removed duplicates)
  - getQobuzImage helper
  - formatQuality/formatAlbumQuality helpers
  - convertQobuzAlbum converter
  - convertQobuzArtist converter

- Add unified DisplayTrack type to $lib/types/index.ts

- Update +page.svelte:
  - Import adapters instead of inline functions
  - Remove duplicate converter functions (−57 lines)
  - Add handleDisplayTrackPlay for view components

- Fix TypeScript type narrowing in view closures
2026-01-10 05:51:48 -06:00
vicrodh 30a33cfc95 refactor: extract track actions to trackActions service
Centralize common track actions that components can import directly:
- Queue operations (queueTrackNext, queueTrackLater)
- Convenience queue functions for different track types
- Favorites handling
- Playlist modal integration
- Sharing (Qobuz link, Song.link)

Removes 100+ lines of duplicate wrapper functions from +page.svelte.
Reduces +page.svelte from 1525 to 1418 lines.
2026-01-10 05:16:32 -06:00
vicrodh ea066ded97 refactor: extract playback logic to playbackService
Move core playback operations to centralized service:
- playTrack() - unified track playback with all side effects
- MPRIS metadata updates
- System notifications
- Last.fm scrobbling and now playing
- Favorite status checking and toggling

Simplifies handlers: handlePlaylistTrackPlay, handleLocalTrackPlay, toggleFavorite.
Reduces +page.svelte from 1675 to 1525 lines.
2026-01-10 05:12:04 -06:00
vicrodh d3ea80c5d4 refactor: extract shared types to $lib/types/
Move type definitions to centralized location:
- Qobuz API types (QobuzTrack, QobuzAlbum, QobuzArtist)
- UI display types (Track, AlbumDetail, ArtistDetail, PlaylistTrack)
- Local library types (LocalLibraryTrack)
- External API types (SongLinkResponse)

Reduces +page.svelte from 1806 to 1675 lines.
2026-01-10 05:07:26 -06:00
vicrodh 3ea2bb937b fix: update playlist and local track play to use playerStore
handlePlaylistTrackPlay and handleLocalTrackPlay were still using
local state variables directly instead of playerStore functions,
causing the UI to not react to playback state changes.
2026-01-10 05:00:57 -06:00
vicrodh c60cfe0525 refactor: extract queue state into queueStore
Move queue management into dedicated store:
- Queue tracks, shuffle, repeat modes
- Local track ID tracking for library playback
- Queue operations: add, clear, sync, navigate
- Backend queue state synchronization
2026-01-10 04:53:00 -06:00
vicrodh 55ec44cdc2 refactor: extract player state into playerStore
Move playback state management into dedicated store:
- PlayingTrack interface
- isPlaying, currentTime, duration, volume, isFavorite
- Polling logic with setOnTrackEnded callback
- Playback controls (togglePlay, seek, setVolume)
2026-01-10 04:48:31 -06:00
vicrodh cef950b08b refactor: extract navigation state into navigationStore
- Create navigationStore.ts for view navigation and history
- Implement navigateTo, goBack, goForward actions
- Add selectPlaylist for playlist detail navigation
- Update +page.svelte to use store subscription and functions
- Simplify navigation wrapper functions
2026-01-10 04:32:44 -06:00
vicrodh e98ea146e3 refactor: extract authentication state into authStore
- Create authStore.ts for managing login state and user info
- Implement setLoggedIn and setLoggedOut actions
- Update +page.svelte to use store subscription
- Simplify handleLoginSuccess and handleLogout handlers
2026-01-10 04:30:11 -06:00
vicrodh 6edfb5db06 refactor: extract UI/overlay states into uiStore
- Create uiStore.ts for overlay and modal visibility states
- Centralize queue panel, fullscreen, focus mode, cast picker states
- Add playlist modal state management with mode and track IDs
- Implement handleEscapeKey for prioritized overlay closing
- Update +page.svelte to use store subscription and functions
2026-01-10 04:28:34 -06:00
vicrodh 0e8371d900 refactor: extract toast notifications into toastStore
- Create toastStore.ts with centralized toast state management
- Add auto-hide functionality with configurable durations per type
- Update +page.svelte to use store subscription instead of local state
- Maintains existing toast behavior with improved separation of concerns
2026-01-10 04:25:45 -06:00
vicrodh baa656a508 feat: add local library tracks to Qobuz playlists
- Create AddToPlaylistModal component for selecting playlists
- Update PlaylistDetailView to merge local and Qobuz tracks
- Add visual indicator (HardDrive icon) for local tracks
- Show notice that local tracks are device-specific
- Add "Add to Playlist" option in Local Library track menu
- Connect local track play handlers for playlists
- Hide download button for local tracks in playlists
2026-01-10 04:01:44 -06:00
vicrodh 16939e02f4 fix: use asset:// protocol for local library artwork in players 2026-01-10 03:48:54 -06:00
vicrodh 762df3e122 fix: Last.fm scrobbling and LocalLibrary cover art
- Restore Last.fm session on app startup (not just when visiting Settings)
- Fix LocalLibrary artwork: use asset://localhost/ instead of file://
- Add fs:allow-read capability for asset protocol
- Enable assetProtocol in tauri.conf.json
2026-01-10 03:36:31 -06:00
vicrodh 2bf9856179 feat(favorites): add download button and search to all tabs
- Add download functionality to FavoritesView tracks tab
- Add search input for each tab (tracks, albums, artists)
- Filter displayed items based on search query
- Show "no results" message when search has no matches
- Display filtered/total counts in toolbar
- Use buildDisplayTrack helper for cleaner code
2026-01-09 20:20:27 -06:00
vicrodh 5a07408acf fix(download): persist download state across views
- Add downloadStateVersion prop to trigger reactivity in child components
- Use version in each block keys to force re-evaluation when state changes
- Ensures download status persists whether track was downloaded from
  album view or playlist view
2026-01-09 20:11:39 -06:00