'use strict' import { app, BrowserWindow, ipcMain } from 'electron'; import * as path from 'path'; import { format as formatUrl } from 'url'; import { exec } from 'child_process'; app.allowRendererProcessReuse = false; const isDevelopment = process.env.NODE_ENV !== 'production'; const platform = process.platform; let mainWindow = null, subWindow1 = null, serWindow1; let random = null; const version = app.getVersion(); let win1 = null, win2 = null, about = null, esptools = null; let tmp = null, appIcon = null, menu = null, trayImg = null; // ------------ Keep only one instance of the app running ------------ // // const singleLock = app.requestSingleInstanceLock(); // !singleLock ? app.quit() : ''; const gotTheLock = app.requestSingleInstanceLock() if (!gotTheLock) { app.quit() } else { app.on('second-instance', (event, commandLine, workingDirectory) => { if (mainWindow) { if (mainWindow.isMinimized()) mainWindow.restore() mainWindow.focus() } }) // Create myWindow, load the rest of the app, etc... app.whenReady().then(() => { }) } // ------------ run auto launch & add ca cert in MacOS ------------ // if (platform === 'darwin') { app.dock.hide(); const sudo = require('sudo-prompt'); const AutoLaunch = require('auto-launch'); const opts = { name: "CocoRoboVDeskTop", isHidden: false, mac: { useLaunchAgent: true } }; autoLaunch(opts); exec(`"${path.join(__dirname, '..', 'verifyCert.bash')}"`, (err, stdout) => { if (!err && stdout.indexOf('No') > -1) sudo.exec( `security add-trusted-cert -d -r trustRoot -k "/Library/Keychains/System.keychain" "${path.join(__dirname, '..', 'ca.crt')}"`, { name: 'CocoRobo X Uploader' }, err => console.log(err) ); else if (err) console.error(err); }); /** * Auto launch when computer boot. * @opts {object} Auto lanuch's options * @returns {void} void */ function autoLaunch(opts) { const autoLaunch = new AutoLaunch(opts); autoLaunch .isEnabled() .then(enabled => enabled ? '' : autoLaunch.enable()) .catch(err => console.error(err)); return; } } /** * Reboot the app. * @returns {void} void */ function reboot() { app.relaunch(); app.exit(); return; } /** * Get windows id & return a list. * @param {string} data Incoming message * @returns {Array} An id list */ function getWindowsId(data) { const result = []; if (data === "already") { const windows = BrowserWindow.getAllWindows(); for (let i = windows.length - 1; i >= 0; i--) result.push(windows[i].id); platform === 'darwin' ? result.reverse() : ''; } return result; } // ------------ IpcMain eventlisteners ------------ // ipcMain.on('tmp', (e, path) => tmp = path); ipcMain.on('version', (e, data) => e.returnValue = data === "already" ? version : ''); ipcMain.on('relaunch', reboot); ipcMain.on('windowsid', (e, data) => e.returnValue = getWindowsId(data)); ipcMain.on('download', (event, url, filePath) => { const request = require('request') const progress = require('request-progress') progress(request(url)) .on('progress', (state) => { event.sender.send('download-progress', state.percent) }) .on('error', (err) => { event.sender.send('download-error', err) }) .pipe(fs.createWriteStream(filePath)) .on('finish', () => { event.sender.send('download-finished') }) }) // ------------ When app is ready ------------ // app.on('ready', () => { //createSubWindow1(); //createSubWindow2(); mainWindow = createMainWindow(); }); // when user acitvate the app, it's useful in mac only app.on('activate', () => { // on macOS it is common to re-create a window even after all windows have been closed mainWindow === null ? mainWindow = createMainWindow() : null; }); function createMainWindow() { let window = new BrowserWindow({ autoHideMenuBar: true, show: false, webPreferences: { nodeIntegration: true }, width: 1280, height: 920, minWidth: 601, minHeight: 670 }); let grantedDeviceThroughPermHandler; window.webContents.session.on('select-usb-device', (event, details, callback) => { //Add events to handle devices being added or removed before the callback on //`select-usb-device` is called. window.webContents.session.on('usb-device-added', (event, device) => { console.log('usb-device-added FIRED WITH', device) //Optionally update details.deviceList }) window.webContents.session.on('usb-device-removed', (event, device) => { console.log('usb-device-removed FIRED WITH', device) //Optionally update details.deviceList }) event.preventDefault() if (details.deviceList && details.deviceList.length > 0) { const deviceToReturn = details.deviceList.find((device) => { // if (!grantedDeviceThroughPermHandler || (device.deviceId != grantedDeviceThroughPermHandler.deviceId)) { // return true // } return true; }) try { if (callback) { if (deviceToReturn) { callback(deviceToReturn.deviceId) } else { callback() } } } catch (e) { console.log(e) } return deviceToReturn; } }) window.webContents.session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => { if (permission === 'usb' && details.securityOrigin === 'file:///') { return true } }) window.webContents.session.setDevicePermissionHandler((details) => { if (details.deviceType === 'usb' && details.origin === 'file://') { return true; // if (!grantedDeviceThroughPermHandler) { // grantedDeviceThroughPermHandler = details.device // return true // } else { // return false // } } }) if (isDevelopment) { window.loadURL(`http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}`); } else { window.loadURL(formatUrl({ pathname: path.join(__dirname, 'cocoblockly-x/index.html'), protocol: 'file', slashes: true, search: "lang=zh-hans", })); } window.once('ready-to-show', () => window.show()); window.on('closed', () => { app.quit() }); // window.webContents.on('devtools-opened', () => window.focus()); // window.webContents.openDevTools({ mode: 'undocked' }); return window; } function createSubWindow1() { let window = new BrowserWindow({ autoHideMenuBar: true, webPreferences: { nodeIntegration: true }, width: 0, height: 0, show: false }); // window.webContents.openDevTools({ mode: "undocked" }); if (isDevelopment) { window.loadURL(`http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}/index.html`); } else { window.loadURL(formatUrl({ pathname: path.join(__dirname, 'index.html'), protocol: 'file', slashes: true })); } window.on('closed', () => window = null); // window.webContents.on('devtools-opened', () => setImmediate(() => window.focus())); // window.webContents.openDevTools({ mode: 'undocked' }); return window; } function createSubWindow2() { let window = new BrowserWindow({ autoHideMenuBar: true, webPreferences: { nodeIntegration: true }, width: 100, height: 100, show: true }); // window.webContents.openDevTools({ mode: "undocked" }); // if (isDevelopment) { // window.loadURL(`http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}/serialport.html`); // } else // window.loadURL(formatUrl({ // pathname: path.join(__dirname, 'serialport.html'), // protocol: 'file', // slashes: true // })); let grantedDeviceThroughPermHandler; window.webContents.session.on('select-usb-device', (event, details, callback) => { //Add events to handle devices being added or removed before the callback on //`select-usb-device` is called. window.webContents.session.on('usb-device-added', (event, device) => { console.log('usb-device-added FIRED WITH', device) //Optionally update details.deviceList }) window.webContents.session.on('usb-device-removed', (event, device) => { console.log('usb-device-removed FIRED WITH', device) //Optionally update details.deviceList }) event.preventDefault() if (details.deviceList && details.deviceList.length > 0) { const deviceToReturn = details.deviceList.find((device) => { // if (!grantedDeviceThroughPermHandler || (device.deviceId != grantedDeviceThroughPermHandler.deviceId)) { // return true // } return true; }) if (deviceToReturn) { callback(deviceToReturn.deviceId) } else { callback() } } }) window.webContents.session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => { if (permission === 'usb' && details.securityOrigin === 'file:///') { return true } }) window.webContents.session.setDevicePermissionHandler((details) => { if (details.deviceType === 'usb' && details.origin === 'file://') { return true; // if (!grantedDeviceThroughPermHandler) { // grantedDeviceThroughPermHandler = details.device // return true // } else { // return false // } } }) if (isDevelopment) { window.loadURL(`http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}`); } else { window.loadURL(formatUrl({ pathname: path.join(__dirname, 'cocoblockly-x/index.html'), protocol: 'file', slashes: true, search: "lang=zh-hans", })); } window.on('closed', () => window = null); window.webContents.on('devtools-opened', () => setImmediate(() => window.focus())); window.webContents.openDevTools({ mode: 'undocked' }); return window; } // ------------ When quit the app ------------ // app.once('quit', () => { if (tmp) { let cmd = platform === 'win32' ? `rd /s /q "${tmp}"` : `rm -rf "${tmp}"`; exec(cmd); } });