diff --git a/web/src/lib/player/store.svelte.ts b/web/src/lib/player/store.svelte.ts index 2078894b..2676d10b 100644 --- a/web/src/lib/player/store.svelte.ts +++ b/web/src/lib/player/store.svelte.ts @@ -211,6 +211,22 @@ export function enqueueTrack(t: TrackRef): void { if (_state === 'idle') _index = 0; } +/** + * M7 #372: insert a track immediately after the currently-playing one + * so it plays next. If the queue is empty, behaves like enqueueTrack + * and starts the queue with this track at index 0. + */ +export function playNext(t: TrackRef): void { + _radioSeedId = null; // M4c: any user-driven enqueue clears the radio refresh state + if (_queue.length === 0) { + _queue = [t]; + _index = 0; + return; + } + const next = _index + 1; + _queue = [..._queue.slice(0, next), t, ..._queue.slice(next)]; +} + export function enqueueTracks(ts: TrackRef[]): void { _radioSeedId = null; // M4c if (ts.length === 0) return; diff --git a/web/src/lib/player/store.test.ts b/web/src/lib/player/store.test.ts index 57a50a30..97fc7642 100644 --- a/web/src/lib/player/store.test.ts +++ b/web/src/lib/player/store.test.ts @@ -280,7 +280,7 @@ describe('player store — shuffle + repeat + audio reports', () => { }); }); -import { enqueueTrack, enqueueTracks, playRadio } from './store.svelte'; +import { enqueueTrack, enqueueTracks, playNext, playRadio } from './store.svelte'; import * as client from '$lib/api/client'; describe('player store — enqueue + playRadio', () => { @@ -334,6 +334,22 @@ describe('player store — enqueue + playRadio', () => { }); }); +describe('playNext', () => { + test('splices at _index + 1, leaving _index unchanged', () => { + playQueue([track('a'), track('b')], 0); + playNext(track('c')); + expect(player.queue.map((t) => t.id)).toEqual(['a', 'c', 'b']); + expect(player.index).toBe(0); + }); + + test('on empty queue, seeds with the track at index 0', () => { + playQueue([]); + playNext(track('x')); + expect(player.queue.map((t) => t.id)).toEqual(['x']); + expect(player.index).toBe(0); + }); +}); + describe('M4c radio auto-refresh at 80%', () => { test('refresh fires at 80% queue consumption', async () => { const tracks = [track('seed'), track('t1'), track('t2'), track('t3'), track('t4')];