From 79c445c5007026fe3badd8960cca9235c0988eb1 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Fri, 15 Sep 2017 23:49:21 +0900 Subject: [PATCH] Add notifyOnly auto-updater --- src/browser/components/UpdaterPage.jsx | 30 +++++++++++++--- src/browser/updater.jsx | 8 +++++ src/main.js | 3 +- src/main/autoUpdater.js | 49 ++++++++++++++++++++++---- 4 files changed, 78 insertions(+), 12 deletions(-) diff --git a/src/browser/components/UpdaterPage.jsx b/src/browser/components/UpdaterPage.jsx index d7c81019..3526b619 100644 --- a/src/browser/components/UpdaterPage.jsx +++ b/src/browser/components/UpdaterPage.jsx @@ -2,6 +2,25 @@ const React = require('react'); const propTypes = require('prop-types'); const {Button, Navbar} = require('react-bootstrap'); +function InstallButton(props) { + if (props.notifyOnly) { + return (); + } + return (); +} + +InstallButton.propTypes = { + notifyOnly: propTypes.bool.isRequired, + onClickInstall: propTypes.func.isRequired, + onClickDownload: propTypes.func.isRequired +}; + function UpdaterPage(props) { return (
@@ -33,10 +52,11 @@ function UpdaterPage(props) { bsStyle='link' onClick={props.onClickRemind} >{'Remind me in 2 days'} - +
@@ -44,7 +64,9 @@ function UpdaterPage(props) { } UpdaterPage.propTypes = { + notifyOnly: propTypes.bool.isRequired, onClickInstall: propTypes.func.isRequired, + onClickDownload: propTypes.func.isRequired, onClickReleaseNotes: propTypes.func.isRequired, onClickRemind: propTypes.func.isRequired, onClickSkip: propTypes.func.isRequired diff --git a/src/browser/updater.jsx b/src/browser/updater.jsx index c0b46f45..7d6cc606 100644 --- a/src/browser/updater.jsx +++ b/src/browser/updater.jsx @@ -1,10 +1,15 @@ const React = require('react'); const ReactDOM = require('react-dom'); const {ipcRenderer} = require('electron'); +const url = require('url'); const UpdaterPage = require('./components/UpdaterPage.jsx'); +const thisURL = url.parse(location.href, true); +const notifyOnly = thisURL.query.notifyOnly === 'true'; + ReactDOM.render( { ipcRenderer.send('click-release-notes'); }} @@ -17,6 +22,9 @@ ReactDOM.render( onClickInstall={() => { ipcRenderer.send('click-install'); }} + onClickDownload={() => { + ipcRenderer.send('click-download'); + }} />, document.getElementById('content') ); diff --git a/src/main.js b/src/main.js index ed1980c1..987b5f36 100644 --- a/src/main.js +++ b/src/main.js @@ -651,7 +651,8 @@ app.on('ready', () => { permissionManager = new PermissionManager(permissionFile, trustedURLs); session.defaultSession.setPermissionRequestHandler(permissionRequestHandler(mainWindow, permissionManager)); - autoUpdater.initialize(appState, mainWindow); + const updaterConfig = autoUpdater.loadConfig(path.resolve(app.getAppPath(), '../app-updater-config.json')); + autoUpdater.initialize(appState, mainWindow, updaterConfig.isNotifyOnly()); ipcMain.on('check-for-updates', autoUpdater.checkForUpdates); mainWindow.once('show', () => { if (autoUpdater.shouldCheckForUpdatesOnStart(appState.updateCheckedDate)) { diff --git a/src/main/autoUpdater.js b/src/main/autoUpdater.js index 8df2fb12..8d487932 100644 --- a/src/main/autoUpdater.js +++ b/src/main/autoUpdater.js @@ -1,4 +1,5 @@ const {app, BrowserWindow, dialog, ipcMain, shell} = require('electron'); +const fs = require('fs'); const path = require('path'); const {autoUpdater} = require('electron-updater'); const semver = require('semver'); @@ -37,10 +38,14 @@ function createUpdaterModal(parentWindow, options) { modal.once('ready-to-show', () => { modal.show(); }); - const updaterURL = (global.isDev ? 'http://localhost:8080' : `file://${app.getAppPath()}`) + '/browser/updater.html'; + let updaterURL = (global.isDev ? 'http://localhost:8080' : `file://${app.getAppPath()}`) + '/browser/updater.html'; + + if (options.notifyOnly) { + updaterURL += '?notifyOnly=true'; + } modal.loadURL(updaterURL); - for (const eventName of ['click-release-notes', 'click-skip', 'click-remind', 'click-install']) { + for (const eventName of ['click-release-notes', 'click-skip', 'click-remind', 'click-install', 'click-download']) { const listener = createEventListener(modal, eventName); ipcMain.on(eventName, listener); modal.on('closed', () => { @@ -73,13 +78,20 @@ function downloadAndInstall() { }); } -function initialize(appState, mainWindow) { +function initialize(appState, mainWindow, notifyOnly = false) { + autoUpdater.notifyOnly = notifyOnly; + if (notifyOnly) { + autoUpdater.autoDownload = false; + } const assetsDir = path.resolve(app.getAppPath(), 'assets'); autoUpdater.on('error', (err) => { console.error('Error in autoUpdater:', err.message); }).on('update-available', (info) => { if (isUpdateApplicable(new Date(), appState.skippedVersion, info)) { - updaterModal = createUpdaterModal(mainWindow, {linuxAppIcon: path.join(assetsDir, 'appicon.png'), nextVersion: '0.0.0'}); + updaterModal = createUpdaterModal(mainWindow, { + linuxAppIcon: path.join(assetsDir, 'appicon.png'), + notifyOnly: autoUpdater.notifyOnly + }); updaterModal.on('closed', () => { updaterModal = null; }); @@ -93,6 +105,8 @@ function initialize(appState, mainWindow) { }).on('click-install', () => { downloadAndInstall(); updaterModal.close(); + }).on('click-download', () => { + shell.openExternal('https://about.mattermost.com/download/#mattermostApps'); }).on('click-release-notes', () => { shell.openExternal(`https://github.com/mattermost/desktop/releases/v${info.version}`); }); @@ -115,7 +129,7 @@ function initialize(appState, mainWindow) { function shouldCheckForUpdatesOnStart(updateCheckedDate) { if (updateCheckedDate) { - if (Date.now() - updateCheckedDate < INTERVAL_48_HOURS_IN_MS) { + if (Date.now() - updateCheckedDate.getTime() < INTERVAL_48_HOURS_IN_MS) { return false; } } @@ -124,15 +138,36 @@ function shouldCheckForUpdatesOnStart(updateCheckedDate) { function checkForUpdates(isManual = false) { autoUpdater.isManual = isManual; - autoUpdater.autoDownload = false; if (!updaterModal) { autoUpdater.checkForUpdates(); } } +class AutoUpdaterConfig { + constructor(file) { + try { + this.data = JSON.parse(fs.readFileSync(file)); + } catch (err) { + this.data = {}; + } + } + + isNotifyOnly() { + if (this.data.notifyOnly === true) { + return true; + } + return false; + } +} + +function loadConfig(file) { + return new AutoUpdaterConfig(file); +} + module.exports = { INTERVAL_48_HOURS_IN_MS, checkForUpdates, shouldCheckForUpdatesOnStart, - initialize + initialize, + loadConfig };