Build and Release / build (x64, ubuntu-latest, linux) (push) Has been skipped
Build and Release / build (arm64, macos-latest, darwin) (push) Has been cancelled
Build and Release / build (x64, macos-latest, darwin) (push) Has been cancelled
Build and Release / build (x64, windows-latest, win32) (push) Has been cancelled
Build and Release / release (push) Has been cancelled
371 lines
12 KiB
JavaScript
371 lines
12 KiB
JavaScript
if (require('electron-squirrel-startup')) {
|
|
process.exit(0);
|
|
}
|
|
|
|
const { app, BrowserWindow, shell, ipcMain } = require('electron');
|
|
const { createWindow, updateGlobalShortcuts } = require('./utils/window');
|
|
const { setupAIProviderIpcHandlers } = require('./utils/ai-provider-manager');
|
|
const { stopMacOSAudioCapture } = require('./utils/gemini');
|
|
const { initLogger, closeLogger, getLogPath } = require('./utils/logger');
|
|
const storage = require('./storage');
|
|
|
|
const geminiSessionRef = { current: null };
|
|
let mainWindow = null;
|
|
|
|
function sendToRenderer(channel, data) {
|
|
const windows = BrowserWindow.getAllWindows();
|
|
if (windows.length > 0) {
|
|
windows[0].webContents.send(channel, data);
|
|
}
|
|
}
|
|
|
|
function createMainWindow() {
|
|
mainWindow = createWindow(sendToRenderer, geminiSessionRef);
|
|
return mainWindow;
|
|
}
|
|
|
|
app.whenReady().then(async () => {
|
|
// Initialize file logger first
|
|
const logPath = initLogger();
|
|
console.log('App starting, log file:', logPath);
|
|
|
|
// Initialize storage (checks version, resets if needed)
|
|
storage.initializeStorage();
|
|
|
|
createMainWindow();
|
|
setupAIProviderIpcHandlers(geminiSessionRef);
|
|
setupStorageIpcHandlers();
|
|
setupGeneralIpcHandlers();
|
|
|
|
// Add handler to get log path from renderer
|
|
ipcMain.handle('get-log-path', () => getLogPath());
|
|
|
|
// Add handler for renderer logs (so they go to the log file)
|
|
ipcMain.on('renderer-log', (event, { level, message }) => {
|
|
const prefix = '[RENDERER]';
|
|
if (level === 'error') console.error(prefix, message);
|
|
else if (level === 'warn') console.warn(prefix, message);
|
|
else console.log(prefix, message);
|
|
});
|
|
});
|
|
|
|
app.on('window-all-closed', () => {
|
|
stopMacOSAudioCapture();
|
|
closeLogger();
|
|
if (process.platform !== 'darwin') {
|
|
app.quit();
|
|
}
|
|
});
|
|
|
|
app.on('before-quit', () => {
|
|
stopMacOSAudioCapture();
|
|
closeLogger();
|
|
});
|
|
|
|
app.on('activate', () => {
|
|
if (BrowserWindow.getAllWindows().length === 0) {
|
|
createMainWindow();
|
|
}
|
|
});
|
|
|
|
function setupStorageIpcHandlers() {
|
|
// ============ CONFIG ============
|
|
ipcMain.handle('storage:get-config', async () => {
|
|
try {
|
|
return { success: true, data: storage.getConfig() };
|
|
} catch (error) {
|
|
console.error('Error getting config:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:set-config', async (event, config) => {
|
|
try {
|
|
storage.setConfig(config);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error setting config:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:update-config', async (event, key, value) => {
|
|
try {
|
|
storage.updateConfig(key, value);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error updating config:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
// ============ CREDENTIALS ============
|
|
ipcMain.handle('storage:get-credentials', async () => {
|
|
try {
|
|
return { success: true, data: storage.getCredentials() };
|
|
} catch (error) {
|
|
console.error('Error getting credentials:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:set-credentials', async (event, credentials) => {
|
|
try {
|
|
storage.setCredentials(credentials);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error setting credentials:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:get-api-key', async () => {
|
|
try {
|
|
return { success: true, data: storage.getApiKey() };
|
|
} catch (error) {
|
|
console.error('Error getting API key:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:set-api-key', async (event, apiKey) => {
|
|
try {
|
|
storage.setApiKey(apiKey);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error setting API key:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:get-openai-credentials', async () => {
|
|
try {
|
|
return { success: true, data: storage.getOpenAICredentials() };
|
|
} catch (error) {
|
|
console.error('Error getting OpenAI credentials:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:set-openai-credentials', async (event, config) => {
|
|
try {
|
|
storage.setOpenAICredentials(config);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error setting OpenAI credentials:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:get-openai-sdk-credentials', async () => {
|
|
try {
|
|
return { success: true, data: storage.getOpenAISDKCredentials() };
|
|
} catch (error) {
|
|
console.error('Error getting OpenAI SDK credentials:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:set-openai-sdk-credentials', async (event, config) => {
|
|
try {
|
|
storage.setOpenAISDKCredentials(config);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error setting OpenAI SDK credentials:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
// ============ PREFERENCES ============
|
|
ipcMain.handle('storage:get-preferences', async () => {
|
|
try {
|
|
return { success: true, data: storage.getPreferences() };
|
|
} catch (error) {
|
|
console.error('Error getting preferences:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:set-preferences', async (event, preferences) => {
|
|
try {
|
|
storage.setPreferences(preferences);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error setting preferences:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:update-preference', async (event, key, value) => {
|
|
try {
|
|
storage.updatePreference(key, value);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error updating preference:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
// ============ KEYBINDS ============
|
|
ipcMain.handle('storage:get-keybinds', async () => {
|
|
try {
|
|
return { success: true, data: storage.getKeybinds() };
|
|
} catch (error) {
|
|
console.error('Error getting keybinds:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:set-keybinds', async (event, keybinds) => {
|
|
try {
|
|
storage.setKeybinds(keybinds);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error setting keybinds:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
// ============ HISTORY ============
|
|
ipcMain.handle('storage:get-all-sessions', async () => {
|
|
try {
|
|
return { success: true, data: storage.getAllSessions() };
|
|
} catch (error) {
|
|
console.error('Error getting sessions:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:get-session', async (event, sessionId) => {
|
|
try {
|
|
return { success: true, data: storage.getSession(sessionId) };
|
|
} catch (error) {
|
|
console.error('Error getting session:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:save-session', async (event, sessionId, data) => {
|
|
try {
|
|
storage.saveSession(sessionId, data);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error saving session:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:delete-session', async (event, sessionId) => {
|
|
try {
|
|
storage.deleteSession(sessionId);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error deleting session:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:delete-all-sessions', async () => {
|
|
try {
|
|
storage.deleteAllSessions();
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error deleting all sessions:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
// ============ LIMITS ============
|
|
ipcMain.handle('storage:get-today-limits', async () => {
|
|
try {
|
|
return { success: true, data: storage.getTodayLimits() };
|
|
} catch (error) {
|
|
console.error('Error getting today limits:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
// ============ CLEAR ALL ============
|
|
ipcMain.handle('storage:clear-all', async () => {
|
|
try {
|
|
storage.clearAllData();
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error clearing all data:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
// ============ MIGRATION ============
|
|
ipcMain.handle('storage:has-old-config', async () => {
|
|
try {
|
|
return { success: true, data: storage.hasOldConfig() };
|
|
} catch (error) {
|
|
console.error('Error checking old config:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('storage:migrate-from-old-config', async () => {
|
|
try {
|
|
const success = storage.migrateFromOldConfig();
|
|
return { success: true, data: success };
|
|
} catch (error) {
|
|
console.error('Error migrating from old config:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
}
|
|
|
|
function setupGeneralIpcHandlers() {
|
|
ipcMain.handle('get-app-version', async () => {
|
|
return app.getVersion();
|
|
});
|
|
|
|
ipcMain.handle('open-logs-folder', async () => {
|
|
try {
|
|
const logPath = getLogPath();
|
|
const logsDir = require('path').dirname(logPath);
|
|
await shell.openPath(logsDir);
|
|
return { success: true, path: logsDir };
|
|
} catch (error) {
|
|
console.error('Error opening logs folder:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('quit-application', async event => {
|
|
try {
|
|
stopMacOSAudioCapture();
|
|
app.quit();
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error quitting application:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('open-external', async (event, url) => {
|
|
try {
|
|
await shell.openExternal(url);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error opening external URL:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.on('update-keybinds', (event, newKeybinds) => {
|
|
if (mainWindow) {
|
|
// Also save to storage
|
|
storage.setKeybinds(newKeybinds);
|
|
updateGlobalShortcuts(newKeybinds, mainWindow, sendToRenderer, geminiSessionRef);
|
|
}
|
|
});
|
|
|
|
// Debug logging from renderer
|
|
ipcMain.on('log-message', (event, msg) => {
|
|
console.log(msg);
|
|
});
|
|
}
|