2021-06-24 14:11:57 +00:00
|
|
|
/*
|
|
|
|
Copyright 2016-2021 New Vector 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.
|
|
|
|
*/
|
|
|
|
|
2022-12-05 12:41:13 +00:00
|
|
|
import { autoUpdater, ipcMain } from "electron";
|
2019-12-06 18:17:34 +00:00
|
|
|
|
|
|
|
const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000;
|
|
|
|
const INITIAL_UPDATE_DELAY_MS = 30 * 1000;
|
|
|
|
|
2021-06-25 13:35:58 +00:00
|
|
|
function installUpdate(): void {
|
2019-12-06 18:17:34 +00:00
|
|
|
// for some reason, quitAndInstall does not fire the
|
|
|
|
// before-quit event, so we need to set the flag here.
|
|
|
|
global.appQuitting = true;
|
|
|
|
autoUpdater.quitAndInstall();
|
|
|
|
}
|
|
|
|
|
2021-06-25 13:35:58 +00:00
|
|
|
function pollForUpdates(): void {
|
2019-12-06 18:17:34 +00:00
|
|
|
try {
|
2022-07-12 06:23:51 +00:00
|
|
|
// If we've already got a new update downloaded, then stop trying to check for new ones, as according to the doc
|
2022-07-03 15:38:17 +00:00
|
|
|
// at https://github.com/electron/electron/blob/main/docs/api/auto-updater.md#autoupdatercheckforupdates
|
|
|
|
// we'll just keep re-downloading the same update.
|
2022-07-12 06:23:51 +00:00
|
|
|
// As a hunch, this might also be causing https://github.com/vector-im/element-web/issues/12433
|
|
|
|
// due to the update checks colliding with the pending install somehow
|
2022-07-03 15:38:17 +00:00
|
|
|
if (!latestUpdateDownloaded) {
|
|
|
|
autoUpdater.checkForUpdates();
|
2022-07-03 15:41:51 +00:00
|
|
|
} else {
|
2022-07-03 15:38:17 +00:00
|
|
|
console.log("Skipping update check as download already present");
|
2022-12-15 11:00:58 +00:00
|
|
|
global.mainWindow?.webContents.send("update-downloaded", latestUpdateDownloaded);
|
2022-07-03 15:38:17 +00:00
|
|
|
}
|
2019-12-06 18:17:34 +00:00
|
|
|
} catch (e) {
|
2022-12-15 11:00:58 +00:00
|
|
|
console.log("Couldn't check for update", e);
|
2019-12-06 18:17:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-25 13:35:58 +00:00
|
|
|
export function start(updateBaseUrl: string): void {
|
2022-12-15 11:00:58 +00:00
|
|
|
if (updateBaseUrl.slice(-1) !== "/") {
|
|
|
|
updateBaseUrl = updateBaseUrl + "/";
|
2019-12-06 18:17:34 +00:00
|
|
|
}
|
|
|
|
try {
|
2022-07-12 06:23:51 +00:00
|
|
|
let url: string;
|
2022-12-05 12:41:13 +00:00
|
|
|
let serverType: "json" | undefined;
|
|
|
|
|
2022-12-15 11:00:58 +00:00
|
|
|
if (process.platform === "darwin") {
|
2022-12-05 12:41:13 +00:00
|
|
|
// On macOS it takes a JSON file with a map between versions and their URLs
|
|
|
|
url = `${updateBaseUrl}macos/releases.json`;
|
|
|
|
serverType = "json";
|
2022-12-15 11:00:58 +00:00
|
|
|
} else if (process.platform === "win32") {
|
2022-12-05 12:41:13 +00:00
|
|
|
// On windows it takes a base path and looks for files under that path.
|
2019-12-06 18:17:34 +00:00
|
|
|
url = `${updateBaseUrl}win32/${process.arch}/`;
|
|
|
|
} 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
|
|
|
|
// implemented it on Linux, or if it would be different again.
|
2022-12-15 11:00:58 +00:00
|
|
|
console.log("Auto update not supported on this platform");
|
2022-10-13 11:42:33 +00:00
|
|
|
return;
|
2019-12-06 18:17:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (url) {
|
2021-06-24 13:45:35 +00:00
|
|
|
console.log(`Update URL: ${url}`);
|
2022-12-05 12:41:13 +00:00
|
|
|
autoUpdater.setFeedURL({ url, serverType });
|
2019-12-06 18:17:34 +00:00
|
|
|
// We check for updates ourselves rather than using 'updater' because we need to
|
|
|
|
// do it in the main process (and we don't really need to check every 10 minutes:
|
|
|
|
// every hour should be just fine for a desktop app)
|
|
|
|
// However, we still let the main window listen for the update events.
|
|
|
|
// We also wait a short time before checking for updates the first time because
|
|
|
|
// of squirrel on windows and it taking a small amount of time to release a
|
|
|
|
// lock file.
|
|
|
|
setTimeout(pollForUpdates, INITIAL_UPDATE_DELAY_MS);
|
|
|
|
setInterval(pollForUpdates, UPDATE_POLL_INTERVAL_MS);
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
// will fail if running in debug mode
|
2022-12-15 11:00:58 +00:00
|
|
|
console.log("Couldn't enable update checking", err);
|
2019-12-06 18:17:34 +00:00
|
|
|
}
|
2021-06-25 13:35:58 +00:00
|
|
|
}
|
2019-12-06 18:17:34 +00:00
|
|
|
|
2022-12-15 11:00:58 +00:00
|
|
|
ipcMain.on("install_update", installUpdate);
|
|
|
|
ipcMain.on("check_updates", pollForUpdates);
|
2019-12-06 18:17:34 +00:00
|
|
|
|
2021-06-25 13:35:58 +00:00
|
|
|
function ipcChannelSendUpdateStatus(status: boolean | string): void {
|
2022-12-15 11:00:58 +00:00
|
|
|
global.mainWindow?.webContents.send("check_updates", status);
|
2019-12-06 18:17:34 +00:00
|
|
|
}
|
|
|
|
|
2021-06-25 13:35:58 +00:00
|
|
|
interface ICachedUpdate {
|
|
|
|
releaseNotes: string;
|
|
|
|
releaseName: string;
|
|
|
|
releaseDate: Date;
|
2021-07-01 08:22:57 +00:00
|
|
|
updateURL: string;
|
2021-06-25 13:35:58 +00:00
|
|
|
}
|
|
|
|
|
2020-06-05 17:36:10 +00:00
|
|
|
// cache the latest update which has been downloaded as electron offers no api to read it
|
2021-06-25 13:35:58 +00:00
|
|
|
let latestUpdateDownloaded: ICachedUpdate;
|
2022-12-15 11:00:58 +00:00
|
|
|
autoUpdater
|
|
|
|
.on("update-available", function () {
|
|
|
|
ipcChannelSendUpdateStatus(true);
|
|
|
|
})
|
|
|
|
.on("update-not-available", function () {
|
|
|
|
if (latestUpdateDownloaded) {
|
|
|
|
// the only time we will get `update-not-available` if `latestUpdateDownloaded` is already set
|
|
|
|
// is if the user used the Manual Update check and there is no update newer than the one we
|
|
|
|
// have downloaded, so show it to them as the latest again.
|
|
|
|
global.mainWindow?.webContents.send("update-downloaded", latestUpdateDownloaded);
|
|
|
|
} else {
|
|
|
|
ipcChannelSendUpdateStatus(false);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.on("error", function (error) {
|
|
|
|
ipcChannelSendUpdateStatus(error.message);
|
|
|
|
});
|
2020-06-05 17:36:10 +00:00
|
|
|
|
2022-12-15 11:00:58 +00:00
|
|
|
autoUpdater.on("update-downloaded", (ev, releaseNotes, releaseName, releaseDate, updateURL) => {
|
2020-06-05 17:36:10 +00:00
|
|
|
// forward to renderer
|
|
|
|
latestUpdateDownloaded = { releaseNotes, releaseName, releaseDate, updateURL };
|
2022-12-15 11:00:58 +00:00
|
|
|
global.mainWindow?.webContents.send("update-downloaded", latestUpdateDownloaded);
|
2020-06-05 17:36:10 +00:00
|
|
|
});
|