Retry updater when in-call app close is cancelled

This commit is contained in:
ayumi-signal 2024-02-26 16:18:50 -08:00 committed by GitHub
parent ab1ae26489
commit 9d2a043191
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 50 additions and 7 deletions

View file

@ -871,6 +871,7 @@ async function createWindow() {
); );
} }
if (!shouldClose) { if (!shouldClose) {
updater.onRestartCancelled();
return; return;
} }

View file

@ -7,6 +7,10 @@ export function markShouldQuit(): void {
shouldQuitFlag = true; shouldQuitFlag = true;
} }
export function markShouldNotQuit(): void {
shouldQuitFlag = false;
}
export function shouldQuit(): boolean { export function shouldQuit(): boolean {
return shouldQuitFlag; return shouldQuitFlag;
} }

View file

@ -21,6 +21,7 @@ import { app, ipcMain } from 'electron';
import * as durations from '../util/durations'; import * as durations from '../util/durations';
import { getTempPath, getUpdateCachePath } from '../../app/attachments'; import { getTempPath, getUpdateCachePath } from '../../app/attachments';
import { markShouldNotQuit, markShouldQuit } from '../../app/window_state';
import { DialogType } from '../types/Dialogs'; import { DialogType } from '../types/Dialogs';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
import { isAlpha, isBeta, isStaging } from '../util/version'; import { isAlpha, isBeta, isStaging } from '../util/version';
@ -117,6 +118,8 @@ export abstract class Updater {
private markedCannotUpdate = false; private markedCannotUpdate = false;
private restarting = false;
private readonly canRunSilently: () => boolean; private readonly canRunSilently: () => boolean;
constructor({ constructor({
@ -148,6 +151,26 @@ export abstract class Updater {
return this.checkForUpdatesMaybeInstall(true); return this.checkForUpdatesMaybeInstall(true);
} }
// If the updater was about to restart the app but the user cancelled it, show dialog
// to let them retry the restart
public onRestartCancelled(): void {
if (!this.restarting) {
return;
}
this.logger.info(
'updater/onRestartCancelled: restart was cancelled. showing update dialog.'
);
this.restarting = false;
markShouldNotQuit();
const mainWindow = this.getMainWindow();
mainWindow?.webContents.send(
'show-update-dialog',
DialogType.DownloadedUpdate
);
}
public async start(): Promise<void> { public async start(): Promise<void> {
this.logger.info('updater/start: starting checks...'); this.logger.info('updater/start: starting checks...');
@ -173,7 +196,7 @@ export abstract class Updater {
// //
protected setUpdateListener( protected setUpdateListener(
performUpdateCallback: () => Promise<void> performUpdateCallback: () => Promise<void> | void
): void { ): void {
ipcMain.removeHandler('start-update'); ipcMain.removeHandler('start-update');
ipcMain.handleOnce('start-update', performUpdateCallback); ipcMain.handleOnce('start-update', performUpdateCallback);
@ -209,6 +232,11 @@ export abstract class Updater {
}); });
} }
protected markRestarting(): void {
this.restarting = true;
markShouldQuit();
}
// //
// Private methods // Private methods
// //

View file

@ -64,6 +64,12 @@ export async function force(): Promise<void> {
} }
} }
export function onRestartCancelled(): void {
if (updater) {
updater.onRestartCancelled();
}
}
function autoUpdateDisabled() { function autoUpdateDisabled() {
return ( return (
process.platform === 'linux' || process.mas || !config.get('updatesEnabled') process.platform === 'linux' || process.mas || !config.get('updatesEnabled')

View file

@ -9,7 +9,6 @@ import { join } from 'path';
import { Updater, createTempDir, deleteTempDir } from './common'; import { Updater, createTempDir, deleteTempDir } from './common';
import { explodePromise } from '../util/explodePromise'; import { explodePromise } from '../util/explodePromise';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
import { markShouldQuit } from '../../app/window_state';
import { DialogType } from '../types/Dialogs'; import { DialogType } from '../types/Dialogs';
export class MacOSUpdater extends Updater { export class MacOSUpdater extends Updater {
@ -41,7 +40,7 @@ export class MacOSUpdater extends Updater {
this.setUpdateListener(async () => { this.setUpdateListener(async () => {
logger.info('downloadAndInstall: restarting...'); logger.info('downloadAndInstall: restarting...');
markShouldQuit(); this.markRestarting();
autoUpdater.quitAndInstall(); autoUpdater.quitAndInstall();
}); });
} }

View file

@ -10,7 +10,6 @@ import { app } from 'electron';
import pify from 'pify'; import pify from 'pify';
import { Updater } from './common'; import { Updater } from './common';
import { markShouldQuit } from '../../app/window_state';
const readdir = pify(readdirCallback); const readdir = pify(readdirCallback);
const unlink = pify(unlinkCallback); const unlink = pify(unlinkCallback);
@ -61,9 +60,9 @@ export class WindowsUpdater extends Updater {
throw error; throw error;
} }
logger.info('downloadAndInstall: restarting...'); // If interrupted at this point, we only want to restart (not reattempt install)
markShouldQuit(); this.setUpdateListener(this.restart);
app.quit(); this.restart();
}; };
if (isSilent) { if (isSilent) {
@ -75,6 +74,12 @@ export class WindowsUpdater extends Updater {
this.setUpdateListener(doInstall); this.setUpdateListener(doInstall);
} }
protected restart(): void {
this.logger.info('downloadAndInstall: restarting...');
this.markRestarting();
app.quit();
}
private async install(filePath: string, isSilent: boolean): Promise<void> { private async install(filePath: string, isSilent: boolean): Promise<void> {
if (this.installing) { if (this.installing) {
return; return;