mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-06-10 03:13:32 -07:00
feat(notifications): add overlay notifications with position config
- Add Catppuccin Macchiato overlay notification stack with 3s transient timeout - Add `notifications.overlayPosition` config (top-left | top | top-right) - Route startup tokenization and subtitle annotation status through configured surfaces - Deduplicate rapid subtitle mode toggle notifications - Change `both` to mean overlay + system; add `osd-system` as legacy alias for old behavior - Keep `osd`/`osd-system` as config-file-only legacy values; Settings UI offers overlay/system/both/none
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import {
|
||||
beginUpdateProgress,
|
||||
createUiFeedbackState,
|
||||
showProgressTick,
|
||||
showStatusNotification,
|
||||
showUpdateResult,
|
||||
} from './ui-feedback';
|
||||
|
||||
@@ -65,3 +66,38 @@ test('showUpdateResult renders failed updates with an x marker', () => {
|
||||
'x Sentence card failed: deck missing',
|
||||
]);
|
||||
});
|
||||
|
||||
test('showStatusNotification falls back to system when overlay delivery is unavailable', () => {
|
||||
const calls: string[] = [];
|
||||
|
||||
showStatusNotification('Waiting for card update', {
|
||||
getNotificationType: () => 'overlay',
|
||||
showOsd: (message) => {
|
||||
calls.push(`osd:${message}`);
|
||||
},
|
||||
showSystemNotification: (title, options) => {
|
||||
calls.push(`system:${title}:${options.body}`);
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepEqual(calls, ['system:SubMiner:Waiting for card update']);
|
||||
});
|
||||
|
||||
test('showStatusNotification does not duplicate system notifications for both', () => {
|
||||
const calls: string[] = [];
|
||||
|
||||
showStatusNotification('Card updated', {
|
||||
getNotificationType: () => 'both',
|
||||
showOsd: (message) => {
|
||||
calls.push(`osd:${message}`);
|
||||
},
|
||||
showOverlayNotification: (payload) => {
|
||||
calls.push(`overlay:${payload.body}`);
|
||||
},
|
||||
showSystemNotification: (title, options) => {
|
||||
calls.push(`system:${title}:${options.body}`);
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepEqual(calls, ['overlay:Card updated', 'system:SubMiner:Card updated']);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { NotificationOptions } from '../types/anki';
|
||||
import type { NotificationOptions } from '../types/anki';
|
||||
import type { NotificationType, OverlayNotificationPayload } from '../types/notification';
|
||||
|
||||
export interface UiFeedbackState {
|
||||
progressDepth: number;
|
||||
@@ -13,8 +14,9 @@ export interface UiFeedbackResult {
|
||||
}
|
||||
|
||||
export interface UiFeedbackNotificationContext {
|
||||
getNotificationType: () => string | undefined;
|
||||
getNotificationType: () => NotificationType | undefined;
|
||||
showOsd: (text: string) => void;
|
||||
showOverlayNotification?: (payload: OverlayNotificationPayload) => void;
|
||||
showSystemNotification: (title: string, options: NotificationOptions) => void;
|
||||
}
|
||||
|
||||
@@ -36,13 +38,29 @@ export function showStatusNotification(
|
||||
message: string,
|
||||
context: UiFeedbackNotificationContext,
|
||||
): void {
|
||||
const type = context.getNotificationType() || 'osd';
|
||||
const type = context.getNotificationType() ?? 'overlay';
|
||||
|
||||
if (type === 'osd' || type === 'both') {
|
||||
if (type === 'none') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === 'overlay' || type === 'both') {
|
||||
if (context.showOverlayNotification) {
|
||||
context.showOverlayNotification({
|
||||
title: 'SubMiner',
|
||||
body: message,
|
||||
variant: 'info',
|
||||
});
|
||||
} else if (type === 'overlay') {
|
||||
context.showSystemNotification('SubMiner', { body: message });
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'osd' || type === 'osd-system') {
|
||||
context.showOsd(message);
|
||||
}
|
||||
|
||||
if (type === 'system' || type === 'both') {
|
||||
if (type === 'system' || type === 'both' || type === 'osd-system') {
|
||||
context.showSystemNotification('SubMiner', { body: message });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user