* feat: only send auto update notification when user indicated the update * fix: add more logging to the auto update process
155 lines
5.6 KiB
TypeScript
155 lines
5.6 KiB
TypeScript
import { ipcMain, BrowserWindow } from 'electron';
|
|
import { autoUpdater } from 'electron-updater';
|
|
import { UpdateInfo, ProgressInfo } from 'builder-util-runtime';
|
|
import * as settings from 'electron-settings';
|
|
import * as isDev from 'electron-is-dev';
|
|
import * as storage from 'electron-settings';
|
|
|
|
import { IpcEvents, LogService } from 'uhk-common';
|
|
import { MainServiceBase } from './main-service-base';
|
|
|
|
export class AppUpdateService extends MainServiceBase {
|
|
|
|
private sendAutoUpdateNotification = false;
|
|
|
|
constructor(protected logService: LogService,
|
|
protected win: Electron.BrowserWindow,
|
|
private app: Electron.App) {
|
|
super(logService, win);
|
|
|
|
this.initListeners();
|
|
logService.info('[AppUpdateService] init success');
|
|
}
|
|
|
|
saveFirtsRun() {
|
|
settings.set('firstRunVersion', this.app.getVersion());
|
|
}
|
|
|
|
private initListeners() {
|
|
autoUpdater.on('checking-for-update', () => {
|
|
this.logService.debug('[AppUpdateService] checking for update');
|
|
this.sendIpcToWindow(IpcEvents.autoUpdater.checkingForUpdate);
|
|
});
|
|
|
|
autoUpdater.on('update-available', async (ev: any, info: UpdateInfo) => {
|
|
this.logService.debug('[AppUpdateService] update available. Downloading started');
|
|
await autoUpdater.downloadUpdate();
|
|
this.sendIpcToWindow(IpcEvents.autoUpdater.updateAvailable, info);
|
|
});
|
|
|
|
autoUpdater.on('update-not-available', (ev: any, info: UpdateInfo) => {
|
|
if (this.sendAutoUpdateNotification) {
|
|
this.logService.debug('[AppUpdateService] update not available');
|
|
this.sendIpcToWindow(IpcEvents.autoUpdater.updateNotAvailable, info);
|
|
}
|
|
});
|
|
|
|
autoUpdater.on('error', (ev: any, err: string) => {
|
|
this.logService.error('[AppUpdateService] error', err);
|
|
let msg = 'Electron updater error';
|
|
if (err) {
|
|
msg = err.substr(0, 100);
|
|
}
|
|
|
|
this.sendIpcToWindow(IpcEvents.autoUpdater.autoUpdateError, msg);
|
|
});
|
|
|
|
autoUpdater.on('download-progress', (progressObj: ProgressInfo) => {
|
|
this.sendIpcToWindow(IpcEvents.autoUpdater.autoUpdateDownloadProgress, progressObj);
|
|
});
|
|
|
|
autoUpdater.on('update-downloaded', (ev: any, info: UpdateInfo) => {
|
|
this.logService.debug('[AppUpdateService] update downloaded');
|
|
this.sendIpcToWindow(IpcEvents.autoUpdater.autoUpdateDownloaded, info);
|
|
});
|
|
|
|
ipcMain.on(IpcEvents.autoUpdater.updateAndRestart, () => {
|
|
this.logService.debug('[AppUpdateService] update and restart from renderer process');
|
|
return autoUpdater.quitAndInstall(true);
|
|
});
|
|
|
|
ipcMain.on(IpcEvents.app.appStarted, () => {
|
|
if (this.checkForUpdateAtStartup()) {
|
|
this.sendAutoUpdateNotification = false;
|
|
this.logService.debug('[AppUpdateService] app started. Automatically check for update.');
|
|
this.checkForUpdate();
|
|
}
|
|
});
|
|
|
|
ipcMain.on(IpcEvents.autoUpdater.checkForUpdate, () => {
|
|
this.logService.debug('[AppUpdateService] checkForUpdate request from renderer process');
|
|
this.sendAutoUpdateNotification = true;
|
|
this.checkForUpdate();
|
|
});
|
|
}
|
|
|
|
private checkForUpdate() {
|
|
if (isDev) {
|
|
const msg = '[AppUpdateService] Application update is not working in dev mode.';
|
|
this.logService.info(msg);
|
|
|
|
if (this.sendAutoUpdateNotification) {
|
|
this.sendIpcToWindow(IpcEvents.autoUpdater.checkForUpdateNotAvailable, msg);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (this.isFirstRun()) {
|
|
const msg = '[AppUpdateService] Application update is skipping at first run.';
|
|
this.logService.info(msg);
|
|
|
|
if (this.sendAutoUpdateNotification) {
|
|
this.sendIpcToWindow(IpcEvents.autoUpdater.checkForUpdateNotAvailable, msg);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
autoUpdater.allowPrerelease = this.allowPreRelease();
|
|
autoUpdater.checkForUpdates()
|
|
.then(() => {
|
|
this.logService.debug('[AppUpdateService] checkForUpdate success');
|
|
})
|
|
.catch(error => {
|
|
this.logService.error('[AppUpdateService] checkForUpdate error:', error);
|
|
});
|
|
}
|
|
|
|
private isFirstRun() {
|
|
if (!settings.has('firstRunVersion')) {
|
|
return true;
|
|
}
|
|
const firstRunVersion = settings.get('firstRunVersion');
|
|
this.logService.info(`firstRunVersion: ${firstRunVersion}`);
|
|
this.logService.info(`package.version: ${this.app.getVersion()}`);
|
|
|
|
return firstRunVersion !== this.app.getVersion();
|
|
}
|
|
|
|
private allowPreRelease() {
|
|
const autoUpdateSettings = this.getAutoUpdateSettings();
|
|
|
|
return autoUpdateSettings && autoUpdateSettings.usePreReleaseUpdate;
|
|
}
|
|
|
|
private checkForUpdateAtStartup() {
|
|
const autoUpdateSettings = this.getAutoUpdateSettings();
|
|
const checkForUpdate = autoUpdateSettings && autoUpdateSettings.checkForUpdateOnStartUp;
|
|
|
|
this.logService.debug('[AppUpdateService] check for update at startup:', {checkForUpdate, autoUpdateSettings});
|
|
|
|
return checkForUpdate;
|
|
}
|
|
|
|
private getAutoUpdateSettings() {
|
|
const value = storage.get('auto-update-settings');
|
|
if (!value) {
|
|
return {checkForUpdateOnStartUp: false, usePreReleaseUpdate: false};
|
|
}
|
|
|
|
return JSON.parse(<string>value);
|
|
}
|
|
|
|
}
|