mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
Merge branch 'master' into electron-201
This commit is contained in:
commit
94d3a9aa38
@ -16,7 +16,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for='image'>image url:</label>
|
<label for='image'>image url:</label>
|
||||||
<input type='text' id='image' value='https://lh3.googleusercontent.com/-s2PXL6wWMCc/AAAAAAAAAAI/AAAAAAAAAAA/AAomvV2gUNMMeFsOijwVVpihfg_anpKWQA/s32-c-mo/photo.jpg'/>
|
<input type='text' id='image' value='https://avatars0.githubusercontent.com/u/13243259?v=4&s=460'/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for='flash'>flash:</label>
|
<label for='flash'>flash:</label>
|
||||||
|
@ -6,6 +6,7 @@ const path = require('path');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const log = require('../log.js');
|
const log = require('../log.js');
|
||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
const buildNumber = require('../../package.json').buildNumber;
|
||||||
|
|
||||||
let aboutWindow;
|
let aboutWindow;
|
||||||
|
|
||||||
@ -78,6 +79,10 @@ function openAboutWindow(windowName) {
|
|||||||
aboutWindow.show();
|
aboutWindow.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
aboutWindow.webContents.on('did-finish-load', () => {
|
||||||
|
aboutWindow.webContents.send('buildNumber', buildNumber || '0');
|
||||||
|
});
|
||||||
|
|
||||||
aboutWindow.on('close', () => {
|
aboutWindow.on('close', () => {
|
||||||
destroyWindow();
|
destroyWindow();
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const { remote } = require('electron');
|
const { remote, ipcRenderer } = require('electron');
|
||||||
|
|
||||||
renderDom();
|
renderDom();
|
||||||
|
|
||||||
@ -9,13 +9,19 @@ renderDom();
|
|||||||
function renderDom() {
|
function renderDom() {
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
const applicationName = remote.app.getName() || 'Symphony';
|
const applicationName = remote.app.getName() || 'Symphony';
|
||||||
const version = remote.app.getVersion();
|
|
||||||
let appName = document.getElementById('app-name');
|
let appName = document.getElementById('app-name');
|
||||||
let versionText = document.getElementById('version');
|
|
||||||
let copyright = document.getElementById('copyright');
|
let copyright = document.getElementById('copyright');
|
||||||
|
|
||||||
appName.innerHTML = applicationName;
|
appName.innerHTML = applicationName;
|
||||||
versionText.innerHTML = version ? `Version ${version} (${version})` : null;
|
|
||||||
copyright.innerHTML = `Copyright © ${new Date().getFullYear()} ${applicationName}`
|
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';
|
||||||
|
}
|
||||||
|
});
|
91
js/basicAuth/basic-auth.html
Normal file
91
js/basicAuth/basic-auth.html
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Authentication Request</title>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
height: 100%;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
padding-top: 10px;
|
||||||
|
text-align: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hostname {
|
||||||
|
font-size: .9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-spacing: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 200px;
|
||||||
|
height: 20px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<span>Please provide your login credentials for:</span>
|
||||||
|
<span id="hostname" class="hostname">hostname</span>
|
||||||
|
<form id="basicAuth" name="Basic Auth" action="Login">
|
||||||
|
<table class="form">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>User name:</td>
|
||||||
|
<td>
|
||||||
|
<input id="username" name="username" title="Username" required>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Password:</td>
|
||||||
|
<td>
|
||||||
|
<input id="password" type="password" title="Password" required>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="footer">
|
||||||
|
<div class="button-container">
|
||||||
|
<button type="submit" id="login">Log In</button>
|
||||||
|
</div>
|
||||||
|
<div class="button-container">
|
||||||
|
<button id="cancel">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
126
js/basicAuth/index.js
Normal file
126
js/basicAuth/index.js
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const electron = require('electron');
|
||||||
|
const BrowserWindow = electron.BrowserWindow;
|
||||||
|
const ipc = electron.ipcMain;
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const log = require('../log.js');
|
||||||
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
|
||||||
|
let basicAuthWindow;
|
||||||
|
|
||||||
|
const local = {};
|
||||||
|
|
||||||
|
let windowConfig = {
|
||||||
|
width: 360,
|
||||||
|
height: 270,
|
||||||
|
show: false,
|
||||||
|
modal: true,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
titleBarStyle: true,
|
||||||
|
resizable: false,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, 'renderer.js'),
|
||||||
|
sandbox: true,
|
||||||
|
nodeIntegration: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* method to get the HTML template path
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getTemplatePath() {
|
||||||
|
let templatePath = path.join(__dirname, 'basic-auth.html');
|
||||||
|
try {
|
||||||
|
fs.statSync(templatePath).isFile();
|
||||||
|
} catch (err) {
|
||||||
|
log.send(logLevels.ERROR, 'basic-auth: Could not find template ("' + templatePath + '").');
|
||||||
|
}
|
||||||
|
return 'file://' + templatePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the basic auth window for authentication
|
||||||
|
* @param {String} windowName - name of the window upon which this window should show
|
||||||
|
* @param {String} hostname - name of the website that requires authentication
|
||||||
|
* @param {Function} callback
|
||||||
|
*/
|
||||||
|
function openBasicAuthWindow(windowName, hostname, callback) {
|
||||||
|
|
||||||
|
// Register callback function
|
||||||
|
if (typeof callback === 'function') {
|
||||||
|
local.authCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This prevents creating multiple instances of the
|
||||||
|
// basic auth window
|
||||||
|
if (basicAuthWindow) {
|
||||||
|
if (basicAuthWindow.isMinimized()) {
|
||||||
|
basicAuthWindow.restore();
|
||||||
|
}
|
||||||
|
basicAuthWindow.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let allWindows = BrowserWindow.getAllWindows();
|
||||||
|
allWindows = allWindows.find((window) => { return window.winName === windowName });
|
||||||
|
|
||||||
|
// if we couldn't find any window matching the window name
|
||||||
|
// it will render as a new window
|
||||||
|
if (allWindows) {
|
||||||
|
windowConfig.parent = allWindows;
|
||||||
|
}
|
||||||
|
|
||||||
|
basicAuthWindow = new BrowserWindow(windowConfig);
|
||||||
|
basicAuthWindow.setVisibleOnAllWorkspaces(true);
|
||||||
|
basicAuthWindow.loadURL(getTemplatePath());
|
||||||
|
|
||||||
|
// sets the AlwaysOnTop property for the basic auth window
|
||||||
|
// if the main window's AlwaysOnTop is true
|
||||||
|
let focusedWindow = BrowserWindow.getFocusedWindow();
|
||||||
|
if (focusedWindow && focusedWindow.isAlwaysOnTop()) {
|
||||||
|
basicAuthWindow.setAlwaysOnTop(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
basicAuthWindow.once('ready-to-show', () => {
|
||||||
|
basicAuthWindow.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
basicAuthWindow.webContents.on('did-finish-load', () => {
|
||||||
|
basicAuthWindow.webContents.send('hostname', hostname);
|
||||||
|
});
|
||||||
|
|
||||||
|
basicAuthWindow.on('close', () => {
|
||||||
|
destroyWindow();
|
||||||
|
});
|
||||||
|
|
||||||
|
basicAuthWindow.on('closed', () => {
|
||||||
|
destroyWindow();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ipc.on('login', (event, args) => {
|
||||||
|
if (typeof args === 'object' && typeof local.authCallback === 'function') {
|
||||||
|
local.authCallback(args.username, args.password);
|
||||||
|
basicAuthWindow.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.on('close-basic-auth', () => {
|
||||||
|
if (basicAuthWindow) {
|
||||||
|
basicAuthWindow.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a window
|
||||||
|
*/
|
||||||
|
function destroyWindow() {
|
||||||
|
basicAuthWindow = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
openBasicAuthWindow: openBasicAuthWindow
|
||||||
|
};
|
55
js/basicAuth/renderer.js
Normal file
55
js/basicAuth/renderer.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
'use strict';
|
||||||
|
const electron = require('electron');
|
||||||
|
const ipc = electron.ipcRenderer;
|
||||||
|
|
||||||
|
renderDom();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that renders application data
|
||||||
|
*/
|
||||||
|
function renderDom() {
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
loadContent();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadContent() {
|
||||||
|
let basicAuth = document.getElementById('basicAuth');
|
||||||
|
let cancel = document.getElementById('cancel');
|
||||||
|
|
||||||
|
if (basicAuth) {
|
||||||
|
basicAuth.onsubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
submitForm();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cancel) {
|
||||||
|
cancel.addEventListener('click', () => {
|
||||||
|
ipc.send('close-basic-auth');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that gets invoked on submitting the form
|
||||||
|
*/
|
||||||
|
function submitForm() {
|
||||||
|
let username = document.getElementById('username').value;
|
||||||
|
let password = document.getElementById('password').value;
|
||||||
|
|
||||||
|
if (username && password) {
|
||||||
|
ipc.send('login', { username, password });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the hosts name
|
||||||
|
*/
|
||||||
|
ipc.on('hostname', (event, host) => {
|
||||||
|
let hostname = document.getElementById('hostname');
|
||||||
|
|
||||||
|
if (hostname){
|
||||||
|
hostname.innerHTML = host || 'unknown';
|
||||||
|
}
|
||||||
|
});
|
61
js/config.js
61
js/config.js
@ -6,6 +6,8 @@ const path = require('path');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const AppDirectory = require('appdirectory');
|
const AppDirectory = require('appdirectory');
|
||||||
const omit = require('lodash.omit');
|
const omit = require('lodash.omit');
|
||||||
|
const pick = require('lodash.pick');
|
||||||
|
const difference = require('lodash.difference');
|
||||||
|
|
||||||
const isDevEnv = require('./utils/misc.js').isDevEnv;
|
const isDevEnv = require('./utils/misc.js').isDevEnv;
|
||||||
const isMac = require('./utils/misc.js').isMac;
|
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
|
* Clears the cached config
|
||||||
*/
|
*/
|
||||||
@ -331,6 +391,7 @@ module.exports = {
|
|||||||
updateConfigField,
|
updateConfigField,
|
||||||
updateUserConfigWin,
|
updateUserConfigWin,
|
||||||
updateUserConfigMac,
|
updateUserConfigMac,
|
||||||
|
getMultipleConfigField,
|
||||||
|
|
||||||
// items below here are only exported for testing, do NOT use!
|
// items below here are only exported for testing, do NOT use!
|
||||||
saveUserConfig,
|
saveUserConfig,
|
||||||
|
25
js/dialogs/showBasicAuth.js
Normal file
25
js/dialogs/showBasicAuth.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const electron = require('electron');
|
||||||
|
|
||||||
|
const basicAuth = require('../basicAuth');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Having a proxy or hosts that requires authentication will allow user to
|
||||||
|
* enter their credentials 'username' & 'password'
|
||||||
|
*/
|
||||||
|
electron.app.on('login', (event, webContents, request, authInfo, callback) => {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// name of the host to display
|
||||||
|
let hostname = authInfo.host || authInfo.realm;
|
||||||
|
let browserWin = electron.BrowserWindow.fromWebContents(webContents);
|
||||||
|
let windowName = browserWin.winName || '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens an electron modal window in which
|
||||||
|
* user can enter credentials fot the host
|
||||||
|
*/
|
||||||
|
basicAuth.openBasicAuthWindow(windowName, hostname, callback);
|
||||||
|
});
|
17
js/main.js
17
js/main.js
@ -11,6 +11,7 @@ const urlParser = require('url');
|
|||||||
|
|
||||||
// Local Dependencies
|
// Local Dependencies
|
||||||
const {getConfigField, updateUserConfigWin, updateUserConfigMac} = require('./config.js');
|
const {getConfigField, updateUserConfigWin, updateUserConfigMac} = require('./config.js');
|
||||||
|
const {setCheckboxValues} = require('./menus/menuTemplate.js');
|
||||||
const { isMac, isDevEnv } = require('./utils/misc.js');
|
const { isMac, isDevEnv } = require('./utils/misc.js');
|
||||||
const protocolHandler = require('./protocolHandler');
|
const protocolHandler = require('./protocolHandler');
|
||||||
const getCmdLineArg = require('./utils/getCmdLineArg.js');
|
const getCmdLineArg = require('./utils/getCmdLineArg.js');
|
||||||
@ -92,7 +93,7 @@ if (isMac) {
|
|||||||
* initialization and is ready to create browser windows.
|
* initialization and is ready to create browser windows.
|
||||||
* Some APIs can only be used after this event occurs.
|
* 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
|
* Is triggered when all the windows are closed
|
||||||
@ -127,6 +128,20 @@ app.on('open-url', function(event, url) {
|
|||||||
handleProtocolAction(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.)
|
* Sets up the app (to handle various things like config changes, protocol handling etc.)
|
||||||
* and opens the main window
|
* and opens the main window
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
const { getConfigField, updateConfigField } = require('../config.js');
|
const { updateConfigField, getMultipleConfigField } = require('../config.js');
|
||||||
const AutoLaunch = require('auto-launch');
|
const AutoLaunch = require('auto-launch');
|
||||||
const isMac = require('../utils/misc.js').isMac;
|
const isMac = require('../utils/misc.js').isMac;
|
||||||
const log = require('../log.js');
|
const log = require('../log.js');
|
||||||
@ -13,8 +13,6 @@ let minimizeOnClose = false;
|
|||||||
let launchOnStartup = false;
|
let launchOnStartup = false;
|
||||||
let isAlwaysOnTop = false;
|
let isAlwaysOnTop = false;
|
||||||
|
|
||||||
setCheckboxValues();
|
|
||||||
|
|
||||||
let symphonyAutoLauncher;
|
let symphonyAutoLauncher;
|
||||||
|
|
||||||
if (isMac) {
|
if (isMac) {
|
||||||
@ -266,39 +264,42 @@ function getTemplate(app) {
|
|||||||
* based on configuration
|
* based on configuration
|
||||||
*/
|
*/
|
||||||
function setCheckboxValues() {
|
function setCheckboxValues() {
|
||||||
getConfigField('minimizeOnClose').then(function(mClose) {
|
return new Promise((resolve) => {
|
||||||
minimizeOnClose = mClose;
|
/**
|
||||||
}).catch(function(err) {
|
* 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';
|
let title = 'Error loading configuration';
|
||||||
log.send(logLevels.ERROR, 'MenuTemplate: error getting config field minimizeOnClose, error: ' + err);
|
log.send(logLevels.ERROR, 'MenuTemplate: error reading configuration fields, error: ' + err);
|
||||||
electron.dialog.showErrorBox(title, title + ': ' + 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() {
|
function getMinimizeOnClose() {
|
||||||
@ -307,5 +308,6 @@ function getMinimizeOnClose() {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getTemplate: getTemplate,
|
getTemplate: getTemplate,
|
||||||
getMinimizeOnClose: getMinimizeOnClose
|
getMinimizeOnClose: getMinimizeOnClose,
|
||||||
|
setCheckboxValues: setCheckboxValues
|
||||||
};
|
};
|
BIN
js/notify/assets/symphony-logo-black.png
Normal file
BIN
js/notify/assets/symphony-logo-black.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
js/notify/assets/symphony-logo-white.png
Normal file
BIN
js/notify/assets/symphony-logo-white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
@ -9,6 +9,8 @@
|
|||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
const ipc = electron.ipcRenderer;
|
const ipc = electron.ipcRenderer;
|
||||||
|
|
||||||
|
const whiteColorRegExp = new RegExp(/^(?:white|#fff(?:fff)?|rgba?\(\s*255\s*,\s*255\s*,\s*255\s*(?:,\s*1\s*)?\))$/i);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets style for a notification
|
* Sets style for a notification
|
||||||
* @param config
|
* @param config
|
||||||
@ -19,7 +21,9 @@ function setStyle(config) {
|
|||||||
let container = notiDoc.getElementById('container');
|
let container = notiDoc.getElementById('container');
|
||||||
let header = notiDoc.getElementById('header');
|
let header = notiDoc.getElementById('header');
|
||||||
let image = notiDoc.getElementById('image');
|
let image = notiDoc.getElementById('image');
|
||||||
|
let logo = notiDoc.getElementById('symphony-logo');
|
||||||
let title = notiDoc.getElementById('title');
|
let title = notiDoc.getElementById('title');
|
||||||
|
let pod = notiDoc.getElementById('pod');
|
||||||
let message = notiDoc.getElementById('message');
|
let message = notiDoc.getElementById('message');
|
||||||
let close = notiDoc.getElementById('close');
|
let close = notiDoc.getElementById('close');
|
||||||
|
|
||||||
@ -37,8 +41,12 @@ function setStyle(config) {
|
|||||||
|
|
||||||
setStyleOnDomElement(config.defaultStyleImage, image);
|
setStyleOnDomElement(config.defaultStyleImage, image);
|
||||||
|
|
||||||
|
setStyleOnDomElement(config.defaultStyleLogo, logo);
|
||||||
|
|
||||||
setStyleOnDomElement(config.defaultStyleTitle, title);
|
setStyleOnDomElement(config.defaultStyleTitle, title);
|
||||||
|
|
||||||
|
setStyleOnDomElement(config.defaultStylePod, pod);
|
||||||
|
|
||||||
setStyleOnDomElement(config.defaultStyleText, message);
|
setStyleOnDomElement(config.defaultStyleText, message);
|
||||||
|
|
||||||
setStyleOnDomElement(config.defaultStyleClose, close);
|
setStyleOnDomElement(config.defaultStyleClose, close);
|
||||||
@ -75,6 +83,20 @@ function setContents(event, notificationObj) {
|
|||||||
|
|
||||||
if (notificationObj.color) {
|
if (notificationObj.color) {
|
||||||
container.style.backgroundColor = notificationObj.color;
|
container.style.backgroundColor = notificationObj.color;
|
||||||
|
let logo = notiDoc.getElementById('symphony-logo');
|
||||||
|
|
||||||
|
if (notificationObj.color.match(whiteColorRegExp)) {
|
||||||
|
logo.src = './assets/symphony-logo-black.png';
|
||||||
|
} else {
|
||||||
|
let title = notiDoc.getElementById('title');
|
||||||
|
let pod = notiDoc.getElementById('pod');
|
||||||
|
let message = notiDoc.getElementById('message');
|
||||||
|
|
||||||
|
message.style.color = '#ffffff';
|
||||||
|
title.style.color = '#ffffff';
|
||||||
|
pod.style.color = notificationObj.color;
|
||||||
|
logo.src = './assets/symphony-logo-white.png';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notificationObj.flash) {
|
if (notificationObj.flash) {
|
||||||
|
@ -2,11 +2,17 @@
|
|||||||
<head></head>
|
<head></head>
|
||||||
<body style='margin:0; overflow: hidden; -webkit-user-select: none;'>
|
<body style='margin:0; overflow: hidden; -webkit-user-select: none;'>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<div id="header">
|
<div>
|
||||||
<img src="" id="image" />
|
<img src="" id="symphony-logo">
|
||||||
<span id="title"></span>
|
</div>
|
||||||
|
<div id="header">
|
||||||
|
<span id="title"></span>
|
||||||
|
<span id="pod"></span>
|
||||||
|
<span id="message"></span>
|
||||||
|
</div>
|
||||||
|
<div id="picture">
|
||||||
|
<img src="" id="image" style="border-radius: 4px" />
|
||||||
</div>
|
</div>
|
||||||
<p id="message"></p>
|
|
||||||
<div id="close">
|
<div id="close">
|
||||||
<svg fill="#000000" height="16" viewBox="0 0 24 24" width="16" xmlns="http://www.w3.org/2000/svg">
|
<svg fill="#000000" height="16" viewBox="0 0 24 24" width="16" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path>
|
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path>
|
||||||
|
@ -55,9 +55,9 @@ let config = {
|
|||||||
// corner to put notifications
|
// corner to put notifications
|
||||||
// upper-right, upper-left, lower-right, lower-left
|
// upper-right, upper-left, lower-right, lower-left
|
||||||
startCorner: 'upper-right',
|
startCorner: 'upper-right',
|
||||||
width: 300,
|
width: 380,
|
||||||
height: 80,
|
height: 70,
|
||||||
borderRadius: 2,
|
borderRadius: 5,
|
||||||
displayTime: 5000,
|
displayTime: 5000,
|
||||||
animationSteps: 5,
|
animationSteps: 5,
|
||||||
animationStepMs: 5,
|
animationStepMs: 5,
|
||||||
@ -67,63 +67,66 @@ let config = {
|
|||||||
defaultStyleContainer: {
|
defaultStyleContainer: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
flexDirection: 'column',
|
|
||||||
backgroundColor: '#f0f0f0',
|
backgroundColor: '#f0f0f0',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
padding: 10,
|
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
lineHeight: '15px',
|
lineHeight: '15px',
|
||||||
boxSizing: 'border-box'
|
boxSizing: 'border-box'
|
||||||
},
|
},
|
||||||
defaultStyleHeader: {
|
defaultStyleHeader: {
|
||||||
flex: '0 0 auto',
|
width: 245,
|
||||||
display: 'flex',
|
minWidth: 230,
|
||||||
flexDirection: 'row'
|
margin: "12px 10px"
|
||||||
},
|
},
|
||||||
defaultStyleImage: {
|
defaultStyleImage: {
|
||||||
flex: '0 0 auto',
|
height: 43,
|
||||||
overflow: 'hidden',
|
borderRadius: 4,
|
||||||
height: 30,
|
marginTop: 12,
|
||||||
width: 30,
|
width: 43
|
||||||
marginLeft: 0,
|
|
||||||
marginRight: 8
|
|
||||||
},
|
},
|
||||||
defaultStyleClose: {
|
defaultStyleClose: {
|
||||||
position: 'absolute',
|
|
||||||
top: 8,
|
|
||||||
right: 8,
|
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
|
margin: "10px 8px 0 8px",
|
||||||
opacity: 0.54,
|
opacity: 0.54,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: '#CCC'
|
color: '#CCC'
|
||||||
},
|
},
|
||||||
defaultStyleTitle: {
|
defaultStyleTitle: {
|
||||||
fontFamily: 'Arial',
|
fontFamily: 'sans-serif',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
opacity: 0.87,
|
color: '#4a4a4a',
|
||||||
marginRight: 10,
|
|
||||||
alignSelf: 'center',
|
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
display: '-webkit-box',
|
display: '-webkit-box',
|
||||||
webkitLineClamp: 2,
|
webkitLineClamp: 1,
|
||||||
|
webkitBoxOrient: 'vertical',
|
||||||
|
},
|
||||||
|
defaultStylePod: {
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
fontSize: 11,
|
||||||
|
color: '#adadad',
|
||||||
|
overflow: 'hidden',
|
||||||
|
filter: 'brightness(70%)',
|
||||||
|
display: '-webkit-box',
|
||||||
|
webkitLineClamp: 1,
|
||||||
webkitBoxOrient: 'vertical',
|
webkitBoxOrient: 'vertical',
|
||||||
},
|
},
|
||||||
defaultStyleText: {
|
defaultStyleText: {
|
||||||
flex: '0 0 auto',
|
fontFamily: 'sans-serif',
|
||||||
fontFamily: 'Calibri',
|
fontSize: 12,
|
||||||
fontSize: 14,
|
color: '#4a4a4a',
|
||||||
fontWeight: 400,
|
marginTop: 12,
|
||||||
opacity: 0.87,
|
|
||||||
margin: 0,
|
|
||||||
marginTop: 4,
|
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
display: '-webkit-box',
|
display: '-webkit-box',
|
||||||
webkitLineClamp: 2,
|
webkitLineClamp: 1,
|
||||||
webkitBoxOrient: 'vertical',
|
webkitBoxOrient: 'vertical',
|
||||||
cursor: 'default'
|
cursor: 'default'
|
||||||
},
|
},
|
||||||
|
defaultStyleLogo: {
|
||||||
|
margin: "12px 0 0 -12px",
|
||||||
|
opacity: 0.6,
|
||||||
|
},
|
||||||
defaultWindow: {
|
defaultWindow: {
|
||||||
alwaysOnTop: true,
|
alwaysOnTop: true,
|
||||||
skipTaskbar: true,
|
skipTaskbar: true,
|
||||||
|
@ -23,6 +23,7 @@ const { isMac, isNodeEnv } = require('./utils/misc');
|
|||||||
|
|
||||||
// show dialog when certificate errors occur
|
// show dialog when certificate errors occur
|
||||||
require('./dialogs/showCertError.js');
|
require('./dialogs/showCertError.js');
|
||||||
|
require('./dialogs/showBasicAuth.js');
|
||||||
|
|
||||||
// Keep a global reference of the window object, if you don't, the window will
|
// Keep a global reference of the window object, if you don't, the window will
|
||||||
// be closed automatically when the JavaScript object is garbage collected.
|
// be closed automatically when the JavaScript object is garbage collected.
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Symphony",
|
"name": "Symphony",
|
||||||
"productName": "Symphony",
|
"productName": "Symphony",
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
|
"buildNumber": "",
|
||||||
"description": "Symphony desktop app (Foundation ODP)",
|
"description": "Symphony desktop app (Foundation ODP)",
|
||||||
"author": "Symphony",
|
"author": "Symphony",
|
||||||
"main": "js/main.js",
|
"main": "js/main.js",
|
||||||
@ -104,6 +105,8 @@
|
|||||||
"filesize": "^3.5.10",
|
"filesize": "^3.5.10",
|
||||||
"keymirror": "0.1.1",
|
"keymirror": "0.1.1",
|
||||||
"lodash.omit": "^4.5.0",
|
"lodash.omit": "^4.5.0",
|
||||||
|
"lodash.pick": "^4.4.0",
|
||||||
|
"lodash.difference": "^4.5.0",
|
||||||
"winreg": "^1.2.3"
|
"winreg": "^1.2.3"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
Loading…
Reference in New Issue
Block a user