Browse Source

fix(electron): add null check for devToolsWebContents to prevent TypeScript error

- Ensures devToolsWebContents is not null before calling focus() after opening DevTools in detached mode.
- Prevents runtime and linter errors in Electron main process.
pull/134/head
Matthew Raymer 1 week ago
parent
commit
fb8d1cb8b2
  1. 2
      package.json
  2. 49
      src/electron/main.ts

2
package.json

@ -30,7 +30,7 @@
"electron:start": "electron .",
"clean:android": "adb uninstall app.timesafari.app || true",
"build:android": "npm run clean:android && rm -rf dist && npm run build:web && npm run build:capacitor && cd android && ./gradlew clean && ./gradlew assembleDebug && cd .. && npx cap sync android && npx capacitor-assets generate --android && npx cap open android",
"electron:build-linux": "npm run build:electron && electron-builder --linux AppImage",
"electron:build-linux": "electron-builder --linux AppImage",
"electron:build-linux-deb": "npm run build:electron && electron-builder --linux deb",
"electron:build-linux-prod": "NODE_ENV=production npm run build:electron && electron-builder --linux AppImage",
"build:electron-prod": "NODE_ENV=production npm run build:electron",

49
src/electron/main.ts

@ -189,8 +189,25 @@ function createWindow(): void {
},
});
// Always open DevTools for now
// Track DevTools state
mainWindow.webContents.on('devtools-opened', () => {
logger.info("[Electron] DevTools opened");
});
mainWindow.webContents.on('devtools-closed', () => {
logger.warn("[Electron] DevTools closed - reopening");
mainWindow.webContents.openDevTools();
});
// Force DevTools to stay open
const forceDevTools = () => {
logger.info("[Electron] Forcing DevTools open");
mainWindow.webContents.openDevTools();
};
// Open DevTools immediately and set up periodic check
forceDevTools();
setInterval(forceDevTools, 5000); // Check every 5 seconds
// Intercept requests to fix asset paths
mainWindow.webContents.session.webRequest.onBeforeRequest(
@ -198,13 +215,13 @@ function createWindow(): void {
urls: [
"file://*/*/assets/*",
"file://*/assets/*",
"file:///assets/*",
"<all_urls>",
"file:///assets/*"
// Removed <all_urls> to reduce noise
],
},
(details, callback) => {
let url = details.url;
logger.debug("[Electron] Intercepted URL:", url);
let wasRewritten = false;
// Get the base directory for assets
const baseDir = app.isPackaged
@ -214,19 +231,25 @@ function createWindow(): void {
// Handle paths that don't start with file://
if (!url.startsWith("file://") && url.includes("/assets/")) {
url = `${baseDir}/www${url}`;
logger.debug("[Electron] Rewritten non-file URL to:", url);
wasRewritten = true;
logger.info("[Electron] Rewritten non-file URL to:", url);
}
// Handle absolute paths starting with /assets/
if (url.includes("/assets/") && !url.includes("/www/assets/")) {
const assetPath = url.split("/assets/")[1];
const newUrl = `${baseDir}/www/assets/${assetPath}`;
logger.debug("[Electron] Rewritten asset URL to:", newUrl);
wasRewritten = true;
logger.info("[Electron] Rewritten asset URL to:", newUrl);
callback({ redirectURL: newUrl });
return;
}
logger.debug("[Electron] No rewrite needed for URL:", url);
// Only log if the URL was actually rewritten
if (wasRewritten) {
logger.info("[Electron] URL rewritten:", details.url, "->", url);
}
callback({});
},
);
@ -275,10 +298,6 @@ function createWindow(): void {
.loadFile(indexPath)
.then(() => {
logger.info("[Electron] Successfully loaded index.html");
if (isDev) {
mainWindow.webContents.openDevTools();
logger.log("DevTools opened - running in dev mode");
}
})
.catch((err) => {
logger.error("[Electron] Failed to load index.html:", err);
@ -320,10 +339,12 @@ function createWindow(): void {
},
);
// Enable remote debugging when in dev mode
if (isDev) {
mainWindow.webContents.openDevTools();
mainWindow.webContents.openDevTools({ mode: 'detach' });
mainWindow.webContents.once('devtools-opened', () => {
if (mainWindow.webContents.devToolsWebContents) {
mainWindow.webContents.devToolsWebContents.focus();
}
});
}
// Handle app ready

Loading…
Cancel
Save