Skip to content

Commit a70dfdf

Browse files
KevenWMarkhamclaude
andcommitted
fix: move IPC handlers inside app.whenReady() callback
Moved IPC handler registration into setupIPCHandlers() function that is called after app.whenReady() to ensure Electron APIs are available. Added validation to detect if running in Node.js vs Electron context. This fixes module loading issues where require('electron') at module level returns the path string instead of the Electron API object. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 9235405 commit a70dfdf

File tree

1 file changed

+53
-37
lines changed

1 file changed

+53
-37
lines changed

electron/main.cjs

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
1-
const { app, BrowserWindow, ipcMain, dialog, Menu, Tray, nativeImage } = require('electron')
21
const path = require('path')
32
const fs = require('fs')
43

4+
// Get Electron modules - only available when running inside Electron
5+
const electron = require('electron')
6+
7+
// Validate that we're running in Electron, not just loading the path
8+
if (typeof electron === 'string' || !electron.app) {
9+
console.error('This file must be run within Electron, not Node.js directly')
10+
console.error('Use: npx electron . or npm run electron:dev')
11+
process.exit(1)
12+
}
13+
14+
const { app, BrowserWindow, dialog, Menu, Tray, nativeImage } = electron
15+
516
let mainWindow = null
617
let tray = null
718

819
// Enable live reload for development
9-
// Check if running in development mode
10-
const isDev = process.env.NODE_ENV === 'development' && !app.isPackaged
20+
// Check if running in development mode - use environment variable or check for dist folder
21+
const isDev = process.env.NODE_ENV === 'development' || !require('fs').existsSync(path.join(__dirname, '../dist/index.html'))
1122

1223
function createWindow() {
1324
mainWindow = new BrowserWindow({
@@ -174,49 +185,54 @@ async function openVideoFile() {
174185
}
175186
}
176187

177-
// IPC Handlers
178-
ipcMain.handle('select-video-file', async () => {
179-
const result = await dialog.showOpenDialog(mainWindow, {
180-
properties: ['openFile'],
181-
filters: [
182-
{ name: 'Videos', extensions: ['mp4', 'webm', 'mov', 'avi', 'mkv', 'm4v'] },
183-
{ name: 'All Files', extensions: ['*'] },
184-
],
185-
})
188+
// Setup IPC Handlers
189+
function setupIPCHandlers() {
190+
const { ipcMain: ipc } = require('electron')
186191

187-
if (!result.canceled && result.filePaths.length > 0) {
188-
return result.filePaths[0]
189-
}
190-
return null
191-
})
192+
ipc.handle('select-video-file', async () => {
193+
const result = await dialog.showOpenDialog(mainWindow, {
194+
properties: ['openFile'],
195+
filters: [
196+
{ name: 'Videos', extensions: ['mp4', 'webm', 'mov', 'avi', 'mkv', 'm4v'] },
197+
{ name: 'All Files', extensions: ['*'] },
198+
],
199+
})
192200

193-
ipcMain.handle('save-transcript', async (event, transcript) => {
194-
const result = await dialog.showSaveDialog(mainWindow, {
195-
defaultPath: `transcript-${Date.now()}.json`,
196-
filters: [
197-
{ name: 'JSON', extensions: ['json'] },
198-
{ name: 'Text', extensions: ['txt'] },
199-
{ name: 'All Files', extensions: ['*'] },
200-
],
201+
if (!result.canceled && result.filePaths.length > 0) {
202+
return result.filePaths[0]
203+
}
204+
return null
201205
})
202206

203-
if (!result.canceled && result.filePath) {
204-
try {
205-
fs.writeFileSync(result.filePath, JSON.stringify(transcript, null, 2))
206-
return { success: true, path: result.filePath }
207-
} catch (error) {
208-
return { success: false, error: error.message }
207+
ipc.handle('save-transcript', async (event, transcript) => {
208+
const result = await dialog.showSaveDialog(mainWindow, {
209+
defaultPath: `transcript-${Date.now()}.json`,
210+
filters: [
211+
{ name: 'JSON', extensions: ['json'] },
212+
{ name: 'Text', extensions: ['txt'] },
213+
{ name: 'All Files', extensions: ['*'] },
214+
],
215+
})
216+
217+
if (!result.canceled && result.filePath) {
218+
try {
219+
fs.writeFileSync(result.filePath, JSON.stringify(transcript, null, 2))
220+
return { success: true, path: result.filePath }
221+
} catch (error) {
222+
return { success: false, error: error.message }
223+
}
209224
}
210-
}
211-
return { success: false, error: 'Cancelled' }
212-
})
225+
return { success: false, error: 'Cancelled' }
226+
})
213227

214-
ipcMain.handle('get-app-version', () => {
215-
return app.getVersion()
216-
})
228+
ipc.handle('get-app-version', () => {
229+
return app.getVersion()
230+
})
231+
}
217232

218233
// App lifecycle
219234
app.whenReady().then(() => {
235+
setupIPCHandlers()
220236
createWindow()
221237
createTray()
222238

0 commit comments

Comments
 (0)