Introduce dialog for long database migrations

This commit is contained in:
Ken Powers 2020-03-25 19:45:37 -04:00 committed by Scott Nonnenberg
parent 30e5051239
commit 750e50812c
8 changed files with 118 additions and 8 deletions

View file

@ -68,7 +68,9 @@ function createTrayIcon(getMainWindow, messages) {
trayContextMenu = Menu.buildFromTemplate([
{
id: 'toggleWindowVisibility',
label: messages[mainWindow.isVisible() ? 'hide' : 'show'].message,
label:
messages[mainWindow && mainWindow.isVisible() ? 'hide' : 'show']
.message,
click: tray.toggleWindowVisibility,
},
{

7
js/loading_start.js Normal file
View file

@ -0,0 +1,7 @@
/* global $ */
$(() => {
'use strict';
$('.message').text(window.i18n('optimizingApplication'));
});

24
loading.html Normal file
View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<link
href="node_modules/sanitize.css/sanitize.css"
rel="stylesheet"
type="text/css"
/>
<link href="stylesheets/manifest.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="app-migration-screen app-loading-screen">
<div class="module-splash-screen__logo module-img--150"></div>
<div class="container">
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
</div>
<div class="message"></div>
</div>
<script type="text/javascript" src="js/components.js"></script>
<script type="text/javascript" src="js/loading_start.js"></script>
</body>
</html>

12
loading_preload.js Normal file
View file

@ -0,0 +1,12 @@
/* global window */
const { ipcRenderer } = require('electron');
const url = require('url');
const i18n = require('./js/modules/i18n');
const config = url.parse(window.location.toString(), true).query;
const { locale } = config;
const localeMessages = ipcRenderer.sendSync('locale-data');
window.i18n = i18n.setup(locale, localeMessages);

56
main.js
View file

@ -49,6 +49,7 @@ app.allowRendererProcessReuse = true;
// 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 loadingWindow;
function getMainWindow() {
return mainWindow;
@ -350,12 +351,6 @@ async function createWindow() {
mainWindow.on('resize', debouncedCaptureStats);
mainWindow.on('move', debouncedCaptureStats);
// Ingested in preload.js via a sendSync call
ipc.on('locale-data', event => {
// eslint-disable-next-line no-param-reassign
event.returnValue = locale.messages;
});
if (config.environment === 'test') {
mainWindow.loadURL(prepareURL([__dirname, 'test', 'index.html']));
} else if (config.environment === 'test-lib') {
@ -807,11 +802,52 @@ app.on('ready', async () => {
key = crypto.randomBytes(32).toString('hex');
userConfig.set('key', key);
}
const success = await sql.initialize({
const sqlInitPromise = sql.initialize({
configDir: userDataPath,
key,
messages: locale.messages,
});
// If the sql initialization takes more than three seconds to complete, we
// want to notify the user that things are happening
const timeout = new Promise(resolve => setTimeout(resolve, 3000, 'timeout'));
// eslint-disable-next-line more/no-then
Promise.race([sqlInitPromise, timeout]).then(maybeTimeout => {
if (maybeTimeout !== 'timeout') {
return;
}
console.log(
'sql.initialize is taking more than three seconds; showing loading dialog'
);
loadingWindow = new BrowserWindow({
show: false,
width: 300,
height: 265,
resizable: false,
frame: false,
backgroundColor: '#3a76f0',
webPreferences: {
nodeIntegration: false,
preload: path.join(__dirname, 'loading_preload.js'),
},
icon: path.join(__dirname, 'images', 'icon_256.png'),
});
loadingWindow.once('ready-to-show', async () => {
loadingWindow.show();
// Wait for sql initialization to complete
await sqlInitPromise;
loadingWindow.destroy();
loadingWindow = null;
});
loadingWindow.loadURL(prepareURL([__dirname, 'loading.html']));
});
const success = await sqlInitPromise;
if (!success) {
console.log('sql.initialize was unsuccessful; returning early');
return;
@ -1159,6 +1195,12 @@ ipc.on('get-built-in-images', async () => {
}
});
// Ingested in preload.js via a sendSync call
ipc.on('locale-data', event => {
// eslint-disable-next-line no-param-reassign
event.returnValue = locale.messages;
});
function getDataFromMainWindow(name, callback) {
ipc.once(`get-success-${name}`, (_event, error, value) =>
callback(error, value)

View file

@ -335,6 +335,7 @@
"settings.html",
"permissions_popup.html",
"debug_log.html",
"loading.html",
"_locales/**",
"protos/*",
"js/**",
@ -349,6 +350,7 @@
"settings_preload.js",
"permissions_popup_preload.js",
"debug_log_preload.js",
"loading_preload.js",
"main.js",
"images/**",
"fonts/**",

View file

@ -307,6 +307,11 @@ $loading-height: 16px;
}
}
.app-migration-screen {
display: flex;
flex-direction: column;
}
.app-loading-screen {
z-index: 99;
position: absolute;

View file

@ -203,6 +203,22 @@
"updated": "2018-09-19T18:13:29.628Z",
"reasonDetail": "Interacting with already-existing DOM nodes"
},
{
"rule": "jQuery-$(",
"path": "js/loading_start.js",
"line": "$(() => {",
"lineNumber": 3,
"reasonCategory": "usageTrusted",
"updated": "2020-03-25T15:45:04.024Z"
},
{
"rule": "jQuery-$(",
"path": "js/loading_start.js",
"line": " $('.message').text(window.i18n('optimizingApplication'));",
"lineNumber": 6,
"reasonCategory": "usageTrusted",
"updated": "2020-03-25T15:45:04.024Z"
},
{
"rule": "jQuery-append(",
"path": "js/modules/debuglogs.js",