Make desktop update downloads optional (#2094)

This commit is contained in:
ekko
2026-07-16 10:03:38 +08:00
committed by GitHub
parent 2b3e84a0af
commit 0f33b4dafc
3 changed files with 45 additions and 13 deletions
+10
View File
@@ -16,6 +16,7 @@ type TranslationKey =
| 'update.currentVersion'
| 'update.availableTitle'
| 'update.availableMessage'
| 'update.availableDetail'
| 'update.downloading'
| 'update.readyTitle'
| 'update.readyMessage'
@@ -71,6 +72,7 @@ const translations: Record<DesktopLocale, Record<TranslationKey, string>> = {
'update.currentVersion': 'Current version: {version}',
'update.availableTitle': 'Update available',
'update.availableMessage': 'Hermes Studio {version} is available.',
'update.availableDetail': 'Choose whether to download this update.',
'update.downloading': 'The update is downloading in the background.',
'update.readyTitle': 'Update ready',
'update.readyMessage': 'Hermes Studio {version} is ready to install.',
@@ -123,6 +125,7 @@ const translations: Record<DesktopLocale, Record<TranslationKey, string>> = {
'update.currentVersion': '当前版本:{version}',
'update.availableTitle': '发现新版本',
'update.availableMessage': 'Hermes Studio {version} 可用。',
'update.availableDetail': '请选择是否下载此更新。',
'update.downloading': '更新正在后台下载。',
'update.readyTitle': '更新已就绪',
'update.readyMessage': 'Hermes Studio {version} 已准备好安装。',
@@ -175,6 +178,7 @@ const translations: Record<DesktopLocale, Record<TranslationKey, string>> = {
'update.currentVersion': '目前版本:{version}',
'update.availableTitle': '發現新版本',
'update.availableMessage': 'Hermes Studio {version} 可用。',
'update.availableDetail': '請選擇是否下載此更新。',
'update.downloading': '更新正在背景下載。',
'update.readyTitle': '更新已就緒',
'update.readyMessage': 'Hermes Studio {version} 已準備好安裝。',
@@ -227,6 +231,7 @@ const translations: Record<DesktopLocale, Record<TranslationKey, string>> = {
'update.currentVersion': '現在のバージョン: {version}',
'update.availableTitle': 'アップデートがあります',
'update.availableMessage': 'Hermes Studio {version} が利用できます。',
'update.availableDetail': 'このアップデートをダウンロードするか選択してください。',
'update.downloading': 'アップデートをバックグラウンドでダウンロードしています。',
'update.readyTitle': 'アップデートの準備ができました',
'update.readyMessage': 'Hermes Studio {version} をインストールできます。',
@@ -279,6 +284,7 @@ const translations: Record<DesktopLocale, Record<TranslationKey, string>> = {
'update.currentVersion': '현재 버전: {version}',
'update.availableTitle': '업데이트 사용 가능',
'update.availableMessage': 'Hermes Studio {version}을 사용할 수 있습니다.',
'update.availableDetail': '이 업데이트를 다운로드할지 선택하세요.',
'update.downloading': '업데이트를 백그라운드에서 다운로드하고 있습니다.',
'update.readyTitle': '업데이트 준비 완료',
'update.readyMessage': 'Hermes Studio {version}을 설치할 준비가 되었습니다.',
@@ -331,6 +337,7 @@ const translations: Record<DesktopLocale, Record<TranslationKey, string>> = {
'update.currentVersion': 'Version actuelle : {version}',
'update.availableTitle': 'Mise a jour disponible',
'update.availableMessage': 'Hermes Studio {version} est disponible.',
'update.availableDetail': 'Choisissez si vous souhaitez telecharger cette mise a jour.',
'update.downloading': 'La mise a jour se telecharge en arriere-plan.',
'update.readyTitle': 'Mise a jour prete',
'update.readyMessage': 'Hermes Studio {version} est pret a etre installe.',
@@ -383,6 +390,7 @@ const translations: Record<DesktopLocale, Record<TranslationKey, string>> = {
'update.currentVersion': 'Version actual: {version}',
'update.availableTitle': 'Actualizacion disponible',
'update.availableMessage': 'Hermes Studio {version} esta disponible.',
'update.availableDetail': 'Elige si deseas descargar esta actualizacion.',
'update.downloading': 'La actualizacion se esta descargando en segundo plano.',
'update.readyTitle': 'Actualizacion lista',
'update.readyMessage': 'Hermes Studio {version} esta listo para instalarse.',
@@ -435,6 +443,7 @@ const translations: Record<DesktopLocale, Record<TranslationKey, string>> = {
'update.currentVersion': 'Aktuelle Version: {version}',
'update.availableTitle': 'Update verfugbar',
'update.availableMessage': 'Hermes Studio {version} ist verfugbar.',
'update.availableDetail': 'Wahlen Sie, ob Sie dieses Update herunterladen mochten.',
'update.downloading': 'Das Update wird im Hintergrund heruntergeladen.',
'update.readyTitle': 'Update bereit',
'update.readyMessage': 'Hermes Studio {version} ist zur Installation bereit.',
@@ -487,6 +496,7 @@ const translations: Record<DesktopLocale, Record<TranslationKey, string>> = {
'update.currentVersion': 'Versao atual: {version}',
'update.availableTitle': 'Atualizacao disponivel',
'update.availableMessage': 'Hermes Studio {version} esta disponivel.',
'update.availableDetail': 'Escolha se deseja baixar esta atualizacao.',
'update.downloading': 'A atualizacao esta sendo baixada em segundo plano.',
'update.readyTitle': 'Atualizacao pronta',
'update.readyMessage': 'Hermes Studio {version} esta pronto para instalar.',
+20 -13
View File
@@ -167,6 +167,21 @@ async function promptInstallDownloadedUpdate(info: UpdateInfo): Promise<void> {
}
}
async function promptDownloadAvailableUpdate(info: UpdateInfo): Promise<void> {
const { response } = await dialog.showMessageBox({
type: 'info',
title: t('update.availableTitle'),
message: t('update.availableMessage', { version: info.version }),
detail: t('update.availableDetail'),
buttons: [t('update.download'), t('update.later')],
defaultId: 0,
cancelId: 1,
})
if (response === 0) {
await autoUpdater.downloadUpdate()
}
}
export function initAutoUpdater(nextOptions: AutoUpdaterOptions = {}) {
options = { ...options, ...nextOptions }
if (initialized) return
@@ -174,18 +189,15 @@ export function initAutoUpdater(nextOptions: AutoUpdaterOptions = {}) {
if (!app.isPackaged) return // dev mode: skip
autoUpdater.autoDownload = true
autoUpdater.autoDownload = false
autoUpdater.autoInstallOnAppQuit = true
autoUpdater.on('update-available', info => {
console.log(`[updater] update available: ${info.version}`)
dialog.showMessageBox({
type: 'info',
title: t('update.availableTitle'),
message: t('update.availableMessage', { version: info.version }),
detail: t('update.downloading'),
buttons: [t('common.ok')],
}).catch(() => undefined)
promptDownloadAvailableUpdate(info).catch(err => {
console.error('[updater] update download failed:', err)
showUpdateCheckFailed()
})
})
autoUpdater.on('update-not-available', info => {
console.log('[updater] up to date')
@@ -211,11 +223,6 @@ export function initAutoUpdater(nextOptions: AutoUpdaterOptions = {}) {
console.error('[updater] initial check failed:', err)
})
}
// Recheck every 6h while app is running
setInterval(() => {
checkForDesktopUpdates(false).catch(() => undefined)
}, 6 * 60 * 60 * 1000)
}
export async function checkForDesktopUpdates(manual: boolean): Promise<void> {
+15
View File
@@ -1,3 +1,5 @@
import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
import { describe, expect, it } from 'vitest'
import { isWindowsUpdaterLockError, pendingUpdateDirectories } from '../../packages/desktop/src/main/updater-helpers'
@@ -19,4 +21,17 @@ describe('desktop updater helpers', () => {
'C:\\Users\\A\\AppData\\Roaming/hermes-studio-updater/pending',
]))
})
it('checks on startup and from the tray without forcing an update', () => {
const updaterSource = readFileSync(resolve('packages/desktop/src/main/updater.ts'), 'utf-8')
const mainSource = readFileSync(resolve('packages/desktop/src/main/index.ts'), 'utf-8')
expect(mainSource).toContain('checkForDesktopUpdates(true)')
expect(updaterSource).toContain('checkForDesktopUpdates(false)')
expect(updaterSource).toContain('autoUpdater.autoDownload = false')
expect(updaterSource).toContain('autoUpdater.autoInstallOnAppQuit = true')
expect(updaterSource).toContain("buttons: [t('update.download'), t('update.later')]")
expect(updaterSource).toContain('if (response === 0) {\n await autoUpdater.downloadUpdate()')
expect(updaterSource).not.toContain('setInterval(')
})
})