mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-28 06:22:45 -08:00
273 lines
8.2 KiB
TypeScript
273 lines
8.2 KiB
TypeScript
/*
|
|
* SubMiner - All-in-one sentence mining overlay
|
|
* Copyright (C) 2024 sudacode
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import { contextBridge, ipcRenderer, IpcRendererEvent } from "electron";
|
|
import type {
|
|
SubtitleData,
|
|
SubtitlePosition,
|
|
MecabStatus,
|
|
Keybinding,
|
|
ElectronAPI,
|
|
SecondarySubMode,
|
|
SubtitleStyleConfig,
|
|
JimakuMediaInfo,
|
|
JimakuSearchQuery,
|
|
JimakuFilesQuery,
|
|
JimakuDownloadQuery,
|
|
JimakuEntry,
|
|
JimakuFileEntry,
|
|
JimakuApiResponse,
|
|
JimakuDownloadResult,
|
|
SubsyncManualPayload,
|
|
SubsyncManualRunRequest,
|
|
SubsyncResult,
|
|
KikuFieldGroupingRequestData,
|
|
KikuFieldGroupingChoice,
|
|
KikuMergePreviewRequest,
|
|
KikuMergePreviewResponse,
|
|
RuntimeOptionApplyResult,
|
|
RuntimeOptionId,
|
|
RuntimeOptionState,
|
|
RuntimeOptionValue,
|
|
MpvSubtitleRenderMetrics,
|
|
} from "./types";
|
|
|
|
const overlayLayerArg = process.argv.find((arg) =>
|
|
arg.startsWith("--overlay-layer="),
|
|
);
|
|
const overlayLayerFromArg = overlayLayerArg?.slice("--overlay-layer=".length);
|
|
const overlayLayer =
|
|
overlayLayerFromArg === "visible" || overlayLayerFromArg === "invisible"
|
|
? overlayLayerFromArg
|
|
: null;
|
|
|
|
const electronAPI: ElectronAPI = {
|
|
getOverlayLayer: () => overlayLayer,
|
|
onSubtitle: (callback: (data: SubtitleData) => void) => {
|
|
ipcRenderer.on(
|
|
"subtitle:set",
|
|
(_event: IpcRendererEvent, data: SubtitleData) => callback(data),
|
|
);
|
|
},
|
|
|
|
onVisibility: (callback: (visible: boolean) => void) => {
|
|
ipcRenderer.on(
|
|
"mpv:subVisibility",
|
|
(_event: IpcRendererEvent, visible: boolean) => callback(visible),
|
|
);
|
|
},
|
|
|
|
onSubtitlePosition: (
|
|
callback: (position: SubtitlePosition | null) => void,
|
|
) => {
|
|
ipcRenderer.on(
|
|
"subtitle-position:set",
|
|
(_event: IpcRendererEvent, position: SubtitlePosition | null) => {
|
|
callback(position);
|
|
},
|
|
);
|
|
},
|
|
|
|
getOverlayVisibility: (): Promise<boolean> =>
|
|
ipcRenderer.invoke("get-overlay-visibility"),
|
|
getCurrentSubtitle: (): Promise<SubtitleData> =>
|
|
ipcRenderer.invoke("get-current-subtitle"),
|
|
getCurrentSubtitleAss: (): Promise<string> =>
|
|
ipcRenderer.invoke("get-current-subtitle-ass"),
|
|
getMpvSubtitleRenderMetrics: () =>
|
|
ipcRenderer.invoke("get-mpv-subtitle-render-metrics"),
|
|
onMpvSubtitleRenderMetrics: (
|
|
callback: (metrics: MpvSubtitleRenderMetrics) => void,
|
|
) => {
|
|
ipcRenderer.on(
|
|
"mpv-subtitle-render-metrics:set",
|
|
(_event: IpcRendererEvent, metrics: MpvSubtitleRenderMetrics) => {
|
|
callback(metrics);
|
|
},
|
|
);
|
|
},
|
|
onSubtitleAss: (callback: (assText: string) => void) => {
|
|
ipcRenderer.on(
|
|
"subtitle-ass:set",
|
|
(_event: IpcRendererEvent, assText: string) => {
|
|
callback(assText);
|
|
},
|
|
);
|
|
},
|
|
onOverlayDebugVisualization: (callback: (enabled: boolean) => void) => {
|
|
ipcRenderer.on(
|
|
"overlay-debug-visualization:set",
|
|
(_event: IpcRendererEvent, enabled: boolean) => {
|
|
callback(enabled);
|
|
},
|
|
);
|
|
},
|
|
|
|
setIgnoreMouseEvents: (ignore: boolean, options?: { forward?: boolean }) => {
|
|
ipcRenderer.send("set-ignore-mouse-events", ignore, options);
|
|
},
|
|
|
|
openYomitanSettings: () => {
|
|
ipcRenderer.send("open-yomitan-settings");
|
|
},
|
|
|
|
getSubtitlePosition: (): Promise<SubtitlePosition | null> =>
|
|
ipcRenderer.invoke("get-subtitle-position"),
|
|
saveSubtitlePosition: (position: SubtitlePosition) => {
|
|
ipcRenderer.send("save-subtitle-position", position);
|
|
},
|
|
|
|
getMecabStatus: (): Promise<MecabStatus> =>
|
|
ipcRenderer.invoke("get-mecab-status"),
|
|
setMecabEnabled: (enabled: boolean) => {
|
|
ipcRenderer.send("set-mecab-enabled", enabled);
|
|
},
|
|
|
|
sendMpvCommand: (command: (string | number)[]) => {
|
|
ipcRenderer.send("mpv-command", command);
|
|
},
|
|
|
|
getKeybindings: (): Promise<Keybinding[]> =>
|
|
ipcRenderer.invoke("get-keybindings"),
|
|
|
|
getJimakuMediaInfo: (): Promise<JimakuMediaInfo> =>
|
|
ipcRenderer.invoke("jimaku:get-media-info"),
|
|
jimakuSearchEntries: (
|
|
query: JimakuSearchQuery,
|
|
): Promise<JimakuApiResponse<JimakuEntry[]>> =>
|
|
ipcRenderer.invoke("jimaku:search-entries", query),
|
|
jimakuListFiles: (
|
|
query: JimakuFilesQuery,
|
|
): Promise<JimakuApiResponse<JimakuFileEntry[]>> =>
|
|
ipcRenderer.invoke("jimaku:list-files", query),
|
|
jimakuDownloadFile: (
|
|
query: JimakuDownloadQuery,
|
|
): Promise<JimakuDownloadResult> =>
|
|
ipcRenderer.invoke("jimaku:download-file", query),
|
|
|
|
quitApp: () => {
|
|
ipcRenderer.send("quit-app");
|
|
},
|
|
|
|
toggleDevTools: () => {
|
|
ipcRenderer.send("toggle-dev-tools");
|
|
},
|
|
|
|
toggleOverlay: () => {
|
|
ipcRenderer.send("toggle-overlay");
|
|
},
|
|
|
|
getAnkiConnectStatus: (): Promise<boolean> =>
|
|
ipcRenderer.invoke("get-anki-connect-status"),
|
|
setAnkiConnectEnabled: (enabled: boolean) => {
|
|
ipcRenderer.send("set-anki-connect-enabled", enabled);
|
|
},
|
|
clearAnkiConnectHistory: () => {
|
|
ipcRenderer.send("clear-anki-connect-history");
|
|
},
|
|
|
|
onSecondarySub: (callback: (text: string) => void) => {
|
|
ipcRenderer.on(
|
|
"secondary-subtitle:set",
|
|
(_event: IpcRendererEvent, text: string) => callback(text),
|
|
);
|
|
},
|
|
|
|
onSecondarySubMode: (callback: (mode: SecondarySubMode) => void) => {
|
|
ipcRenderer.on(
|
|
"secondary-subtitle:mode",
|
|
(_event: IpcRendererEvent, mode: SecondarySubMode) => callback(mode),
|
|
);
|
|
},
|
|
|
|
getSecondarySubMode: (): Promise<SecondarySubMode> =>
|
|
ipcRenderer.invoke("get-secondary-sub-mode"),
|
|
getCurrentSecondarySub: (): Promise<string> =>
|
|
ipcRenderer.invoke("get-current-secondary-sub"),
|
|
getSubtitleStyle: (): Promise<SubtitleStyleConfig | null> =>
|
|
ipcRenderer.invoke("get-subtitle-style"),
|
|
onSubsyncManualOpen: (callback: (payload: SubsyncManualPayload) => void) => {
|
|
ipcRenderer.on(
|
|
"subsync:open-manual",
|
|
(_event: IpcRendererEvent, payload: SubsyncManualPayload) => {
|
|
callback(payload);
|
|
},
|
|
);
|
|
},
|
|
runSubsyncManual: (
|
|
request: SubsyncManualRunRequest,
|
|
): Promise<SubsyncResult> =>
|
|
ipcRenderer.invoke("subsync:run-manual", request),
|
|
|
|
onKikuFieldGroupingRequest: (
|
|
callback: (data: KikuFieldGroupingRequestData) => void,
|
|
) => {
|
|
ipcRenderer.on(
|
|
"kiku:field-grouping-request",
|
|
(_event: IpcRendererEvent, data: KikuFieldGroupingRequestData) =>
|
|
callback(data),
|
|
);
|
|
},
|
|
kikuBuildMergePreview: (
|
|
request: KikuMergePreviewRequest,
|
|
): Promise<KikuMergePreviewResponse> =>
|
|
ipcRenderer.invoke("kiku:build-merge-preview", request),
|
|
|
|
kikuFieldGroupingRespond: (choice: KikuFieldGroupingChoice) => {
|
|
ipcRenderer.send("kiku:field-grouping-respond", choice);
|
|
},
|
|
|
|
getRuntimeOptions: (): Promise<RuntimeOptionState[]> =>
|
|
ipcRenderer.invoke("runtime-options:get"),
|
|
setRuntimeOptionValue: (
|
|
id: RuntimeOptionId,
|
|
value: RuntimeOptionValue,
|
|
): Promise<RuntimeOptionApplyResult> =>
|
|
ipcRenderer.invoke("runtime-options:set", id, value),
|
|
cycleRuntimeOption: (
|
|
id: RuntimeOptionId,
|
|
direction: 1 | -1,
|
|
): Promise<RuntimeOptionApplyResult> =>
|
|
ipcRenderer.invoke("runtime-options:cycle", id, direction),
|
|
onRuntimeOptionsChanged: (
|
|
callback: (options: RuntimeOptionState[]) => void,
|
|
) => {
|
|
ipcRenderer.on(
|
|
"runtime-options:changed",
|
|
(_event: IpcRendererEvent, options: RuntimeOptionState[]) => {
|
|
callback(options);
|
|
},
|
|
);
|
|
},
|
|
onOpenRuntimeOptions: (callback: () => void) => {
|
|
ipcRenderer.on("runtime-options:open", () => {
|
|
callback();
|
|
});
|
|
},
|
|
onOpenJimaku: (callback: () => void) => {
|
|
ipcRenderer.on("jimaku:open", () => {
|
|
callback();
|
|
});
|
|
},
|
|
notifyOverlayModalClosed: (modal: "runtime-options" | "subsync") => {
|
|
ipcRenderer.send("overlay:modal-closed", modal);
|
|
},
|
|
};
|
|
|
|
contextBridge.exposeInMainWorld("electronAPI", electronAPI);
|