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:
2026-06-04 21:56:51 -07:00
parent c09d009a3e
commit 144373db52
82 changed files with 2290 additions and 243 deletions
+10
View File
@@ -59,6 +59,7 @@ import type {
YoutubePickerOpenPayload,
YoutubePickerResolveRequest,
YoutubePickerResolveResult,
OverlayNotificationEventPayload,
} from './types';
import { IPC_CHANNELS } from './shared/ipc/contracts';
@@ -206,6 +207,11 @@ const onSubtitleSetEvent = createLatestValueIpcListenerWithPayload<SubtitleData>
const onOverlayPointerRecoveryRequestEvent = createQueuedIpcListener(
IPC_CHANNELS.event.overlayPointerRecoveryRequest,
);
const onOverlayNotificationEvent =
createQueuedIpcListenerWithPayload<OverlayNotificationEventPayload>(
IPC_CHANNELS.event.overlayNotification,
(payload) => payload as OverlayNotificationEventPayload,
);
const onSubtitleVisibilityEvent = createLatestValueIpcListenerWithPayload<boolean>(
IPC_CHANNELS.event.subtitleVisibility,
(payload) => payload === true,
@@ -229,6 +235,10 @@ const electronAPI: ElectronAPI = {
onSubtitleSetEvent(callback);
},
onOverlayPointerRecoveryRequested: onOverlayPointerRecoveryRequestEvent,
onOverlayNotification: onOverlayNotificationEvent,
sendOverlayNotificationAction: (notificationId: string, actionId: string) => {
ipcRenderer.send(IPC_CHANNELS.command.overlayNotificationAction, { notificationId, actionId });
},
onVisibility: (callback: (visible: boolean) => void) => {
onSubtitleVisibilityEvent(callback);