diff --git a/main.js b/main.js index cbd5fe2..8b3c809 100644 --- a/main.js +++ b/main.js @@ -1,18 +1,18 @@ /* global __dirname, process */ const { - app: APP, BrowserWindow, Menu, + app, shell } = require('electron'); const isDev = require('electron-is-dev'); const { autoUpdater } = require('electron-updater'); const windowStateKeeper = require('electron-window-state'); const { - setupAlwaysOnTopMain, initPopupsConfigurationMain, - getPopupTarget + getPopupTarget, + setupAlwaysOnTopMain } = require('jitsi-meet-electron-utils'); const path = require('path'); const URL = require('url'); @@ -25,155 +25,104 @@ autoUpdater.logger.transports.file.level = 'info'; */ require('electron-debug')({ showDevTools: false }); -/** - * Path to root directory - */ -const basePath = isDev ? __dirname : APP.getAppPath(); - -/** - * URL for index.html which will be our entry point. - */ -const indexURL = URL.format({ - pathname: path.resolve(basePath, './build/index.html'), - protocol: 'file:', - slashes: true -}); - /** * The window object that will load the iframe with Jitsi Meet. * IMPORTANT: Must be defined as global in order to not be garbage collected * acidentally. */ -let jitsiMeetWindow = null; +let mainWindow = null; /** - * Force Single Instance Application + * Sets the application menu. It is hidden on all platforms except macOS because + * otherwise copy and paste functionality is not available. */ -const isSecondInstance = APP.makeSingleInstance(() => { - /** - * If someone creates second instance of the application, set focus on - * existing window. - */ - if (jitsiMeetWindow) { - if (jitsiMeetWindow.isMinimized()) { - jitsiMeetWindow.restore(); - } - jitsiMeetWindow.focus(); - } -}); - -/** - * We should quit the second instance. - */ -if (isSecondInstance) { - APP.quit(); - process.exit(0); -} - -/** - * Sets the APP object listeners. - */ -function setAPPListeners() { - APP.on('ready', createJitsiMeetWindow); - APP.on('window-all-closed', () => { - // Don't quit the application for macOS. - if (process.platform !== 'darwin') { - APP.quit(); - } - }); - APP.on('activate', () => { - if (jitsiMeetWindow === null) { - createJitsiMeetWindow(); - } - }); - APP.on('certificate-error', - // eslint-disable-next-line max-params - (event, webContents, url, error, certificate, callback) => { - if (url.startsWith('https://localhost')) { - event.preventDefault(); - callback(true); - } else { - callback(false); +function setApplicationMenu() { + if (process.platform === 'darwin') { + const template = [ { + label: app.getName(), + submenu: [ { + label: 'Quit', + accelerator: 'Command+Q', + click() { + app.quit(); + } + } ] + }, { + label: 'Edit', + submenu: [ { + label: 'Undo', + accelerator: 'CmdOrCtrl+Z', + selector: 'undo:' + }, + { + label: 'Redo', + accelerator: 'Shift+CmdOrCtrl+Z', + selector: 'redo:' + }, + { + type: 'separator' + }, + { + label: 'Cut', + accelerator: 'CmdOrCtrl+X', + selector: 'cut:' + }, + { + label: 'Copy', + accelerator: 'CmdOrCtrl+C', + selector: 'copy:' + }, + { + label: 'Paste', + accelerator: 'CmdOrCtrl+V', + selector: 'paste:' + }, + { + label: 'Select All', + accelerator: 'CmdOrCtrl+A', + selector: 'selectAll:' } - } - ); -} + ] + } ]; -/** - * Template for Application menu (MacOS) - */ -const template = [ { - label: APP.getName(), - submenu: [ { - label: 'Quit', - accelerator: 'Command+Q', - click() { - APP.quit(); - } - } ] -}, { - label: 'Edit', - submenu: [ { - label: 'Undo', - accelerator: 'CmdOrCtrl+Z', - selector: 'undo:' - }, - { - label: 'Redo', - accelerator: 'Shift+CmdOrCtrl+Z', - selector: 'redo:' - }, - { - type: 'separator' - }, - { - label: 'Cut', - accelerator: 'CmdOrCtrl+X', - selector: 'cut:' - }, - { - label: 'Copy', - accelerator: 'CmdOrCtrl+C', - selector: 'copy:' - }, - { - label: 'Paste', - accelerator: 'CmdOrCtrl+V', - selector: 'paste:' - }, - { - label: 'Select All', - accelerator: 'CmdOrCtrl+A', - selector: 'selectAll:' + Menu.setApplicationMenu(Menu.buildFromTemplate(template)); + } else { + Menu.setApplicationMenu(null); } - ] -} ]; +} /** * Opens new window with index.html(Jitsi Meet is loaded in iframe there). */ function createJitsiMeetWindow() { - if (process.platform === 'darwin') { - Menu.setApplicationMenu(Menu.buildFromTemplate(template)); - } else { - Menu.setApplicationMenu(null); - } + // Application menu. + setApplicationMenu(); // Check for Updates. autoUpdater.checkForUpdatesAndNotify(); - // Load the previous state with fallback to defaults - const jitsiMeetWindowState = windowStateKeeper({ + // Load the previous window state with fallback to defaults. + const windowState = windowStateKeeper({ defaultWidth: 800, defaultHeight: 600 }); + // Path to root directory. + const basePath = isDev ? __dirname : app.getAppPath(); + + // URL for index.html which will be our entry point. + const indexURL = URL.format({ + pathname: path.resolve(basePath, './build/index.html'), + protocol: 'file:', + slashes: true + }); + // Options used when creating the main Jitsi Meet window. - const jitsiMeetWindowOptions = { - x: jitsiMeetWindowState.x, - y: jitsiMeetWindowState.y, - width: jitsiMeetWindowState.width, - height: jitsiMeetWindowState.height, + const options = { + x: windowState.x, + y: windowState.y, + width: windowState.width, + height: windowState.height, icon: path.resolve(basePath, './resources/icons/icon_512x512.png'), minWidth: 800, minHeight: 600, @@ -184,12 +133,14 @@ function createJitsiMeetWindow() { } }; - jitsiMeetWindow = new BrowserWindow(jitsiMeetWindowOptions); - jitsiMeetWindowState.manage(jitsiMeetWindow); - jitsiMeetWindow.loadURL(indexURL); - initPopupsConfigurationMain(jitsiMeetWindow); + mainWindow = new BrowserWindow(options); + windowState.manage(mainWindow); + mainWindow.loadURL(indexURL); - jitsiMeetWindow.webContents.on('new-window', (event, url, frameName) => { + initPopupsConfigurationMain(mainWindow); + setupAlwaysOnTopMain(mainWindow); + + mainWindow.webContents.on('new-window', (event, url, frameName) => { const target = getPopupTarget(url, frameName); if (!target || target === 'browser') { @@ -197,16 +148,58 @@ function createJitsiMeetWindow() { shell.openExternal(url); } }); - - setupAlwaysOnTopMain(jitsiMeetWindow); - - jitsiMeetWindow.on('closed', () => { - jitsiMeetWindow = null; + mainWindow.on('closed', () => { + mainWindow = null; }); - jitsiMeetWindow.once('ready-to-show', () => { - jitsiMeetWindow.show(); + mainWindow.once('ready-to-show', () => { + mainWindow.show(); }); } -// Start the application: -setAPPListeners(); +/** + * Force Single Instance Application. + */ +const isSecondInstance = app.makeSingleInstance(() => { + /** + * If someone creates second instance of the application, set focus on + * existing window. + */ + if (mainWindow) { + if (mainWindow.isMinimized()) { + mainWindow.restore(); + } + mainWindow.focus(); + } +}); + +if (isSecondInstance) { + app.quit(); + process.exit(0); +} + +/** + * Run the application. + */ +app.on('activate', () => { + if (mainWindow === null) { + createJitsiMeetWindow(); + } +}); +app.on('certificate-error', + // eslint-disable-next-line max-params + (event, webContents, url, error, certificate, callback) => { + if (url.startsWith('https://localhost')) { + event.preventDefault(); + callback(true); + } else { + callback(false); + } + } +); +app.on('ready', createJitsiMeetWindow); +app.on('window-all-closed', () => { + // Don't quit the application for macOS. + if (process.platform !== 'darwin') { + app.quit(); + } +});