mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-25 07:16:02 +00:00
Split all source files exceeding 500 lines into smaller, focused modules:
- electron/main.ts → mainBootstrapHelpers, mainRuntimeState, mainUpdateIntegration, mainWindowControls
- electron/windows.ts → editorWindows, hudWindows, windowShared
- electron/updater.ts → updaterDialogs, updaterEventHandlers, updaterShared
- electron/preload.ts → preloadExtensionsBridge, preloadUpdateBridge
- electron/ipc/register/recording.ts → recording/ directory with focused handlers
- src/components/video-editor/VideoEditor.tsx → EditorContent, EditorHeader, EditorSidebar, EditorToolbar, hooks/
- src/components/video-editor/SettingsPanel.tsx → settings/ directory with per-section components
- src/components/video-editor/AnnotationSettingsPanel.tsx → tab components
- src/components/video-editor/ExtensionManager.tsx → extension-manager/ directory
- src/components/video-editor/VideoPlayback.tsx → videoPlaybackComponent/ directory
- src/components/video-editor/projectPersistence.ts → projectPersistence{Normalization,Paths,Regions,Shared}.ts
- src/components/video-editor/timeline/TimelineEditor.tsx → TimelineEditor/ directory
- src/components/video-editor/types.ts → focused type modules
- src/components/launch/LaunchWindow.tsx → LaunchWindow/ directory
- src/hooks/useScreenRecorder.ts → useScreenRecorder/ directory
- src/lib/exporter/audioEncoder.ts → audioEncoder/ directory
- src/lib/exporter/frameRenderer.ts → frameRenderer modules
- src/lib/exporter/modernFrameRenderer.ts → filters and lifecycle modules
- src/lib/exporter/modernVideoExporter.ts → modernVideoExporter/ directory
- src/lib/exporter/videoExporter.ts → video-exporter/ directory
- src/lib/exporter/streamingDecoder.ts → streamingDecoderHelpers.ts
- src/lib/extensions/extensionHost.ts → extensionHost{ApiFactory,QueryApi,RegistrationApi,Shared,State}.ts
- src/lib/extensions/types.ts → focused type modules
- electron/native/ScreenCaptureKitRecorder.swift → ScreenCaptureKitRecorder/ directory
- scripts/benchmark-export-queues.mjs → benchmark-export-queues/ directory
- .github/workflows/release.yml → extracted merge-macos-metadata composite action
- scripts/build-native-helpers.mjs → updated for multi-file Swift compilation
Also incorporates upstream default export quality change (good → source).
188 lines
6.0 KiB
TypeScript
188 lines
6.0 KiB
TypeScript
import { app } from "electron";
|
|
import { autoUpdater } from "electron-updater";
|
|
import {
|
|
clearDeferredReminderTimer,
|
|
clearDevPreviewProgressTimer,
|
|
clearVisibleUpdateToast,
|
|
createAutoCheckErrorToastPayload,
|
|
createAvailableUpdateToastPayload,
|
|
createDownloadedUpdateToastPayload,
|
|
createDownloadingUpdateToastPayload,
|
|
createUpdateErrorToastPayload,
|
|
emitUpdateToastState,
|
|
getUpdateCheckIntervalMs,
|
|
setUpdateStatusSummary,
|
|
shouldSurfaceAutomaticCheckErrors,
|
|
type GetMainWindow,
|
|
type UpdateToastSender,
|
|
updaterState,
|
|
writeUpdaterLog,
|
|
} from "./updaterShared";
|
|
|
|
interface UpdaterEventHandlerDialogs {
|
|
showNoUpdatesDialog: (getMainWindow: GetMainWindow) => Promise<void>;
|
|
showUpdateErrorDialog: (getMainWindow: GetMainWindow, error: unknown) => Promise<void>;
|
|
showAvailableUpdateDialog: (
|
|
getMainWindow: GetMainWindow,
|
|
version: string,
|
|
sendToRenderer: UpdateToastSender | undefined,
|
|
) => Promise<void>;
|
|
showDownloadedUpdateDialog: (getMainWindow: GetMainWindow, version: string) => Promise<void>;
|
|
}
|
|
|
|
export function registerAutoUpdaterEventHandlers(
|
|
getMainWindow: GetMainWindow,
|
|
sendToRenderer: UpdateToastSender,
|
|
dialogs: UpdaterEventHandlerDialogs,
|
|
checkForAppUpdates: (getMainWindow: GetMainWindow, options?: { manual?: boolean }) => Promise<void>,
|
|
) {
|
|
autoUpdater.on("checking-for-update", () => {
|
|
setUpdateStatusSummary({
|
|
status: "checking",
|
|
availableVersion: null,
|
|
detail: "Checking for updates...",
|
|
});
|
|
writeUpdaterLog("electron-updater emitted checking-for-update.");
|
|
});
|
|
|
|
autoUpdater.on("update-available", (info) => {
|
|
writeUpdaterLog(`Update available: version=${info.version}`);
|
|
updaterState.updateCheckInProgress = false;
|
|
updaterState.availableVersion = info.version;
|
|
updaterState.pendingDownloadedVersion = null;
|
|
updaterState.downloadInProgress = false;
|
|
updaterState.downloadToastDismissed = false;
|
|
setUpdateStatusSummary({
|
|
status: "available",
|
|
availableVersion: info.version,
|
|
detail: `Recordly ${info.version} is available.`,
|
|
});
|
|
if (updaterState.skippedVersion === info.version) {
|
|
updaterState.manualCheckRequested = false;
|
|
return;
|
|
}
|
|
|
|
const payload = createAvailableUpdateToastPayload(info.version);
|
|
if (emitUpdateToastState(sendToRenderer, payload)) {
|
|
updaterState.manualCheckRequested = false;
|
|
return;
|
|
}
|
|
|
|
if (updaterState.manualCheckRequested) {
|
|
void dialogs.showAvailableUpdateDialog(getMainWindow, info.version, sendToRenderer);
|
|
updaterState.manualCheckRequested = false;
|
|
}
|
|
});
|
|
|
|
autoUpdater.on("update-not-available", () => {
|
|
writeUpdaterLog("No update available.");
|
|
updaterState.updateCheckInProgress = false;
|
|
updaterState.availableVersion = null;
|
|
updaterState.pendingDownloadedVersion = null;
|
|
updaterState.downloadInProgress = false;
|
|
updaterState.downloadToastDismissed = false;
|
|
setUpdateStatusSummary({
|
|
status: "up-to-date",
|
|
availableVersion: null,
|
|
detail: `Recordly ${app.getVersion()} is up to date.`,
|
|
});
|
|
clearVisibleUpdateToast(sendToRenderer);
|
|
const shouldReport = updaterState.manualCheckRequested;
|
|
updaterState.manualCheckRequested = false;
|
|
if (shouldReport) {
|
|
void dialogs.showNoUpdatesDialog(getMainWindow);
|
|
}
|
|
});
|
|
|
|
autoUpdater.on("download-progress", (progress) => {
|
|
if (!updaterState.availableVersion) {
|
|
return;
|
|
}
|
|
|
|
updaterState.downloadInProgress = true;
|
|
setUpdateStatusSummary({
|
|
status: "downloading",
|
|
availableVersion: updaterState.availableVersion,
|
|
detail: `Downloading Recordly ${updaterState.availableVersion}`,
|
|
});
|
|
writeUpdaterLog(
|
|
`Download progress for ${updaterState.availableVersion}: ${progress.percent.toFixed(1)}%`,
|
|
);
|
|
if (updaterState.downloadToastDismissed) {
|
|
return;
|
|
}
|
|
|
|
emitUpdateToastState(
|
|
sendToRenderer,
|
|
createDownloadingUpdateToastPayload(updaterState.availableVersion, progress.percent),
|
|
);
|
|
});
|
|
|
|
autoUpdater.on("error", (error) => {
|
|
updaterState.updateCheckInProgress = false;
|
|
const shouldReport = updaterState.manualCheckRequested;
|
|
updaterState.manualCheckRequested = false;
|
|
if (!updaterState.downloadInProgress) {
|
|
updaterState.updateCheckErrorHandled = true;
|
|
}
|
|
setUpdateStatusSummary({
|
|
status: "error",
|
|
availableVersion: updaterState.availableVersion,
|
|
detail: String(error),
|
|
});
|
|
writeUpdaterLog("electron-updater emitted error.", error);
|
|
console.error("Auto-updater error:", error);
|
|
if (updaterState.downloadInProgress && updaterState.availableVersion) {
|
|
updaterState.downloadInProgress = false;
|
|
updaterState.downloadToastDismissed = false;
|
|
emitUpdateToastState(
|
|
sendToRenderer,
|
|
createUpdateErrorToastPayload(updaterState.availableVersion, error),
|
|
);
|
|
}
|
|
if (shouldReport) {
|
|
void dialogs.showUpdateErrorDialog(getMainWindow, error);
|
|
} else if (shouldSurfaceAutomaticCheckErrors()) {
|
|
emitUpdateToastState(sendToRenderer, createAutoCheckErrorToastPayload());
|
|
}
|
|
});
|
|
|
|
autoUpdater.on("update-downloaded", (info) => {
|
|
writeUpdaterLog(`Update downloaded: version=${info.version}`);
|
|
updaterState.updateCheckInProgress = false;
|
|
updaterState.manualCheckRequested = false;
|
|
updaterState.downloadInProgress = false;
|
|
updaterState.downloadToastDismissed = false;
|
|
if (updaterState.skippedVersion === info.version) {
|
|
return;
|
|
}
|
|
updaterState.availableVersion = info.version;
|
|
updaterState.pendingDownloadedVersion = info.version;
|
|
setUpdateStatusSummary({
|
|
status: "ready",
|
|
availableVersion: info.version,
|
|
detail: `Recordly ${info.version} is ready to install.`,
|
|
});
|
|
clearDeferredReminderTimer();
|
|
|
|
if (emitUpdateToastState(sendToRenderer, createDownloadedUpdateToastPayload(info.version))) {
|
|
return;
|
|
}
|
|
|
|
void dialogs.showDownloadedUpdateDialog(getMainWindow, info.version);
|
|
});
|
|
|
|
void checkForAppUpdates(getMainWindow);
|
|
updaterState.periodicCheckTimer = setInterval(() => {
|
|
void checkForAppUpdates(getMainWindow);
|
|
}, getUpdateCheckIntervalMs());
|
|
|
|
app.on("before-quit", () => {
|
|
clearDeferredReminderTimer();
|
|
clearDevPreviewProgressTimer();
|
|
if (updaterState.periodicCheckTimer) {
|
|
clearInterval(updaterState.periodicCheckTimer);
|
|
updaterState.periodicCheckTimer = null;
|
|
}
|
|
});
|
|
} |