mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-11-09 15:33:31 +00:00
Push selected-source changes from Electron to the launch window instead of polling every 500ms, reducing constant renderer and IPC churn. Also restore the TimelineEditor audio path narrowing fix so the current tree stays type-safe.
287 lines
11 KiB
TypeScript
287 lines
11 KiB
TypeScript
import { contextBridge, ipcRenderer } from "electron";
|
|
|
|
contextBridge.exposeInMainWorld("electronAPI", {
|
|
hudOverlayHide: () => {
|
|
ipcRenderer.send("hud-overlay-hide");
|
|
},
|
|
hudOverlayClose: () => {
|
|
ipcRenderer.send("hud-overlay-close");
|
|
},
|
|
setHudOverlayExpanded: (expanded: boolean) => {
|
|
ipcRenderer.send("set-hud-overlay-expanded", expanded);
|
|
},
|
|
setHudOverlayCompactWidth: (width: number) => {
|
|
ipcRenderer.send("set-hud-overlay-compact-width", width);
|
|
},
|
|
setHudOverlayMeasuredHeight: (height: number, expanded: boolean) => {
|
|
ipcRenderer.send("set-hud-overlay-measured-height", height, expanded);
|
|
},
|
|
getHudOverlayCaptureProtection: () => {
|
|
return ipcRenderer.invoke("get-hud-overlay-capture-protection");
|
|
},
|
|
setHudOverlayCaptureProtection: (enabled: boolean) => {
|
|
return ipcRenderer.invoke("set-hud-overlay-capture-protection", enabled);
|
|
},
|
|
getAssetBasePath: async () => {
|
|
return await ipcRenderer.invoke("get-asset-base-path");
|
|
},
|
|
listAssetDirectory: (relativeDir: string) => {
|
|
return ipcRenderer.invoke("list-asset-directory", relativeDir);
|
|
},
|
|
readLocalFile: (filePath: string) => {
|
|
return ipcRenderer.invoke("read-local-file", filePath);
|
|
},
|
|
getSources: async (opts: Electron.SourcesOptions) => {
|
|
return await ipcRenderer.invoke("get-sources", opts);
|
|
},
|
|
switchToEditor: () => {
|
|
return ipcRenderer.invoke("switch-to-editor");
|
|
},
|
|
openSourceSelector: () => {
|
|
return ipcRenderer.invoke("open-source-selector");
|
|
},
|
|
selectSource: (source: any) => {
|
|
return ipcRenderer.invoke("select-source", source);
|
|
},
|
|
showSourceHighlight: (source: any) => {
|
|
return ipcRenderer.invoke("show-source-highlight", source);
|
|
},
|
|
getSelectedSource: () => {
|
|
return ipcRenderer.invoke("get-selected-source");
|
|
},
|
|
onSelectedSourceChanged: (callback: (source: any) => void) => {
|
|
const listener = (_event: Electron.IpcRendererEvent, payload: any) => callback(payload);
|
|
ipcRenderer.on("selected-source-changed", listener);
|
|
return () => ipcRenderer.removeListener("selected-source-changed", listener);
|
|
},
|
|
startNativeScreenRecording: (
|
|
source: any,
|
|
options?: {
|
|
capturesSystemAudio?: boolean;
|
|
capturesMicrophone?: boolean;
|
|
microphoneDeviceId?: string;
|
|
microphoneLabel?: string;
|
|
},
|
|
) => {
|
|
return ipcRenderer.invoke("start-native-screen-recording", source, options);
|
|
},
|
|
stopNativeScreenRecording: () => {
|
|
return ipcRenderer.invoke("stop-native-screen-recording");
|
|
},
|
|
pauseNativeScreenRecording: () => {
|
|
return ipcRenderer.invoke("pause-native-screen-recording");
|
|
},
|
|
resumeNativeScreenRecording: () => {
|
|
return ipcRenderer.invoke("resume-native-screen-recording");
|
|
},
|
|
startFfmpegRecording: (source: any) => {
|
|
return ipcRenderer.invoke("start-ffmpeg-recording", source);
|
|
},
|
|
stopFfmpegRecording: () => {
|
|
return ipcRenderer.invoke("stop-ffmpeg-recording");
|
|
},
|
|
storeRecordedVideo: (videoData: ArrayBuffer, fileName: string) => {
|
|
return ipcRenderer.invoke("store-recorded-video", videoData, fileName);
|
|
},
|
|
getRecordedVideoPath: () => {
|
|
return ipcRenderer.invoke("get-recorded-video-path");
|
|
},
|
|
setRecordingState: (recording: boolean) => {
|
|
return ipcRenderer.invoke("set-recording-state", recording);
|
|
},
|
|
setCursorScale: (scale: number) => {
|
|
return ipcRenderer.invoke("set-cursor-scale", scale);
|
|
},
|
|
getCursorTelemetry: (videoPath?: string) => {
|
|
return ipcRenderer.invoke("get-cursor-telemetry", videoPath);
|
|
},
|
|
getSystemCursorAssets: () => {
|
|
return ipcRenderer.invoke("get-system-cursor-assets");
|
|
},
|
|
onStopRecordingFromTray: (callback: () => void) => {
|
|
const listener = () => callback();
|
|
ipcRenderer.on("stop-recording-from-tray", listener);
|
|
return () => ipcRenderer.removeListener("stop-recording-from-tray", listener);
|
|
},
|
|
onRecordingStateChanged: (
|
|
callback: (state: { recording: boolean; sourceName: string }) => void,
|
|
) => {
|
|
const listener = (
|
|
_event: Electron.IpcRendererEvent,
|
|
payload: { recording: boolean; sourceName: string },
|
|
) => callback(payload);
|
|
ipcRenderer.on("recording-state-changed", listener);
|
|
return () => ipcRenderer.removeListener("recording-state-changed", listener);
|
|
},
|
|
onRecordingInterrupted: (callback: (state: { reason: string; message: string }) => void) => {
|
|
const listener = (
|
|
_event: Electron.IpcRendererEvent,
|
|
payload: { reason: string; message: string },
|
|
) => callback(payload);
|
|
ipcRenderer.on("recording-interrupted", listener);
|
|
return () => ipcRenderer.removeListener("recording-interrupted", listener);
|
|
},
|
|
onCursorStateChanged: (
|
|
callback: (state: { cursorType: CursorTelemetryPoint["cursorType"] }) => void,
|
|
) => {
|
|
const listener = (
|
|
_event: Electron.IpcRendererEvent,
|
|
payload: { cursorType: CursorTelemetryPoint["cursorType"] },
|
|
) => callback(payload);
|
|
ipcRenderer.on("cursor-state-changed", listener);
|
|
return () => ipcRenderer.removeListener("cursor-state-changed", listener);
|
|
},
|
|
openExternalUrl: (url: string) => {
|
|
return ipcRenderer.invoke("open-external-url", url);
|
|
},
|
|
getAccessibilityPermissionStatus: () => {
|
|
return ipcRenderer.invoke("get-accessibility-permission-status");
|
|
},
|
|
requestAccessibilityPermission: () => {
|
|
return ipcRenderer.invoke("request-accessibility-permission");
|
|
},
|
|
getScreenRecordingPermissionStatus: () => {
|
|
return ipcRenderer.invoke("get-screen-recording-permission-status");
|
|
},
|
|
openScreenRecordingPreferences: () => {
|
|
return ipcRenderer.invoke("open-screen-recording-preferences");
|
|
},
|
|
openAccessibilityPreferences: () => {
|
|
return ipcRenderer.invoke("open-accessibility-preferences");
|
|
},
|
|
saveExportedVideo: (videoData: ArrayBuffer, fileName: string) => {
|
|
return ipcRenderer.invoke("save-exported-video", videoData, fileName);
|
|
},
|
|
openVideoFilePicker: () => {
|
|
return ipcRenderer.invoke("open-video-file-picker");
|
|
},
|
|
openAudioFilePicker: () => {
|
|
return ipcRenderer.invoke("open-audio-file-picker");
|
|
},
|
|
openWhisperExecutablePicker: () => {
|
|
return ipcRenderer.invoke("open-whisper-executable-picker");
|
|
},
|
|
openWhisperModelPicker: () => {
|
|
return ipcRenderer.invoke("open-whisper-model-picker");
|
|
},
|
|
getWhisperSmallModelStatus: () => {
|
|
return ipcRenderer.invoke("get-whisper-small-model-status");
|
|
},
|
|
downloadWhisperSmallModel: () => {
|
|
return ipcRenderer.invoke("download-whisper-small-model");
|
|
},
|
|
deleteWhisperSmallModel: () => {
|
|
return ipcRenderer.invoke("delete-whisper-small-model");
|
|
},
|
|
onWhisperSmallModelDownloadProgress: (
|
|
callback: (state: { status: "idle" | "downloading" | "downloaded" | "error"; progress: number; path?: string | null; error?: string }) => void,
|
|
) => {
|
|
const listener = (
|
|
_event: Electron.IpcRendererEvent,
|
|
payload: { status: "idle" | "downloading" | "downloaded" | "error"; progress: number; path?: string | null; error?: string },
|
|
) => callback(payload);
|
|
ipcRenderer.on("whisper-small-model-download-progress", listener);
|
|
return () => ipcRenderer.removeListener("whisper-small-model-download-progress", listener);
|
|
},
|
|
generateAutoCaptions: (options: {
|
|
videoPath: string;
|
|
whisperExecutablePath?: string;
|
|
whisperModelPath: string;
|
|
language?: string;
|
|
}) => {
|
|
return ipcRenderer.invoke("generate-auto-captions", options);
|
|
},
|
|
setCurrentVideoPath: (path: string) => {
|
|
return ipcRenderer.invoke("set-current-video-path", path);
|
|
},
|
|
setCurrentRecordingSession: (session: { videoPath: string; webcamPath?: string | null }) => {
|
|
return ipcRenderer.invoke("set-current-recording-session", session);
|
|
},
|
|
getCurrentRecordingSession: () => {
|
|
return ipcRenderer.invoke("get-current-recording-session");
|
|
},
|
|
getCurrentVideoPath: () => {
|
|
return ipcRenderer.invoke("get-current-video-path");
|
|
},
|
|
clearCurrentVideoPath: () => {
|
|
return ipcRenderer.invoke("clear-current-video-path");
|
|
},
|
|
deleteRecordingFile: (filePath: string) => {
|
|
return ipcRenderer.invoke("delete-recording-file", filePath);
|
|
},
|
|
saveProjectFile: (projectData: unknown, suggestedName?: string, existingProjectPath?: string) => {
|
|
return ipcRenderer.invoke("save-project-file", projectData, suggestedName, existingProjectPath);
|
|
},
|
|
loadProjectFile: () => {
|
|
return ipcRenderer.invoke("load-project-file");
|
|
},
|
|
loadCurrentProjectFile: () => {
|
|
return ipcRenderer.invoke("load-current-project-file");
|
|
},
|
|
onMenuLoadProject: (callback: () => void) => {
|
|
const listener = () => callback();
|
|
ipcRenderer.on("menu-load-project", listener);
|
|
return () => ipcRenderer.removeListener("menu-load-project", listener);
|
|
},
|
|
onMenuSaveProject: (callback: () => void) => {
|
|
const listener = () => callback();
|
|
ipcRenderer.on("menu-save-project", listener);
|
|
return () => ipcRenderer.removeListener("menu-save-project", listener);
|
|
},
|
|
onMenuSaveProjectAs: (callback: () => void) => {
|
|
const listener = () => callback();
|
|
ipcRenderer.on("menu-save-project-as", listener);
|
|
return () => ipcRenderer.removeListener("menu-save-project-as", listener);
|
|
},
|
|
getPlatform: () => {
|
|
return ipcRenderer.invoke("get-platform");
|
|
},
|
|
revealInFolder: (filePath: string) => {
|
|
return ipcRenderer.invoke("reveal-in-folder", filePath);
|
|
},
|
|
openRecordingsFolder: () => {
|
|
return ipcRenderer.invoke("open-recordings-folder");
|
|
},
|
|
getRecordingsDirectory: () => {
|
|
return ipcRenderer.invoke("get-recordings-directory");
|
|
},
|
|
chooseRecordingsDirectory: () => {
|
|
return ipcRenderer.invoke("choose-recordings-directory");
|
|
},
|
|
getShortcuts: () => {
|
|
return ipcRenderer.invoke("get-shortcuts");
|
|
},
|
|
saveShortcuts: (shortcuts: unknown) => {
|
|
return ipcRenderer.invoke("save-shortcuts", shortcuts);
|
|
},
|
|
setHasUnsavedChanges: (hasChanges: boolean) => {
|
|
ipcRenderer.send("set-has-unsaved-changes", hasChanges);
|
|
},
|
|
onRequestSaveBeforeClose: (callback: () => Promise<boolean>) => {
|
|
const listener = async () => {
|
|
let saved = false;
|
|
try {
|
|
saved = await callback();
|
|
} catch {
|
|
saved = false;
|
|
}
|
|
ipcRenderer.send("save-before-close-done", saved);
|
|
};
|
|
ipcRenderer.on("request-save-before-close", listener);
|
|
return () => ipcRenderer.removeListener("request-save-before-close", listener);
|
|
},
|
|
isNativeWindowsCaptureAvailable: () => ipcRenderer.invoke("is-native-windows-capture-available"),
|
|
muxNativeWindowsRecording: () => ipcRenderer.invoke("mux-native-windows-recording"),
|
|
hideOsCursor: () => ipcRenderer.invoke("hide-cursor"),
|
|
getCountdownDelay: () => ipcRenderer.invoke("get-countdown-delay"),
|
|
setCountdownDelay: (delay: number) => ipcRenderer.invoke("set-countdown-delay", delay),
|
|
startCountdown: (seconds: number) => ipcRenderer.invoke("start-countdown", seconds),
|
|
cancelCountdown: () => ipcRenderer.invoke("cancel-countdown"),
|
|
getActiveCountdown: () => ipcRenderer.invoke("get-active-countdown"),
|
|
onCountdownTick: (callback: (seconds: number) => void) => {
|
|
const listener = (_event: Electron.IpcRendererEvent, seconds: number) => callback(seconds);
|
|
ipcRenderer.on("countdown-tick", listener);
|
|
return () => ipcRenderer.removeListener("countdown-tick", listener);
|
|
},
|
|
});
|