diff --git a/electron_app/src/electron-main.js b/electron_app/src/electron-main.js
index ef0d173c..f1a9e37a 100644
--- a/electron_app/src/electron-main.js
+++ b/electron_app/src/electron-main.js
@@ -120,6 +120,7 @@ process.on('uncaughtException', function(error) {
});
electron.ipcMain.on('install_update', installUpdate);
+electron.ipcMain.on('checkForUpdates', pollForUpdates);
let focusHandlerAttached = false;
electron.ipcMain.on('setBadgeCount', function(ev, count) {
diff --git a/src/components/views/globals/UpdateCheckBar.js b/src/components/views/globals/UpdateCheckBar.js
new file mode 100644
index 00000000..65fe84c9
--- /dev/null
+++ b/src/components/views/globals/UpdateCheckBar.js
@@ -0,0 +1,89 @@
+/*
+Copyright 2015, 2016 OpenMarket Ltd
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+'use strict';
+
+import React from 'react';
+import dis from 'matrix-react-sdk/lib/dispatcher';
+import { _t } from 'matrix-react-sdk/lib/languageHandler';
+import PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg';
+import {updateStateEnum} from '../../../vector/platform/VectorBasePlatform';
+import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton';
+
+export default React.createClass({
+
+ getInitialState: function() {
+ return {
+ message: 'Checking for an update...',
+ done: false,
+ };
+ },
+
+ componentWillMount: function() {
+ PlatformPeg.get().checkForUpdate().done((state) => {
+ if (this._unmounted) return;
+
+ console.log('checkForUpdate done, ', state);
+
+ // We will be replaced by NewVersionBar
+ if (state === updateStateEnum.Ready) return;
+
+ let done = true;
+ let message;
+ switch (state) {
+ case updateStateEnum.Error:
+ message = 'Error encountered when checking for an update';
+ break;
+ case updateStateEnum.NotAvailable:
+ message = 'No update found';
+ break;
+ case updateStateEnum.Downloading:
+ message = 'Update is being downloaded';
+ done = false;
+ break;
+ }
+
+ this.setState({message, done});
+ });
+ },
+
+ componentWillUnmount: function() {
+ this._unmounted = true;
+ },
+
+ hideToolbar: function() {
+ dis.dispatch({
+ action: 'check_updates',
+ value: false,
+ });
+ },
+
+ render: function() {
+ const imgSrc = this.state.done ? 'img/warning.svg' : 'img/spinner.gif';
+
+ return (
+
+
+
+ {this.state.message}
+
+
+
+
+
+ );
+ }
+});
diff --git a/src/vector/platform/ElectronPlatform.js b/src/vector/platform/ElectronPlatform.js
index fa0f999c..1ed1c0d8 100644
--- a/src/vector/platform/ElectronPlatform.js
+++ b/src/vector/platform/ElectronPlatform.js
@@ -17,7 +17,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import VectorBasePlatform from './VectorBasePlatform';
+import VectorBasePlatform, {updateStateEnum} from './VectorBasePlatform';
import dis from 'matrix-react-sdk/lib/dispatcher';
import { _t } from 'matrix-react-sdk/lib/languageHandler';
import q from 'q';
@@ -66,6 +66,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
constructor() {
super();
dis.register(_onAction);
+ this.updatable = Boolean(remote.autoUpdater.getFeedURL());
}
getHumanReadableName(): string {
@@ -137,10 +138,28 @@ export default class ElectronPlatform extends VectorBasePlatform {
return q(remote.app.getVersion());
}
- pollForUpdate() {
- // In electron we control the update process ourselves, since
- // it needs to run in the main process, so we just run the timer
- // loop in the main electron process instead.
+ checkForUpdate() { // manual update check for this platform
+ const deferred = q.defer();
+
+ const _onUpdateAvailable = function() {
+ electron.autoUpdater.removeListener('update-not-available', _onUpdateNotAvailable);
+ deferred.resolve(updateStateEnum.Downloading);
+ }
+
+ const _onUpdateNotAvailable = function() {
+ electron.autoUpdater.removeListener('update-available', _onUpdateAvailable);
+ deferred.resolve(updateStateEnum.NotAvailable);
+ }
+
+ electron.autoUpdater.once('update-available', _onUpdateAvailable);
+ electron.autoUpdater.once('update-not-available', _onUpdateNotAvailable);
+
+ electron.ipcRenderer.send('checkForUpdates');
+ return deferred.promise.timeout(10000).catch(() => {
+ electron.autoUpdater.removeListener('update-not-available', _onUpdateNotAvailable);
+ electron.autoUpdater.removeListener('update-available', _onUpdateAvailable);
+ return updateStateEnum.Error;
+ });
}
installUpdate() {
diff --git a/src/vector/platform/VectorBasePlatform.js b/src/vector/platform/VectorBasePlatform.js
index 8e998402..5ae620cb 100644
--- a/src/vector/platform/VectorBasePlatform.js
+++ b/src/vector/platform/VectorBasePlatform.js
@@ -22,6 +22,13 @@ import { _t } from 'matrix-react-sdk/lib/languageHandler';
import Favico from 'favico.js';
+export const updateStateEnum = {
+ Error: -1,
+ NotAvailable: 0,
+ Downloading: 1,
+ Ready: 2,
+};
+
/**
* Vector-specific extensions to the BasePlatform template
*/
@@ -35,6 +42,7 @@ export default class VectorBasePlatform extends BasePlatform {
// so we'd need to fix that if enabling the animation.
this.favicon = new Favico({animation: 'none'});
this._updateFavicon();
+ this.updatable = true;
}
getHumanReadableName(): string {
@@ -80,13 +88,21 @@ export default class VectorBasePlatform extends BasePlatform {
startUpdater() {
}
+ /**
+ * Whether we can call checkForUpdate on this platform build
+ */
+ canSelfUpdate(): boolean {
+ return this.updatable;
+ }
+
/**
* Check for the availability of an update to the version of the
* app that's currently running.
* If an update is available, this function should dispatch the
* 'new_version' action.
+ * @returns Promise
*/
- pollForUpdate() {
+ checkForUpdate(): Promise {
}
/**
diff --git a/src/vector/platform/WebPlatform.js b/src/vector/platform/WebPlatform.js
index c589af38..318a3fe9 100644
--- a/src/vector/platform/WebPlatform.js
+++ b/src/vector/platform/WebPlatform.js
@@ -17,7 +17,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import VectorBasePlatform from './VectorBasePlatform';
+import VectorBasePlatform, {updateStateEnum} from './VectorBasePlatform';
import request from 'browser-request';
import dis from 'matrix-react-sdk/lib/dispatcher.js';
import { _t } from 'matrix-react-sdk/lib/languageHandler';
@@ -135,12 +135,12 @@ export default class WebPlatform extends VectorBasePlatform {
}
startUpdater() {
- this.pollForUpdate();
- setInterval(this.pollForUpdate, POKE_RATE_MS);
+ this.checkForUpdate();
+ setInterval(this.checkForUpdate, POKE_RATE_MS);
}
- pollForUpdate() {
- this._getVersion().done((ver) => {
+ checkForUpdate() {
+ return this._getVersion().then((ver) => {
if (this.runningVersion === null) {
this.runningVersion = ver;
} else if (this.runningVersion !== ver) {
@@ -149,9 +149,12 @@ export default class WebPlatform extends VectorBasePlatform {
currentVersion: this.runningVersion,
newVersion: ver,
});
+ return updateStateEnum.Ready;
}
+ return updateStateEnum.NotAvailable;
}, (err) => {
console.error("Failed to poll for update", err);
+ return updateStateEnum.Error;
});
}