Merge remote-tracking branch 'upstream/master' into ELECTRON-174

This commit is contained in:
Kiran Niranjan
2017-11-05 10:41:47 +05:30
22 changed files with 328 additions and 8242 deletions

View File

@@ -6,6 +6,7 @@ const path = require('path');
const fs = require('fs');
const log = require('../log.js');
const logLevels = require('../enums/logLevels.js');
const buildNumber = require('../../package.json').buildNumber;
let aboutWindow;
@@ -78,6 +79,10 @@ function openAboutWindow(windowName) {
aboutWindow.show();
});
aboutWindow.webContents.on('did-finish-load', () => {
aboutWindow.webContents.send('buildNumber', buildNumber || '0');
});
aboutWindow.on('close', () => {
destroyWindow();
});

View File

@@ -1,5 +1,5 @@
'use strict';
const { remote } = require('electron');
const { remote, ipcRenderer } = require('electron');
renderDom();
@@ -9,13 +9,19 @@ renderDom();
function renderDom() {
document.addEventListener('DOMContentLoaded', function () {
const applicationName = remote.app.getName() || 'Symphony';
const version = remote.app.getVersion();
let appName = document.getElementById('app-name');
let versionText = document.getElementById('version');
let copyright = document.getElementById('copyright');
appName.innerHTML = applicationName;
versionText.innerHTML = version ? `Version ${version} (${version})` : null;
copyright.innerHTML = `Copyright © ${new Date().getFullYear()} ${applicationName}`
});
}
ipcRenderer.on('buildNumber', (event, buildNumber) => {
let versionText = document.getElementById('version');
const version = remote.app.getVersion();
if (versionText) {
versionText.innerHTML = version ? `Version ${version} (${version}.${buildNumber})` : 'N/A';
}
});

View File

@@ -6,6 +6,8 @@ const path = require('path');
const fs = require('fs');
const AppDirectory = require('appdirectory');
const omit = require('lodash.omit');
const pick = require('lodash.pick');
const difference = require('lodash.difference');
const isDevEnv = require('./utils/misc.js').isDevEnv;
const isMac = require('./utils/misc.js').isMac;
@@ -314,6 +316,64 @@ function updateUserConfigMac() {
});
}
/**
* Method that tries to grab multiple config field from user config
* if field doesn't exist tries reading from global config
*
* @param {Array} fieldNames - array of config filed names
* @returns {Promise} - object all the config data from user and global config
*/
function getMultipleConfigField(fieldNames) {
return new Promise((resolve, reject) => {
let userConfigData;
if (!fieldNames && fieldNames.length < 0) {
reject('cannot read config file, invalid fields');
return;
}
// reads user config data
readUserConfig().then((config) => {
userConfigData = pick(config, fieldNames);
let userConfigKeys = userConfigData ? Object.keys(userConfigData) : undefined;
/**
* Condition to validate data from user config,
* if all the required fields are not present
* this tries to fetch the remaining fields from global config
*/
if (!userConfigKeys || userConfigKeys.length < fieldNames.length) {
// remainingConfig - config field that are not present in the user config
let remainingConfig = difference(fieldNames, userConfigKeys);
if (remainingConfig && Object.keys(remainingConfig).length > 0) {
readGlobalConfig().then((globalConfigData) => {
// assigns the remaining fields from global config to the user config
userConfigData = Object.assign(userConfigData, pick(globalConfigData, remainingConfig));
resolve(userConfigData);
}).catch((err) => {
reject(err);
});
}
} else {
resolve(userConfigData);
}
}).catch(() => {
// This reads global config if there was any
// error while reading user config
readGlobalConfig().then((config) => {
userConfigData = pick(config, fieldNames);
resolve(userConfigData);
}).catch((err) => {
reject(err);
});
});
});
}
/**
* Clears the cached config
*/
@@ -331,6 +391,7 @@ module.exports = {
updateConfigField,
updateUserConfigWin,
updateUserConfigMac,
getMultipleConfigField,
// items below here are only exported for testing, do NOT use!
saveUserConfig,

View File

@@ -11,6 +11,7 @@ const urlParser = require('url');
// Local Dependencies
const {getConfigField, updateUserConfigWin, updateUserConfigMac} = require('./config.js');
const {setCheckboxValues} = require('./menus/menuTemplate.js');
const { isMac, isDevEnv } = require('./utils/misc.js');
const protocolHandler = require('./protocolHandler');
const getCmdLineArg = require('./utils/getCmdLineArg.js');
@@ -92,7 +93,7 @@ if (isMac) {
* initialization and is ready to create browser windows.
* Some APIs can only be used after this event occurs.
*/
app.on('ready', setupThenOpenMainWindow);
app.on('ready', readConfigThenOpenMainWindow);
/**
* Is triggered when all the windows are closed
@@ -127,6 +128,20 @@ app.on('open-url', function(event, url) {
handleProtocolAction(url);
});
/**
* Reads the config fields that are required for the menu items
* then opens the main window
*
* This is a workaround for the issue where the menu template was returned
* even before the config data was populated
* https://perzoinc.atlassian.net/browse/ELECTRON-154
*/
function readConfigThenOpenMainWindow() {
setCheckboxValues()
.then(setupThenOpenMainWindow)
.catch(setupThenOpenMainWindow)
}
/**
* Sets up the app (to handle various things like config changes, protocol handling etc.)
* and opens the main window

View File

@@ -1,7 +1,7 @@
'use strict';
const electron = require('electron');
const { getConfigField, updateConfigField } = require('../config.js');
const { updateConfigField, getMultipleConfigField } = require('../config.js');
const AutoLaunch = require('auto-launch');
const isMac = require('../utils/misc.js').isMac;
const log = require('../log.js');
@@ -13,8 +13,6 @@ let minimizeOnClose = false;
let launchOnStartup = false;
let isAlwaysOnTop = false;
setCheckboxValues();
let symphonyAutoLauncher;
if (isMac) {
@@ -266,39 +264,42 @@ function getTemplate(app) {
* based on configuration
*/
function setCheckboxValues() {
getConfigField('minimizeOnClose').then(function(mClose) {
minimizeOnClose = mClose;
}).catch(function(err) {
let title = 'Error loading configuration';
log.send(logLevels.ERROR, 'MenuTemplate: error getting config field minimizeOnClose, error: ' + err);
electron.dialog.showErrorBox(title, title + ': ' + err);
return new Promise((resolve) => {
/**
* Method that reads multiple config fields
*/
getMultipleConfigField(['minimizeOnClose', 'launchOnStartup', 'alwaysOnTop', 'notificationSettings'])
.then(function (configData) {
for (let key in configData) {
if (configData.hasOwnProperty(key)) { // eslint-disable-line no-prototype-builtins
switch (key) {
case 'minimizeOnClose':
minimizeOnClose = configData[key];
break;
case 'launchOnStartup':
launchOnStartup = configData[key];
break;
case 'alwaysOnTop':
isAlwaysOnTop = configData[key];
eventEmitter.emit('isAlwaysOnTop', configData[key]);
break;
case 'notificationSettings':
eventEmitter.emit('notificationSettings', configData[key]);
break;
default:
break;
}
}
}
return resolve();
})
.catch((err) => {
let title = 'Error loading configuration';
log.send(logLevels.ERROR, 'MenuTemplate: error reading configuration fields, error: ' + err);
electron.dialog.showErrorBox(title, title + ': ' + err);
return resolve();
});
});
getConfigField('launchOnStartup').then(function(lStartup) {
launchOnStartup = lStartup;
}).catch(function(err) {
let title = 'Error loading configuration';
log.send(logLevels.ERROR, 'MenuTemplate: error getting config field launchOnStartup, error: ' + err);
electron.dialog.showErrorBox(title, title + ': ' + err);
});
getConfigField('alwaysOnTop').then(function(mAlwaysOnTop) {
isAlwaysOnTop = mAlwaysOnTop;
eventEmitter.emit('isAlwaysOnTop', isAlwaysOnTop);
}).catch(function(err) {
let title = 'Error loading configuration';
log.send(logLevels.ERROR, 'MenuTemplate: error getting config field alwaysOnTop, error: ' + err);
electron.dialog.showErrorBox(title, title + ': ' + err);
});
getConfigField('notificationSettings').then(function(notfObject) {
eventEmitter.emit('notificationSettings', notfObject);
}).catch(function(err) {
let title = 'Error loading configuration';
log.send(logLevels.ERROR, 'MenuTemplate: error getting config field notificationSettings, error: ' + err);
electron.dialog.showErrorBox(title, title + ': ' + err);
});
}
function getMinimizeOnClose() {
@@ -307,5 +308,6 @@ function getMinimizeOnClose() {
module.exports = {
getTemplate: getTemplate,
getMinimizeOnClose: getMinimizeOnClose
getMinimizeOnClose: getMinimizeOnClose,
setCheckboxValues: setCheckboxValues
};

View File

@@ -171,7 +171,7 @@ function setup() {
setupConfig();
// if display added/removed/changed then re-run setup and remove all existing
// notifications. ToDo: should reposition notifications rather than closing.
// notifications.
electron.screen.on('display-added', setupConfig);
electron.screen.on('display-removed', setupConfig);
electron.screen.on('display-metrics-changed', setupConfig);
@@ -238,7 +238,6 @@ function calcDimensions() {
* Setup the notification config
*/
function setupConfig() {
closeAll();
// This feature only applies to windows
if (!isMac) {
@@ -694,33 +693,6 @@ function getWindow() {
})
}
/**
* Closes all the notifications and windows
*/
function closeAll() {
// Clear out animation Queue and close windows
animationQueue.clear();
activeNotifications.forEach(function(window) {
if (window.displayTimer) {
clearTimeout(window.displayTimer);
}
if (window.electronNotifyOnCloseFunc) {
// ToDo: fix this: shouldn't delete method on arg
/* eslint-disable */
delete window.electronNotifyOnCloseFunc;
/* eslint-enable */
}
window.close();
});
cleanUpInactiveWindow();
// Reset certain vars
nextInsertPos = {};
activeNotifications = [];
}
/**
* Once a minute, remove inactive windows to free up memory used.
*/

View File

@@ -48,12 +48,15 @@ function updateScreens() {
screens = electron.screen.getAllDisplays();
// Notifying renderer when a display is added/removed
if (configurationWindow && screens && screens.length >= 0) {
configurationWindow.webContents.send('screens', screens);
if (configurationWindow) {
// Event that updates the DOM elements
// notification position checkbox and monitor selection drop-down
configurationWindow.webContents.send('notificationSettings', {position: position, display: display});
if (screens && screens.length >= 0) {
configurationWindow.webContents.send('screens', screens);
}
}
// Event that updates the DOM elements
// notification position checkbox and monitor selection drop-down
configurationWindow.webContents.send('notificationSettings', {position: position, display: display});
}
/**

View File

@@ -41,7 +41,11 @@ let sandboxed = false;
const preloadMainScript = path.join(__dirname, 'preload/_preloadMain.js');
const MIN_WIDTH = 300;
const MIN_HEIGHT = 600;
const MIN_HEIGHT = 300;
// Default window size for pop-out windows
const DEFAULT_WIDTH = 300;
const DEFAULT_HEIGHT = 600;
/**
* Adds a window key
@@ -294,8 +298,8 @@ function doCreateMainWindow(initialUrl, initialBounds) {
let x = 0;
let y = 0;
let width = newWinOptions.width || MIN_WIDTH;
let height = newWinOptions.height || MIN_HEIGHT;
let width = newWinOptions.width || DEFAULT_WIDTH;
let height = newWinOptions.height || DEFAULT_HEIGHT;
// try getting x and y position from query parameters
let query = newWinParsedUrl && querystring.parse(newWinParsedUrl.query);
@@ -324,8 +328,8 @@ function doCreateMainWindow(initialUrl, initialBounds) {
/* eslint-disable no-param-reassign */
newWinOptions.x = x;
newWinOptions.y = y;
newWinOptions.width = Math.max(width, MIN_WIDTH);
newWinOptions.height = Math.max(height, MIN_HEIGHT);
newWinOptions.width = Math.max(width, DEFAULT_WIDTH);
newWinOptions.height = Math.max(height, DEFAULT_HEIGHT);
newWinOptions.minWidth = MIN_WIDTH;
newWinOptions.minHeight = MIN_HEIGHT;
newWinOptions.alwaysOnTop = alwaysOnTop;