mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-10-25 23:35:21 -07:00
mpv's sub-start/sub-end and parsed cues carry the subtitle file's own timestamps; sub-delay (z/x, sub-step) only moves where mpv plays them. Mining now shifts subtitle timings onto the video clock before media generation, review, and MiscInfo timestamps.
650 lines
21 KiB
TypeScript
650 lines
21 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,
|
|
SubtitleSidebarPlaybackState,
|
|
SubtitleSidebarSnapshot,
|
|
SubtitleRendererStyleConfig,
|
|
} 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;
|
|
/** mpv `sub-delay`; `sub-start`/`sub-end` do not include it. */
|
|
currentSubDelay: 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 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;
|
|
onSubtitlePosition: (callback: (position: SubtitlePosition | null) => void) => void;
|
|
getCurrentSubtitle: () => Promise<SubtitleData>;
|
|
getCurrentSubtitleRaw: () => Promise<string>;
|
|
getSubtitleSidebarSnapshot: () => Promise<SubtitleSidebarSnapshot>;
|
|
getSubtitleSidebarPlaybackState: () => Promise<SubtitleSidebarPlaybackState>;
|
|
copySubtitleSidebarSelection: (text: string) => Promise<void>;
|
|
getSubtitleSidebarOpen: () => Promise<boolean>;
|
|
getPlaybackPaused: () => Promise<boolean | null>;
|
|
setIgnoreMouseEvents: (ignore: boolean, options?: { forward?: boolean }) => void;
|
|
reportOverlayInteractive: (interactive: boolean) => void;
|
|
recordYomitanLookup: (context?: SubtitleMiningContext | null) => void;
|
|
getSubtitlePosition: () => Promise<SubtitlePosition | null>;
|
|
saveSubtitlePosition: (position: SubtitlePosition) => void;
|
|
sendMpvCommand: (command: (string | number)[]) => void;
|
|
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>;
|
|
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[]>;
|
|
toggleDevTools: () => void;
|
|
toggleStatsOverlay: () => 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>;
|
|
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;
|
|
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;
|
|
}
|
|
}
|