Commit Graph

17 Commits

Author SHA1 Message Date
joren
3182c0585c fix: move media controls next to track info, not centered
Controls (prev/play/next) and progress bar are now stacked vertically
to the right of the album art + track label, all in the left section.
Right side keeps volume, shuffle, queue, search toggles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 10:20:44 +01:00
joren
647054dab2 feat: spotify-style toolbar layout
Three-column layout matching spotify-qt:
- Left: album art thumbnail + track title/artist (stacked, 2 lines)
- Center: prev/play/next controls above elapsed / progress / total
- Right: volume button, shuffle, queue toggle, search toggle

Controls and toggles use QToolButton directly instead of QAction so the
layout is driven by HBoxLayout + VBoxLayout with equal stretch on left
and right, keeping the player controls perfectly centred at all widths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 10:16:59 +01:00
joren
373fc2b43c feat: queue panel skip-to-track and drag reorder; remove visualizer
Queue panel:
- Double-clicking an upcoming track skips to it immediately: drops all
  tracks before it from the queue and starts playback (skipToUpcoming)
- Items can be dragged to reorder; rowsMoved rebuilds the queue via
  setUpcomingOrder()
- Track JSON stored per-item so order survives drag operations
- New PlayQueue methods: skipToUpcoming(), setUpcomingOrder()
- New QueuePanel signal: skipToTrackRequested(qint64) wired to MainWindow

Remove visualizer:
- Drop VisualizerWidget, Qt6::OpenGLWidgets, projectM CMake detection
- Remove qobuz_backend_read_pcm FFI (Rust + C header + Qt wrapper)
- Remove pcm_visualizer from PlayerStatus and PCM tap from AudioOutput

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 10:12:30 +01:00
joren
74e43b9713 fix: store TypeRole in col 0 for search album results
When the H badge column was added, TypeRole was accidentally stored in
col 1 but the double-click handler reads it from col 0, breaking album
navigation from search. Move TypeRole back to col 0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 10:12:22 +01:00
joren
7e2a04ecff fix: placeholder text color and H badge in search album results
- Add QPalette::PlaceholderText (#8C8C8C) to the dark palette so
  placeholder text in search box and settings fields is readable
- Add H column to search album results (same gold badge as album list view)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 01:25:42 +01:00
joren
4a9a7f9cbb feat: gold H badge on hi-res albums in album list view
Adds a narrow first column showing a small bold gold "H" for any album
with hires_streamable=true. Applies to both fav albums and artist pages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 01:22:57 +01:00
joren
b9b47f80e7 feat: seeking support and Last.fm scrobbling
Seeking:
- Rust player: seek_requested/seek_target_secs atomics on PlayerStatus
- Decoder loop checks for seek each iteration, calls format.seek() and resets decoder
- New qobuz_backend_seek C FFI + QobuzBackend::seek(quint64)
- Progress slider onProgressReleased now seeks to the dragged position

Last.fm:
- LastFmScrobbler: now-playing + scrobble (50% or 240s threshold, min 30s)
- API signature follows Last.fm spec (sorted params, md5)
- Settings dialog: API key/secret, username/password, Connect button with status
- AppSettings: lastfm/enabled, api_key, api_secret, session_key
- Scrobbler wired to trackChanged, positionChanged, trackFinished in MainWindow

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 01:13:06 +01:00
joren
ecaee4d907 fix: sorting never changes the queue
Removed the sortApplied→syncQueueToModel connection. Sorting the track
list only reorders the view; the queue is only set when a track is
actually played (double-click or Play Now), at which point the current
sorted order and clicked row are used.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 01:01:18 +01:00
joren
d5dedacc36 feat: album list, artist list, and artist detail views
- Fav albums: now shows a sortable list (title/artist/year/tracks);
  double-click opens the album
- Fav artists: now shows a sortable list; double-click opens the artist
- Artist detail page: name, biography summary, and their album list
- Rust ArtistDto gains albums field; get_artist fixed to extra=albums only
- Volume popup minimum width set so "100%" label is never clipped

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 00:59:02 +01:00
joren
2436b53697 fix: only set queue context when a track is actually played
Opening a playlist/album no longer resets the queue. The queue context
is now set inside onDoubleClicked and the "Play Now" context menu action,
using the current (possibly sorted) model order at the moment of play.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 00:55:16 +01:00
joren
cb5c7471c3 fix: play next track correctly skips to queued track 2026-03-24 00:43:08 +01:00
joren
2ccd95b276 fix: play next track correctly skips to queued track
advance() was removing the playNext item then calling current(), which
fell back to m_queue[m_index] — the same track already playing. Fix:
use takeFirst() and return that item directly, only advancing m_index
when the playNext list is empty.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 00:43:08 +01:00
joren
2852ffb0b7 fix: make volume/progress sliders draggable
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 00:41:10 +01:00
joren
cb2323bc32 feat: initial qobuz-qt source
Lightweight Qt6 desktop client for Qobuz with a Rust audio backend
(Symphonia/CPAL via staticlib FFI). Mirrors the spotify-qt layout:
toolbar with playback controls, library/context docks on the left,
tabbed search side panel on the right, queue panel, now-playing dock.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 00:41:04 +01:00
joren
157d0f9ffe fix: make volume/progress sliders draggable
ClickableSlider previously accepted the mouse press without forwarding
to QSlider, so the drag mechanism never started. Now setSliderPosition
is called first (jumping the handle to the click point) and the event
is always forwarded so Qt enters normal drag mode. mouseMoveEvent is
also overridden to keep snapping to the cursor during a drag.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 00:40:29 +01:00
joren
35ae649fc9 first commit 2026-03-24 00:39:45 +01:00
joren
9402dca7ed Initial implementation of qobuz-qt
- Rust backend (qobuz-backend static lib): Qobuz API client (reqwest/tokio),
  Symphonia audio decoder, CPAL audio output, extern "C" FFI bridge
- Qt 6 frontend mirroring spotify-qt layout: toolbar with playback controls,
  left library dock, central track list, right search panel
- Auth: email/password login with MD5-signed requests; session token persisted
  via QSettings
- Playback: double-click a track → Rust fetches stream URL → Symphonia decodes
  → CPAL outputs to default audio device
- Dark Fusion palette matching spotify-qt feel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:34:23 +01:00