Skip to content

Commit

Permalink
Merge pull request #411 from RocketChat/feature/update
Browse files Browse the repository at this point in the history
Auto update when new version is released
  • Loading branch information
engelgabriel authored Apr 11, 2017
2 parents 50ac357 + 95ec9a8 commit 866031d
Show file tree
Hide file tree
Showing 8 changed files with 369 additions and 48 deletions.
4 changes: 3 additions & 1 deletion build/win/installer.nsh
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@
!macroend

!macro customUnInstall
Delete "$SMSTARTUP\Rocket.Chat+.lnk"
${IfNot} ${Silent}
Delete "$SMSTARTUP\Rocket.Chat+.lnk"
${endif}
!macroend
13 changes: 11 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Rocket.Chat Native Cross-Platform Desktop Application via Electron.",
"version": "2.7.0-develop",
"author": "Rocket.Chat Support <[email protected]>",
"copyright": "© 2016, Rocket.Chat",
"copyright": "© 2017, Rocket.Chat",
"homepage": "https://rocket.chat",
"license": "MIT",
"main": "app/background.js",
Expand Down Expand Up @@ -48,7 +48,15 @@
"deb",
"rpm"
]
},
"publish": [
{
"provider": "github",
"owner": "RocketChat",
"repo": "Rocket.Chat.Electron",
"vPrefixedTagName": false
}
]
},
"scripts": {
"postinstall": "install-app-deps && electron-rebuild",
Expand All @@ -64,6 +72,7 @@
},
"dependencies": {
"@paulcbetts/system-idle-time": "^1.0.4",
"electron-updater": "^1.11.2",
"fs-jetpack": "^0.13.3",
"lodash": "^4.17.4",
"spellchecker": "^3.3.1"
Expand All @@ -72,8 +81,8 @@
"chai": "^3.5.0",
"electron": "^1.6.2",
"electron-builder": "^16.8.2",
"electron-rebuild": "^1.5.7",
"electron-mocha": "^3.4.0",
"electron-rebuild": "^1.5.7",
"gulp": "^3.9.1",
"gulp-batch": "^1.0.5",
"gulp-less": "^3.3.0",
Expand Down
3 changes: 3 additions & 0 deletions src/background.custom.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import windowStateKeeper from './background/windowState';
import certificate from './background/certificate';
import Toaster from './Toaster';
import idle from '@paulcbetts/system-idle-time';
import { checkForUpdates } from './background/autoUpdate';

process.env.GOOGLE_API_KEY = 'AIzaSyADqUh_c1Qhji3Cp1NE43YrcpuPkmhXD-c';

Expand Down Expand Up @@ -145,4 +146,6 @@ export function afterMainWindow (mainWindow) {
}

certificate.initWindow(mainWindow);

checkForUpdates();
}
128 changes: 128 additions & 0 deletions src/background/autoUpdate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { app, ipcMain, BrowserWindow, dialog } from 'electron';
import { autoUpdater } from 'electron-updater';
import jetpack from 'fs-jetpack';

const userDataDir = jetpack.cwd(app.getPath('userData'));
const updateStoreFile = 'update.json';
let checkForUpdatesEvent;

autoUpdater.autoDownload = false;

let updateFile = {};
try {
updateFile = userDataDir.read(updateStoreFile, 'json') || {};
} catch (err) {
console.log(err);
}

function updateDownloaded () {
dialog.showMessageBox({
title: 'Update Ready to Install',
message: 'Update has been downloaded',
buttons: [
'Install Later',
'Install Now'
],
defaultId: 1
}, (response) => {
if (response === 0) {
dialog.showMessageBox({
title: 'Installing Later',
message: 'Update will be installed when you exit the app'
});
} else {
autoUpdater.quitAndInstall();
}
});
}

function updateAvailable ({version}) {
if (checkForUpdatesEvent) {
checkForUpdatesEvent.sender.send('update-result', true);
} else if (updateFile.skip === version) {
console.log(`Skipping version: ${version}`);
return;
}

let window = new BrowserWindow({
title: 'Update Available',
width: 600,
height: 330,
show : false,
center: true,
resizable: false,
maximizable: false,
minimizable: false
});

window.loadURL(`file://${__dirname}/public/update.html`);
window.setMenuBarVisibility(false);

window.webContents.on('did-finish-load', () => {
window.webContents.send('new-version', version);
window.show();
});

ipcMain.once('update-response', (e, type) => {
switch (type) {
case 'skip':
updateFile.skip = version;
userDataDir.write(updateStoreFile, updateFile, { atomic: true });
dialog.showMessageBox({
title: 'Skip Update',
message: 'We will notify you when the next update is available\n' +
'If you change your mind you can check for updates from the About menu.'
}, () => window.close());
break;
case 'remind':
dialog.showMessageBox({
title: 'Remind Later',
message: 'We will remind you next time you start the app'
}, () => window.close());
break;
case 'update':
dialog.showMessageBox({
title: 'Downloading Update',
message: 'You will be notified when the update is ready to be installed'
}, () => window.close());
autoUpdater.downloadUpdate();
break;
}
});

window.on('closed', () => {
window = null;
ipcMain.removeAllListeners('update-response');
});
}

function checkForUpdates () {
autoUpdater.on('update-available', updateAvailable);

autoUpdater.on('download-progress', ({percent}) => {
console.log(`Update progress: ${percent}`);
});

autoUpdater.on('update-downloaded', updateDownloaded);

// Event from about window
ipcMain.on('check-for-updates', (e, autoUpdate) => {
if (autoUpdate === true || autoUpdate === false) {
updateFile.autoUpdate = autoUpdate;
userDataDir.write(updateStoreFile, updateFile, { atomic: true });
} else if (autoUpdate === 'auto') {
e.returnValue = updateFile.autoUpdate;
} else {
checkForUpdatesEvent = e;
autoUpdater.checkForUpdates();
}
});

if (updateFile.autoUpdate !== false) {
autoUpdater.checkForUpdates();
}
}

export {
checkForUpdates
};
59 changes: 53 additions & 6 deletions src/public/about.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
<head>
<title></title>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="../stylesheets/main.css">

<style>
html {
background-color: #ececec;
Expand All @@ -26,26 +28,71 @@
}

.app-version {
margin-top: 15px;
font-size: 11px;
position: fixed;
bottom: 30px;
}

.app-version .version {
font-weight: bold;
}

.update {
margin-top:10px;
}

.copyright {
font-size: 10px;
position: absolute;
bottom: 0;
margin-left: auto;
margin-right: auto;
left: 0;
right: 0;
}

.auto-update-container {
margin: 5px 0;
}
</style>
</head>
<body>
<img src="images/icon.png">
<div class="app-name">

</div>
<div class="app-version">
<div class="app-version"></div>
<span class="update-spin icon-spin3 animate-spin" style="display:none;"></span>

</div>
<button class="update">Check for Updates</button>
<p class="auto-update-container"><input type="checkbox" id="auto-update" checked /> Check for Updates on Start</p>
<p class="copyright">Copyright &copy; 2017, Rocket.Chat</p>
<script>
var remote = require('electron').remote;
const { remote, ipcRenderer } = require('electron');
const autoUpdate = ipcRenderer.sendSync('check-for-updates', 'auto');
if (!autoUpdate) {
document.querySelector('#auto-update').removeAttribute('checked');
}
document.querySelector('.app-name').innerHTML = remote.app.getName();
document.querySelector('.app-version').innerHTML = 'Version '+remote.app.getVersion();
document.querySelector('.app-version').innerHTML = `Version <span class="version">${remote.app.getVersion()}</span>`;
document.querySelector('.update').onclick = function(e) {
document.querySelector('.update-spin').setAttribute('style', '');
document.querySelector('.update').setAttribute('disabled', 'disabled');
ipcRenderer.send('check-for-updates');

}
document.querySelector('#auto-update').onclick = function(e) {
ipcRenderer.send('check-for-updates', e.target.checked);
}
ipcRenderer.on('update-result', (e, updateAvailable) => {
document.querySelector('.update-spin').setAttribute('style', 'display:none');
document.querySelector('.update').removeAttribute('disabled');
if (!updateAvailable) {
alert('No updates are available');
}
});



</script>
</body>
</html>
103 changes: 103 additions & 0 deletions src/public/update.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<!doctype html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<style>
html {
background-color: #ececec;
font-family: helvetica;
padding: 10px;
}

body {
margin: 0px;
text-align: center;
}

img {
height: 60px;
margin-bottom: 10px;
}

table {
margin: 0 auto;
}

.update {
font-size: 15px;
font-weight: bold;
color: #fff;
background-color: #13679a;
border-width: 0;
padding: 6px 8px;
border-radius: 4px;
cursor: pointer;
position: fixed;
right: 10px;
bottom: 5px;
}

.skip {
position: fixed;
left: 10px;
}

.remind {
position: fixed;
right: 150px;
}

.controls {
font-size: 12px;
position: fixed;
bottom: 15px;
}

.controls a {
text-decoration: none;
}

.old, .new {
font-weight: bold;
}
</style>
</head>
<body>
<h3>New Update is Available</h3>
<hr />
<div style="text-align:center;">
<img src="images/icon.png"/>
<p>A new version of the Rocket.Chat Desktop App is available!</p>
<table>
<tr>
<td style="text-align:right;">Current Version:</td>
<td class="old"></td>
</tr>
<tr>
<td style="text-align:right;">New Version:</td>
<td class="new"></td>
</tr>
</table>
</div>
<hr />
<p class="controls">
<a class="skip response" data-type="skip" href="#">Skip This Version</a>
<a class="remind response" data-type="remind" href="#">Remind Me Later</a>
<button class="update response" data-type="update">Install Update</button>
</p>
<script>
const remote = require('electron').remote;
require('electron').ipcRenderer.on('new-version', function(e, version) {
document.querySelector('.old').innerHTML = remote.app.getVersion();
document.querySelector('.new').innerHTML = version;
});
document.querySelectorAll('.response').forEach((item) => {
item.onclick = function(e) {
const type = e.target.getAttribute('data-type');
require('electron').ipcRenderer.send('update-response', type);
}
});
</script>
</body>
</html>
Loading

0 comments on commit 866031d

Please sign in to comment.