From caf65cb59cf75291bbd5ca5ac8b54277e068a72e Mon Sep 17 00:00:00 2001 From: webadderall <131426131+webadderall@users.noreply.github.com> Date: Sat, 28 Mar 2026 22:00:15 +1100 Subject: [PATCH] fix(dev): isolate app data paths from production --- electron/appPaths.ts | 11 +++++++++++ electron/ipc/handlers.ts | 12 ++++++------ electron/main.ts | 9 +-------- electron/windows.ts | 5 +++-- src/components/launch/UpdateToastWindow.tsx | 5 ----- 5 files changed, 21 insertions(+), 21 deletions(-) create mode 100644 electron/appPaths.ts diff --git a/electron/appPaths.ts b/electron/appPaths.ts new file mode 100644 index 00000000..75f7b51b --- /dev/null +++ b/electron/appPaths.ts @@ -0,0 +1,11 @@ +import path from "node:path"; +import { app } from "electron"; + +if (process.env["VITE_DEV_SERVER_URL"]) { + const devUserDataPath = path.join(app.getPath("appData"), "Recordly-dev"); + app.setPath("userData", devUserDataPath); + app.setPath("sessionData", path.join(devUserDataPath, "session")); +} + +export const USER_DATA_PATH = app.getPath("userData"); +export const RECORDINGS_DIR = path.join(USER_DATA_PATH, "recordings"); \ No newline at end of file diff --git a/electron/ipc/handlers.ts b/electron/ipc/handlers.ts index 5e0527ae..5fb34b43 100644 --- a/electron/ipc/handlers.ts +++ b/electron/ipc/handlers.ts @@ -9,8 +9,8 @@ import { fileURLToPath, pathToFileURL } from 'node:url' import { promisify } from 'node:util' import type { SaveDialogOptions } from 'electron' import { app, BrowserWindow, desktopCapturer, dialog, ipcMain, shell, systemPreferences } from 'electron' +import { RECORDINGS_DIR, USER_DATA_PATH } from '../appPaths' import { hideCursor, showCursor } from '../cursorHider' -import { RECORDINGS_DIR } from '../main' import { closeCountdownWindow, createCountdownWindow, getCountdownWindow } from '../windows' import { resolveWindowsCaptureDisplay } from './windowsCaptureSelection' @@ -21,18 +21,18 @@ const PROJECT_FILE_EXTENSION = 'recordly' const LEGACY_PROJECT_FILE_EXTENSIONS = ['openscreen'] const PROJECTS_DIRECTORY_NAME = 'Projects' const PROJECT_THUMBNAIL_SUFFIX = '.preview.png' -const RECENT_PROJECTS_FILE = path.join(app.getPath('userData'), 'recent-projects.json') +const RECENT_PROJECTS_FILE = path.join(USER_DATA_PATH, 'recent-projects.json') const MAX_RECENT_PROJECTS = 16 -const SHORTCUTS_FILE = path.join(app.getPath('userData'), 'shortcuts.json') -const RECORDINGS_SETTINGS_FILE = path.join(app.getPath('userData'), 'recordings-settings.json') -const COUNTDOWN_SETTINGS_FILE = path.join(app.getPath('userData'), 'countdown-settings.json') +const SHORTCUTS_FILE = path.join(USER_DATA_PATH, 'shortcuts.json') +const RECORDINGS_SETTINGS_FILE = path.join(USER_DATA_PATH, 'recordings-settings.json') +const COUNTDOWN_SETTINGS_FILE = path.join(USER_DATA_PATH, 'countdown-settings.json') const AUTO_RECORDING_PREFIX = 'recording-' const AUTO_RECORDING_RETENTION_COUNT = 20 const AUTO_RECORDING_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1000 const ALLOW_RECORDLY_WINDOW_CAPTURE = Boolean(process.env['VITE_DEV_SERVER_URL']) const RECORDING_SESSION_MANIFEST_SUFFIX = '.recordly-session.json' const WHISPER_MODEL_DOWNLOAD_URL = 'https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.bin' -const WHISPER_MODEL_DIR = path.join(app.getPath('userData'), 'whisper') +const WHISPER_MODEL_DIR = path.join(USER_DATA_PATH, 'whisper') const WHISPER_SMALL_MODEL_PATH = path.join(WHISPER_MODEL_DIR, 'ggml-small.bin') function getAssetRootPath() { diff --git a/electron/main.ts b/electron/main.ts index b91ef168..3b369837 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -13,6 +13,7 @@ import { systemPreferences, Tray, } from "electron"; +import { RECORDINGS_DIR } from "./appPaths"; import { showCursor } from "./cursorHider"; import { getSelectedSourceId, @@ -42,18 +43,10 @@ import { const __dirname = path.dirname(fileURLToPath(import.meta.url)); -if (process.env["VITE_DEV_SERVER_URL"]) { - const devUserDataPath = path.join(app.getPath("appData"), "Recordly-dev"); - app.setPath("userData", devUserDataPath); - app.setPath("sessionData", path.join(devUserDataPath, "session")); -} - if (process.platform === "darwin") { app.commandLine.appendSwitch("disable-features", "MacCatapLoopbackAudioForScreenShare"); } -export const RECORDINGS_DIR = path.join(app.getPath("userData"), "recordings"); - async function ensureRecordingsDir() { try { await fs.mkdir(RECORDINGS_DIR, { recursive: true }); diff --git a/electron/windows.ts b/electron/windows.ts index f5729f25..c68fc5bc 100644 --- a/electron/windows.ts +++ b/electron/windows.ts @@ -2,7 +2,8 @@ import fs from "node:fs"; import { createRequire } from "node:module"; import path from "node:path"; import { fileURLToPath } from "node:url"; -import { app, BrowserWindow, ipcMain } from "electron"; +import { BrowserWindow, ipcMain } from "electron"; +import { USER_DATA_PATH } from "./appPaths"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const nodeRequire = createRequire(import.meta.url); @@ -22,7 +23,7 @@ let hudOverlayCaptureProtectionLoaded = false; let countdownWindow: BrowserWindow | null = null; let updateToastWindow: BrowserWindow | null = null; -const HUD_OVERLAY_SETTINGS_FILE = path.join(app.getPath("userData"), "hud-overlay-settings.json"); +const HUD_OVERLAY_SETTINGS_FILE = path.join(USER_DATA_PATH, "hud-overlay-settings.json"); const HUD_BOTTOM_CLEARANCE_CM = 3.5; const DIP_PER_INCH = 96; const CM_PER_INCH = 2.54; diff --git a/src/components/launch/UpdateToastWindow.tsx b/src/components/launch/UpdateToastWindow.tsx index 1e63e6c6..3ea71b91 100644 --- a/src/components/launch/UpdateToastWindow.tsx +++ b/src/components/launch/UpdateToastWindow.tsx @@ -191,11 +191,6 @@ export function UpdateToastWindow() {