add various error dialogs (#25)

This commit is contained in:
Lynn 2017-02-28 14:45:04 -08:00 committed by GitHub
parent 1c078fb2f8
commit c337c62e03
4 changed files with 151 additions and 13 deletions

View File

@ -0,0 +1,42 @@
'use strict';
const electron = require('electron');
let ignoreAllCertErrors = false;
/**
* If certificate error occurs allow user to deny or allow particular certificate
* error. If user selects 'Ignore All', then all subsequent certificate errors
* will ignored during this session.
*
* Note: the dialog is synchronous so further processing is blocked until
* user provides a response.
*/
electron.app.on('certificate-error', function(event, webContents, url, error,
certificate, callback) {
if (ignoreAllCertErrors) {
event.preventDefault();
callback(true);
return;
}
let browserWin = electron.BrowserWindow.fromWebContents(webContents);
var buttonId = electron.dialog.showMessageBox(browserWin, {
type: 'warning',
buttons: [ 'Allow', 'Deny', 'Ignore All' ],
defaultId: 1,
cancelId: 1,
noLink: true,
title: 'Certificate Error',
message: 'Certificate Error: ' + error + '\nURL: ' + url,
});
event.preventDefault();
if (buttonId === 2) {
ignoreAllCertErrors = true;
}
callback(buttonId !== 1);
});

View File

@ -0,0 +1,61 @@
'use strict';
const electron = require('electron');
/**
* Show dialog pinned to given window when loading error occurs
* @param {BrowserWindow} win Window to host dialog
* @param {String} url Url that failed
* @param {String} errorDesc Description of error
* @param {Number} errorCode Error code
* @param {callback} retryCallback Callback when user clicks reload
*/
function showLoadFailure(win, url, errorDesc, errorCode, retryCallback) {
let msg;
if (url) {
msg = 'Error loading URL:\n' + url;
} else {
msg = 'Error loading window'
}
if (errorDesc) {
msg += '\n\n' + errorDesc;
}
if (errorCode) {
msg += '\n\nError Code: ' + errorCode;
}
electron.dialog.showMessageBox(win, {
type: 'error',
buttons: [ 'Reload', 'Ignore' ],
defaultId: 0,
cancelId: 0,
noLink: true,
title: 'Loading Error',
message: msg
}, response);
// async handle of user input
function response(buttonId) {
// ignore button hit, do nothing
if (buttonId === 1) {
return;
}
if (typeof retryCallback === 'function') {
retryCallback();
}
}
}
/**
* Show message indicating network connectivity has been lost.
* @param {BrowserWindow} win Window to host dialog
* @param {String} url Url that failed
* @param {callback} retryCallback Callback when user clicks reload
*/
function showNetworkConnectivityError(win, url, retryCallback) {
var errorDesc = 'Network connectivity has been lost, check your internet connection.';
showLoadFailure(win, url, errorDesc, 0, retryCallback);
}
module.exports = { showLoadFailure, showNetworkConnectivityError };

View File

@ -8,29 +8,29 @@ const app = electron.app;
const nodeURL = require('url');
const getConfig = require('./getConfig.js');
const { isMac, isDevEnv, getGuid } = require('./utils.js');
const loadErrors = require('./dialogs/showLoadError.js');
// show dialog when certificate errors occur
require('./dialogs/showCertError.js');
// 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.
let mainWindow;
let windows = {};
let willQuitApp = false;
let isOnline = true;
if (require('electron-squirrel-startup')) {
return;
}
if (isDevEnv) {
// needed for development env because local server doesn't have cert
app.commandLine.appendSwitch('--ignore-certificate-errors');
}
function createMainWindow (url) {
let key = getGuid();
mainWindow = new electron.BrowserWindow({
title: 'Symphony',
width: 1024, height: 768,
show: true,
webPreferences: {
sandbox: true,
nodeIntegration: false,
@ -39,13 +39,28 @@ function createMainWindow (url) {
}
});
mainWindow.webContents.once('did-fail-load', function() {
// ToDo: show ui when failure occurs
console.error('failed to load window');
function retry() {
if (isOnline) {
mainWindow.webContents && mainWindow.webContents.reload();
} else {
loadErrors.showNetworkConnectivityError(mainWindow, url, retry);
}
}
// content can be cached and will still finish load but
// we might not have netowrk connectivity, so warn the user.
mainWindow.webContents.once('did-finish-load', function() {
if (!isOnline) {
loadErrors.showNetworkConnectivityError(mainWindow, url, retry);
}
});
mainWindow.webContents.once('did-fail-load', function(event, errorCode,
errorDesc, validatedURL, isMainFrame) {
loadErrors.showLoadFailure(mainWindow, url, errorDesc, errorCode, retry);
});
storeWindowKey(key, mainWindow);
mainWindow.loadURL(url);
const menu = electron.Menu.buildFromTemplate(menuTemplate(app));
@ -138,7 +153,12 @@ electron.ipcMain.on('symphony-msg', (event, arg) => {
}
if (!isCmdAllowed(event, arg && arg.cmd)) {
console.log('cmd is not allowed for this window: ' + arg.cmd);
console.log('cmd not allowed for this window: ' + arg.cmd);
return;
}
if (arg && arg.cmd === 'isOnline') {
isOnline = arg.isOnline;
return;
}
@ -188,8 +208,8 @@ function getUrlAndOpenMainWindow() {
});
createMainWindow(url);
}).catch(function(err) {
// ToDo: show ui when failure occurs
console.error(err);
let title = 'Error loading configuration';
electron.dialog.showErrorBox(title, title + ': ' + err);
});
}

View File

@ -31,7 +31,22 @@ window.SYM_API = {
cmd: 'open',
url: url
});
},
networkStatusChange: function(isOnline) {
local.ipcRenderer.send('symphony-msg', {
cmd: 'isOnline',
isOnline: isOnline
});
}
};
function updateOnlineStatus() {
window.SYM_API.networkStatusChange(navigator.onLine);
}
window.addEventListener('offline', updateOnlineStatus, false);
window.addEventListener('online', updateOnlineStatus, false);
updateOnlineStatus();
Object.freeze(window.SYM_API);