mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-10-22 05:01:24 -07:00
* fix(overlay): reload imported mpv keys after mpv connects The overlay fetched mpv's input-bindings before SubMiner connected to mpv, cached an empty list, and never refetched because the connect-time refresh only broadcast session bindings when their compiled signature changed. Keys from input.conf and mpv defaults (9/0 volume, m mute) then did nothing while the overlay had focus, most often in mpv.backend x11 mode. Main now emits mpv-input-bindings:changed whenever the discovered mpv key set or client changes, and the renderer refreshes its imported keys on it. * fix(overlay): subscribe to mpv key changes before initial discovery The renderer registered the mpv-input-bindings:changed listener only after awaiting setupMpvInputForwarding and several other startup calls. If mpv connected in that window, the event was dropped and the imported mpv keys stayed empty.
668 lines
22 KiB
TypeScript
668 lines
22 KiB
TypeScript
import type { MpvInputBindingsSnapshot } from './session-bindings';
|
|
import type {
|
|
KikuFieldGroupingChoice,
|
|
KikuFieldGroupingRequestData,
|
|
KikuMergePreviewRequest,
|
|
KikuMergePreviewResponse,
|
|
MediaTimingReviewActionResult,
|
|
MediaTimingReviewOpenPayload,
|
|
MediaTimingReviewPreviewPosition,
|
|
MediaTimingReviewPreviewRequest,
|
|
MediaTimingReviewResolveRequest,
|
|
MediaTimingReviewFrameRequest,
|
|
MediaTimingReviewFrameResult,
|
|
MediaTimingReviewWaveformRequest,
|
|
MediaTimingReviewWaveformResult,
|
|
} from './anki';
|
|
import type { ChangelogSnapshot } from './changelog';
|
|
import type { SubtitleGenerationProgress } from '../shared/subtitle-generation';
|
|
import type { SubtitleGenerationModelId } from '../shared/subtitle-generation-model-catalog';
|
|
import type {
|
|
SubtitleGenerationResult,
|
|
SubtitleGenerationStatus,
|
|
} from '../shared/subtitle-generation-ipc';
|
|
import type { ResolvedConfig, ShortcutsConfig } from './config';
|
|
import type {
|
|
CompiledSessionBinding,
|
|
SessionActionId,
|
|
SessionActionPayload,
|
|
SessionBindingWarning,
|
|
} from './session-bindings';
|
|
import type {
|
|
TsukihimeApiResponse,
|
|
TsukihimeDownloadQuery,
|
|
TsukihimeDownloadResult,
|
|
TsukihimeEntry,
|
|
TsukihimeFilesQuery,
|
|
TsukihimeSearchQuery,
|
|
TsukihimeSubtitleFile,
|
|
JimakuApiResponse,
|
|
JimakuDownloadQuery,
|
|
JimakuDownloadResult,
|
|
JimakuEntry,
|
|
JimakuFileEntry,
|
|
JimakuFilesQuery,
|
|
JimakuMediaInfo,
|
|
JimakuSearchQuery,
|
|
YoutubePickerOpenPayload,
|
|
YoutubePickerResolveRequest,
|
|
YoutubePickerResolveResult,
|
|
} from './integrations';
|
|
import type {
|
|
PrimarySubMode,
|
|
ResolvedSubtitleSidebarConfig,
|
|
SecondarySubMode,
|
|
SubtitleData,
|
|
SubtitleMiningContext,
|
|
SubtitlePosition,
|
|
SubtitleSidebarSnapshot,
|
|
SubtitleRendererStyleConfig,
|
|
SubtitleStyleConfig,
|
|
} from './subtitle';
|
|
import type {
|
|
RuntimeOptionApplyResult,
|
|
RuntimeOptionId,
|
|
RuntimeOptionState,
|
|
RuntimeOptionValue,
|
|
} from './runtime-options';
|
|
import type {
|
|
OverlayNotificationAction,
|
|
OverlayNotificationEventPayload,
|
|
OverlayNotificationPosition,
|
|
} from './notification';
|
|
|
|
export interface WindowGeometry {
|
|
x: number;
|
|
y: number;
|
|
width: number;
|
|
height: number;
|
|
}
|
|
|
|
export interface Keybinding {
|
|
key: string;
|
|
command: (string | number)[] | null;
|
|
}
|
|
|
|
export interface MpvClient {
|
|
currentSubText: string;
|
|
currentVideoPath: string;
|
|
currentMediaTitle?: string | null;
|
|
currentTimePos: number;
|
|
currentSubStart: number;
|
|
currentSubEnd: number;
|
|
currentAudioStreamIndex: number | null;
|
|
requestProperty?: (name: string) => Promise<unknown>;
|
|
send(command: { command: unknown[]; request_id?: number }): boolean;
|
|
}
|
|
|
|
export interface SubsyncSubtitleTrack {
|
|
id: number;
|
|
label: string;
|
|
}
|
|
|
|
export interface SubsyncManualPayload {
|
|
subtitleTracks: SubsyncSubtitleTrack[];
|
|
defaultReferenceTrackId: number | null;
|
|
defaultTargetTrackId: number | null;
|
|
videoReferenceAvailable: boolean;
|
|
ffsubsyncAvailable: boolean;
|
|
}
|
|
|
|
export type SubsyncReferenceMode = 'track' | 'video';
|
|
|
|
export interface SubsyncManualRunRequest {
|
|
engine: 'alass' | 'ffsubsync';
|
|
/** alass reference source: another subtitle track, or the loaded media file itself. */
|
|
referenceMode?: SubsyncReferenceMode;
|
|
referenceTrackId?: number | null;
|
|
/** Subtitle track to retime. Defaults to the active primary track. */
|
|
targetTrackId?: number | null;
|
|
}
|
|
|
|
export interface SubsyncResult {
|
|
ok: boolean;
|
|
message: string;
|
|
}
|
|
|
|
export interface PlaylistBrowserDirectoryItem {
|
|
path: string;
|
|
basename: string;
|
|
episodeLabel?: string | null;
|
|
isCurrentFile: boolean;
|
|
}
|
|
|
|
export interface PlaylistBrowserQueueItem {
|
|
index: number;
|
|
id: number | null;
|
|
filename: string;
|
|
title: string | null;
|
|
displayLabel: string;
|
|
current: boolean;
|
|
playing: boolean;
|
|
path: string | null;
|
|
}
|
|
|
|
export interface PlaylistBrowserSnapshot {
|
|
directoryPath: string | null;
|
|
directoryAvailable: boolean;
|
|
directoryStatus: string;
|
|
directoryItems: PlaylistBrowserDirectoryItem[];
|
|
playlistItems: PlaylistBrowserQueueItem[];
|
|
playingIndex: number | null;
|
|
currentFilePath: string | null;
|
|
}
|
|
|
|
export interface PlaylistBrowserMutationResult {
|
|
ok: boolean;
|
|
message: string;
|
|
snapshot?: PlaylistBrowserSnapshot;
|
|
}
|
|
|
|
export type ControllerButtonBinding =
|
|
| 'none'
|
|
| 'select'
|
|
| 'buttonSouth'
|
|
| 'buttonEast'
|
|
| 'buttonNorth'
|
|
| 'buttonWest'
|
|
| 'leftShoulder'
|
|
| 'rightShoulder'
|
|
| 'leftStickPress'
|
|
| 'rightStickPress'
|
|
| 'leftTrigger'
|
|
| 'rightTrigger';
|
|
|
|
export type ControllerAxisBinding = 'leftStickX' | 'leftStickY' | 'rightStickX' | 'rightStickY';
|
|
export type ControllerTriggerInputMode = 'auto' | 'digital' | 'analog';
|
|
export type ControllerAxisDirection = 'negative' | 'positive';
|
|
export type ControllerDpadFallback = 'none' | 'horizontal' | 'vertical';
|
|
|
|
export interface ControllerNoneBinding {
|
|
kind: 'none';
|
|
}
|
|
|
|
export interface ControllerButtonInputBinding {
|
|
kind: 'button';
|
|
buttonIndex: number;
|
|
}
|
|
|
|
export interface ControllerAxisDirectionInputBinding {
|
|
kind: 'axis';
|
|
axisIndex: number;
|
|
direction: ControllerAxisDirection;
|
|
}
|
|
|
|
export interface ControllerAxisInputBinding {
|
|
kind: 'axis';
|
|
axisIndex: number;
|
|
dpadFallback?: ControllerDpadFallback;
|
|
}
|
|
|
|
export type ControllerDiscreteBindingConfig =
|
|
| ControllerButtonBinding
|
|
| ControllerNoneBinding
|
|
| ControllerButtonInputBinding
|
|
| ControllerAxisDirectionInputBinding;
|
|
|
|
export type ResolvedControllerDiscreteBinding =
|
|
| ControllerNoneBinding
|
|
| ControllerButtonInputBinding
|
|
| ControllerAxisDirectionInputBinding;
|
|
|
|
export type ControllerAxisBindingConfig =
|
|
| ControllerAxisBinding
|
|
| ControllerNoneBinding
|
|
| ControllerAxisInputBinding;
|
|
|
|
export type ResolvedControllerAxisBinding =
|
|
| ControllerNoneBinding
|
|
| {
|
|
kind: 'axis';
|
|
axisIndex: number;
|
|
dpadFallback: ControllerDpadFallback;
|
|
};
|
|
|
|
export interface ControllerBindingsConfig {
|
|
toggleLookup?: ControllerDiscreteBindingConfig;
|
|
closeLookup?: ControllerDiscreteBindingConfig;
|
|
toggleKeyboardOnlyMode?: ControllerDiscreteBindingConfig;
|
|
mineCard?: ControllerDiscreteBindingConfig;
|
|
quitMpv?: ControllerDiscreteBindingConfig;
|
|
previousAudio?: ControllerDiscreteBindingConfig;
|
|
nextAudio?: ControllerDiscreteBindingConfig;
|
|
playCurrentAudio?: ControllerDiscreteBindingConfig;
|
|
toggleMpvPause?: ControllerDiscreteBindingConfig;
|
|
leftStickHorizontal?: ControllerAxisBindingConfig;
|
|
leftStickVertical?: ControllerAxisBindingConfig;
|
|
rightStickHorizontal?: ControllerAxisBindingConfig;
|
|
rightStickVertical?: ControllerAxisBindingConfig;
|
|
}
|
|
|
|
export interface ResolvedControllerBindingsConfig {
|
|
toggleLookup?: ResolvedControllerDiscreteBinding;
|
|
closeLookup?: ResolvedControllerDiscreteBinding;
|
|
toggleKeyboardOnlyMode?: ResolvedControllerDiscreteBinding;
|
|
mineCard?: ResolvedControllerDiscreteBinding;
|
|
quitMpv?: ResolvedControllerDiscreteBinding;
|
|
previousAudio?: ResolvedControllerDiscreteBinding;
|
|
nextAudio?: ResolvedControllerDiscreteBinding;
|
|
playCurrentAudio?: ResolvedControllerDiscreteBinding;
|
|
toggleMpvPause?: ResolvedControllerDiscreteBinding;
|
|
leftStickHorizontal?: ResolvedControllerAxisBinding;
|
|
leftStickVertical?: ResolvedControllerAxisBinding;
|
|
rightStickHorizontal?: ResolvedControllerAxisBinding;
|
|
rightStickVertical?: ResolvedControllerAxisBinding;
|
|
}
|
|
|
|
export interface ControllerButtonIndicesConfig {
|
|
select?: number;
|
|
buttonSouth?: number;
|
|
buttonEast?: number;
|
|
buttonNorth?: number;
|
|
buttonWest?: number;
|
|
leftShoulder?: number;
|
|
rightShoulder?: number;
|
|
leftStickPress?: number;
|
|
rightStickPress?: number;
|
|
leftTrigger?: number;
|
|
rightTrigger?: number;
|
|
}
|
|
|
|
export interface ControllerProfileConfig {
|
|
label?: string;
|
|
buttonIndices?: ControllerButtonIndicesConfig;
|
|
bindings?: ControllerBindingsConfig;
|
|
}
|
|
|
|
export interface ResolvedControllerProfileConfig {
|
|
label: string;
|
|
buttonIndices: Required<ControllerButtonIndicesConfig>;
|
|
bindings: Required<ResolvedControllerBindingsConfig>;
|
|
}
|
|
|
|
export interface ControllerConfig {
|
|
enabled?: boolean;
|
|
preferredGamepadId?: string;
|
|
preferredGamepadLabel?: string;
|
|
smoothScroll?: boolean;
|
|
scrollPixelsPerSecond?: number;
|
|
horizontalJumpPixels?: number;
|
|
stickDeadzone?: number;
|
|
triggerInputMode?: ControllerTriggerInputMode;
|
|
triggerDeadzone?: number;
|
|
repeatDelayMs?: number;
|
|
repeatIntervalMs?: number;
|
|
buttonIndices?: ControllerButtonIndicesConfig;
|
|
bindings?: ControllerBindingsConfig;
|
|
profiles?: Record<string, ControllerProfileConfig>;
|
|
}
|
|
|
|
export interface ControllerPreferenceUpdate {
|
|
preferredGamepadId: string;
|
|
preferredGamepadLabel: string;
|
|
}
|
|
|
|
export type ControllerConfigUpdate = ControllerConfig;
|
|
|
|
export interface ControllerDeviceInfo {
|
|
id: string;
|
|
index: number;
|
|
mapping: string;
|
|
connected: boolean;
|
|
}
|
|
|
|
export interface ControllerButtonSnapshot {
|
|
value: number;
|
|
pressed: boolean;
|
|
touched?: boolean;
|
|
}
|
|
|
|
export interface ControllerRuntimeSnapshot {
|
|
connectedGamepads: ControllerDeviceInfo[];
|
|
activeGamepadId: string | null;
|
|
rawAxes: number[];
|
|
rawButtons: ControllerButtonSnapshot[];
|
|
}
|
|
|
|
export interface MpvSubtitleRenderMetrics {
|
|
subPos: number;
|
|
subFontSize: number;
|
|
subScale: number;
|
|
subMarginY: number;
|
|
subMarginX: number;
|
|
subFont: string;
|
|
subSpacing: number;
|
|
subBold: boolean;
|
|
subItalic: boolean;
|
|
subBorderSize: number;
|
|
subShadowOffset: number;
|
|
subAssOverride: string;
|
|
subScaleByWindow: boolean;
|
|
subUseMargins: boolean;
|
|
osdHeight: number;
|
|
osdDimensions: {
|
|
w: number;
|
|
h: number;
|
|
ml: number;
|
|
mr: number;
|
|
mt: number;
|
|
mb: number;
|
|
} | null;
|
|
}
|
|
|
|
export type OverlayLayer = 'visible';
|
|
|
|
export interface OverlayContentRect {
|
|
x: number;
|
|
y: number;
|
|
width: number;
|
|
height: number;
|
|
}
|
|
|
|
export interface OverlayContentMeasurement {
|
|
layer: OverlayLayer;
|
|
measuredAtMs: number;
|
|
viewport: {
|
|
width: number;
|
|
height: number;
|
|
};
|
|
contentRect: OverlayContentRect | null;
|
|
interactiveRects?: OverlayContentRect[];
|
|
}
|
|
|
|
export interface MecabStatus {
|
|
available: boolean;
|
|
enabled: boolean;
|
|
path: string | null;
|
|
}
|
|
|
|
export interface ClipboardAppendResult {
|
|
ok: boolean;
|
|
message: string;
|
|
}
|
|
|
|
export interface ConfigHotReloadPayload {
|
|
keybindings: Keybinding[];
|
|
sessionBindings: CompiledSessionBinding[];
|
|
sessionBindingWarnings: SessionBindingWarning[];
|
|
subtitleStyle: SubtitleRendererStyleConfig | null;
|
|
subtitleSidebar: ResolvedSubtitleSidebarConfig;
|
|
primarySubMode: PrimarySubMode;
|
|
secondarySubMode: SecondarySubMode;
|
|
}
|
|
|
|
export interface SessionActionDispatchRequest {
|
|
actionId: SessionActionId;
|
|
payload?: SessionActionPayload;
|
|
}
|
|
|
|
export type ResolvedControllerConfig = ResolvedConfig['controller'];
|
|
|
|
export interface CharacterDictionaryCandidate {
|
|
id: number;
|
|
title: string;
|
|
episodes: number | null;
|
|
}
|
|
|
|
export interface CharacterDictionarySelectionSnapshot {
|
|
seriesKey: string;
|
|
guessTitle: string | null;
|
|
current: CharacterDictionaryCandidate | null;
|
|
override: CharacterDictionaryCandidate | null;
|
|
candidates: CharacterDictionaryCandidate[];
|
|
}
|
|
|
|
export interface CharacterDictionarySelectionResult {
|
|
ok: boolean;
|
|
seriesKey: string;
|
|
selected: CharacterDictionaryCandidate;
|
|
staleMediaIds: number[];
|
|
}
|
|
|
|
export interface CharacterDictionaryManagerEntry {
|
|
mediaId: number;
|
|
label: string;
|
|
title: string;
|
|
current: boolean;
|
|
}
|
|
|
|
export interface CharacterDictionaryManagerSnapshot {
|
|
entries: CharacterDictionaryManagerEntry[];
|
|
}
|
|
|
|
export type CharacterDictionaryManagerMutationResult =
|
|
| (CharacterDictionaryManagerSnapshot & { ok: true; rebuildRequired?: boolean })
|
|
| { ok: false; message: string; entries: CharacterDictionaryManagerEntry[] };
|
|
|
|
/** Sent with session-help:open; commands only run when a video is loaded in mpv. */
|
|
export interface SessionHelpOpenPayload {
|
|
commandsEnabled: boolean;
|
|
}
|
|
|
|
export interface SessionNumericSelectionStartPayload {
|
|
actionId: Extract<SessionActionId, 'copySubtitleMultiple' | 'mineSentenceMultiple'>;
|
|
timeoutMs: number;
|
|
}
|
|
|
|
export interface ElectronAPI {
|
|
requestSubtitleGenerationOpen: () => Promise<boolean>;
|
|
onSubtitleGenerationOpen: (callback: () => void) => void;
|
|
getSubtitleGenerationStatus: () => Promise<SubtitleGenerationStatus>;
|
|
selectSubtitleGenerationModel: (
|
|
model: SubtitleGenerationModelId,
|
|
) => Promise<SubtitleGenerationStatus>;
|
|
startSubtitleGeneration: () => Promise<SubtitleGenerationResult>;
|
|
downloadSubtitleGenerationModel: () => Promise<SubtitleGenerationResult>;
|
|
downloadSubtitleGenerationVadModel: () => Promise<SubtitleGenerationResult>;
|
|
setSubtitleGenerationVadEnabled: (enabled: boolean) => Promise<SubtitleGenerationStatus>;
|
|
cancelSubtitleGeneration: () => Promise<void>;
|
|
onSubtitleGenerationProgress: (
|
|
callback: (progress: SubtitleGenerationProgress) => void,
|
|
) => () => void;
|
|
getOverlayLayer: () => 'visible' | 'modal' | null;
|
|
getPathForFile: (file: File) => string;
|
|
onSubtitle: (callback: (data: SubtitleData) => void) => void;
|
|
onOverlayPointerRecoveryRequested: (callback: () => void) => void;
|
|
onOverlayNotification: (callback: (payload: OverlayNotificationEventPayload) => void) => void;
|
|
sendOverlayNotificationAction?: (
|
|
notificationId: string,
|
|
actionId: string,
|
|
options?: Pick<OverlayNotificationAction, 'noteId'>,
|
|
) => void;
|
|
onNotificationHistoryToggle: (callback: () => void) => void;
|
|
onVisibility: (callback: (visible: boolean) => void) => void;
|
|
onSubtitlePosition: (callback: (position: SubtitlePosition | null) => void) => void;
|
|
getOverlayVisibility: () => Promise<boolean>;
|
|
getCurrentSubtitle: () => Promise<SubtitleData>;
|
|
getCurrentSubtitleRaw: () => Promise<string>;
|
|
getCurrentSubtitleAss: () => Promise<string>;
|
|
getSubtitleSidebarSnapshot: () => Promise<SubtitleSidebarSnapshot>;
|
|
copySubtitleSidebarSelection: (text: string) => Promise<void>;
|
|
getSubtitleSidebarOpen: () => Promise<boolean>;
|
|
getPlaybackPaused: () => Promise<boolean | null>;
|
|
onSubtitleAss: (callback: (assText: string) => void) => void;
|
|
setIgnoreMouseEvents: (ignore: boolean, options?: { forward?: boolean }) => void;
|
|
reportOverlayInteractive: (interactive: boolean) => void;
|
|
openYomitanSettings: () => void;
|
|
recordYomitanLookup: (context?: SubtitleMiningContext | null) => void;
|
|
getSubtitlePosition: () => Promise<SubtitlePosition | null>;
|
|
saveSubtitlePosition: (position: SubtitlePosition) => void;
|
|
getMecabStatus: () => Promise<MecabStatus>;
|
|
setMecabEnabled: (enabled: boolean) => void;
|
|
sendMpvCommand: (command: (string | number)[]) => void;
|
|
getKeybindings: () => Promise<Keybinding[]>;
|
|
getMpvInputBindings: () => Promise<MpvInputBindingsSnapshot>;
|
|
getSessionBindings: () => Promise<CompiledSessionBinding[]>;
|
|
getConfiguredShortcuts: () => Promise<Required<ShortcutsConfig>>;
|
|
dispatchSessionAction: (
|
|
actionId: SessionActionId,
|
|
payload?: SessionActionPayload,
|
|
) => Promise<void>;
|
|
getStatsToggleKey: () => Promise<string>;
|
|
getMarkWatchedKey: () => Promise<string>;
|
|
getOverlayNotificationPosition: () => Promise<OverlayNotificationPosition>;
|
|
markActiveVideoWatched: () => Promise<boolean>;
|
|
getControllerConfig: () => Promise<ResolvedControllerConfig>;
|
|
saveControllerConfig: (update: ControllerConfigUpdate) => Promise<void>;
|
|
saveControllerPreference: (update: ControllerPreferenceUpdate) => Promise<void>;
|
|
getJimakuMediaInfo: () => Promise<JimakuMediaInfo>;
|
|
jimakuSearchEntries: (query: JimakuSearchQuery) => Promise<JimakuApiResponse<JimakuEntry[]>>;
|
|
jimakuListFiles: (query: JimakuFilesQuery) => Promise<JimakuApiResponse<JimakuFileEntry[]>>;
|
|
jimakuDownloadFile: (query: JimakuDownloadQuery) => Promise<JimakuDownloadResult>;
|
|
tsukihimeSearchEntries: (
|
|
query: TsukihimeSearchQuery,
|
|
) => Promise<TsukihimeApiResponse<TsukihimeEntry[]>>;
|
|
tsukihimeListFiles: (
|
|
query: TsukihimeFilesQuery,
|
|
) => Promise<TsukihimeApiResponse<TsukihimeSubtitleFile[]>>;
|
|
tsukihimeDownloadFile: (query: TsukihimeDownloadQuery) => Promise<TsukihimeDownloadResult>;
|
|
tsukihimeGetSecondaryLanguages: () => Promise<string[]>;
|
|
quitApp: () => void;
|
|
toggleDevTools: () => void;
|
|
toggleOverlay: () => void;
|
|
toggleStatsOverlay: () => void;
|
|
getAnkiConnectStatus: () => Promise<boolean>;
|
|
setAnkiConnectEnabled: (enabled: boolean) => void;
|
|
clearAnkiConnectHistory: () => void;
|
|
onSecondarySub: (callback: (text: string) => void) => void;
|
|
onSecondarySubMode: (callback: (mode: SecondarySubMode) => void) => void;
|
|
getSecondarySubMode: () => Promise<SecondarySubMode>;
|
|
getCurrentSecondarySub: () => Promise<string>;
|
|
focusMainWindow: () => Promise<void>;
|
|
activatePlaybackWindowForOverlayInteraction: () => Promise<boolean>;
|
|
getSubtitleStyle: () => Promise<SubtitleRendererStyleConfig | null>;
|
|
onSubtitleSelectionOpen: (callback: () => void) => void;
|
|
getSubtitleSelection: () => Promise<
|
|
import('../shared/subtitle-selection').SubtitleSelectionState
|
|
>;
|
|
applySubtitleSelection: (
|
|
request: import('../shared/subtitle-selection').SubtitleSelectionRequest,
|
|
) => Promise<void>;
|
|
onSubsyncManualOpen: (callback: (payload: SubsyncManualPayload) => void) => void;
|
|
runSubsyncManual: (request: SubsyncManualRunRequest) => Promise<SubsyncResult>;
|
|
onKikuFieldGroupingRequest: (callback: (data: KikuFieldGroupingRequestData) => void) => void;
|
|
onKikuFieldGroupingCancel: (callback: () => void) => void;
|
|
kikuBuildMergePreview: (request: KikuMergePreviewRequest) => Promise<KikuMergePreviewResponse>;
|
|
kikuFieldGroupingRespond: (choice: KikuFieldGroupingChoice) => void;
|
|
getRuntimeOptions: () => Promise<RuntimeOptionState[]>;
|
|
setRuntimeOptionValue: (
|
|
id: RuntimeOptionId,
|
|
value: RuntimeOptionValue,
|
|
) => Promise<RuntimeOptionApplyResult>;
|
|
cycleRuntimeOption: (id: RuntimeOptionId, direction: 1 | -1) => Promise<RuntimeOptionApplyResult>;
|
|
onRuntimeOptionsChanged: (callback: (options: RuntimeOptionState[]) => void) => void;
|
|
onOpenRuntimeOptions: (callback: () => void) => void;
|
|
onOpenSessionHelp: (callback: (payload: SessionHelpOpenPayload) => void) => void;
|
|
onOpenChangelog: (callback: () => void) => void;
|
|
getChangelogSnapshot: (options?: { refresh?: boolean }) => Promise<ChangelogSnapshot>;
|
|
onOpenControllerSelect: (callback: () => void) => void;
|
|
onOpenControllerDebug: (callback: () => void) => void;
|
|
onOpenJimaku: (callback: () => void) => void;
|
|
onOpenTsukihime: (callback: () => void) => void;
|
|
onOpenYoutubeTrackPicker: (callback: (payload: YoutubePickerOpenPayload) => void) => void;
|
|
onOpenMediaTimingReview: (callback: (payload: MediaTimingReviewOpenPayload) => void) => void;
|
|
onMediaTimingReviewPreviewEnded: (callback: (reviewId: string) => void) => void;
|
|
onMediaTimingReviewPreviewPosition: (
|
|
callback: (position: MediaTimingReviewPreviewPosition) => void,
|
|
) => void;
|
|
previewMediaTimingReview: (
|
|
request: MediaTimingReviewPreviewRequest,
|
|
) => Promise<MediaTimingReviewActionResult>;
|
|
getMediaTimingReviewFrame: (
|
|
request: MediaTimingReviewFrameRequest,
|
|
) => Promise<MediaTimingReviewFrameResult>;
|
|
getMediaTimingReviewWaveform: (
|
|
request: MediaTimingReviewWaveformRequest,
|
|
) => Promise<MediaTimingReviewWaveformResult>;
|
|
stopMediaTimingReviewPreview: (reviewId: string) => Promise<MediaTimingReviewActionResult>;
|
|
resolveMediaTimingReview: (
|
|
request: MediaTimingReviewResolveRequest,
|
|
) => Promise<MediaTimingReviewActionResult>;
|
|
onOpenPlaylistBrowser: (callback: () => void) => void;
|
|
onOpenCharacterDictionaryManager: (callback: () => void) => void;
|
|
onSubtitleSidebarToggle: (callback: () => void) => void;
|
|
onPrimarySubtitleBarToggle: (callback: () => void) => void;
|
|
onCancelYoutubeTrackPicker: (callback: () => void) => void;
|
|
onSessionNumericSelectionStart: (
|
|
callback: (payload: SessionNumericSelectionStartPayload) => void,
|
|
) => void;
|
|
onKeyboardModeToggleRequested: (callback: () => void) => void;
|
|
onLookupWindowToggleRequested: (callback: () => void) => void;
|
|
appendClipboardVideoToQueue: () => Promise<ClipboardAppendResult>;
|
|
getPlaylistBrowserSnapshot: () => Promise<PlaylistBrowserSnapshot>;
|
|
appendPlaylistBrowserFile: (path: string) => Promise<PlaylistBrowserMutationResult>;
|
|
playPlaylistBrowserIndex: (index: number) => Promise<PlaylistBrowserMutationResult>;
|
|
removePlaylistBrowserIndex: (index: number) => Promise<PlaylistBrowserMutationResult>;
|
|
movePlaylistBrowserIndex: (
|
|
index: number,
|
|
direction: 1 | -1,
|
|
) => Promise<PlaylistBrowserMutationResult>;
|
|
youtubePickerResolve: (
|
|
request: YoutubePickerResolveRequest,
|
|
) => Promise<YoutubePickerResolveResult>;
|
|
getCharacterDictionarySelection: (
|
|
searchTitle?: string,
|
|
) => Promise<CharacterDictionarySelectionSnapshot>;
|
|
setCharacterDictionarySelection: (
|
|
mediaId: number,
|
|
replaceManagedMediaId?: number,
|
|
mediaTitle?: string,
|
|
) => Promise<CharacterDictionarySelectionResult | CharacterDictionaryManagerMutationResult>;
|
|
getCharacterDictionaryManagerSnapshot: () => Promise<CharacterDictionaryManagerSnapshot>;
|
|
removeCharacterDictionaryManagedEntry: (
|
|
mediaId: number,
|
|
) => Promise<CharacterDictionaryManagerMutationResult>;
|
|
moveCharacterDictionaryManagedEntry: (
|
|
mediaId: number,
|
|
direction: 1 | -1,
|
|
) => Promise<CharacterDictionaryManagerMutationResult>;
|
|
notifyOverlayModalClosed: (
|
|
modal:
|
|
| 'runtime-options'
|
|
| 'subsync'
|
|
| 'subtitle-selection'
|
|
| 'subtitle-generation'
|
|
| 'jimaku'
|
|
| 'tsukihime'
|
|
| 'youtube-track-picker'
|
|
| 'media-timing-review'
|
|
| 'playlist-browser'
|
|
| 'kiku'
|
|
| 'controller-select'
|
|
| 'controller-debug'
|
|
| 'subtitle-sidebar'
|
|
| 'session-help'
|
|
| 'character-dictionary'
|
|
| 'changelog',
|
|
) => void;
|
|
notifyOverlayModalOpened: (
|
|
modal:
|
|
| 'runtime-options'
|
|
| 'subsync'
|
|
| 'subtitle-selection'
|
|
| 'subtitle-generation'
|
|
| 'jimaku'
|
|
| 'tsukihime'
|
|
| 'youtube-track-picker'
|
|
| 'media-timing-review'
|
|
| 'playlist-browser'
|
|
| 'kiku'
|
|
| 'controller-select'
|
|
| 'controller-debug'
|
|
| 'subtitle-sidebar'
|
|
| 'session-help'
|
|
| 'character-dictionary'
|
|
| 'changelog',
|
|
) => void;
|
|
reportOverlayContentBounds: (measurement: OverlayContentMeasurement) => void;
|
|
onSessionBindingsChanged: (callback: (bindings: CompiledSessionBinding[]) => void) => void;
|
|
onMpvInputBindingsChanged: (callback: () => void) => void;
|
|
onConfigHotReload: (callback: (payload: ConfigHotReloadPayload) => void) => void;
|
|
}
|
|
|
|
declare global {
|
|
interface Window {
|
|
electronAPI: ElectronAPI;
|
|
}
|
|
}
|