fix(voice): queue split TTS segments after pause without replacing track

Detect consecutive tts_auto items on the same assistant bubble via listKey (uuid_seg_n / uuid_part_n). When paused, skip the 'clear queue and play latest only' path so later segments enqueue instead of wiping playback. Add regression test.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Kevin
2026-05-15 17:25:44 +08:00
parent 6452019a1e
commit ddc701f22d
2 changed files with 98 additions and 3 deletions

View File

@@ -207,4 +207,47 @@ describe('usePlayer', () => {
expect(play.mock.calls.length).toBeGreaterThan(playCountAfterFirst);
expect(result.current.currentSource).toBe('file:///latest.mp3');
});
test('after pause, next uuid_seg tts_auto queues without replacing current (multi-segment TTS)', async () => {
const aid = '78b32c06-d2f9-453b-9cc4-354e68fbcb2d';
mockUseAudioPlayerStatus.mockReturnValue({
isLoaded: true,
playing: false,
currentTime: 0.1,
duration: 10,
});
const pause = jest.fn();
const play = jest.fn();
mockUseAudioPlayer.mockReturnValue({ pause, play });
const { result } = renderHook(() => usePlayer());
await act(async () => {
await result.current.enqueue({
uri: 'file:///seg0.mp3',
kind: 'tts_auto',
messageRef: { listKey: `${aid}_seg_0` },
});
});
expect(result.current.status).toBe('playing');
expect(result.current.currentSource).toBe('file:///seg0.mp3');
act(() => {
result.current.pausePlayback();
});
expect(result.current.status).toBe('paused');
await act(async () => {
await result.current.enqueue({
uri: 'file:///seg1.mp3',
kind: 'tts_auto',
messageRef: { listKey: `${aid}_seg_1` },
});
});
expect(result.current.status).toBe('paused');
expect(result.current.currentSource).toBe('file:///seg0.mp3');
expect(result.current.queueLength).toBe(1);
});
});