From 9a41b9e192749920f7fac6846f477ce39cccf39f Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Tue, 30 Jan 2018 22:35:50 +0000 Subject: [PATCH] Electron: Improved auto-update process to avoid random crashes --- ElectronClient/app/app.js | 8 +++- ElectronClient/app/bridge.js | 5 ++ ElectronClient/app/checkForUpdates.js | 67 +++++++++++++++++++++++++++ ReactNativeClient/lib/logger.js | 4 ++ 4 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 ElectronClient/app/checkForUpdates.js diff --git a/ElectronClient/app/app.js b/ElectronClient/app/app.js index 3dbedb922..deda6d727 100644 --- a/ElectronClient/app/app.js +++ b/ElectronClient/app/app.js @@ -43,6 +43,7 @@ class Application extends BaseApplication { constructor() { super(); this.lastMenuScreen_ = null; + this.checkForUpdateLoggerPath_ = Setting.value('profileDir') + '/log-autoupdater.txt'; } hasGui() { @@ -294,6 +295,11 @@ class Application extends BaseApplication { label: _('Website and documentation'), accelerator: 'F1', click () { bridge().openExternal('http://joplin.cozic.net') } + }, { + label: _('Check for updates...'), + click: () => { + bridge().checkForUpdates(false, this.checkForUpdateLoggerPath_); + } }, { label: _('About Joplin'), click: () => { @@ -387,7 +393,7 @@ class Application extends BaseApplication { if (shim.isWindows() || shim.isMac()) { const runAutoUpdateCheck = function() { if (Setting.value('autoUpdateEnabled')) { - bridge().checkForUpdatesAndNotify(Setting.value('profileDir') + '/log-autoupdater.txt'); + bridge().checkForUpdates(true, this.checkForUpdateLoggerPath_); } } diff --git a/ElectronClient/app/bridge.js b/ElectronClient/app/bridge.js index da7995fb8..00ae3dfc0 100644 --- a/ElectronClient/app/bridge.js +++ b/ElectronClient/app/bridge.js @@ -125,6 +125,11 @@ class Bridge { } } + checkForUpdates(inBackground, logFilePath) { + const { checkForUpdates } = require('./checkForUpdates.js'); + checkForUpdates(inBackground, logFilePath); + } + } let bridge_ = null; diff --git a/ElectronClient/app/checkForUpdates.js b/ElectronClient/app/checkForUpdates.js new file mode 100644 index 000000000..1ce1ad6b6 --- /dev/null +++ b/ElectronClient/app/checkForUpdates.js @@ -0,0 +1,67 @@ +const { dialog } = require('electron') +const { autoUpdater } = require('electron-updater') +const { Logger } = require('lib/logger.js'); +const { _ } = require('lib/locale.js'); + +let autoUpdateLogger_ = new Logger(); +let checkInBackground_ = false; + +autoUpdater.autoDownload = false; + +autoUpdater.on('error', (error) => { + autoUpdateLogger_.error(error); + if (checkInBackground_) return; + dialog.showErrorBox(_('Error'), error == null ? "unknown" : (error.stack || error).toString()) +}) + +autoUpdater.on('update-available', () => { + dialog.showMessageBox({ + type: 'info', + message: _('An update is available, do you want to update now?'), + buttons: ['Sure', 'No'] + }, (buttonIndex) => { + if (buttonIndex === 0) { + try { + autoUpdater.downloadUpdate() + } catch (error) { + autoUpdateLogger_.error(error); + dialog.showErrorBox(_('Error'), _('Could not download the update: %s', error.message)); + } + } + }) +}) + +autoUpdater.on('update-not-available', () => { + if (checkInBackground_) return; + + dialog.showMessageBox({ message: _('Current version is up-to-date.') }) +}) + +autoUpdater.on('update-downloaded', () => { + dialog.showMessageBox({ message: _('New version downloaded - application will quit now and update...') }, () => { + setTimeout(() => { + try { + autoUpdater.quitAndInstall(); + } catch (error) { + autoUpdateLogger_.error(error); + dialog.showErrorBox(_('Error'), _('Could not install the update: %s', error.message)); + } + }, 100); + }) +}) + +function checkForUpdates(inBackground, logFilePath) { + if (logFilePath && !autoUpdateLogger_.targets().length) { + autoUpdateLogger_ = new Logger(); + autoUpdateLogger_.addTarget('file', { path: logFilePath }); + autoUpdateLogger_.setLevel(Logger.LEVEL_DEBUG); + autoUpdateLogger_.info('checkForUpdates: Initializing...'); + autoUpdater.logger = autoUpdateLogger_; + } + + checkInBackground_ = inBackground; + + autoUpdater.checkForUpdates() +} + +module.exports.checkForUpdates = checkForUpdates \ No newline at end of file diff --git a/ReactNativeClient/lib/logger.js b/ReactNativeClient/lib/logger.js index 15ba1084e..9e68e91fc 100644 --- a/ReactNativeClient/lib/logger.js +++ b/ReactNativeClient/lib/logger.js @@ -25,6 +25,10 @@ class Logger { return this.level_; } + targets() { + return this.targets_; + } + clearTargets() { this.targets_.clear(); }