import { app, ipcMain, IpcMainEvent } from 'electron'; import * as path from 'path'; import * as url from 'url'; import { AppWindow } from './app/AppWindow'; import { now } from './util/now'; import { showUncaughtException } from './crash/show-uncaught-exception'; import { Channel } from '@ucap-webmessenger/native-electron'; let appWindow: AppWindow | null = null; const launchTime = now(); let readyTime: number | null = null; type OnDidLoadFn = (window: AppWindow) => void; let onDidLoadFns: Array | null = []; let preventQuit = false; function handleUncaughtException(error: Error) { preventQuit = true; // If we haven't got a window we'll assume it's because // we've just launched and haven't created it yet. // It could also be because we're encountering an unhandled // exception on shutdown but that's less likely and since // this only affects the presentation of the crash dialog // it's a safe assumption to make. const isLaunchError = appWindow === null; if (appWindow) { appWindow.destroy(); appWindow = null; } showUncaughtException(isLaunchError, error); } function getUptimeInSeconds() { return (now() - launchTime) / 1000; } process.on('uncaughtException', (error: Error) => { // error = withSourceMappedStack(error); // reportError(error, getExtraErrorContext()); handleUncaughtException(error); }); let isDuplicateInstance = false; const gotSingleInstanceLock = app.requestSingleInstanceLock(); isDuplicateInstance = !gotSingleInstanceLock; app.on('second-instance', (event, args, workingDirectory) => { // Someone tried to run a second instance, we should focus our window. if (appWindow) { if (appWindow.isMinimized()) { appWindow.restore(); } if (!appWindow.isVisible()) { appWindow.show(); } appWindow.focus(); } }); if (isDuplicateInstance) { app.quit(); } function createWindow() { const window = new AppWindow(); if (__DEV__) { const { default: installExtension, REDUX_DEVTOOLS } = require('electron-devtools-installer'); require('electron-debug')({ showDevTools: true }); const ChromeLens = { id: 'idikgljglpfilbhaboonnpnnincjhjkd', electron: '>=1.2.1' }; const extensions = [REDUX_DEVTOOLS, ChromeLens]; for (const extension of extensions) { try { installExtension(extension); } catch (e) {} } } window.onClose(() => { appWindow = null; if (!__DARWIN__ && !preventQuit) { app.quit(); } }); window.onDidLoad(() => { window.show(); const fns = onDidLoadFns; onDidLoadFns = null; for (const fn of fns) { fn(window); } }); window.load(); appWindow = window; } // 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', () => { if (isDuplicateInstance) { return; } readyTime = now() - launchTime; createWindow(); ipcMain.on('uncaught-exception', (event: IpcMainEvent, error: Error) => { handleUncaughtException(error); }); ipcMain.on( 'send-error-report', ( event: IpcMainEvent, { error, extra }: { error: Error; extra: { [key: string]: string } } ) => {} ); }); // Quit when all windows are closed. app.on('window-all-closed', () => { // On OS X it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== 'darwin') { app.quit(); } }); app.on('activate', () => { onDidLoad(window => { window.show(); }); }); function onDidLoad(fn: OnDidLoadFn) { if (onDidLoadFns) { onDidLoadFns.push(fn); } else { if (appWindow) { fn(appWindow); } } } ipcMain.on(Channel.checkForUpdates, (event: IpcMainEvent, ...args: any[]) => { event.returnValue = false; });