You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
221 lines
6.7 KiB
221 lines
6.7 KiB
import { app, BrowserWindow } from "electron";
|
|
import path from "path";
|
|
import fs from "fs";
|
|
|
|
// Simple logger implementation
|
|
const logger = {
|
|
// eslint-disable-next-line no-console
|
|
log: (...args: unknown[]) => console.log(...args),
|
|
// eslint-disable-next-line no-console
|
|
error: (...args: unknown[]) => console.error(...args),
|
|
// eslint-disable-next-line no-console
|
|
info: (...args: unknown[]) => console.info(...args),
|
|
// eslint-disable-next-line no-console
|
|
warn: (...args: unknown[]) => console.warn(...args),
|
|
// eslint-disable-next-line no-console
|
|
debug: (...args: unknown[]) => console.debug(...args),
|
|
};
|
|
|
|
// Check if running in dev mode
|
|
const isDev = process.argv.includes("--inspect");
|
|
|
|
async function createWindow(): Promise<void> {
|
|
// Add before createWindow function
|
|
const preloadPath = app.isPackaged
|
|
? path.join(app.getAppPath(), "dist-electron", "preload.js")
|
|
: path.join(__dirname, "preload.js");
|
|
logger.log("Checking preload path:", preloadPath);
|
|
logger.log("Preload exists:", fs.existsSync(preloadPath));
|
|
|
|
// Log environment and paths
|
|
logger.log("process.cwd():", process.cwd());
|
|
logger.log("__dirname:", __dirname);
|
|
logger.log("app.getAppPath():", app.getAppPath());
|
|
logger.log("app.isPackaged:", app.isPackaged);
|
|
|
|
// List files in __dirname and __dirname/www
|
|
try {
|
|
logger.log("Files in __dirname:", fs.readdirSync(__dirname));
|
|
const wwwDir = path.join(__dirname, "www");
|
|
if (fs.existsSync(wwwDir)) {
|
|
logger.log("Files in www:", fs.readdirSync(wwwDir));
|
|
} else {
|
|
logger.log("www directory does not exist in __dirname");
|
|
}
|
|
} catch (e) {
|
|
logger.error("Error reading directories:", e);
|
|
}
|
|
|
|
// Create the browser window.
|
|
const mainWindow = new BrowserWindow({
|
|
width: 1200,
|
|
height: 800,
|
|
webPreferences: {
|
|
nodeIntegration: false,
|
|
contextIsolation: true,
|
|
webSecurity: true,
|
|
allowRunningInsecureContent: false,
|
|
preload: preloadPath,
|
|
},
|
|
});
|
|
|
|
// Always open DevTools for now
|
|
mainWindow.webContents.openDevTools();
|
|
|
|
// Intercept requests to robustly fix asset paths for Electron
|
|
mainWindow.webContents.session.webRequest.onBeforeRequest(
|
|
{ urls: ["*://*/*"] },
|
|
(details, callback) => {
|
|
const url = details.url;
|
|
logger.log('[main.ts] Intercepted request:', url);
|
|
|
|
// Match both file:///assets/... and /assets/...
|
|
const assetMatch = url.match(/(?:file:\/\/\/|file:\/\/|https?:\/\/[^\/]+)?\/assets\/(.+)/);
|
|
if (assetMatch) {
|
|
const assetRelPath = assetMatch[1];
|
|
const assetAbsPath = path.join(app.getAppPath(), "dist-electron", "www", "assets", assetRelPath);
|
|
logger.log('[main.ts] Asset request detected:', {
|
|
originalUrl: url,
|
|
assetRelPath,
|
|
assetAbsPath,
|
|
exists: fs.existsSync(assetAbsPath)
|
|
});
|
|
|
|
if (fs.existsSync(assetAbsPath)) {
|
|
const newUrl = `file://${assetAbsPath}`;
|
|
logger.log('[main.ts] Redirecting to:', newUrl);
|
|
callback({ redirectURL: newUrl });
|
|
return;
|
|
} else {
|
|
logger.error('[main.ts] Asset file not found:', assetAbsPath);
|
|
}
|
|
}
|
|
callback({});
|
|
}
|
|
);
|
|
|
|
if (isDev) {
|
|
// Debug info
|
|
logger.log("Debug Info:");
|
|
logger.log("Running in dev mode:", isDev);
|
|
logger.log("App is packaged:", app.isPackaged);
|
|
logger.log("Process resource path:", process.resourcesPath);
|
|
logger.log("App path:", app.getAppPath());
|
|
logger.log("__dirname:", __dirname);
|
|
logger.log("process.cwd():", process.cwd());
|
|
}
|
|
|
|
let indexPath: string;
|
|
if (app.isPackaged) {
|
|
indexPath = path.join(
|
|
app.getAppPath(),
|
|
"dist-electron",
|
|
"www",
|
|
"index.html",
|
|
);
|
|
logger.log("[main.ts] Using packaged indexPath:", indexPath);
|
|
} else {
|
|
indexPath = path.resolve(
|
|
process.cwd(),
|
|
"dist-electron",
|
|
"www",
|
|
"index.html",
|
|
);
|
|
logger.log("[main.ts] Using dev indexPath:", indexPath);
|
|
if (!fs.existsSync(indexPath)) {
|
|
logger.error("[main.ts] Dev index.html not found:", indexPath);
|
|
throw new Error("Index file not found");
|
|
}
|
|
}
|
|
|
|
if (isDev) {
|
|
logger.log("Loading index from:", indexPath);
|
|
logger.log("www path:", path.join(__dirname, "www"));
|
|
logger.log("www assets path:", path.join(__dirname, "www", "assets"));
|
|
}
|
|
|
|
// Add CSP headers to allow API connections
|
|
mainWindow.webContents.session.webRequest.onHeadersReceived(
|
|
(details, callback) => {
|
|
callback({
|
|
responseHeaders: {
|
|
...details.responseHeaders,
|
|
"Content-Security-Policy": [
|
|
"default-src 'self';" +
|
|
"connect-src 'self' https://api.endorser.ch https://*.timesafari.app;" +
|
|
"img-src 'self' data: https: blob:;" +
|
|
"script-src 'self' 'unsafe-inline' 'unsafe-eval';" +
|
|
"style-src 'self' 'unsafe-inline';" +
|
|
"font-src 'self' data:;",
|
|
],
|
|
},
|
|
});
|
|
},
|
|
);
|
|
|
|
// Load the index.html with the correct base URL for assets
|
|
const baseURL = `file://${path.dirname(indexPath)}/`;
|
|
logger.log('[main.ts] Loading with base URL:', baseURL);
|
|
|
|
try {
|
|
await mainWindow.loadURL(`file://${indexPath}`);
|
|
logger.log("Successfully loaded index.html");
|
|
if (isDev) {
|
|
mainWindow.webContents.openDevTools();
|
|
logger.log("DevTools opened - running in dev mode");
|
|
}
|
|
} catch (err) {
|
|
logger.error("Failed to load index.html:", err);
|
|
logger.error("Attempted path:", indexPath);
|
|
}
|
|
|
|
// Listen for console messages from the renderer
|
|
mainWindow.webContents.on("console-message", (_event, _level, message) => {
|
|
logger.log("Renderer Console:", message);
|
|
});
|
|
|
|
// Add right after creating the BrowserWindow
|
|
mainWindow.webContents.on(
|
|
"did-fail-load",
|
|
(_event, errorCode, errorDescription) => {
|
|
logger.error("Page failed to load:", errorCode, errorDescription);
|
|
},
|
|
);
|
|
|
|
mainWindow.webContents.on("preload-error", (_event, preloadPath, error) => {
|
|
logger.error("Preload script error:", preloadPath, error);
|
|
});
|
|
|
|
mainWindow.webContents.on(
|
|
"console-message",
|
|
(_event, _level, message, line, sourceId) => {
|
|
logger.log("Renderer Console:", line, sourceId, message);
|
|
},
|
|
);
|
|
|
|
// Enable remote debugging when in dev mode
|
|
if (isDev) {
|
|
mainWindow.webContents.openDevTools();
|
|
}
|
|
}
|
|
|
|
// Handle app ready
|
|
app.whenReady().then(createWindow);
|
|
|
|
// Handle all windows closed
|
|
app.on("window-all-closed", () => {
|
|
if (process.platform !== "darwin") {
|
|
app.quit();
|
|
}
|
|
});
|
|
|
|
app.on("activate", () => {
|
|
if (BrowserWindow.getAllWindows().length === 0) {
|
|
createWindow();
|
|
}
|
|
});
|
|
|
|
// Handle any errors
|
|
process.on("uncaughtException", (error) => {
|
|
logger.error("Uncaught Exception:", error);
|
|
});
|
|
|