feat(notifications): add overlay notifications with position config (#110)

This commit is contained in:
2026-06-10 22:46:52 -07:00
committed by GitHub
parent c09d009a3e
commit 7be1843c41
177 changed files with 7524 additions and 440 deletions
@@ -161,6 +161,34 @@ test('startup OSD reset keeps tokenization ready after first warmup', () => {
assert.deepEqual(osdMessages, ['Updating character dictionary for Frieren...']);
});
test('startup OSD reset preserves in-flight tokenization loading for ready update', () => {
const calls: string[] = [];
const sequencer = createStartupOsdSequencer({
getNotificationType: () => 'both',
showOsd: (message) => {
calls.push(`osd:${message}`);
},
showOverlayNotification: (payload) => {
calls.push(
`overlay:${payload.id}:${payload.title}:${payload.body}:${payload.variant}:${payload.persistent ? 'pin' : 'auto'}`,
);
},
showDesktopNotification: (title, options) => {
calls.push(`desktop:${title}:${options.body ?? ''}`);
},
});
sequencer.showTokenizationLoading('Loading subtitle tokenization...');
sequencer.reset();
sequencer.markTokenizationReady();
assert.deepEqual(calls, [
'overlay:startup-tokenization:Subtitle tokenization:Loading subtitle tokenization...:progress:pin',
'overlay:startup-tokenization:Subtitle tokenization:Subtitle tokenization ready:success:auto',
'desktop:SubMiner:Subtitle tokenization ready',
]);
});
test('startup OSD shows later dictionary progress immediately once tokenization is ready', () => {
const osdMessages: string[] = [];
const sequencer = createStartupOsdSequencer({
@@ -222,3 +250,35 @@ test('startup OSD keeps dictionary progress pending when mpv osd is unavailable'
'Character dictionary ready for Frieren',
]);
});
test('startup notifications route tokenization and annotation status to overlay and system without osd for both', () => {
const calls: string[] = [];
const sequencer = createStartupOsdSequencer({
getNotificationType: () => 'both',
showOsd: (message) => {
calls.push(`osd:${message}`);
},
showOverlayNotification: (payload) => {
calls.push(
`overlay:${payload.id}:${payload.title}:${payload.body}:${payload.variant}:${payload.persistent ? 'pin' : 'auto'}`,
);
},
showDesktopNotification: (title, options) => {
calls.push(`desktop:${title}:${options.body ?? ''}`);
},
});
sequencer.showTokenizationLoading('Loading subtitle tokenization...');
sequencer.markTokenizationReady();
sequencer.showAnnotationLoading('Loading subtitle annotations |');
sequencer.markAnnotationLoadingComplete('Subtitle annotations loaded');
assert.deepEqual(calls, [
'overlay:startup-tokenization:Subtitle tokenization:Loading subtitle tokenization...:progress:pin',
'overlay:startup-tokenization:Subtitle tokenization:Subtitle tokenization ready:success:auto',
'desktop:SubMiner:Subtitle tokenization ready',
'overlay:startup-subtitle-annotations:Subtitle annotations:Loading subtitle annotations |:progress:pin',
'overlay:startup-subtitle-annotations:Subtitle annotations:Subtitle annotations loaded:success:auto',
'desktop:SubMiner:Subtitle annotations loaded',
]);
});