mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-09-21 17:16:20 -07:00
feat(anime): queue episodes to play next across anime
- Episode rows gain Play/Queue actions (and matching context-menu items); queued rows show their place in line, with a queue count and Clear queue in the episode header - Queue lives in the main process (`anime-browser-queue.ts`) so it survives the browser window closing and advances on mpv's end-file even when nobody is watching; streams resolve at play time so a signed URL cannot expire while queued - Holds mpv's keep-open off while the queue waits and restores it once empty; queueing with nothing playing just plays immediately - Adds anime-browser-queue and episode-queue unit tests, IPC channels/contracts, and doc updates
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { describeQueuePosition, queueKey, queuePositions } from './episode-queue';
|
||||
import type { AnimeBrowserQueueEntry } from '../types/anime-browser';
|
||||
|
||||
function entry(overrides: Partial<AnimeBrowserQueueEntry> = {}): AnimeBrowserQueueEntry {
|
||||
return {
|
||||
sourceId: 'source',
|
||||
animeUrl: '/anime',
|
||||
animeTitle: 'Anime',
|
||||
episodeUrl: '/episode-1',
|
||||
episodeName: 'Episode 1',
|
||||
episodeNumber: 1,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
test('positions count across the whole queue, not within one anime', () => {
|
||||
const positions = queuePositions([
|
||||
entry(),
|
||||
entry({ animeUrl: '/other', episodeUrl: '/other-1' }),
|
||||
entry({ episodeUrl: '/episode-2' }),
|
||||
]);
|
||||
|
||||
assert.equal(positions.get(queueKey('source', '/episode-1')), 1);
|
||||
assert.equal(positions.get(queueKey('source', '/other-1')), 2);
|
||||
assert.equal(positions.get(queueKey('source', '/episode-2')), 3);
|
||||
});
|
||||
|
||||
test('the same episode url on two sources keeps two positions', () => {
|
||||
const positions = queuePositions([entry(), entry({ sourceId: 'other' })]);
|
||||
|
||||
assert.equal(positions.get(queueKey('source', '/episode-1')), 1);
|
||||
assert.equal(positions.get(queueKey('other', '/episode-1')), 2);
|
||||
});
|
||||
|
||||
test('the episode about to play is named rather than numbered', () => {
|
||||
assert.equal(describeQueuePosition(1), 'next up');
|
||||
assert.equal(describeQueuePosition(4), '#4 in queue');
|
||||
});
|
||||
Reference in New Issue
Block a user