Skip to content

feat(frontend): event-driven player state - #403

Merged
prokosna merged 7 commits into
mainfrom
feat/event-driven-player
Oct 18, 2026
Merged

prokosna merged 7 commits into
mainfrom
feat/event-driven-player

Conversation

@prokosna

Copy link
Copy Markdown
Owner
  • Refresh player state on MPD PLAYER/OPTIONS events; interpolate elapsed locally with a 15 s safety resync (was 1 s polling)
  • Re-subscribe to MPD events after a Socket.IO reconnect and refetch MPD-backed state
  • Keep the seek bar on the dragged position

🤖 Generated with Claude Code

prokosna and others added 4 commits October 17, 2026 11:06
The backend drops a socket's MPD subscriptions when it disconnects, and the
client never re-sent the subscribe request, so idle events stopped arriving
after any Socket.IO reconnect until the page was reloaded.

MessagingClient gains onReconnect (a no-op for Electron IPC, which cannot
reconnect within a renderer's lifetime). MpdListenerSocketIo uses it to
re-subscribe the current profile, and exposes onSubscribed so callers can
refetch state that may have changed while events were not delivered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lling

The current song and player status were polled every second. They are now
refetched on PLAYER and OPTIONS events, after each acknowledged
subscription (initial subscribe, profile switch, transport reconnect), and
on UPDATE for the database-updating flag.

Elapsed time is interpolated locally from the last status snapshot and a
monotonic clock that ticks every 500 ms only while playing, clamped to the
song duration. A 15 s resync of status and current song recovers from
events missed while the backend's MPD idle connection reconnects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Events for the play queue, playlists, stats and volume may have been
missed while the transport was down, so refetch them on resubscription.
The first subscription keeps refreshing only the player.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The seek bar was bound to the elapsed value with no drag state, so with
elapsed now interpolated every 500 ms the thumb and its label fought
the user while dragging. Hold the dragged position, then the pending
seek until MPD reports a new status.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
prokosna and others added 3 commits October 18, 2026 13:39
… trailing seek

A second release less than a second after a seek was dropped, so the bar
snapped back to the first seek's position. Releases inside the window now
collapse into one seek sent when the window ends, and the bar holds the
latest position until a status newer than that seek arrives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
While stopped or on a live stream there is nothing to seek, and no status
event follows a seek attempt, so a dragged position stayed on the bar until
the next resync.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cription

Every MPD-backed atom, including the current song and the player status,
already fetches on first read, so only a re-subscription needs a refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@prokosna
prokosna merged commit efb6bc1 into main Oct 18, 2026
1 check passed
@prokosna
prokosna deleted the feat/event-driven-player branch October 18, 2026 11:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant