import { BrowserWindow, ipcMain, Menu } from 'electron' import path, { dirname } from 'path' import { fileURLToPath } from 'url' const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename) let win function attachKeyboardShortcuts(browserWindow) { if (!browserWindow) return // Keyboard shortcuts for the main window can be added here if needed } function setupWindowEvents() { if (!win) return win.on('maximize', () => { win.webContents.send('window-state', { isMaximized: true }) }) win.on('enter-full-screen', () => { console.log('Entered fullscreen') win.webContents.send('window-state', { isFullScreen: true }) }) win.on('leave-full-screen', () => { win.webContents.send('window-state', { isFullScreen: false }) }) win.on('unmaximize', () => { win.webContents.send('window-state', { isMaximized: false }) }) } export function createWindow() { win = new BrowserWindow({ width: 1200, height: 800, frame: false, titleBarStyle: 'hiddenInset', trafficLightPosition: { x: 14, y: 12 }, backgroundColor: '#141414', icon: path.join(__dirname, './logo512.png'), webPreferences: { nodeIntegration: true, contextIsolation: false } }) // Set up custom menu bar const env = (process.env.NODE_ENV || 'development').trim() if (env === 'development') { const devMenu = [ { label: 'Developer', submenu: [ { label: 'Toggle Developer Tools', accelerator: process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I', click: () => { win.webContents.toggleDevTools() } } ] } ] const menu = Menu.buildFromTemplate(devMenu) Menu.setApplicationMenu(menu) } else { Menu.setApplicationMenu(null) } // For development, load from localhost; for production, load the built index.html if (process.env.ELECTRON_START_URL) { win.loadURL(process.env.ELECTRON_START_URL) } else { win.loadFile(path.join(__dirname, '../build/index.html')) } setupWindowEvents() attachKeyboardShortcuts(win) } export function getWindow() { return win } export function setupMainWindowIPC() { // IPC handler to get window state ipcMain.handle('window-state', () => { if (!win || win.isDestroyed()) return { isFullScreen: false, isMaximized: false } return { isFullScreen: win ? win.isFullScreen() : false, isMaximized: win ? win.isMaximized() : false } }) // IPC handlers for window controls ipcMain.on('window-control', (event, action) => { if (!win) return switch (action) { case 'minimize': win.minimize() break case 'maximize': if (win.isMaximized()) { win.unmaximize() } else { win.maximize() } break case 'close': win.close() break default: break } }) ipcMain.handle('open-internal-url', (event, url) => { if (!win || win.isDestroyed()) { createWindow() // Wait for window to finish loading before sending navigate event win.webContents.once('did-finish-load', () => { setTimeout(() => { win.webContents.send('navigate', url) win.show() win.focus() }, 100) }) } else { win.webContents.send('navigate', url) win.show() win.focus() } return true }) } export function setupMainWindowAppEvents(app) { app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit() }) app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow() }) app.on('open-url', (event, url) => { event.preventDefault() if (url.startsWith('farmcontrol://app')) { // Extract the path/query after 'farmcontrol://app' const redirectPath = url.replace('farmcontrol://app', '') || '/' if (win && win.webContents) { win.webContents.send('navigate', redirectPath) } } }) } export function setupDevAuthServer() { const env = (process.env.NODE_ENV || 'development').trim() if (env == 'development') { console.log('Starting development auth web server...') import('express').then(({ default: express }) => { const app = express() const port = 3500 app.use((req, res) => { const redirectPath = req.originalUrl res.send( `Open Farmcontrol to continue... (Redirect path: ${redirectPath})` ) if (win && win.webContents) { win.webContents.send('navigate', redirectPath) win.show() win.focus() } }) app.listen(port, () => { console.log(`Dev auth server running on http://localhost:${port}`) }) }) } else { console.log('Will use url scheme instead of auth server.') } }