mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-04-28 16:19:31 -07:00
Windows update (#49)
This commit is contained in:
@@ -11,6 +11,7 @@ export const OVERLAY_HOSTED_MODALS = [
|
||||
'controller-select',
|
||||
'controller-debug',
|
||||
'subtitle-sidebar',
|
||||
'session-help',
|
||||
] as const;
|
||||
export type OverlayHostedModal = (typeof OVERLAY_HOSTED_MODALS)[number];
|
||||
|
||||
@@ -37,6 +38,7 @@ export const IPC_CHANNELS = {
|
||||
overlayModalOpened: 'overlay:modal-opened',
|
||||
toggleStatsOverlay: 'stats:toggle-overlay',
|
||||
markActiveVideoWatched: 'immersion:mark-active-video-watched',
|
||||
dispatchSessionAction: 'session-action:dispatch',
|
||||
},
|
||||
request: {
|
||||
getVisibleOverlayVisibility: 'get-visible-overlay-visibility',
|
||||
@@ -49,6 +51,7 @@ export const IPC_CHANNELS = {
|
||||
getSubtitleStyle: 'get-subtitle-style',
|
||||
getMecabStatus: 'get-mecab-status',
|
||||
getKeybindings: 'get-keybindings',
|
||||
getSessionBindings: 'get-session-bindings',
|
||||
getConfigShortcuts: 'get-config-shortcuts',
|
||||
getStatsToggleKey: 'get-stats-toggle-key',
|
||||
getMarkWatchedKey: 'get-mark-watched-key',
|
||||
@@ -109,6 +112,10 @@ export const IPC_CHANNELS = {
|
||||
playlistBrowserOpen: 'playlist-browser:open',
|
||||
keyboardModeToggleRequested: 'keyboard-mode-toggle:requested',
|
||||
lookupWindowToggleRequested: 'lookup-window-toggle:requested',
|
||||
sessionHelpOpen: 'session-help:open',
|
||||
controllerSelectOpen: 'controller-select:open',
|
||||
controllerDebugOpen: 'controller-debug:open',
|
||||
subtitleSidebarToggle: 'subtitle-sidebar:toggle',
|
||||
configHotReload: 'config:hot-reload',
|
||||
},
|
||||
} as const;
|
||||
|
||||
@@ -8,12 +8,41 @@ import type {
|
||||
import type {
|
||||
ControllerConfigUpdate,
|
||||
ControllerPreferenceUpdate,
|
||||
SessionActionDispatchRequest,
|
||||
SubsyncManualRunRequest,
|
||||
} from '../../types/runtime';
|
||||
import type { RuntimeOptionId, RuntimeOptionValue } from '../../types/runtime-options';
|
||||
import type { SessionActionId, SessionActionPayload } from '../../types/session-bindings';
|
||||
import type { SubtitlePosition } from '../../types/subtitle';
|
||||
import { OVERLAY_HOSTED_MODALS, type OverlayHostedModal } from './contracts';
|
||||
|
||||
const SESSION_ACTION_IDS: SessionActionId[] = [
|
||||
'toggleStatsOverlay',
|
||||
'toggleVisibleOverlay',
|
||||
'copySubtitle',
|
||||
'copySubtitleMultiple',
|
||||
'updateLastCardFromClipboard',
|
||||
'triggerFieldGrouping',
|
||||
'triggerSubsync',
|
||||
'mineSentence',
|
||||
'mineSentenceMultiple',
|
||||
'toggleSecondarySub',
|
||||
'markAudioCard',
|
||||
'toggleSubtitleSidebar',
|
||||
'openRuntimeOptions',
|
||||
'openSessionHelp',
|
||||
'openControllerSelect',
|
||||
'openControllerDebug',
|
||||
'openJimaku',
|
||||
'openYoutubePicker',
|
||||
'openPlaylistBrowser',
|
||||
'replayCurrentSubtitle',
|
||||
'playNextSubtitle',
|
||||
'shiftSubDelayPrevLine',
|
||||
'shiftSubDelayNextLine',
|
||||
'cycleRuntimeOption',
|
||||
];
|
||||
|
||||
const RUNTIME_OPTION_IDS: RuntimeOptionId[] = [
|
||||
'anki.autoUpdateNewCards',
|
||||
'subtitle.annotation.nPlusOne',
|
||||
@@ -35,6 +64,43 @@ function isInteger(value: unknown): value is number {
|
||||
return typeof value === 'number' && Number.isInteger(value);
|
||||
}
|
||||
|
||||
function isSessionActionId(value: unknown): value is SessionActionId {
|
||||
return typeof value === 'string' && SESSION_ACTION_IDS.includes(value as SessionActionId);
|
||||
}
|
||||
|
||||
function parseSessionActionPayload(
|
||||
actionId: SessionActionId,
|
||||
value: unknown,
|
||||
): SessionActionPayload | undefined | null {
|
||||
if (actionId === 'copySubtitleMultiple' || actionId === 'mineSentenceMultiple') {
|
||||
if (value === undefined) return undefined;
|
||||
if (!isObject(value)) return null;
|
||||
const keys = Object.keys(value);
|
||||
if (keys.some((key) => key !== 'count')) return null;
|
||||
if (value.count === undefined) return null;
|
||||
if (!isInteger(value.count) || value.count < 1) return null;
|
||||
return { count: value.count };
|
||||
}
|
||||
|
||||
if (actionId === 'cycleRuntimeOption') {
|
||||
if (!isObject(value)) return null;
|
||||
const keys = Object.keys(value);
|
||||
if (keys.some((key) => key !== 'runtimeOptionId' && key !== 'direction')) return null;
|
||||
if (typeof value.runtimeOptionId !== 'string' || value.runtimeOptionId.trim().length === 0) {
|
||||
return null;
|
||||
}
|
||||
if (value.direction !== 1 && value.direction !== -1) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
runtimeOptionId: value.runtimeOptionId,
|
||||
direction: value.direction,
|
||||
};
|
||||
}
|
||||
|
||||
return value === undefined ? undefined : null;
|
||||
}
|
||||
|
||||
export function parseOverlayHostedModal(value: unknown): OverlayHostedModal | null {
|
||||
if (typeof value !== 'string') return null;
|
||||
return OVERLAY_HOSTED_MODALS.includes(value as OverlayHostedModal)
|
||||
@@ -182,6 +248,17 @@ export function parseRuntimeOptionValue(value: unknown): RuntimeOptionValue | nu
|
||||
: null;
|
||||
}
|
||||
|
||||
export function parseSessionActionDispatchRequest(
|
||||
value: unknown,
|
||||
): SessionActionDispatchRequest | null {
|
||||
if (!isObject(value)) return null;
|
||||
if (!isSessionActionId(value.actionId)) return null;
|
||||
|
||||
const payload = parseSessionActionPayload(value.actionId, value.payload);
|
||||
if (payload === null) return null;
|
||||
return payload === undefined ? { actionId: value.actionId } : { actionId: value.actionId, payload };
|
||||
}
|
||||
|
||||
export function parseMpvCommand(value: unknown): Array<string | number> | null {
|
||||
if (!Array.isArray(value)) return null;
|
||||
return value.every((entry) => typeof entry === 'string' || typeof entry === 'number')
|
||||
|
||||
Reference in New Issue
Block a user