mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-09-23 05:16:23 -07:00
85 lines
3.2 KiB
TypeScript
85 lines
3.2 KiB
TypeScript
import type { CharacterDictionaryAutoSyncStatusEvent } from './character-dictionary-auto-sync';
|
|
import type { StartupOsdSequencerCharacterDictionaryEvent } from './startup-osd-sequencer';
|
|
import type { NotificationType, OverlayNotificationPayload } from '../../types/notification';
|
|
import { shouldShowDesktop, shouldShowOverlay, shouldShowOsd } from './notification-routing';
|
|
|
|
export type CharacterDictionaryAutoSyncNotificationEvent = CharacterDictionaryAutoSyncStatusEvent;
|
|
|
|
export interface CharacterDictionaryAutoSyncNotificationDeps {
|
|
getNotificationType: () => NotificationType | undefined;
|
|
showOsd: (message: string) => boolean | void;
|
|
showOverlayNotification?: (payload: OverlayNotificationPayload) => void;
|
|
showDesktopNotification: (title: string, options: { body?: string; replaceId?: string }) => void;
|
|
startupOsdSequencer?: {
|
|
notifyCharacterDictionaryStatus: (
|
|
event: StartupOsdSequencerCharacterDictionaryEvent,
|
|
) => boolean;
|
|
};
|
|
}
|
|
|
|
// One live desktop notification for the whole sync: progress updates replace each other and the
|
|
// terminal ready/failed message replaces the last progress one, matching the overlay toast.
|
|
const CHARACTER_DICTIONARY_DESKTOP_NOTIFICATION_ID = 'character-dictionary-auto-sync';
|
|
|
|
function isTerminalPhase(phase: CharacterDictionaryAutoSyncNotificationEvent['phase']): boolean {
|
|
return phase === 'ready' || phase === 'failed';
|
|
}
|
|
|
|
function overlayVariantForPhase(
|
|
phase: CharacterDictionaryAutoSyncNotificationEvent['phase'],
|
|
): OverlayNotificationPayload['variant'] {
|
|
if (phase === 'ready') return 'success';
|
|
if (phase === 'failed') return 'error';
|
|
return 'progress';
|
|
}
|
|
|
|
function historyIdForEvent(event: CharacterDictionaryAutoSyncNotificationEvent): string {
|
|
const mediaId = typeof event.mediaId === 'number' ? String(event.mediaId) : 'current';
|
|
return `character-dictionary-auto-sync-${mediaId}-${event.phase}`;
|
|
}
|
|
|
|
export function notifyCharacterDictionaryAutoSyncStatus(
|
|
event: CharacterDictionaryAutoSyncNotificationEvent,
|
|
deps: CharacterDictionaryAutoSyncNotificationDeps,
|
|
): void {
|
|
const type = deps.getNotificationType() ?? 'overlay';
|
|
if (type === 'none') return;
|
|
let startupSequencerShown = false;
|
|
|
|
if (shouldShowOverlay(type)) {
|
|
if (deps.showOverlayNotification) {
|
|
deps.showOverlayNotification({
|
|
id: 'character-dictionary-auto-sync',
|
|
historyId: historyIdForEvent(event),
|
|
title: 'Character dictionary',
|
|
body: event.message,
|
|
variant: overlayVariantForPhase(event.phase),
|
|
persistent: !isTerminalPhase(event.phase),
|
|
});
|
|
} else if (!shouldShowDesktop(type)) {
|
|
deps.showDesktopNotification('SubMiner', {
|
|
body: event.message,
|
|
replaceId: CHARACTER_DICTIONARY_DESKTOP_NOTIFICATION_ID,
|
|
});
|
|
}
|
|
}
|
|
|
|
if (shouldShowOsd(type)) {
|
|
if (deps.startupOsdSequencer) {
|
|
startupSequencerShown = deps.startupOsdSequencer.notifyCharacterDictionaryStatus({
|
|
phase: event.phase,
|
|
message: event.message,
|
|
});
|
|
} else {
|
|
deps.showOsd(event.message);
|
|
}
|
|
}
|
|
|
|
if (shouldShowDesktop(type) && !startupSequencerShown) {
|
|
deps.showDesktopNotification('SubMiner', {
|
|
body: event.message,
|
|
replaceId: CHARACTER_DICTIONARY_DESKTOP_NOTIFICATION_ID,
|
|
});
|
|
}
|
|
}
|