diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-16 11:01:02 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-16 11:01:02 +0200 |
| commit | 20706fb9a4ec646816b44a10842aa8f58ea0fd75 (patch) | |
| tree | 126be97d794491196c6033ae76d4680f24188595 /packages/meshbay-hub/src/meshbay_hub/static/app.js | |
| parent | a79a38a22a6145c475f50eeadb79b451aee31c11 (diff) | |
| download | meshbay-20706fb9a4ec646816b44a10842aa8f58ea0fd75.tar.gz | |
music: play, play next, add to queue
The player's queue could only be replaced: every onPlayQueue reset
tracks/order/pos together. It becomes one reducer (queue-ops.js) with
an `op`, because two appends batched into one tick cannot both read the
track count out of separate useStates.
A shared pop-up menu (menu.js) carries the three verbs, on right-click
and on a dots button. A track row is now a div holding two buttons: a
button cannot contain a button.
Found by the browser probe: both music wrappers took two arguments and
forwarded two, so every "add to queue" arrived as a plain play.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/app.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/app.js | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/app.js b/packages/meshbay-hub/src/meshbay_hub/static/app.js index a249ccf..ef8d1e9 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/app.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/app.js @@ -725,17 +725,27 @@ function App() { return { transport: conn.transport, gek: conn.gek }; }, []); - const handlePlayQueue = useCallback((tracks, startIndex, source) => { - if (source && source.transportRef) { - groupTransportRef.current = { - groupId: source.groupId, - transportRef: source.transportRef, - gekRef: source.gekRef, - }; - } else { - groupTransportRef.current = null; + // `op` is 'replace' (the default, and what playing an album or loading a + // playlist means), 'next', or 'append' โ docs/playlists.md ยง9.2. + const handlePlayQueue = useCallback((tracks, startIndex, source, op) => { + const how = op || 'replace'; + // A single-slot fast path for the group whose page is open, so playing + // from it reuses the live transport instead of dialing through the pool. + // Only a replace is about that group: repointing it because one track + // from somewhere else was enqueued would drop whatever is *playing* back + // to the pool, for nothing. + if (how === 'replace') { + if (source && source.transportRef) { + groupTransportRef.current = { + groupId: source.groupId, + transportRef: source.transportRef, + gekRef: source.gekRef, + }; + } else { + groupTransportRef.current = null; + } } - setMusicQueue({ tracks, startIndex, nonce: Date.now() }); + setMusicQueue({ tracks, startIndex, nonce: Date.now(), op: how }); }, []); const handleStopMusic = useCallback(() => setMusicQueue(null), []); |