Skip to content

Commit

Permalink
Add "Check for Updates" menu item (Automattic#1090)
Browse files Browse the repository at this point in the history
* Refactor updater

* Add menu item to Check for Updates

* Show update/download progress

* Ensure that preDownloadProgressBar is closed

* Add comment about delay

* Refactor initProgressBar

* Make only the download progress window closable

* Remove unneeded variable

* Rename progressUpdater

* Extract progress updating logic

* Fix breakage on Linux

* Set OK button for Linux

* Handle errors
  • Loading branch information
mirka authored Jan 15, 2019
1 parent 8c0b9e7 commit ef1e0d3
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 40 deletions.
7 changes: 6 additions & 1 deletion desktop/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@ const {
const path = require('path');
const windowStateKeeper = require('electron-window-state');

const config = require('./config');
const createMenuTemplate = require('./menus');
const platform = require('./platform');
const updater = require('./updater');
const { isDev } = require('./env');

require('module').globalPaths.push(path.resolve(path.join(__dirname)));

module.exports = function main() {
require('./updater')();
app.on('will-finish-launching', function() {
setTimeout(updater.ping.bind(updater), config.updater.delay);
});

const url =
isDev && process.env.DEV_SERVER
? 'http://localhost:4000' // TODO: find a solution to use host and port based on make config.
Expand Down
6 changes: 5 additions & 1 deletion desktop/menus/help-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ const submenu = [
},
];

const defaultSubmenuAdditions = [{ type: 'separator' }, menuItems.about];
const defaultSubmenuAdditions = [
{ type: 'separator' },
menuItems.checkForUpdates,
menuItems.about,
];

const helpMenu = {
label: '&Help',
Expand Down
1 change: 1 addition & 0 deletions desktop/menus/mac-app-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const macAppMenu = {
label: app.getName(),
submenu: [
menuItems.about,
menuItems.checkForUpdates,
{ type: 'separator' },
menuItems.preferences,
{ type: 'separator' },
Expand Down
7 changes: 7 additions & 0 deletions desktop/menus/menu-items.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const { app } = require('electron');

const { appCommandSender } = require('./utils');
const updater = require('../updater');
const DialogTypes = require('../../shared/dialog-types');

const about = {
Expand All @@ -11,6 +12,11 @@ const about = {
}),
};

const checkForUpdates = {
label: '&Check for Updates…',
click: updater.pingAndShowProgress.bind(updater),
};

const preferences = {
label: 'P&references…',
accelerator: 'CommandOrControl+,',
Expand All @@ -22,5 +28,6 @@ const preferences = {

module.exports = {
about,
checkForUpdates,
preferences,
};
11 changes: 11 additions & 0 deletions desktop/updater/auto-updater/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const { autoUpdater } = require('electron-updater');
*/
const Updater = require('../lib/Updater');
const AppQuit = require('../../app-quit');
const setupProgressUpdates = require('../lib/setup-progress-updates');

class AutoUpdater extends Updater {
constructor({ changelogUrl, options = {} }) {
Expand All @@ -22,10 +23,20 @@ class AutoUpdater extends Updater {
autoUpdater.autoInstallOnAppQuit = false;
}

// For non-user-initiated checks.
// Check and download in the background, and only notify the user if
// an update exists and has completed downloading.
ping() {
autoUpdater.checkForUpdates();
}

// For user-initiated checks.
// Will check and download, displaying progress dialogs.
pingAndShowProgress() {
setupProgressUpdates({ updater: autoUpdater, willAutoDownload: true });
autoUpdater.checkForUpdates();
}

onConfirm() {
AppQuit.allowQuit();
autoUpdater.quitAndInstall();
Expand Down
44 changes: 17 additions & 27 deletions desktop/updater/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
'use strict';

/**
* External Dependencies
*/
const { app } = require('electron');

/**
* Internal dependencies
*/
Expand All @@ -15,26 +10,21 @@ const ManualUpdater = require('./manual-updater');

let updater = false;

module.exports = function() {
app.on('will-finish-launching', function() {
if (platform.isOSX() || platform.isWindows() || process.env.APPIMAGE) {
updater = new AutoUpdater({
changelogUrl: config.updater.changelogUrl,
});
} else {
updater = new ManualUpdater({
downloadUrl: config.updater.downloadUrl,
apiUrl: config.updater.apiUrl,
changelogUrl: config.updater.changelogUrl,
options: {
dialogMessage:
'{name} {newVersion} is now available — you have {currentVersion}. Would you like to download it now?',
confirmLabel: 'Download',
},
});
}

// Start one straight away
setTimeout(updater.ping.bind(updater), config.updater.delay);
if (platform.isOSX() || platform.isWindows() || process.env.APPIMAGE) {
updater = new AutoUpdater({
changelogUrl: config.updater.changelogUrl,
});
} else {
updater = new ManualUpdater({
downloadUrl: config.updater.downloadUrl,
apiUrl: config.updater.apiUrl,
changelogUrl: config.updater.changelogUrl,
options: {
dialogMessage:
'{name} {newVersion} is now available — you have {currentVersion}. Would you like to download it now?',
confirmLabel: 'Download',
},
});
};
}

module.exports = updater;
104 changes: 104 additions & 0 deletions desktop/updater/lib/setup-progress-updates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const { app, dialog } = require('electron');
const ProgressBar = require('electron-progressbar');
const prettyBytes = require('pretty-bytes');

const progressBarBlue = '#4895d9';

/**
* Set up progress bar dialogs, and add/remove listeners on the updater.
*/
const setupProgressUpdates = ({ updater, willAutoDownload }) => {
let progressBar;
const title = 'Update Simplenote';
const style = {
bar: {
height: '8px',
'border-radius': '0',
'box-shadow': 'none',
},
value: {
'background-color': progressBarBlue,
'border-radius': '0',
'box-shadow': 'none',
},
};

const preDownloadProgressBar = new ProgressBar({
title,
text: 'Checking for Updates…',
style,
});

const notifyNoUpdate = () => {
updater.removeListener('update-not-available', notifyNoUpdate);
closeProgressAndShowMessage({
message: 'You’re up to date!',
detail: `Simplenote ${app.getVersion()} is currently the newest version available.`,
});
};

const notifyError = () => {
updater.removeListener('error', notifyError);
closeProgressAndShowMessage({
message: 'Something went wrong!',
detail: `Please try again later.`,
});
};

const closeProgressAndShowMessage = ({ message, detail }) => {
preDownloadProgressBar.setCompleted();
setTimeout(() => {
dialog.showMessageBox({
message,
detail,
buttons: ['OK'], // needs to be set explicitly for Linux
});
}, 500); // Allow time for preDownloadProgressBar to close
};

const initProgressBar = totalBytes => {
progressBar = new ProgressBar({
indeterminate: false,
title,
text: 'Downloading…',
maxValue: totalBytes,
browserWindow: { closable: true },
style,
});
progressBar.on('progress', value => {
progressBar.detail =
prettyBytes(value) + ` of ${prettyBytes(totalBytes)} downloaded…`;
});
progressBar.on('aborted', () =>
updater.removeListener('download-progress', updateProgress)
);
};

const updateProgress = progress => {
if (!progressBar) {
preDownloadProgressBar.setCompleted();
initProgressBar(progress.total);
}
progressBar.value = progress.transferred;
};

updater.on('error', notifyError);
updater.on('update-not-available', notifyNoUpdate);
updater.on('update-available', () => {
if (!willAutoDownload) {
preDownloadProgressBar.setCompleted();

// Allow time for preDownloadProgressBar to close
setTimeout(() => updater.notify(), 500);
}
});
updater.on('download-progress', updateProgress);
updater.on('update-downloaded', () => {
if (preDownloadProgressBar) {
preDownloadProgressBar.setCompleted();
}
updater.removeListener('download-progress', updateProgress);
});
};

module.exports = setupProgressUpdates;
16 changes: 15 additions & 1 deletion desktop/updater/manual-updater/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const semver = require('semver');
* Internal dependencies
*/
const Updater = require('../lib/Updater');
const setupProgressUpdates = require('../lib/setup-progress-updates');

class ManualUpdater extends Updater {
constructor({ apiUrl, downloadUrl, changelogUrl, options = {} }) {
Expand All @@ -21,6 +22,13 @@ class ManualUpdater extends Updater {
this.downloadUrl = downloadUrl;
}

// For user-initiated checks.
// Will check and display a progress dialog.
pingAndShowProgress() {
setupProgressUpdates({ updater: this, willAutoDownload: false });
this.ping();
}

async ping() {
const options = {
headers: {
Expand All @@ -32,6 +40,8 @@ class ManualUpdater extends Updater {
const releaseResp = await fetch(this.apiUrl, options);

if (releaseResp.status !== 200) {
this.emit('error');
console.log(releaseResp);
return;
}

Expand All @@ -47,6 +57,8 @@ class ManualUpdater extends Updater {
);

if (configResp.status !== 200) {
this.emit('error');
console.log(configResp);
return;
}

Expand All @@ -59,12 +71,14 @@ class ManualUpdater extends Updater {
releaseConfig.version
);
this.setVersion(releaseConfig.version);
this.notify();
this.emit('update-available');
} else {
this.emit('update-not-available');
return;
}
}
} catch (err) {
this.emit('error');
console.log(err.message);
}
}
Expand Down
32 changes: 22 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
"draft-js": "0.10.5",
"draft-js-simpledecorator": "1.0.2",
"electron-fetch": "^1.2.1",
"electron-progressbar": "1.1.0",
"electron-spellchecker": "^1.1.2",
"electron-updater": "^3.1.6",
"electron-window-state": "4.1.1",
Expand All @@ -120,6 +121,7 @@
"js-yaml": "^3.12.0",
"jszip": "3.1.5",
"lodash": "4.17.5",
"pretty-bytes": "5.1.0",
"promise": "7.1.1",
"prop-types": "15.6.0",
"randombytes": "2.0.6",
Expand Down

0 comments on commit ef1e0d3

Please sign in to comment.