aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/app.js
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-16 11:01:02 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-16 11:01:02 +0200
commit20706fb9a4ec646816b44a10842aa8f58ea0fd75 (patch)
tree126be97d794491196c6033ae76d4680f24188595 /packages/meshbay-hub/src/meshbay_hub/static/app.js
parenta79a38a22a6145c475f50eeadb79b451aee31c11 (diff)
downloadmeshbay-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.js30
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), []);