diff --git a/desktop/ELECTRON_EVENTS.ts b/desktop/ELECTRON_EVENTS.ts index de0bd655e12c..607ad7b21580 100644 --- a/desktop/ELECTRON_EVENTS.ts +++ b/desktop/ELECTRON_EVENTS.ts @@ -9,6 +9,7 @@ const ELECTRON_EVENTS = { KEYBOARD_SHORTCUTS_PAGE: 'keyboard-shortcuts-page', START_UPDATE: 'start-update', UPDATE_DOWNLOADED: 'update-downloaded', + SILENT_UPDATE: 'silent-update', } as const; export default ELECTRON_EVENTS; diff --git a/desktop/contextBridge.ts b/desktop/contextBridge.ts index 689c69de0cc8..487e528a7485 100644 --- a/desktop/contextBridge.ts +++ b/desktop/contextBridge.ts @@ -16,6 +16,7 @@ const WHITELIST_CHANNELS_RENDERER_TO_MAIN = [ ELECTRON_EVENTS.REQUEST_VISIBILITY, ELECTRON_EVENTS.START_UPDATE, ELECTRON_EVENTS.LOCALE_UPDATED, + ELECTRON_EVENTS.SILENT_UPDATE, ] as const; const WHITELIST_CHANNELS_MAIN_TO_RENDERER = [ELECTRON_EVENTS.KEYBOARD_SHORTCUTS_PAGE, ELECTRON_EVENTS.UPDATE_DOWNLOADED, ELECTRON_EVENTS.FOCUS, ELECTRON_EVENTS.BLUR] as const; diff --git a/desktop/main.ts b/desktop/main.ts index 6e14d661b345..b40557464ec1 100644 --- a/desktop/main.ts +++ b/desktop/main.ts @@ -111,6 +111,7 @@ process.argv.forEach((arg) => { // happens correctly. let hasUpdate = false; let downloadedVersion: string; +let isSilentUpdating = false; // Note that we have to subscribe to this separately and cannot use Localize.translateLocal, // because the only way code can be shared between the main and renderer processes at runtime is via the context bridge @@ -127,16 +128,20 @@ const quitAndInstallWithUpdate = () => { autoUpdater.quitAndInstall(); }; -/** Menu Item callback to triggers an update check */ -const manuallyCheckForUpdates = (menuItem: MenuItem, browserWindow?: BrowserWindow) => { - // Disable item until the check (and download) is complete - // eslint: menu item flags like enabled or visible can be dynamically toggled by mutating the object - // eslint-disable-next-line no-param-reassign - menuItem.enabled = false; +/** Menu Item callback to trigger an update check */ +const manuallyCheckForUpdates = (menuItem?: MenuItem, browserWindow?: BrowserWindow) => { + if (menuItem) { + // Disable item until the check (and download) is complete + // eslint-disable-next-line no-param-reassign -- menu item flags like enabled or visible can be dynamically toggled by mutating the object + menuItem.enabled = false; + } autoUpdater .checkForUpdates() - .catch((error) => ({error})) + .catch((error) => { + isSilentUpdating = false; + return {error}; + }) .then((result) => { const downloadPromise = result && 'downloadPromise' in result ? result.downloadPromise : undefined; @@ -148,7 +153,7 @@ const manuallyCheckForUpdates = (menuItem: MenuItem, browserWindow?: BrowserWind dialog.showMessageBox(browserWindow, { type: 'info', message: Localize.translate(preferredLocale, 'checkForUpdatesModal.available.title'), - detail: Localize.translate(preferredLocale, 'checkForUpdatesModal.available.message'), + detail: Localize.translate(preferredLocale, 'checkForUpdatesModal.available.message', {isSilentUpdating}), buttons: [Localize.translate(preferredLocale, 'checkForUpdatesModal.available.soundsGood')], }); } else if (result && 'error' in result && result.error) { @@ -172,6 +177,10 @@ const manuallyCheckForUpdates = (menuItem: MenuItem, browserWindow?: BrowserWind return downloadPromise; }) .finally(() => { + isSilentUpdating = false; + if (!menuItem) { + return; + } // eslint-disable-next-line no-param-reassign menuItem.enabled = true; }); @@ -201,7 +210,7 @@ const electronUpdater = (browserWindow: BrowserWindow): PlatformSpecificUpdater if (checkForUpdatesMenuItem) { checkForUpdatesMenuItem.visible = false; } - if (browserWindow.isVisible()) { + if (browserWindow.isVisible() && !isSilentUpdating) { browserWindow.webContents.send(ELECTRON_EVENTS.UPDATE_DOWNLOADED, info.version); } else { quitAndInstallWithUpdate(); @@ -604,6 +613,15 @@ const mainWindow = (): Promise => { } }); + // Automatically check for and install the latest version in the background + ipcMain.on(ELECTRON_EVENTS.SILENT_UPDATE, () => { + if (isSilentUpdating) { + return; + } + isSilentUpdating = true; + manuallyCheckForUpdates(undefined, browserWindow); + }); + return browserWindow; }) diff --git a/src/languages/en.ts b/src/languages/en.ts index 9d33d29c59bd..1b87137eb2cf 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2623,7 +2623,8 @@ export default { checkForUpdatesModal: { available: { title: 'Update Available', - message: "The new version will be available shortly. We'll notify you when we're ready to update.", + message: ({isSilentUpdating}: {isSilentUpdating: boolean}) => + `The new version will be available shortly.${!isSilentUpdating ? " We'll notify you when we're ready to update." : ''}`, soundsGood: 'Sounds good', }, notAvailable: { diff --git a/src/languages/es.ts b/src/languages/es.ts index ab170e06acc5..4a77eeedea17 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2655,7 +2655,8 @@ export default { checkForUpdatesModal: { available: { title: 'Actualización disponible', - message: 'La nueva versión estará disponible dentro de poco. Te notificaremos cuando esté lista.', + message: ({isSilentUpdating}: {isSilentUpdating: boolean}) => + `La nueva versión estará disponible dentro de poco.${isSilentUpdating ? ' Te notificaremos cuando esté lista.' : ''}`, soundsGood: 'Suena bien', }, notAvailable: { diff --git a/src/libs/actions/AppUpdate/updateApp/index.desktop.ts b/src/libs/actions/AppUpdate/updateApp/index.desktop.ts index fb3a7d649baa..5c1ecbe05742 100644 --- a/src/libs/actions/AppUpdate/updateApp/index.desktop.ts +++ b/src/libs/actions/AppUpdate/updateApp/index.desktop.ts @@ -1,6 +1,5 @@ -import {Linking} from 'react-native'; -import CONST from '@src/CONST'; +import ELECTRON_EVENTS from '@desktop/ELECTRON_EVENTS'; export default function updateApp() { - Linking.openURL(CONST.APP_DOWNLOAD_LINKS.DESKTOP); + window.electron.send(ELECTRON_EVENTS.SILENT_UPDATE); }