diff --git a/app/index.ts b/app/index.ts index 84a804a4da14..2717e4a1189c 100644 --- a/app/index.ts +++ b/app/index.ts @@ -34,6 +34,7 @@ import parseUrl from 'parse-url'; import * as AppMenu from './menus/menu'; import * as plugins from './plugins'; import {newWindow} from './ui/window'; +import {installUpdateIfNoWindows} from './updater'; import {installCLI} from './utils/cli-install'; import * as windowUtils from './utils/window-utils'; @@ -168,6 +169,9 @@ app.on('ready', () => }); app.on('window-all-closed', () => { + if (installUpdateIfNoWindows()) { + return; + } if (process.platform !== 'darwin') { app.quit(); } diff --git a/app/updater.ts b/app/updater.ts index c7d07d4d4f73..6cfcf9969a94 100644 --- a/app/updater.ts +++ b/app/updater.ts @@ -10,6 +10,7 @@ import autoUpdaterLinux from './auto-updater-linux'; import {getDefaultProfile} from './config'; import {version} from './package.json'; import {getDecoratedConfig} from './plugins'; +import {shouldAutoInstallUpdate} from './utils/should-auto-install-update'; const {platform} = process; const isLinux = platform === 'linux'; @@ -36,6 +37,15 @@ const checkForUpdates = async () => { let isInit = false; // Default to the "stable" update channel let canaryUpdates = false; +let updateReady = false; + +export function installUpdateIfNoWindows(): boolean { + if (!shouldAutoInstallUpdate(updateReady, app.getWindows().size, platform)) { + return false; + } + autoUpdater.quitAndInstall(); + return true; +} const buildFeedUrl = (canary: boolean, currentVersion: string) => { const updatePrefix = canary ? 'releases-canary' : 'releases'; @@ -61,6 +71,13 @@ async function init() { autoUpdater.setFeedURL({url: feedURL}); + if (!isLinux) { + autoUpdater.on('update-downloaded', () => { + updateReady = true; + installUpdateIfNoWindows(); + }); + } + setTimeout(() => { void checkForUpdates(); }, ms('10s')); diff --git a/app/utils/should-auto-install-update.ts b/app/utils/should-auto-install-update.ts new file mode 100644 index 000000000000..8a416e31be2e --- /dev/null +++ b/app/utils/should-auto-install-update.ts @@ -0,0 +1,7 @@ +export function shouldAutoInstallUpdate( + updateReady: boolean, + openWindowCount: number, + platform: NodeJS.Platform +): boolean { + return updateReady && openWindowCount === 0 && platform === 'darwin'; +} diff --git a/test/unit/updater.test.ts b/test/unit/updater.test.ts new file mode 100644 index 000000000000..7003506206b8 --- /dev/null +++ b/test/unit/updater.test.ts @@ -0,0 +1,24 @@ +import test from 'ava'; + +import {shouldAutoInstallUpdate} from '../../app/utils/should-auto-install-update'; + +test('installs on darwin when an update is ready and no windows are open', (t) => { + t.true(shouldAutoInstallUpdate(true, 0, 'darwin')); +}); + +test('does not install on win32 when an update is ready and no windows are open', (t) => { + t.false(shouldAutoInstallUpdate(true, 0, 'win32')); +}); + +test('does not install on linux when an update is ready and no windows are open', (t) => { + t.false(shouldAutoInstallUpdate(true, 0, 'linux')); +}); + +test('does not install while windows are still open', (t) => { + t.false(shouldAutoInstallUpdate(true, 1, 'darwin')); + t.false(shouldAutoInstallUpdate(true, 3, 'darwin')); +}); + +test('does not install when no update has been downloaded', (t) => { + t.false(shouldAutoInstallUpdate(false, 0, 'darwin')); +});