fix: persist presets and theme preferences

This commit is contained in:
webadderall
2026-05-17 18:32:59 +10:00
parent 6255890556
commit eef387b0ed
10 changed files with 287 additions and 28 deletions
+2
View File
@@ -805,6 +805,8 @@ interface Window {
}>;
getShortcuts: () => Promise<Record<string, unknown> | null>;
saveShortcuts: (shortcuts: unknown) => Promise<{ success: boolean; error?: string }>;
getAppSetting: (key: string) => unknown;
setAppSetting: (key: string, value: unknown) => boolean;
setHasUnsavedChanges: (hasChanges: boolean) => void;
onRequestSaveBeforeClose: (callback: () => Promise<boolean>) => () => void;
isNativeWindowsCaptureAvailable: () => Promise<{ available: boolean }>;
+1
View File
@@ -10,6 +10,7 @@ export const MAX_RECENT_PROJECTS = 16;
export const SHORTCUTS_FILE = path.join(USER_DATA_PATH, "shortcuts.json");
export const RECORDINGS_SETTINGS_FILE = path.join(USER_DATA_PATH, "recordings-settings.json");
export const COUNTDOWN_SETTINGS_FILE = path.join(USER_DATA_PATH, "countdown-settings.json");
export const APP_SETTINGS_FILE = path.join(USER_DATA_PATH, "app-settings.json");
export const AUTO_RECORDING_PREFIX = "recording-";
export const AUTO_RECORDING_RETENTION_COUNT = 20;
export const AUTO_RECORDING_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1000;
+55
View File
@@ -1,8 +1,10 @@
import { readFileSync, writeFileSync } from "node:fs";
import fs from "node:fs/promises";
import { app, ipcMain } from "electron";
import { hideCursor } from "../../cursorHider";
import { closeCountdownWindow, createCountdownWindow, getCountdownWindow } from "../../windows";
import {
APP_SETTINGS_FILE,
COUNTDOWN_SETTINGS_FILE,
RECORDINGS_SETTINGS_FILE,
SHORTCUTS_FILE,
@@ -40,6 +42,24 @@ function getBrowserMicrophoneProfileFromEnv() {
};
}
function readAppSettingsStore(): Record<string, unknown> {
try {
const content = readFileSync(APP_SETTINGS_FILE, "utf-8");
const parsed = parseJsonWithByteOrderMark<unknown>(content);
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
return {};
}
return parsed as Record<string, unknown>;
} catch {
return {};
}
}
function writeAppSettingsStore(store: Record<string, unknown>) {
writeFileSync(APP_SETTINGS_FILE, JSON.stringify(store, null, 2), "utf-8");
}
export function registerSettingsHandlers() {
ipcMain.handle('app:getVersion', () => {
return app.getVersion()
@@ -49,6 +69,41 @@ export function registerSettingsHandlers() {
return process.platform;
});
ipcMain.on("app-settings:get", (event, key: unknown) => {
try {
if (typeof key !== "string" || key.length === 0) {
event.returnValue = { success: false, value: null };
return;
}
const store = readAppSettingsStore();
event.returnValue = {
success: true,
value: Object.prototype.hasOwnProperty.call(store, key) ? store[key] : null,
};
} catch (error) {
console.error("Failed to read app setting:", error);
event.returnValue = { success: false, value: null };
}
});
ipcMain.on("app-settings:set", (event, key: unknown, value: unknown) => {
try {
if (typeof key !== "string" || key.length === 0) {
event.returnValue = { success: false };
return;
}
const store = readAppSettingsStore();
store[key] = value;
writeAppSettingsStore(store);
event.returnValue = { success: true };
} catch (error) {
console.error("Failed to save app setting:", error);
event.returnValue = { success: false };
}
});
// ---------------------------------------------------------------------------
// Cursor hiding for the browser-capture fallback.
// The IPC promise resolves only after the cursor hide attempt completes.
+13
View File
@@ -866,6 +866,19 @@ contextBridge.exposeInMainWorld("electronAPI", {
saveShortcuts: (shortcuts: unknown) => {
return ipcRenderer.invoke("save-shortcuts", shortcuts);
},
getAppSetting: (key: string) => {
const result = ipcRenderer.sendSync("app-settings:get", key) as {
success?: boolean;
value?: unknown;
};
return result?.success ? result.value ?? null : null;
},
setAppSetting: (key: string, value: unknown) => {
const result = ipcRenderer.sendSync("app-settings:set", key, value) as {
success?: boolean;
};
return result?.success === true;
},
setHasUnsavedChanges: (hasChanges: boolean) => {
ipcRenderer.send("set-has-unsaved-changes", hasChanges);
},