import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { BrowserWindow, app, ipcMain, shell } from 'electron'; import started from 'electron-squirrel-startup'; import { Redis } from 'ioredis'; // Handle creating/removing shortcuts on Windows when installing/uninstalling. if (started) { app.quit(); } // Redis connection for pubsub let redisSubscriber: Redis | null = null; const connectRedis = () => { try { redisSubscriber = new Redis({ host: 'bismillahdao-redis', port: 6379, lazyConnect: true, }); console.log('Redis subscriber connection initialized'); } catch (error) { console.error('Failed to initialize Redis subscriber:', error); } }; const createWindow = () => { // Create the browser window. const mainWindow = new BrowserWindow({ minHeight: 800, minWidth: 1080, maxHeight: 1080, maxWidth: 1920, height: 1024, width: 1280, titleBarStyle: 'hidden', webPreferences: { nodeIntegration: false, contextIsolation: true, preload: path.join(__dirname, 'preload.cjs'), }, }); mainWindow.setMenuBarVisibility(false); // Listen for maximize/unmaximize events mainWindow.on('maximize', () => { mainWindow.webContents.send('window-maximize-changed', true); }); mainWindow.on('unmaximize', () => { mainWindow.webContents.send('window-maximize-changed', false); }); mainWindow.webContents.on('will-navigate', function (event, reqUrl) { const requestedHost = new URL(reqUrl).host; const currentHost = new URL(mainWindow.webContents.getURL()).host; if (requestedHost && requestedHost != currentHost) { event.preventDefault(); shell.openExternal(reqUrl); } }); // Set up Redis pubsub when window is ready mainWindow.webContents.once('dom-ready', () => { setupRedisPubSub(mainWindow); }); const isDev = process.env.NODE_ENV === 'development'; // and load the index.html of the app. if (isDev) { mainWindow.setIcon(fileURLToPath(new URL('../../public/favicon.ico', import.meta.url))); mainWindow.loadURL('http://localhost:3000'); mainWindow.webContents.openDevTools(); } else { mainWindow.loadFile(path.join(__dirname, '../renderer/index.html')); } return mainWindow; }; const setupRedisPubSub = (mainWindow: BrowserWindow) => { if (!redisSubscriber) { console.error('Redis subscriber not initialized'); return; } try { // Subscribe to the channels redisSubscriber.subscribe('new_token_created', 'token_cex_updated', 'max_depth_reached'); redisSubscriber.on('message', (channel: string, message: string) => { try { const data = JSON.parse(message); // Send data to renderer process mainWindow.webContents.send('redis-data', { channel, data, timestamp: Date.now(), }); console.log(`Received data from channel ${channel}:`, data); } catch (error) { console.error('Error parsing Redis message:', error); } }); console.log('Redis pubsub setup complete'); } catch (error) { console.error('Error setting up Redis pubsub:', error); } }; // IPC handlers ipcMain.handle('window-minimize', () => { const window = BrowserWindow.getFocusedWindow(); if (window) window.minimize(); }); ipcMain.handle('window-maximize', () => { const window = BrowserWindow.getFocusedWindow(); if (window) { if (window.isMaximized()) { window.unmaximize(); } else { window.maximize(); } } }); ipcMain.handle('window-close', () => { const window = BrowserWindow.getFocusedWindow(); if (window) window.close(); }); ipcMain.handle('window-is-maximized', () => { const window = BrowserWindow.getFocusedWindow(); return window ? window.isMaximized() : false; }); ipcMain.handle('open-external', (event, url: string) => { shell.openExternal(url); }); // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.on('ready', () => { connectRedis(); createWindow(); }); // Quit when all windows are closed, except on macOS. There, it's common // for applications and their menu bar to stay active until the user quits // explicitly with Cmd + Q. app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } }); app.on('activate', () => { // On OS X it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (BrowserWindow.getAllWindows().length === 0) { createWindow(); } }); // Clean up Redis connection on app quit app.on('before-quit', () => { if (redisSubscriber) { redisSubscriber.disconnect(); } }); // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and import them here.