mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-11-10 04:46:07 -08:00
783 lines
26 KiB
TypeScript
783 lines
26 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';
|
||
/**
|
||
* Face button style: Xbox (A at the bottom), Nintendo (A on the right) or PlayStation
|
||
* (╳ at the bottom, laid out like Xbox). Decides button names and where letters land.
|
||
*/
|
||
export type ControllerFaceButtonLabels = 'xbox' | 'nintendo' | 'playstation';
|
||
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;
|
||
holdSecondarySub?: ControllerDiscreteBindingConfig;
|
||
previousEntry?: ControllerDiscreteBindingConfig;
|
||
nextEntry?: ControllerDiscreteBindingConfig;
|
||
previousSubtitle?: ControllerDiscreteBindingConfig;
|
||
nextSubtitle?: ControllerDiscreteBindingConfig;
|
||
replaySubtitle?: ControllerDiscreteBindingConfig;
|
||
playNextSubtitle?: 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;
|
||
holdSecondarySub?: ResolvedControllerDiscreteBinding;
|
||
previousEntry?: ResolvedControllerDiscreteBinding;
|
||
nextEntry?: ResolvedControllerDiscreteBinding;
|
||
previousSubtitle?: ResolvedControllerDiscreteBinding;
|
||
nextSubtitle?: ResolvedControllerDiscreteBinding;
|
||
replaySubtitle?: ResolvedControllerDiscreteBinding;
|
||
playNextSubtitle?: 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;
|
||
}
|
||
|
||
/** Every button on the media timing review dialog, named by what it does. */
|
||
export type ControllerReviewAction =
|
||
| 'confirm'
|
||
| 'cancel'
|
||
| 'play'
|
||
| 'resetTiming'
|
||
| 'showEarlier'
|
||
| 'showLater'
|
||
| 'framePrevious'
|
||
| 'frameNext'
|
||
| 'frameReset'
|
||
| 'startBack'
|
||
| 'startForward'
|
||
| 'previousLineAdd'
|
||
| 'previousLineRemove'
|
||
| 'endBack'
|
||
| 'endForward'
|
||
| 'nextLineAdd'
|
||
| 'nextLineRemove'
|
||
| 'useOriginal'
|
||
| 'keepEditing'
|
||
| 'skipMedia'
|
||
| 'discard';
|
||
|
||
/** Every button on the duplicate-card field grouping dialog, named by what it does. */
|
||
export type ControllerFieldGroupingAction =
|
||
| 'selectOriginal'
|
||
| 'selectNew'
|
||
| 'toggleDeleteDuplicate'
|
||
| 'continue'
|
||
| 'cancel'
|
||
| 'confirmMerge'
|
||
| 'back'
|
||
| 'cancelMerge'
|
||
| 'toggleView'
|
||
| 'scrollUp'
|
||
| 'scrollDown';
|
||
|
||
export type ControllerFaceLetter = 'a' | 'b' | 'x' | 'y';
|
||
export type ControllerDpadDirection = 'left' | 'right' | 'up' | 'down';
|
||
|
||
/**
|
||
* One input in a review binding. `button` and `axis` are raw indices recorded by Learn;
|
||
* `face` (printed letter, via `faceButtonLabels`) and `dpad` (any D-pad report) keep the
|
||
* defaults working on every controller layout.
|
||
*/
|
||
export type ControllerReviewInput =
|
||
| { kind: 'button'; buttonIndex: number }
|
||
| { kind: 'axis'; axisIndex: number; direction: ControllerAxisDirection }
|
||
| { kind: 'face'; letter: ControllerFaceLetter }
|
||
| { kind: 'dpad'; direction: ControllerDpadDirection };
|
||
|
||
/** Press `press`, optionally while holding `hold`. */
|
||
export type ControllerReviewBindingConfig =
|
||
| { kind: 'none' }
|
||
| { kind?: 'combo'; press: ControllerReviewInput; hold?: ControllerReviewInput | null };
|
||
|
||
export type ResolvedControllerReviewBinding =
|
||
| { kind: 'none' }
|
||
| { kind: 'combo'; press: ControllerReviewInput; hold: ControllerReviewInput | null };
|
||
|
||
export type ControllerReviewBindingsConfig = Partial<
|
||
Record<ControllerReviewAction, ControllerReviewBindingConfig>
|
||
>;
|
||
export type ResolvedControllerReviewBindings = Record<
|
||
ControllerReviewAction,
|
||
ResolvedControllerReviewBinding
|
||
>;
|
||
|
||
export type ControllerFieldGroupingBindingsConfig = Partial<
|
||
Record<ControllerFieldGroupingAction, ControllerReviewBindingConfig>
|
||
>;
|
||
export type ResolvedControllerFieldGroupingBindings = Record<
|
||
ControllerFieldGroupingAction,
|
||
ResolvedControllerReviewBinding
|
||
>;
|
||
|
||
export interface ControllerProfileConfig {
|
||
label?: string;
|
||
/** Overrides `controller.faceButtonLabels` for this controller; set from Alt+C. */
|
||
faceButtonLabels?: ControllerFaceButtonLabels;
|
||
buttonIndices?: ControllerButtonIndicesConfig;
|
||
bindings?: ControllerBindingsConfig;
|
||
reviewBindings?: ControllerReviewBindingsConfig;
|
||
fieldGroupingBindings?: ControllerFieldGroupingBindingsConfig;
|
||
}
|
||
|
||
export interface ResolvedControllerProfileConfig {
|
||
label: string;
|
||
faceButtonLabels: ControllerFaceButtonLabels;
|
||
buttonIndices: Required<ControllerButtonIndicesConfig>;
|
||
bindings: Required<ResolvedControllerBindingsConfig>;
|
||
reviewBindings: ResolvedControllerReviewBindings;
|
||
fieldGroupingBindings: ResolvedControllerFieldGroupingBindings;
|
||
}
|
||
|
||
export interface ControllerConfig {
|
||
enabled?: boolean;
|
||
preferredGamepadId?: string;
|
||
preferredGamepadLabel?: string;
|
||
smoothScroll?: boolean;
|
||
scrollPixelsPerSecond?: number;
|
||
horizontalJumpPixels?: number;
|
||
stickDeadzone?: number;
|
||
triggerInputMode?: ControllerTriggerInputMode;
|
||
faceButtonLabels?: ControllerFaceButtonLabels;
|
||
triggerDeadzone?: number;
|
||
repeatDelayMs?: number;
|
||
repeatIntervalMs?: number;
|
||
buttonIndices?: ControllerButtonIndicesConfig;
|
||
bindings?: ControllerBindingsConfig;
|
||
reviewBindings?: ControllerReviewBindingsConfig;
|
||
fieldGroupingBindings?: ControllerFieldGroupingBindingsConfig;
|
||
profiles?: Record<string, ControllerProfileConfig>;
|
||
}
|
||
|
||
export type ControllerConfigUpdate = ControllerConfig;
|
||
|
||
export interface ControllerDeviceInfo {
|
||
id: string;
|
||
index: number;
|
||
mapping: string;
|
||
connected: boolean;
|
||
/** Gamepad API timestamp of the pad's last input; the newest is the one being used. */
|
||
timestamp?: number;
|
||
}
|
||
|
||
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;
|
||
}
|
||
|
||
/** Content of the shared plugin panel. `panelId` changes each time a plugin opens a new panel. */
|
||
export interface PluginPanelSnapshot {
|
||
panelId: number;
|
||
title: string;
|
||
markdown: string;
|
||
}
|
||
|
||
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>;
|
||
/** The overlay reports which controller it is reading (null when none). */
|
||
reportActiveController: (gamepadId: string | null) => void;
|
||
/** The controller the overlay last reported, for Alt+C before it sees a pad itself. */
|
||
getActiveControllerId: () => Promise<string | null>;
|
||
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>;
|
||
onOpenPluginPanel: (callback: (snapshot: PluginPanelSnapshot) => void) => void;
|
||
onPluginPanelUpdate: (callback: (snapshot: PluginPanelSnapshot) => void) => void;
|
||
onPluginPanelClose: (callback: (panelId: number) => void) => void;
|
||
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;
|
||
onControllerSuspendedChanged: (callback: (suspended: boolean) => void) => void;
|
||
/** Alt+C saved controller settings; reload them with `getControllerConfig`. */
|
||
onControllerConfigChanged: (callback: () => void) => void;
|
||
/** macOS: a button pressed while mpv was in front, which the Gamepad API never saw. */
|
||
onControllerBackgroundPress: (callback: (buttonIndex: number) => void) => void;
|
||
/** mpv's pause property changed, from any source. */
|
||
onPlaybackPauseChanged: (callback: (paused: boolean) => 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'
|
||
| 'plugin-panel',
|
||
/** Which instance closed, for modals that swap content in place (the plugin panel's id). */
|
||
instanceId?: number,
|
||
) => 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'
|
||
| 'plugin-panel',
|
||
) => 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;
|
||
}
|
||
}
|