Skip to content

Commit 5d0965f

Browse files
author
ottendorfcipher
committed
feat: comprehensive Electron app improvements for v1.0.4
- Replace Express with direct Next.js HTTP server integration - Fix platform-specific application icons (macOS .icns, Windows .ico, Linux .png) - Optimize startup performance with Promise-based server readiness detection - Remove arbitrary delays in favor of actual server ready state - Fix development mode environment variable detection - Add proper window focus and visibility optimizations - Improve error handling with user-friendly dialogs - Remove Express dependency to reduce bundle size
1 parent 2e59cc5 commit 5d0965f

File tree

3 files changed

+66
-678
lines changed

3 files changed

+66
-678
lines changed

electron/main.js

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,42 @@ let mainWindow;
66
let server;
77

88
function startServer() {
9-
if (!isDev) {
10-
// In production, serve the built Next.js files using Express
11-
const express = require('express');
12-
const next = require('next');
13-
14-
const nextApp = next({
15-
dev: false,
16-
dir: path.join(__dirname, '..'),
17-
});
18-
19-
const handle = nextApp.getRequestHandler();
20-
21-
nextApp.prepare().then(() => {
22-
const expressApp = express();
9+
return new Promise((resolve, reject) => {
10+
if (!isDev) {
11+
// In production, start Next.js server directly
12+
const next = require('next');
13+
const http = require('http');
2314

24-
expressApp.all('*', (req, res) => {
25-
return handle(req, res);
15+
const nextApp = next({
16+
dev: false,
17+
dir: path.join(__dirname, '..'),
2618
});
2719

28-
server = expressApp.listen(3000, (err) => {
29-
if (err) throw err;
30-
console.log('> Ready on http://localhost:3000');
20+
const handle = nextApp.getRequestHandler();
21+
22+
nextApp.prepare().then(() => {
23+
// Create HTTP server with Next.js handler
24+
server = http.createServer((req, res) => {
25+
handle(req, res);
26+
});
27+
28+
server.listen(3000, (err) => {
29+
if (err) {
30+
console.error('Error starting server:', err);
31+
reject(err);
32+
return;
33+
}
34+
console.log('> Next.js server ready on http://localhost:3000');
35+
resolve();
36+
});
37+
}).catch((ex) => {
38+
console.error('Error preparing Next.js:', ex);
39+
reject(ex);
3140
});
32-
}).catch((ex) => {
33-
console.error('Error starting Next.js:', ex);
34-
process.exit(1);
35-
});
36-
}
41+
} else {
42+
resolve(); // In development, resolve immediately
43+
}
44+
});
3745
}
3846

3947
function createWindow() {
@@ -49,22 +57,35 @@ function createWindow() {
4957
enableRemoteModule: false,
5058
webSecurity: true,
5159
},
52-
icon: path.join(__dirname, 'assets/icon.png'),
60+
icon: path.join(__dirname, 'assets', process.platform === 'win32' ? 'icon.ico' : process.platform === 'darwin' ? 'icon.icns' : 'icon.png'),
5361
titleBarStyle: 'default',
5462
show: false,
63+
backgroundColor: '#ffffff', // Set a background color to avoid flashing
5564
});
5665

5766
const startUrl = 'http://localhost:3000';
5867

59-
// Wait a bit for the server to start in production
60-
const delay = isDev ? 0 : 3000;
61-
setTimeout(() => {
68+
// Load URL immediately in development, wait for server in production
69+
if (isDev) {
6270
mainWindow.loadURL(startUrl);
63-
}, delay);
71+
} else {
72+
// Wait for server to be ready, then load
73+
startServer().then(() => {
74+
mainWindow.loadURL(startUrl);
75+
}).catch((err) => {
76+
dialog.showErrorBox('Server Error', `Failed to start server: ${err.message}`);
77+
});
78+
}
6479

6580
// Show window when ready
6681
mainWindow.once('ready-to-show', () => {
6782
mainWindow.show();
83+
84+
// Focus the window
85+
if (process.platform === 'darwin') {
86+
app.dock.show();
87+
}
88+
mainWindow.focus();
6889
});
6990

7091
// Open external links in browser
@@ -86,7 +107,6 @@ function createWindow() {
86107

87108
// App event handlers
88109
app.whenReady().then(() => {
89-
startServer();
90110
createWindow();
91111

92112
app.on('activate', () => {

0 commit comments

Comments
 (0)