mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-10-03 02:57:55 +00:00
fix: persist presets and theme preferences
This commit is contained in:
@@ -37,9 +37,27 @@ function createStorageMock(initialValues: Record<string, string> = {}): Storage
|
||||
};
|
||||
}
|
||||
|
||||
function stubElectronSettings(initialValues: Record<string, unknown> = {}) {
|
||||
const store = new Map(Object.entries(initialValues));
|
||||
|
||||
Object.defineProperty(globalThis, "electronAPI", {
|
||||
configurable: true,
|
||||
value: {
|
||||
getAppSetting: (key: string) => (store.has(key) ? store.get(key) : null),
|
||||
setAppSetting: (key: string, value: unknown) => {
|
||||
store.set(key, value);
|
||||
return true;
|
||||
},
|
||||
} as Pick<Window["electronAPI"], "getAppSetting" | "setAppSetting">,
|
||||
});
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
describe("editorPreferences", () => {
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
Reflect.deleteProperty(globalThis, "electronAPI");
|
||||
});
|
||||
|
||||
it("normalizes invalid values back to safe defaults", () => {
|
||||
@@ -69,10 +87,10 @@ describe("editorPreferences", () => {
|
||||
expect(DEFAULT_EDITOR_PREFERENCES.exportQuality).toBe("source");
|
||||
});
|
||||
|
||||
it("defaults cursor preferences to macOS at 2.5x with lighter sway", () => {
|
||||
it("defaults cursor preferences to macOS at 2.5x with gentler sway", () => {
|
||||
expect(DEFAULT_EDITOR_PREFERENCES.cursorStyle).toBe("macos");
|
||||
expect(DEFAULT_EDITOR_PREFERENCES.cursorSize).toBe(2.5);
|
||||
expect(DEFAULT_EDITOR_PREFERENCES.cursorSway).toBe(0.25);
|
||||
expect(DEFAULT_EDITOR_PREFERENCES.cursorSway).toBe(0.4);
|
||||
});
|
||||
|
||||
it("defaults MP4 exports to the Lightning pipeline", () => {
|
||||
@@ -309,6 +327,24 @@ describe("editorPreferences", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("loads editor preferences from Electron app settings when available", () => {
|
||||
stubElectronSettings({
|
||||
[EDITOR_PREFERENCES_STORAGE_KEY]: {
|
||||
wallpaper: "#0f172a",
|
||||
showCursor: false,
|
||||
customAspectWidth: "3",
|
||||
customAspectHeight: "2",
|
||||
},
|
||||
});
|
||||
|
||||
expect(loadEditorPreferences()).toMatchObject({
|
||||
wallpaper: "#0f172a",
|
||||
showCursor: false,
|
||||
customAspectWidth: "3",
|
||||
customAspectHeight: "2",
|
||||
});
|
||||
});
|
||||
|
||||
it("saves editor presets and reports success", () => {
|
||||
const localStorage = createStorageMock();
|
||||
vi.stubGlobal("localStorage", localStorage);
|
||||
@@ -337,6 +373,32 @@ describe("editorPreferences", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("saves editor presets to Electron app settings when available", () => {
|
||||
const settingsStore = stubElectronSettings();
|
||||
|
||||
expect(
|
||||
saveEditorPresets([
|
||||
{
|
||||
id: "preset-1",
|
||||
name: "Demo Preset",
|
||||
createdAt: "2026-05-01T00:00:00.000Z",
|
||||
updatedAt: "2026-05-02T00:00:00.000Z",
|
||||
snapshot: {
|
||||
...DEFAULT_EDITOR_PREFERENCES,
|
||||
autoCaptionSettings: DEFAULT_AUTO_CAPTION_SETTINGS,
|
||||
},
|
||||
},
|
||||
]),
|
||||
).toBe(true);
|
||||
|
||||
expect(settingsStore.get(EDITOR_PRESETS_STORAGE_KEY)).toMatchObject([
|
||||
{
|
||||
id: "preset-1",
|
||||
name: "Demo Preset",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("returns false when preset persistence fails", () => {
|
||||
const localStorage = createStorageMock();
|
||||
localStorage.setItem = () => {
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
stripPersistedDevMotionBlurSettings,
|
||||
type ProjectEditorState,
|
||||
} from "./projectPersistence";
|
||||
import { loadAppSetting, saveAppSetting } from "../../lib/appSettings";
|
||||
|
||||
type PersistedEditorControls = Pick<
|
||||
ProjectEditorState,
|
||||
@@ -422,12 +423,13 @@ export function normalizeEditorPreferences(
|
||||
}
|
||||
|
||||
export function loadEditorPreferences(): EditorPreferences {
|
||||
if (typeof globalThis.localStorage === "undefined") {
|
||||
return DEFAULT_EDITOR_PREFERENCES;
|
||||
const persisted = loadAppSetting<unknown>(EDITOR_PREFERENCES_STORAGE_KEY);
|
||||
if (persisted !== null) {
|
||||
return normalizeEditorPreferences(persisted);
|
||||
}
|
||||
|
||||
try {
|
||||
const stored = globalThis.localStorage.getItem(EDITOR_PREFERENCES_STORAGE_KEY);
|
||||
const stored = globalThis.localStorage?.getItem(EDITOR_PREFERENCES_STORAGE_KEY);
|
||||
if (!stored) {
|
||||
return DEFAULT_EDITOR_PREFERENCES;
|
||||
}
|
||||
@@ -439,16 +441,14 @@ export function loadEditorPreferences(): EditorPreferences {
|
||||
}
|
||||
|
||||
export function saveEditorPreferences(preferences: Partial<EditorPreferences>): void {
|
||||
if (typeof globalThis.localStorage === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const current = loadEditorPreferences();
|
||||
const merged = normalizeEditorPreferences({ ...current, ...preferences }, current);
|
||||
globalThis.localStorage.setItem(
|
||||
const persisted = stripPersistedDevMotionBlurSettings(merged);
|
||||
saveAppSetting(EDITOR_PREFERENCES_STORAGE_KEY, persisted);
|
||||
globalThis.localStorage?.setItem(
|
||||
EDITOR_PREFERENCES_STORAGE_KEY,
|
||||
JSON.stringify(stripPersistedDevMotionBlurSettings(merged)),
|
||||
JSON.stringify(persisted),
|
||||
);
|
||||
} catch {
|
||||
// Ignore storage failures so editor controls still work.
|
||||
@@ -456,12 +456,13 @@ export function saveEditorPreferences(preferences: Partial<EditorPreferences>):
|
||||
}
|
||||
|
||||
export function loadEditorPresets(): EditorPreset[] {
|
||||
if (typeof globalThis.localStorage === "undefined") {
|
||||
return [];
|
||||
const persisted = loadAppSetting<unknown>(EDITOR_PRESETS_STORAGE_KEY);
|
||||
if (persisted !== null) {
|
||||
return normalizeEditorPresets(persisted);
|
||||
}
|
||||
|
||||
try {
|
||||
const stored = globalThis.localStorage.getItem(EDITOR_PRESETS_STORAGE_KEY);
|
||||
const stored = globalThis.localStorage?.getItem(EDITOR_PRESETS_STORAGE_KEY);
|
||||
if (!stored) {
|
||||
return [];
|
||||
}
|
||||
@@ -473,14 +474,11 @@ export function loadEditorPresets(): EditorPreset[] {
|
||||
}
|
||||
|
||||
export function saveEditorPresets(presets: EditorPreset[]): boolean {
|
||||
if (typeof globalThis.localStorage === "undefined") {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const normalized = normalizeEditorPresets(presets);
|
||||
globalThis.localStorage.setItem(EDITOR_PRESETS_STORAGE_KEY, JSON.stringify(normalized));
|
||||
return true;
|
||||
const persisted = saveAppSetting(EDITOR_PRESETS_STORAGE_KEY, normalized);
|
||||
globalThis.localStorage?.setItem(EDITOR_PRESETS_STORAGE_KEY, JSON.stringify(normalized));
|
||||
return persisted || typeof globalThis.localStorage !== "undefined";
|
||||
} catch {
|
||||
// Ignore storage failures so editor controls still work.
|
||||
return false;
|
||||
|
||||
@@ -101,7 +101,7 @@ export const DEFAULT_CURSOR_SMOOTHING = 0.67;
|
||||
export const DEFAULT_CURSOR_MOTION_BLUR = 0.4;
|
||||
export const DEFAULT_CURSOR_CLICK_BOUNCE = 2.5;
|
||||
export const DEFAULT_CURSOR_CLICK_BOUNCE_DURATION = 350;
|
||||
export const DEFAULT_CURSOR_SWAY = 0.25;
|
||||
export const DEFAULT_CURSOR_SWAY = 0.4;
|
||||
export const DEFAULT_ZOOM_SMOOTHNESS = 0.5;
|
||||
export const DEFAULT_ZOOM_MOTION_BLUR = 0.35;
|
||||
export interface ZoomMotionBlurTuning {
|
||||
|
||||
Reference in New Issue
Block a user