SymphonyElectron/js/preload/preloadMain.js

162 lines
4.5 KiB
JavaScript
Raw Normal View History

2017-02-14 19:44:15 -06:00
'use strict';
2017-02-10 20:20:09 -06:00
// script run before others and still has access to node integration, even
2017-02-13 18:31:42 -06:00
// when turned off - allows us to leak only what want into window object.
2017-02-10 20:20:09 -06:00
// see: http://electron.atom.io/docs/api/browser-window/
//
// to leak some node module into:
// https://medium.com/@leonli/securing-embedded-external-content-in-electron-node-js-8b6ef665cd8e#.fex4e68p7
// https://slack.engineering/building-hybrid-applications-with-electron-dc67686de5fb#.tp6zz1nrk
//
// also to bring pieces of node.js:
// https://github.com/electron/electron/issues/2984
//
2017-04-03 18:50:35 -05:00
const { ipcRenderer, remote } = require('electron');
2017-02-10 20:20:09 -06:00
2017-03-09 12:12:28 -06:00
const throttle = require('../utils/throttle.js');
2017-03-07 16:44:31 -06:00
const apiEnums = require('../enums/api.js');
const apiCmds = apiEnums.cmds;
const apiName = apiEnums.apiName;
2017-02-10 20:20:09 -06:00
// hold ref so doesn't get GC'ed
const local = {
ipcRenderer: ipcRenderer,
2017-02-13 18:31:42 -06:00
};
2017-02-10 20:20:09 -06:00
2017-04-03 18:50:35 -05:00
var notify = remote.require('./notify/notifyImpl.js');
2017-03-09 12:12:28 -06:00
// throttle calls to this func to at most once per sec, called on leading edge.
const throttledSetBadgeCount = throttle(1000, function(count) {
local.ipcRenderer.send(apiName, {
cmd: apiCmds.setBadgeCount,
count: count
});
});
2017-03-07 16:44:31 -06:00
//
// API exposed to renderer main window process.
//
2017-02-13 11:04:16 -06:00
window.SYM_API = {
2017-03-03 18:07:48 -06:00
// api version
version: '1.0.0',
2017-02-14 19:44:15 -06:00
2017-02-10 20:20:09 -06:00
openWindow: function(url) {
2017-03-07 16:44:31 -06:00
local.ipcRenderer.send(apiName, {
cmd: apiCmds.open,
2017-02-10 20:20:09 -06:00
url: url
});
2017-02-28 16:45:04 -06:00
},
2017-03-01 18:32:21 -06:00
2017-03-06 23:09:10 -06:00
/**
* sets the count on the tray icon to the given number.
* @param {number} count count to be displayed
* note: count of 0 will remove the displayed count.
2017-03-09 12:12:28 -06:00
* note: for mac the number displayed will be 1 to infinity
* note: for windws the number displayed will be 1 to 99 and 99+
2017-03-06 23:09:10 -06:00
*/
setBadgeCount: function(count) {
2017-03-09 12:12:28 -06:00
throttledSetBadgeCount(count);
2017-03-06 23:09:10 -06:00
},
/**
* provides api similar to html5 Notification, see details
2017-04-03 18:50:35 -05:00
* in notify/notifyImpl.js
*/
2017-04-03 18:50:35 -05:00
Notification: notify,
2017-03-01 18:32:21 -06:00
/**
* allows JS to register a logger that can be used by electron main process.
* @param {Object} logger function that can be called accepting
* object: {
* logLevel: 'ERROR'|'CONFLICT'|'WARN'|'ACTION'|'INFO'|'DEBUG',
* logDetails: String
* }
*
* note: only main window is allowed to register a logger, others are
* ignored.
*/
registerLogger: function(logger) {
if (typeof logger === 'function') {
local.logger = logger;
// only main window can register
2017-03-07 16:44:31 -06:00
local.ipcRenderer.send(apiName, {
cmd: apiCmds.registerLogger
2017-03-01 18:32:21 -06:00
});
}
2017-02-10 20:20:09 -06:00
}
};
2017-03-06 23:09:10 -06:00
Object.freeze(window.SYM_API);
2017-03-01 18:32:21 -06:00
// listen for log message from main process
2017-04-03 18:50:35 -05:00
local.ipcRenderer.on('log', (event, arg) => {
2017-03-01 18:32:21 -06:00
if (local.logger && arg && arg.level && arg.msg) {
local.logger({
logLevel: arg.level,
logDetails: arg.msg
});
}
});
2017-03-06 23:09:10 -06:00
/**
* Use render process to create badge count img and send back to main process.
* If number is greater than 99 then 99+ img is returned.
* note: with sandboxing turned on only get arg and no event passed in, so
* need to use ipcRenderer to callback to main process.
* @type {object} arg.count - number: count to be displayed
*/
2017-04-03 18:50:35 -05:00
local.ipcRenderer.on('createBadgeDataUrl', (event, arg) => {
2017-03-06 23:09:10 -06:00
const count = arg && arg.count || 0;
// create 32 x 32 img
let radius = 16;
let canvas = document.createElement('canvas');
canvas.height = radius * 2;
canvas.width = radius * 2;
let ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(radius, radius, radius, 0, 2 * Math.PI, false);
ctx.fill();
ctx.textAlign = 'center';
ctx.fillStyle = 'white';
let text = count > 99 ? '99+' : count.toString();
if (text.length > 2) {
ctx.font = 'bold 18px sans-serif';
ctx.fillText(text, radius, 22);
} else if (text.length > 1) {
ctx.font = 'bold 24px sans-serif';
ctx.fillText(text, radius, 24);
} else {
ctx.font = 'bold 26px sans-serif';
ctx.fillText(text, radius, 26);
}
let dataUrl = canvas.toDataURL('image/png', 1.0);
2017-03-07 16:44:31 -06:00
local.ipcRenderer.send(apiName, {
cmd: apiCmds.badgeDataUrl,
2017-03-06 23:09:10 -06:00
dataUrl: dataUrl,
count: count
});
});
2017-02-28 16:45:04 -06:00
function updateOnlineStatus() {
2017-03-07 16:44:31 -06:00
local.ipcRenderer.send(apiName, {
cmd: apiCmds.isOnline,
2017-03-03 18:07:48 -06:00
isOnline: window.navigator.onLine
2017-03-01 18:32:21 -06:00
});
2017-02-28 16:45:04 -06:00
}
window.addEventListener('offline', updateOnlineStatus, false);
window.addEventListener('online', updateOnlineStatus, false);
updateOnlineStatus();