From ec0826fb017f80f4df5aca3ff074fade34be840e Mon Sep 17 00:00:00 2001 From: webadderall <131426131+webadderall@users.noreply.github.com> Date: Sat, 5 Sep 2026 16:34:40 +1000 Subject: [PATCH] fix: resolve packaged wallpaper assets --- electron/ipc/register/assets.ts | 8 +++++-- src/lib/assetPath.test.ts | 41 ++++++++++++++++++++++++++++++++- src/lib/assetPath.ts | 19 ++++++++------- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/electron/ipc/register/assets.ts b/electron/ipc/register/assets.ts index fae8d708..a9e97278 100644 --- a/electron/ipc/register/assets.ts +++ b/electron/ipc/register/assets.ts @@ -2,10 +2,10 @@ import { existsSync } from "node:fs"; import fs from "node:fs/promises"; import path from "node:path"; import { pathToFileURL } from "node:url"; -import { ipcMain } from "electron"; +import { app, ipcMain } from "electron"; import { USER_DATA_PATH } from "../../appPaths"; -import { normalizePath } from "../utils"; import { getAssetRootPath } from "../project/manager"; +import { normalizePath } from "../utils"; export function registerAssetHandlers() { async function resolveReadableLocalFilePath(filePath: string) { @@ -73,6 +73,10 @@ export function registerAssetHandlers() { // Return base path for assets so renderer can resolve file:// paths in production ipcMain.handle("get-asset-base-path", () => { + if (!app.isPackaged) { + return null; + } + try { const assetPath = getAssetRootPath(); return pathToFileURL(`${assetPath}${path.sep}`).toString(); diff --git a/src/lib/assetPath.test.ts b/src/lib/assetPath.test.ts index 0cf6cd06..8956f291 100644 --- a/src/lib/assetPath.test.ts +++ b/src/lib/assetPath.test.ts @@ -1,5 +1,44 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -import { getExportableVideoUrl, getRenderableAssetUrl, getRenderableVideoUrl } from "./assetPath"; +import { + getAssetPath, + getExportableVideoUrl, + getRenderableAssetUrl, + getRenderableVideoUrl, +} from "./assetPath"; + +describe("getAssetPath", () => { + beforeEach(() => { + vi.unstubAllGlobals(); + }); + + it("uses the packaged asset directory from an HTTP renderer", async () => { + vi.stubGlobal("window", { + location: { protocol: "http:" }, + electronAPI: { + getAssetBasePath: vi.fn( + async () => "file:///Applications/Recordly.app/Contents/Resources/assets/", + ), + }, + }); + + await expect(getAssetPath("wallpapers/tahoe-light.jpg")).resolves.toBe( + "file:///Applications/Recordly.app/Contents/Resources/assets/wallpapers/tahoe-light.jpg", + ); + }); + + it("uses root-relative assets when the dev server has no packaged asset base", async () => { + vi.stubGlobal("window", { + location: { protocol: "http:" }, + electronAPI: { + getAssetBasePath: vi.fn(async () => null), + }, + }); + + await expect(getAssetPath("wallpapers/tahoe-light.jpg")).resolves.toBe( + "/wallpapers/tahoe-light.jpg", + ); + }); +}); describe("getRenderableAssetUrl", () => { beforeEach(() => { diff --git a/src/lib/assetPath.ts b/src/lib/assetPath.ts index d6acbfbc..f810c153 100644 --- a/src/lib/assetPath.ts +++ b/src/lib/assetPath.ts @@ -59,19 +59,13 @@ export async function getAssetPath(relativePath: string): Promise { const isWebContext = typeof window !== "undefined" && Boolean(window.location?.protocol?.startsWith("http")); - if (isWebContext) { - return `/${encodedRelativePath}`; - } - try { if (typeof window !== "undefined") { if (typeof window.electronAPI?.getAssetBasePath === "function") { const base = await window.electronAPI.getAssetBasePath(); - if (!base) { - throw new Error(`Failed to resolve asset base path for ${relativePath}`); + if (base) { + return new URL(encodedRelativePath, ensureTrailingSlash(base)).toString(); } - - return new URL(encodedRelativePath, ensureTrailingSlash(base)).toString(); } } } catch (error) { @@ -80,8 +74,13 @@ export async function getAssetPath(relativePath: string): Promise { } } - // Fallback for web/dev server: public/wallpapers are served at '/wallpapers/...' - return `/${encodedRelativePath}`; + if (isWebContext) { + // Dev and browser contexts serve public assets from the site root. Packaged + // Electron windows resolve above to the single extraResources asset copy. + return `/${encodedRelativePath}`; + } + + throw new Error(`Failed to resolve asset base path for ${relativePath}`); } const BASE64_CHUNK_SIZE = 0x8000;