diff --git a/electron/build/install-spinner.gif b/electron/build/install-spinner.gif new file mode 100644 index 00000000..c4f832c3 Binary files /dev/null and b/electron/build/install-spinner.gif differ diff --git a/electron/img/riot.ico b/electron/img/riot.ico new file mode 100644 index 00000000..8b681ffb Binary files /dev/null and b/electron/img/riot.ico differ diff --git a/electron/src/electron-main.js b/electron/src/electron-main.js index a6e5a776..59cbca42 100644 --- a/electron/src/electron-main.js +++ b/electron/src/electron-main.js @@ -28,6 +28,16 @@ const url = require('url'); const VectorMenu = require('./vectormenu'); +let vectorConfig = {}; +try { + vectorConfig = require('../../vector/config.json'); +} catch (e) { + // it would be nice to check the error code here and bail if the config + // is unparseable, but we get MODULE_NOT_FOUND in the case of a missing + // file or invalid json, so node is just very unhelpful. + // Continue with the defaults (ie. an empty config) +} + const PERMITTED_URL_SCHEMES = [ 'http:', 'https:', @@ -91,19 +101,10 @@ function pollForUpdates() { } } -// handle uncaught errors otherwise it displays -// stack traces in popup dialogs, which is terrible (which -// it will do any time the auto update poke fails, and there's -// no other way to catch this error). -// Assuming we generally run from the console when developing, -// this is far preferable. -process.on('uncaughtException', function (error) { - console.log("Unhandled exception", error); -}); - -electron.ipcMain.on('install_update', installUpdate); - -electron.app.on('ready', () => { +function startAutoUpdate(update_url) { + if (update_url.slice(-1) !== '/') { + update_url = update_url + '/'; + } try { // For reasons best known to Squirrel, the way it checks for updates // is completely different between macOS and windows. On macOS, it @@ -111,9 +112,9 @@ electron.app.on('ready', () => { // 204 No Content. On windows it takes a base path and looks for // files under that path. if (process.platform == 'darwin') { - electron.autoUpdater.setFeedURL("https://riot.im/autoupdate/desktop/"); + electron.autoUpdater.setFeedURL(update_url); } else if (process.platform == 'win32') { - electron.autoUpdater.setFeedURL("https://riot.im/download/desktop/win32/"); + electron.autoUpdater.setFeedURL(update_url + 'win32/'); } else { // Squirrel / electron only supports auto-update on these two platforms. // I'm not even going to try to guess which feed style they'd use if they @@ -133,6 +134,27 @@ electron.app.on('ready', () => { // will fail if running in debug mode console.log("Couldn't enable update checking", err); } +} + +// handle uncaught errors otherwise it displays +// stack traces in popup dialogs, which is terrible (which +// it will do any time the auto update poke fails, and there's +// no other way to catch this error). +// Assuming we generally run from the console when developing, +// this is far preferable. +process.on('uncaughtException', function (error) { + console.log("Unhandled exception", error); +}); + +electron.ipcMain.on('install_update', installUpdate); + +electron.app.on('ready', () => { + if (vectorConfig.update_url) { + console.log("Starting auto update with URL: " + vectorConfig.update_url); + startAutoUpdate(vectorConfig.update_url); + } else { + console.log("No update_url is defined: auto update is disabled"); + } mainWindow = new electron.BrowserWindow({ icon: `${__dirname}/../img/riot.ico`, diff --git a/electron/src/squirrelhooks.js b/electron/src/squirrelhooks.js new file mode 100644 index 00000000..10fb8d9e --- /dev/null +++ b/electron/src/squirrelhooks.js @@ -0,0 +1,30 @@ +const path = require('path'); +const spawn = require('child_process').spawn; +const app = require('electron').app; + +function run_update_exe(args, done) { + const updateExe = path.resolve(path.dirname(process.execPath), '..', 'Update.exe'); + spawn(updateExe, args, { + detached: true + }).on('close', done); +}; + +function check_squirrel_hooks() { + if (process.platform != 'win32') return false; + + const cmd = process.argv[1]; + const target = path.basename(process.execPath); + if (cmd === '--squirrel-install' || cmd === '--squirrel-updated') { + run_update_exe(['--createShortcut=' + target + ''], app.quit); + return true; + } else if (cmd === '--squirrel-uninstall') { + run_update_exe(['--removeShortcut=' + target + ''], app.quit); + return true; + } else if (cmd === '--squirrel-obsolete') { + app.quit(); + return true; + } + return false; +} + +module.exports = check_squirrel_hooks; diff --git a/src/skins/vector/css/matrix-react-sdk/views/rooms/RoomSettings.css b/src/skins/vector/css/matrix-react-sdk/views/rooms/RoomSettings.css index 1fd8349a..6a3b1ac8 100644 --- a/src/skins/vector/css/matrix-react-sdk/views/rooms/RoomSettings.css +++ b/src/skins/vector/css/matrix-react-sdk/views/rooms/RoomSettings.css @@ -20,7 +20,9 @@ limitations under the License. } .mx_RoomSettings_leaveButton, -.mx_RoomSettings_integrationsButton { +.mx_RoomSettings_integrationsButton, +.mx_RoomSettings_integrationsButton_error { + position: relative; height: 36px; background-color: #76cfa6; border-radius: 36px; @@ -33,6 +35,21 @@ limitations under the License. padding-left: 12px; padding-right: 12px; } +.mx_RoomSettings_integrationsButton_error { + pointer: not-allowed; +} +.mx_RoomSettings_integrationsButton_errorPopup { + position: absolute; + top: 110%; + left: -26%; + width: 150%; + padding: 2%; + font-size: 10pt; + line-height: 1.5em; + border-radius: 5px; + background-color: #000; + color: #fff; +} .mx_RoomSettings_e2eIcon { padding-left: 4px;