electron-97: refactored the code as per the ticket (points 3 & 4 covered)

This commit is contained in:
Vishwas Shashidhar 2017-08-24 16:18:32 +05:30
parent 28bd9399aa
commit 5f557247a7
20 changed files with 347 additions and 46 deletions

View File

@ -84,6 +84,11 @@ function send(data) {
}
}
/**
* Set the activity's window
* @param period
* @param win
*/
function setActivityWindow(period, win) {
maxIdleTime = period;
activityWindow = win;

View File

@ -10,6 +10,10 @@ const maxCount = 1e8;
const log = require('./log.js');
const logLevels = require('./enums/logLevels.js');
/**
* Shows the badge count
* @param count
*/
function show(count) {
if (typeof count !== 'number') {
log.send(logLevels.WARN, 'badgeCount: invalid func arg, must be a number: ' + count);
@ -37,6 +41,11 @@ function show(count) {
}
}
/**
* Sets the data url
* @param dataUrl
* @param count
*/
function setDataUrl(dataUrl, count) {
const mainWindow = windowMgr.getMainWindow();
if (mainWindow && dataUrl && count) {

View File

@ -21,11 +21,21 @@ function getNextId() {
return ++nextId;
}
// |options.type| can not be empty and has to include 'window' or 'screen'.
/**
* Checks if the options and their types are valid
* @param options |options.type| can not be empty and has to include 'window' or 'screen'.
* @returns {boolean}
*/
function isValid(options) {
return ((options !== null ? options.types : undefined) !== null) && Array.isArray(options.types);
}
/**
* Gets the sources for capturing screens / windows
* @param options
* @param callback
* @returns {*}
*/
function getSources(options, callback) {
let captureScreen, captureWindow, id;
if (!isValid(options)) {

View File

@ -19,6 +19,7 @@ local.ipcRenderer.on('downloadProgress', () => {
/**
* Open file in default app.
* @param id
*/
function openFile(id) {
let fileIndex = local.downloadItems.findIndex((item) => {
@ -34,6 +35,7 @@ function openFile(id) {
/**
* Show downloaded file in explorer or finder.
* @param id
*/
function showInFinder(id) {
let showFileIndex = local.downloadItems.findIndex((item) => {
@ -47,6 +49,10 @@ function showInFinder(id) {
}
}
/**
* Create the document object model
* @param arg
*/
function createDOM(arg) {
if (arg && arg._id) {
@ -149,6 +155,9 @@ function createDOM(arg) {
}
}
/**
* Initiate the download manager
*/
function initiate() {
let mainFooter = document.getElementById('footer');
let mainDownloadDiv = document.getElementById('download-manager-footer');

View File

@ -2,6 +2,10 @@
let keyMirror = require('keymirror');
/**
* Set of APIs exposed to the remote object
* @type {Object}
*/
const cmds = keyMirror({
isOnline: null,
registerLogger: null,

View File

@ -2,6 +2,10 @@
let keyMirror = require('keymirror');
/**
* The different log levels
* @type {Object}
*/
module.exports = keyMirror({
ERROR: null,
CONFLICT: null,

View File

@ -5,6 +5,7 @@ const getCmdLineArg = require('./utils/getCmdLineArg.js');
const MAX_LOG_QUEUE_LENGTH = 100;
class Logger {
constructor() {
// browser window that has registered a logger
this.logWindow = null;
@ -45,6 +46,10 @@ class Logger {
}
}
/**
* Sets a window instance for the remote object
* @param win
*/
setLogWindow(win) {
this.logWindow = win;

View File

@ -78,10 +78,17 @@ if (isMac) {
*/
app.on('ready', setupThenOpenMainWindow);
/**
* Is triggered when all the windows are closed
* In which case we quit the app
*/
app.on('window-all-closed', function() {
app.quit();
});
/**
* Is triggered when the app is up & running
*/
app.on('activate', function() {
if (windowMgr.isMainWindow(null)) {
setupThenOpenMainWindow();
@ -95,13 +102,19 @@ app.on('activate', function() {
// and registry keys in windows
app.setAsDefaultProtocolClient('symphony');
// This event is emitted only on macOS
// at this moment, support for windows
// is in pipeline (https://github.com/electron/electron/pull/8052)
/**
* This event is emitted only on macOS
* at this moment, support for windows
* is in pipeline (https://github.com/electron/electron/pull/8052)
*/
app.on('open-url', function(event, url) {
handleProtocolAction(url);
});
/**
* Sets up the app (to handle various things like config changes, protocol handling etc.)
* and opens the main window
*/
function setupThenOpenMainWindow() {
processProtocolAction(process.argv);
@ -140,6 +153,11 @@ function setupThenOpenMainWindow() {
electron.screen.on('display-removed', windowMgr.verifyDisplays);
}
/**
* Sets Symphony on startup
* @param lStartup
* @returns {Promise}
*/
function setStartup(lStartup) {
return symphonyAutoLauncher.isEnabled()
.then(function(isEnabled) {
@ -155,7 +173,10 @@ function setStartup(lStartup) {
});
}
// Method to overwrite user config on mac installer
/**
* Method to overwrite user config on mac installer
* @returns {Promise}
*/
function updateUserConfigMac() {
return new Promise((resolve, reject) => {
let userConfigPath = dirs.userConfig() + '/';
@ -171,7 +192,10 @@ function updateUserConfigMac() {
});
}
// Method to overwrite user config on windows installer
/**
* Method to overwrite user config on windows installer
* @returns {Promise}
*/
function updateUserConfigWin() {
return new Promise((resolve, reject) => {
let userConfigPath = app.getPath('userData');
@ -186,6 +210,10 @@ function updateUserConfigWin() {
});
}
/**
* Checks for the url argument, processes it
* and creates the main window
*/
function getUrlAndCreateMainWindow() {
// for dev env allow passing url argument
if (isDevEnv) {
@ -203,6 +231,10 @@ function getUrlAndCreateMainWindow() {
});
}
/**
* Creates a window
* @param urlFromConfig
*/
function createWin(urlFromConfig) {
let protocol = '';
// add https protocol if none found.
@ -247,6 +279,10 @@ function processProtocolAction(argv) {
}
}
/**
* Handles a protocol action based on the current state of the app
* @param uri
*/
function handleProtocolAction(uri) {
if (!isAppAlreadyOpen) {
// app is opened by the protocol url, cache the protocol url to be used later

View File

@ -6,6 +6,9 @@ const logLevels = require('./enums/logLevels.js');
// once a minute
setInterval(gatherMemory, 1000 * 60);
/**
* Gathers system memory and logs it to the remote system
*/
function gatherMemory() {
let memory = process.getProcessMemoryInfo();
let details =

View File

@ -243,6 +243,10 @@ function getTemplate(app) {
return template;
}
/**
* Sets the checkbox values for different menu items
* based on configuration
*/
function setCheckboxValues() {
getConfigField('minimizeOnClose').then(function(mClose) {
minimizeOnClose = mClose;

View File

@ -3,13 +3,21 @@
const log = require('../log.js');
const logLevels = require('../enums/logLevels.js');
// One animation at a time
/**
* Manages one animation at a time
* @param options
* @constructor
*/
const AnimationQueue = function(options) {
this.options = options;
this.queue = [];
this.running = false;
};
/**
* Pushes each animation to a queue
* @param object
*/
AnimationQueue.prototype.push = function(object) {
if (this.running) {
this.queue.push(object);
@ -19,6 +27,10 @@ AnimationQueue.prototype.push = function(object) {
}
};
/**
* Animates an animation that is part of the queue
* @param object
*/
AnimationQueue.prototype.animate = function(object) {
object.func.apply(null, object.args)
.then(function() {
@ -39,6 +51,9 @@ AnimationQueue.prototype.animate = function(object) {
})
};
/**
* Clears the queue
*/
AnimationQueue.prototype.clear = function() {
this.queue = [];
};

View File

@ -9,6 +9,10 @@
const electron = require('electron');
const ipc = electron.ipcRenderer;
/**
* Sets style for a notification
* @param config
*/
function setStyle(config) {
// Style it
let notiDoc = window.document;
@ -40,6 +44,11 @@ function setStyle(config) {
setStyleOnDomElement(config.defaultStyleClose, close);
}
/**
* Sets contents for a notification
* @param event
* @param notificationObj
*/
function setContents(event, notificationObj) {
// sound
if (notificationObj.sound) {
@ -111,6 +120,11 @@ function setContents(event, notificationObj) {
}
}
/**
* Sets style on a notification for a DOM element
* @param styleObj
* @param domElement
*/
function setStyleOnDomElement(styleObj, domElement) {
try {
let styleAttr = Object.keys(styleObj);
@ -124,10 +138,18 @@ function setStyleOnDomElement(styleObj, domElement) {
}
}
/**
* Loads the config
* @param event
* @param conf
*/
function loadConfig(event, conf) {
setStyle(conf || {})
}
/**
* Resets the notification window
*/
function reset() {
let notiDoc = window.document;
let container = notiDoc.getElementById('container');

View File

@ -140,19 +140,16 @@ let config = {
}
};
// function setConfig(customConfig) {
// Object.assign(customConfig, config);
//
// calcDimensions();
// }
if (app.isReady()) {
setup();
} else {
app.on('ready', setup);
}
// Method to update notification config
/**
* Method to update notification config
* @param customConfig
*/
function updateConfig(customConfig) {
// Fetching user preferred notification position from config
if (customConfig.position) {
@ -167,6 +164,9 @@ function updateConfig(customConfig) {
}
}
/**
* Method to setup the notification configuration
*/
function setup() {
setupConfig();
@ -177,6 +177,10 @@ function setup() {
electron.screen.on('display-metrics-changed', setupConfig);
}
/**
* Method to get the notification template path
* @returns {string|*}
*/
function getTemplatePath() {
let templatePath = path.join(__dirname, 'electron-notify.html');
try {
@ -188,6 +192,9 @@ function getTemplatePath() {
return config.templatePath;
}
/**
* Calculates the dimensions of the screen
*/
function calcDimensions() {
const vertSpaceBetweenNotf = 8;
@ -227,6 +234,9 @@ function calcDimensions() {
nextInsertPos.y = config.firstPos.y
}
/**
* Setup the notification config
*/
function setupConfig() {
closeAll();
@ -273,6 +283,11 @@ function setupConfig() {
config.maxVisibleNotifications = config.maxVisibleNotifications > 5 ? 5 : config.maxVisibleNotifications;
}
/**
* Notifies the user
* @param notification
* @returns {*}
*/
function notify(notification) {
// Is it an object and only one argument?
if (arguments.length === 1 && typeof notification === 'object') {
@ -290,10 +305,18 @@ function notify(notification) {
return null;
}
/**
* Increment the notification
*/
function incrementId() {
latestID++;
}
/**
* Shows the notification to the user
* @param notificationObj
* @returns {Promise}
*/
function showNotification(notificationObj) {
return new Promise(function(resolve) {
@ -378,6 +401,12 @@ function showNotification(notificationObj) {
})
}
/**
* Sets the HTML notification contents along with other options
* @param notfWindow
* @param notfObj
* @returns {*}
*/
function setNotificationContents(notfWindow, notfObj) {
// Display time per notification basis.
@ -437,7 +466,13 @@ function setNotificationContents(notfWindow, notfObj) {
return updatedNotificationWindow;
}
// Close notification function
/**
* Closes the notification
* @param notificationWindow
* @param notificationObj
* @param getTimeoutId
* @returns {Function}
*/
function buildCloseNotification(notificationWindow, notificationObj, getTimeoutId) {
return function(event) {
if (closedNotifications[notificationObj.id]) {
@ -480,8 +515,13 @@ function buildCloseNotification(notificationWindow, notificationObj, getTimeoutI
}
}
// Always add to animationQueue to prevent erros (e.g. notification
// got closed while it was moving will produce an error)
/**
* Adds an active notification the close notification queue
* Always add to animationQueue to prevent erros (e.g. notification
* got closed while it was moving will produce an error)
* @param closeFunc
* @returns {Function}
*/
function buildCloseNotificationSafely(closeFunc) {
return function(reason) {
animationQueue.push({
@ -509,10 +549,10 @@ ipc.on('electron-notify-click', function (event, winId, notificationObj) {
}
});
/*
* Checks for queued notifications and add them
* to AnimationQueue if possible
*/
/**
* Checks for queued notifications and add them
* to AnimationQueue if possible
*/
function checkForQueuedNotifications() {
if (notificationQueue.length > 0 &&
activeNotifications.length < config.maxVisibleNotifications) {
@ -524,12 +564,12 @@ function checkForQueuedNotifications() {
}
}
/*
* Moves the notifications one position down,
* starting with notification at startPos
*
* @param {int} startPos
*/
/**
* Moves the notifications one position down,
* starting with notification at startPos
* @param startPos
* @returns {Promise}
*/
function moveOneDown(startPos) {
return new Promise(function(resolve) {
if (startPos >= activeNotifications || startPos === -1) {
@ -552,6 +592,11 @@ function moveOneDown(startPos) {
})
}
/**
* Moves the notification animation
* @param i
* @param done
*/
function moveNotificationAnimation(i, done) {
// Get notification to move
let notificationWindow = activeNotifications[i];
@ -588,15 +633,21 @@ function moveNotificationAnimation(i, done) {
}, config.animationStepMs)
}
/**
* Sets the window's position
* @param browserWin
* @param posX
* @param posY
*/
function setWindowPosition(browserWin, posX, posY) {
if (!browserWin.isDestroyed()) {
browserWin.setPosition(parseInt(posX, 10), parseInt(posY, 10))
}
}
/*
* Find next possible insert position (on top)
*/
/**
* Find next possible insert position (on top)
*/
function calcInsertPos() {
if (activeNotifications.length < config.maxVisibleNotifications) {
switch(config.startCorner) {
@ -614,11 +665,11 @@ function calcInsertPos() {
}
}
/*
* Get a window to display a notification. Use inactiveWindows or
* create a new window
* @return {Window}
*/
/**
* Get a window to display a notification. Use inactiveWindows or
* create a new window
* @returns {Promise}
*/
function getWindow() {
return new Promise(function(resolve) {
let notificationWindow;
@ -643,6 +694,9 @@ function getWindow() {
})
}
/**
* Closes all the notifications and windows
*/
function closeAll() {
// Clear out animation Queue and close windows
animationQueue.clear();
@ -668,10 +722,13 @@ function closeAll() {
}
/**
/* once a minute, remove inactive windows to free up memory used.
* Once a minute, remove inactive windows to free up memory used.
*/
setInterval(cleanUpInactiveWindow, 60000);
/**
* Cleans up inactive windows
*/
function cleanUpInactiveWindow() {
inactiveWindows.forEach(function(window) {
window.close();

View File

@ -51,6 +51,10 @@ class Notify {
this._data = options.data || null;
/**
* Handles on show event
* @param arg
*/
function onShow(arg) {
if (arg.id === this._id) {
log.send(logLevels.INFO, 'showing notification, id=' + this._id);
@ -61,6 +65,10 @@ class Notify {
}
}
/**
* Handles on click event
* @param arg
*/
function onClick(arg) {
if (arg.id === this._id) {
log.send(logLevels.INFO, 'clicking notification, id=' + this._id);
@ -70,6 +78,10 @@ class Notify {
}
}
/**
* Handles on close event
* @param arg
*/
function onClose(arg) {
if (arg.id === this._id || arg.event === 'close-all') {
log.send(logLevels.INFO, 'closing notification, id=' + this._id);
@ -80,6 +92,10 @@ class Notify {
}
}
/**
* Handles on error event
* @param arg
*/
function onError(arg) {
if (arg.id === this._id) {
// don't raise error event if handler doesn't exist, node
@ -95,7 +111,7 @@ class Notify {
}
/**
* close notification
* Closes notification
*/
close() {
if (typeof this._closeNotification === 'function') {
@ -105,7 +121,7 @@ class Notify {
}
/**
* always allow showing notifications.
* Always allow showing notifications.
* @return {string} 'granted'
*/
static get permission() {
@ -113,14 +129,14 @@ class Notify {
}
/**
* returns data object passed in via constructor options
* Returns data object passed in via constructor options
*/
get data() {
return this._data;
}
/**
* add event listeners for 'click', 'close', 'show', 'error' events
* Adds event listeners for 'click', 'close', 'show', 'error' events
*
* @param {String} event event to listen for
* @param {func} cb callback invoked when event occurs
@ -132,7 +148,7 @@ class Notify {
}
/**
* remove event listeners for 'click', 'close', 'show', 'error' events
* Removes event listeners for 'click', 'close', 'show', 'error' events
*
* @param {String} event event to stop listening for.
* @param {func} cb callback associated with original addEventListener
@ -144,7 +160,7 @@ class Notify {
}
/**
* removes all event listeners
* Removes all event listeners
*/
removeAllEvents() {
this.destroy();

View File

@ -9,7 +9,9 @@ let selectedDisplay;
renderSettings();
// Method that renders the data from user config
/**
* Method that renders the data from user config
*/
function renderSettings() {
document.addEventListener('DOMContentLoaded', function () {
@ -33,6 +35,9 @@ function renderSettings() {
}
/**
* Updates the configuration and closes the alert
*/
function updateAndClose() {
ipc.send('update-config', {position: selectedPosition, display: selectedDisplay});
ipc.send('close-alert');

View File

@ -41,6 +41,9 @@ app.on('ready', () => {
electron.screen.on('display-removed', updateScreens);
});
/**
* Update all the screens
*/
function updateScreens() {
screens = electron.screen.getAllDisplays();
@ -50,6 +53,10 @@ function updateScreens() {
}
}
/**
* Gets the template path
* @returns {string}
*/
function getTemplatePath() {
let templatePath = path.join(__dirname, 'configure-notification-position.html');
try {
@ -60,6 +67,10 @@ function getTemplatePath() {
return 'file://' + templatePath;
}
/**
* Opens the configuration window for a specific window
* @param windowName
*/
function openConfigurationWindow(windowName) {
let allWindows = BrowserWindow.getAllWindows();
allWindows = allWindows.find((window) => { return window.winName === windowName });
@ -94,6 +105,9 @@ function openConfigurationWindow(windowName) {
});
}
/**
* Destroys a window
*/
function destroyWindow() {
configurationWindow = null;
}

View File

@ -43,6 +43,10 @@ function setProtocolUrl(uri) {
protocolUrl = uri;
}
/**
* gets the protocol url set against an instance
* @returns {*}
*/
function getProtocolUrl() {
return protocolUrl;
}

View File

@ -84,9 +84,15 @@ class ScreenSnippet {
}
}
// this function was moved outside of class since class is exposed to web
// client via preload API, we do NOT want web client to be able to call this
// method - then they could read any file on the disk!
/**
* this function was moved outside of class since class is exposed to web
* client via preload API, we do NOT want web client to be able to call this
* method - then they could read any file on the disk!
* @param outputFileName
* @param resolve
* @param reject
* @param childProcessErr
*/
function readResult(outputFileName, resolve, reject, childProcessErr) {
fs.readFile(outputFileName, (readErr, data) => {
if (readErr) {
@ -135,12 +141,22 @@ function readResult(outputFileName, resolve, reject, childProcessErr) {
}
/* eslint-disable class-methods-use-this */
/**
* Create an error object with the ERROR level
* @param msg
* @returns {Error}
*/
function createError(msg) {
let err = new Error(msg);
err.type = 'ERROR';
return err;
}
/**
* Create an error object with the WARN level
* @param msg
* @returns {Error}
*/
function createWarn(msg) {
let err = new Error(msg);
err.type = 'WARN';

View File

@ -5,6 +5,9 @@ const { SpellCheckHandler, ContextMenuListener, ContextMenuBuilder } = require('
class SpellCheckHelper {
/**
* A constructor to create an instance of the spell checker
*/
constructor() {
this.spellCheckHandler = new SpellCheckHandler();
}

View File

@ -42,18 +42,36 @@ const preloadMainScript = path.join(__dirname, 'preload/_preloadMain.js');
const MIN_WIDTH = 300;
const MIN_HEIGHT = 600;
/**
* Adds a window key
* @param key
* @param browserWin
*/
function addWindowKey(key, browserWin) {
windows[key] = browserWin;
}
/**
* Removes a window key
* @param key
*/
function removeWindowKey(key) {
delete windows[key];
}
/**
* Gets the parsed url
* @param url
* @returns {Url}
*/
function getParsedUrl(url) {
return nodeURL.parse(url);
}
/**
* Creates the main window
* @param initialUrl
*/
function createMainWindow(initialUrl) {
getConfigField('mainWinPos').then(
function (bounds) {
@ -66,6 +84,11 @@ function createMainWindow(initialUrl) {
)
}
/**
* Creates the main window with bounds
* @param initialUrl
* @param initialBounds
*/
function doCreateMainWindow(initialUrl, initialBounds) {
let url = initialUrl;
let key = getGuid();
@ -318,10 +341,16 @@ function doCreateMainWindow(initialUrl, initialBounds) {
}
/**
* Handles the event before-quit emitted by electron
*/
app.on('before-quit', function () {
willQuitApp = true;
});
/**
* Saves the main window bounds
*/
function saveMainWinBounds() {
let newBounds = getWindowSizeAndPosition(mainWindow);
@ -330,10 +359,19 @@ function saveMainWinBounds() {
}
}
/**
* Gets the main window
* @returns {*}
*/
function getMainWindow() {
return mainWindow;
}
/**
* Gets a window's size and position
* @param window
* @returns {*}
*/
function getWindowSizeAndPosition(window) {
if (window) {
let newPos = window.getPosition();
@ -353,14 +391,28 @@ function getWindowSizeAndPosition(window) {
return null;
}
/**
* Shows the main window
*/
function showMainWindow() {
mainWindow.show();
}
/**
* Tells if a window is the main window
* @param win
* @returns {boolean}
*/
function isMainWindow(win) {
return mainWindow === win;
}
/**
* Checks if the window and a key has a window
* @param win
* @param winKey
* @returns {*}
*/
function hasWindow(win, winKey) {
if (win instanceof BrowserWindow) {
let browserWin = windows[winKey];
@ -370,6 +422,10 @@ function hasWindow(win, winKey) {
return false;
}
/**
* Sets if a user is online
* @param status
*/
function setIsOnline(status) {
isOnline = status;
}
@ -417,6 +473,10 @@ function sendChildWinBoundsChange(window) {
}
}
/**
* Opens an external url in the system's default browser
* @param urlToOpen
*/
function openUrlInDefaultBrower(urlToOpen) {
if (urlToOpen) {
electron.shell.openExternal(urlToOpen);