Add an Electron desktop shell for the SPA
desktop/ serves the normal frontend build over a privileged app://j621 scheme, so localStorage, OPFS, Web Workers, WebCodecs and history routing behave exactly like Chrome. Development points at the Vite dev server; `npm run smoke` runs headless Electron and checks the bundled app. External links open in the system browser, and download navigations (?download=1 or media URLs) are rerouted through webContents.downloadURL, since preventing them cancels the download. The setup screen names the shell's origin when the connection test fails, and the deploy docs list app://j621 for CORS_ALLOWED_ORIGINS.
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* The only bridge between the desktop shell and the SPA. Keep it tiny: the
|
||||
* renderer is the normal web build and must not need Electron to work.
|
||||
*/
|
||||
import { contextBridge, ipcRenderer } from "electron";
|
||||
|
||||
contextBridge.exposeInMainWorld("j621Desktop", {
|
||||
isDesktop: true as const,
|
||||
platform: process.platform,
|
||||
// The SPA's own origin (`app://j621`), shown by the setup screen when it
|
||||
// has to explain which origin to allow in the backend's CORS settings.
|
||||
origin: window.location.origin,
|
||||
getVersion: (): Promise<string> => ipcRenderer.invoke("j621:version"),
|
||||
});
|
||||
|
||||
// Menu → "Open backend in browser": read the SPA's stored backend URL and
|
||||
// hand it to the main process after checking it is a real web URL.
|
||||
ipcRenderer.on("j621:open-backend", () => {
|
||||
let url = "";
|
||||
try {
|
||||
url = window.localStorage.getItem("j621.backend") ?? "";
|
||||
} catch {
|
||||
// Storage can be unavailable in rare cases; nothing to open then.
|
||||
}
|
||||
if (url === "none") url = "";
|
||||
if (url) void ipcRenderer.invoke("j621:open-external", url);
|
||||
});
|
||||
Reference in New Issue
Block a user