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. 53
      src/electron/main.ts

2
package.json

@ -30,7 +30,7 @@
"electron:start": "electron .", "electron:start": "electron .",
"clean:android": "adb uninstall app.timesafari.app || true", "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", "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-deb": "npm run build:electron && electron-builder --linux deb",
"electron:build-linux-prod": "NODE_ENV=production npm run build:electron && electron-builder --linux AppImage", "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", "build:electron-prod": "NODE_ENV=production npm run build:electron",

53
src/electron/main.ts

@ -189,8 +189,25 @@ function createWindow(): void {
}, },
}); });
// Always open DevTools for now // Track DevTools state
mainWindow.webContents.openDevTools(); 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 // Intercept requests to fix asset paths
mainWindow.webContents.session.webRequest.onBeforeRequest( mainWindow.webContents.session.webRequest.onBeforeRequest(
@ -198,13 +215,13 @@ function createWindow(): void {
urls: [ urls: [
"file://*/*/assets/*", "file://*/*/assets/*",
"file://*/assets/*", "file://*/assets/*",
"file:///assets/*", "file:///assets/*"
"<all_urls>", // Removed <all_urls> to reduce noise
], ],
}, },
(details, callback) => { (details, callback) => {
let url = details.url; let url = details.url;
logger.debug("[Electron] Intercepted URL:", url); let wasRewritten = false;
// Get the base directory for assets // Get the base directory for assets
const baseDir = app.isPackaged const baseDir = app.isPackaged
@ -214,19 +231,25 @@ function createWindow(): void {
// Handle paths that don't start with file:// // Handle paths that don't start with file://
if (!url.startsWith("file://") && url.includes("/assets/")) { if (!url.startsWith("file://") && url.includes("/assets/")) {
url = `${baseDir}/www${url}`; 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/ // Handle absolute paths starting with /assets/
if (url.includes("/assets/") && !url.includes("/www/assets/")) { if (url.includes("/assets/") && !url.includes("/www/assets/")) {
const assetPath = url.split("/assets/")[1]; const assetPath = url.split("/assets/")[1];
const newUrl = `${baseDir}/www/assets/${assetPath}`; 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 }); callback({ redirectURL: newUrl });
return; 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({}); callback({});
}, },
); );
@ -275,10 +298,6 @@ function createWindow(): void {
.loadFile(indexPath) .loadFile(indexPath)
.then(() => { .then(() => {
logger.info("[Electron] Successfully loaded index.html"); logger.info("[Electron] Successfully loaded index.html");
if (isDev) {
mainWindow.webContents.openDevTools();
logger.log("DevTools opened - running in dev mode");
}
}) })
.catch((err) => { .catch((err) => {
logger.error("[Electron] Failed to load index.html:", err); logger.error("[Electron] Failed to load index.html:", err);
@ -320,10 +339,12 @@ function createWindow(): void {
}, },
); );
// Enable remote debugging when in dev mode mainWindow.webContents.openDevTools({ mode: 'detach' });
if (isDev) { mainWindow.webContents.once('devtools-opened', () => {
mainWindow.webContents.openDevTools(); if (mainWindow.webContents.devToolsWebContents) {
} mainWindow.webContents.devToolsWebContents.focus();
}
});
} }
// Handle app ready // Handle app ready

Loading…
Cancel
Save