mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
ELECTRON-635 (Custom auto launch implementation)[Windows] (#484)
* ELECTRON-635: add support for auto launch custom path * ELECTRON-635 - autolaunch aip testing * ELECTRON-635 - Add quot * ELECTRON-635 - Escape quot * ELECTRON-635 - Escape quot * ELECTRON-635 - Fix escape auto launch path * ELECTRON-635 - Fix escape auto launch path * ELECTRON-635 - Fix escape auto launch path * ELECTRON-635 - add empty property to the AUTO_LAUNCH_PATH property * ELECTRON-635 - final fix for auto launch * ELECTRON-635 - Fix auto launch issue * ELECTRON-635 - Fix path escape * ELECTRON-635 - Fix first time launch * ELECTRON-635 - Mock app.getVersion * ELECTRON-635 - Fix per user app path
This commit is contained in:
committed by
Vishwas Shashidhar
parent
0d04ac03e2
commit
274f4811f0
@@ -31,5 +31,6 @@
|
|||||||
"pointerLock": true,
|
"pointerLock": true,
|
||||||
"fullscreen": true,
|
"fullscreen": true,
|
||||||
"openExternal": true
|
"openExternal": true
|
||||||
}
|
},
|
||||||
|
"autoLaunchPath": ""
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
60
js/autoLaunch/index.js
Normal file
60
js/autoLaunch/index.js
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
const AutoLaunch = require('auto-launch');
|
||||||
|
|
||||||
|
// Local Dependencies
|
||||||
|
const log = require('../log.js');
|
||||||
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
const { readConfigFileSync } = require('../config.js');
|
||||||
|
const { isMac } = require('../utils/misc.js');
|
||||||
|
|
||||||
|
const globalConfigData = readConfigFileSync();
|
||||||
|
const props = isMac ? {
|
||||||
|
name: 'Symphony',
|
||||||
|
mac: {
|
||||||
|
useLaunchAgent: true,
|
||||||
|
},
|
||||||
|
path: process.execPath,
|
||||||
|
} : {
|
||||||
|
name: 'Symphony',
|
||||||
|
path: getAutoLaunchPath() || process.execPath,
|
||||||
|
};
|
||||||
|
|
||||||
|
class AutoLaunchController extends AutoLaunch {
|
||||||
|
|
||||||
|
constructor(opts) {
|
||||||
|
super(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable auto launch
|
||||||
|
* @return {Promise<void>}
|
||||||
|
*/
|
||||||
|
enableAutoLaunch() {
|
||||||
|
log.send(logLevels.INFO, `Enabling auto launch!`);
|
||||||
|
return this.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable auto launch
|
||||||
|
* @return {Promise<void>}
|
||||||
|
*/
|
||||||
|
disableAutoLaunch() {
|
||||||
|
log.send(logLevels.INFO, `Disabling auto launch!`);
|
||||||
|
return this.disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace forward slash in the path to backward slash
|
||||||
|
* @return {any}
|
||||||
|
*/
|
||||||
|
function getAutoLaunchPath() {
|
||||||
|
const autoLaunchPath = globalConfigData && globalConfigData.autoLaunchPath || null;
|
||||||
|
return autoLaunchPath ? autoLaunchPath.replace(/\//g, '\\') : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const autoLaunchInstance = new AutoLaunchController(props);
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
enable: autoLaunchInstance.enableAutoLaunch.bind(autoLaunchInstance),
|
||||||
|
disable: autoLaunchInstance.disableAutoLaunch.bind(autoLaunchInstance)
|
||||||
|
};
|
||||||
62
js/config.js
62
js/config.js
@@ -76,9 +76,7 @@ function getUserConfigField(fieldName) {
|
|||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
function readUserConfig(customConfigPath) {
|
function readUserConfig(customConfigPath) {
|
||||||
|
|
||||||
log.send(logLevels.INFO, `custom config path ${customConfigPath}`);
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
if (userConfig) {
|
if (userConfig) {
|
||||||
@@ -197,7 +195,7 @@ function updateConfigField(fieldName, newValue) {
|
|||||||
// add configVersion - just in case in future we need to provide
|
// add configVersion - just in case in future we need to provide
|
||||||
// upgrade capabilities.
|
// upgrade capabilities.
|
||||||
return saveUserConfig(fieldName, newValue, {
|
return saveUserConfig(fieldName, newValue, {
|
||||||
configVersion: '1.0.0'
|
configVersion: app.getVersion().toString(),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -258,14 +256,18 @@ function updateUserConfig(oldUserConfig) {
|
|||||||
userConfigFile = path.join(app.getPath('userData'), configFileName);
|
userConfigFile = path.join(app.getPath('userData'), configFileName);
|
||||||
|
|
||||||
if (!userConfigFile) {
|
if (!userConfigFile) {
|
||||||
return reject(`user config file doesn't exist`);
|
reject(`user config file doesn't exist`);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write the new user config changes to the user config file
|
// write the new user config changes to the user config file
|
||||||
fs.writeFileSync(userConfigFile, newUserConfigString, 'utf-8');
|
fs.writeFile(userConfigFile, newUserConfigString, 'utf-8', (err) => {
|
||||||
|
if (err) {
|
||||||
return resolve();
|
reject(`Failed to update user config error: ${err}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -275,33 +277,27 @@ function updateUserConfig(oldUserConfig) {
|
|||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
function updateUserConfigOnLaunch() {
|
function updateUserConfigOnLaunch() {
|
||||||
|
// we get the user config path using electron
|
||||||
|
const userConfigFile = path.join(app.getPath('userData'), configFileName);
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
// if it's not a per user installation or if the
|
||||||
|
// user config file doesn't exist, we simple move on
|
||||||
|
if (!fs.existsSync(userConfigFile)) {
|
||||||
|
log.send(logLevels.WARN, 'config: Could not find the user config file!');
|
||||||
|
return Promise.reject('config: Could not find the user config file!');
|
||||||
|
}
|
||||||
|
|
||||||
// we get the user config path using electron
|
// In case the file exists, we remove it so that all the
|
||||||
const userConfigFile = path.join(app.getPath('userData'), configFileName);
|
// values are fetched from the global config
|
||||||
|
// https://perzoinc.atlassian.net/browse/ELECTRON-126
|
||||||
// if it's not a per user installation or if the
|
return readUserConfig(userConfigFile).then((data) => {
|
||||||
// user config file doesn't exist, we simple move on
|
// Add version info to the user config data
|
||||||
if (!fs.existsSync(userConfigFile)) {
|
const version = app.getVersion().toString() || '1.0.0';
|
||||||
log.send(logLevels.WARN, 'config: Could not find the user config file!');
|
const updatedData = Object.assign(data || {}, { configVersion: version });
|
||||||
reject();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// In case the file exists, we remove it so that all the
|
|
||||||
// values are fetched from the global config
|
|
||||||
// https://perzoinc.atlassian.net/browse/ELECTRON-126
|
|
||||||
readUserConfig(userConfigFile).then((data) => {
|
|
||||||
// Add version info to the user config data
|
|
||||||
const version = app.getVersion().toString();
|
|
||||||
const updatedData = Object.assign(data, { version });
|
|
||||||
|
|
||||||
resolve(updateUserConfig(updatedData));
|
|
||||||
}).catch((err) => {
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
return updateUserConfig(updatedData);
|
||||||
|
}).catch((err) => {
|
||||||
|
return Promise.reject(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
84
js/main.js
84
js/main.js
@@ -7,7 +7,6 @@ const crashReporter = electron.crashReporter;
|
|||||||
const nodeURL = require('url');
|
const nodeURL = require('url');
|
||||||
const shellPath = require('shell-path');
|
const shellPath = require('shell-path');
|
||||||
const squirrelStartup = require('electron-squirrel-startup');
|
const squirrelStartup = require('electron-squirrel-startup');
|
||||||
const AutoLaunch = require('auto-launch');
|
|
||||||
const urlParser = require('url');
|
const urlParser = require('url');
|
||||||
const nodePath = require('path');
|
const nodePath = require('path');
|
||||||
const compareSemVersions = require('./utils/compareSemVersions.js');
|
const compareSemVersions = require('./utils/compareSemVersions.js');
|
||||||
@@ -15,7 +14,6 @@ const compareSemVersions = require('./utils/compareSemVersions.js');
|
|||||||
// Local Dependencies
|
// Local Dependencies
|
||||||
const {
|
const {
|
||||||
getConfigField,
|
getConfigField,
|
||||||
getGlobalConfigField,
|
|
||||||
readConfigFileSync,
|
readConfigFileSync,
|
||||||
updateUserConfigOnLaunch,
|
updateUserConfigOnLaunch,
|
||||||
getUserConfigField
|
getUserConfigField
|
||||||
@@ -26,6 +24,7 @@ const protocolHandler = require('./protocolHandler');
|
|||||||
const getCmdLineArg = require('./utils/getCmdLineArg.js');
|
const getCmdLineArg = require('./utils/getCmdLineArg.js');
|
||||||
const log = require('./log.js');
|
const log = require('./log.js');
|
||||||
const logLevels = require('./enums/logLevels.js');
|
const logLevels = require('./enums/logLevels.js');
|
||||||
|
const autoLaunch = require('./autoLaunch');
|
||||||
|
|
||||||
require('electron-dl')();
|
require('electron-dl')();
|
||||||
|
|
||||||
@@ -95,23 +94,6 @@ if (!allowMultiInstance && shouldQuit) {
|
|||||||
app.quit();
|
app.quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
let symphonyAutoLauncher;
|
|
||||||
|
|
||||||
if (isMac) {
|
|
||||||
symphonyAutoLauncher = new AutoLaunch({
|
|
||||||
name: 'Symphony',
|
|
||||||
mac: {
|
|
||||||
useLaunchAgent: true,
|
|
||||||
},
|
|
||||||
path: process.execPath,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
symphonyAutoLauncher = new AutoLaunch({
|
|
||||||
name: 'Symphony',
|
|
||||||
path: process.execPath,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets chrome authentication flags in electron
|
* Sets chrome authentication flags in electron
|
||||||
*/
|
*/
|
||||||
@@ -204,7 +186,8 @@ setChromeFlags();
|
|||||||
*/
|
*/
|
||||||
app.on('ready', () => {
|
app.on('ready', () => {
|
||||||
checkFirstTimeLaunch()
|
checkFirstTimeLaunch()
|
||||||
.then(readConfigThenOpenMainWindow);
|
.then(readConfigThenOpenMainWindow)
|
||||||
|
.catch(readConfigThenOpenMainWindow);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -282,31 +265,24 @@ function setupThenOpenMainWindow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function checkFirstTimeLaunch() {
|
function checkFirstTimeLaunch() {
|
||||||
|
return getUserConfigField('configVersion')
|
||||||
|
.then((configVersion) => {
|
||||||
|
const appVersionString = app.getVersion().toString();
|
||||||
|
const execPath = nodePath.dirname(app.getPath('exe'));
|
||||||
|
const shouldUpdateUserConfig = execPath.indexOf('AppData\\Local\\Programs') !== -1 || isMac;
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
if (!(configVersion
|
||||||
|
&& typeof configVersion === 'string'
|
||||||
getUserConfigField('version')
|
&& (compareSemVersions.check(appVersionString, configVersion) !== 1)) && shouldUpdateUserConfig) {
|
||||||
.then((configVersion) => {
|
|
||||||
|
|
||||||
const appVersionString = app.getVersion().toString();
|
|
||||||
|
|
||||||
const execPath = nodePath.dirname(app.getPath('exe'));
|
|
||||||
const shouldUpdateUserConfig = execPath.indexOf('AppData/Local/Programs') !== -1 || isMac;
|
|
||||||
|
|
||||||
if (!(configVersion
|
|
||||||
&& typeof configVersion === 'string'
|
|
||||||
&& (compareSemVersions.check(appVersionString, configVersion) !== 1)) && shouldUpdateUserConfig) {
|
|
||||||
return setupFirstTimeLaunch();
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolve();
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
return setupFirstTimeLaunch();
|
return setupFirstTimeLaunch();
|
||||||
});
|
}
|
||||||
return resolve();
|
log.send(logLevels.INFO, `not a first-time launch as
|
||||||
});
|
configVersion: ${configVersion} appVersion: ${appVersionString} shouldUpdateUserConfig: ${shouldUpdateUserConfig}`);
|
||||||
|
return Promise.resolve();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
return setupFirstTimeLaunch();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -316,20 +292,10 @@ function checkFirstTimeLaunch() {
|
|||||||
* @return {Promise<any>}
|
* @return {Promise<any>}
|
||||||
*/
|
*/
|
||||||
function setupFirstTimeLaunch() {
|
function setupFirstTimeLaunch() {
|
||||||
return new Promise(resolve => {
|
log.send(logLevels.INFO, 'setting first time launch config');
|
||||||
log.send(logLevels.INFO, 'setting first time launch config');
|
return getConfigField('launchOnStartup')
|
||||||
getGlobalConfigField('launchOnStartup')
|
.then(setStartup)
|
||||||
.then(setStartup)
|
.then(updateUserConfigOnLaunch);
|
||||||
.then(updateUserConfigOnLaunch)
|
|
||||||
.then(() => {
|
|
||||||
log.send(logLevels.INFO, 'first time launch config changes succeeded -> ');
|
|
||||||
return resolve();
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
log.send(logLevels.ERROR, 'first time launch config changes failed -> ' + err);
|
|
||||||
return resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -344,10 +310,10 @@ function setStartup(lStartup) {
|
|||||||
log.send(logLevels.INFO, `launchOnStartup value is ${launchOnStartup}`);
|
log.send(logLevels.INFO, `launchOnStartup value is ${launchOnStartup}`);
|
||||||
if (launchOnStartup) {
|
if (launchOnStartup) {
|
||||||
log.send(logLevels.INFO, `enabling launch on startup`);
|
log.send(logLevels.INFO, `enabling launch on startup`);
|
||||||
symphonyAutoLauncher.enable();
|
autoLaunch.enable();
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
symphonyAutoLauncher.disable();
|
autoLaunch.disable();
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const AutoLaunch = require('auto-launch');
|
|
||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
|
|
||||||
const { updateConfigField, getMultipleConfigField } = require('../config.js');
|
const { updateConfigField, getMultipleConfigField } = require('../config.js');
|
||||||
@@ -13,6 +12,7 @@ const eventEmitter = require('../eventEmitter');
|
|||||||
const aboutApp = require('../aboutApp');
|
const aboutApp = require('../aboutApp');
|
||||||
const titleBarStyles = require('../enums/titleBarStyles');
|
const titleBarStyles = require('../enums/titleBarStyles');
|
||||||
const i18n = require('../translation/i18n');
|
const i18n = require('../translation/i18n');
|
||||||
|
const autoLaunch = require('../autoLaunch');
|
||||||
|
|
||||||
const configFields = [
|
const configFields = [
|
||||||
'minimizeOnClose',
|
'minimizeOnClose',
|
||||||
@@ -31,8 +31,6 @@ let bringToFront = false;
|
|||||||
let memoryRefresh = false;
|
let memoryRefresh = false;
|
||||||
let titleBarStyle = titleBarStyles.CUSTOM;
|
let titleBarStyle = titleBarStyles.CUSTOM;
|
||||||
|
|
||||||
let symphonyAutoLauncher;
|
|
||||||
|
|
||||||
const windowsAccelerator = Object.assign({
|
const windowsAccelerator = Object.assign({
|
||||||
undo: 'Ctrl+Z',
|
undo: 'Ctrl+Z',
|
||||||
redo: 'Ctrl+Y',
|
redo: 'Ctrl+Y',
|
||||||
@@ -49,21 +47,6 @@ const windowsAccelerator = Object.assign({
|
|||||||
close: 'Ctrl+W',
|
close: 'Ctrl+W',
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isMac) {
|
|
||||||
symphonyAutoLauncher = new AutoLaunch({
|
|
||||||
name: 'Symphony',
|
|
||||||
mac: {
|
|
||||||
useLaunchAgent: true,
|
|
||||||
},
|
|
||||||
path: process.execPath,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
symphonyAutoLauncher = new AutoLaunch({
|
|
||||||
name: 'Symphony',
|
|
||||||
path: process.execPath,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTemplate(app) {
|
function getTemplate(app) {
|
||||||
|
|
||||||
const template = [{
|
const template = [{
|
||||||
@@ -306,7 +289,7 @@ function getTemplate(app) {
|
|||||||
checked: launchOnStartup,
|
checked: launchOnStartup,
|
||||||
click: function (item, focusedWindow) {
|
click: function (item, focusedWindow) {
|
||||||
if (item.checked) {
|
if (item.checked) {
|
||||||
symphonyAutoLauncher.enable()
|
autoLaunch.enable()
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
let title = 'Error setting AutoLaunch configuration';
|
let title = 'Error setting AutoLaunch configuration';
|
||||||
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
||||||
@@ -319,7 +302,7 @@ function getTemplate(app) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
symphonyAutoLauncher.disable()
|
autoLaunch.disable()
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
let title = 'Error setting AutoLaunch configuration';
|
let title = 'Error setting AutoLaunch configuration';
|
||||||
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class TitleBar {
|
|||||||
this.closeButton = document.getElementById('title-bar-close-button');
|
this.closeButton = document.getElementById('title-bar-close-button');
|
||||||
|
|
||||||
this.initiateEventListeners();
|
this.initiateEventListeners();
|
||||||
|
|
||||||
this.updateTitleBar(this.window.isFullScreen());
|
this.updateTitleBar(this.window.isFullScreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,16 @@ let userConfigDir;
|
|||||||
jest.mock('electron', function() {
|
jest.mock('electron', function() {
|
||||||
return {
|
return {
|
||||||
app: {
|
app: {
|
||||||
getPath: mockedGetPath
|
getPath: mockedGetPath,
|
||||||
|
getVersion: mockedGetVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function mockedGetVersion() {
|
||||||
|
return '3.1.0';
|
||||||
|
}
|
||||||
|
|
||||||
function mockedGetPath(type) {
|
function mockedGetPath(type) {
|
||||||
if (type === 'exe') {
|
if (type === 'exe') {
|
||||||
return globalConfigDir;
|
return globalConfigDir;
|
||||||
|
|||||||
Reference in New Issue
Block a user