From 8be503bf409d7ee2a3aca7da45edc37b4b310526 Mon Sep 17 00:00:00 2001 From: 0xTyson <32617253+debugzhao@users.noreply.github.com> Date: Tue, 1 Sep 2026 11:09:44 +0800 Subject: [PATCH] feat(update): download app updates in the background --- apps/desktop/src/App.vue | 8 +- .../src/components/layout/AppToolbar.vue | 19 +- .../components/layout/ToolbarUpdateIcon.vue | 39 ++- .../components/layout/UpdateDialog.spec.ts | 53 ++-- .../src/components/layout/UpdateDialog.vue | 27 +-- .../__tests__/ToolbarUpdateIcon.spec.ts | 52 ++++ .../__tests__/useAppUpdater.spec.ts | 229 +++++++++++++----- apps/desktop/src/composables/useAppUpdater.ts | 72 ++++-- apps/desktop/src/i18n/locales/en.ts | 9 +- apps/desktop/src/i18n/locales/es.ts | 9 +- apps/desktop/src/i18n/locales/it.ts | 9 +- apps/desktop/src/i18n/locales/ja.ts | 9 +- apps/desktop/src/i18n/locales/ko.ts | 9 +- apps/desktop/src/i18n/locales/pt-BR.ts | 9 +- apps/desktop/src/i18n/locales/zh-CN.ts | 9 +- apps/desktop/src/i18n/locales/zh-TW.ts | 9 +- .../src/lib/app/appUpdateInstallFlow.ts | 18 -- packages/app-tests/appUpdater.test.ts | 30 +-- 18 files changed, 448 insertions(+), 171 deletions(-) diff --git a/apps/desktop/src/App.vue b/apps/desktop/src/App.vue index 06d34e43ea..a3573e6816 100644 --- a/apps/desktop/src/App.vue +++ b/apps/desktop/src/App.vue @@ -207,7 +207,7 @@ const { checkUpdates, openLatestRelease, ignoreCurrentVersion, - downloadAndInstallUpdate, + downloadUpdateInBackground, cancelDownload, installDownloadedUpdate, restartApp, @@ -3011,6 +3011,10 @@ onUnmounted(() => { :show-settings-page="showSettingsPage" :checking-updates="checkingUpdates" :has-update-available="toolbarHasUpdateAvailable" + :is-downloading-update="isDownloadingUpdate" + :download-progress="downloadProgress" + :update-ready-to-install="updateDownloaded" + :update-ready="updateReady" :agent-driver-update-count="toolbarAgentDriverUpdateCount" :has-mcp-update-available="toolbarMcpUpdateAvailable" :has-connections="connectionStore.connections.length > 0" @@ -3343,7 +3347,7 @@ onUnmounted(() => { :is-ignoring-update="isIgnoringUpdate" :active-task-count="activeUpdateTaskCount" @open-latest-release="openLatestRelease" - @download-and-install="downloadAndInstallUpdate" + @download-in-background="downloadUpdateInBackground" @cancel-download="cancelDownload" @install-downloaded="installDownloadedUpdate" @restart="restartApp" diff --git a/apps/desktop/src/components/layout/AppToolbar.vue b/apps/desktop/src/components/layout/AppToolbar.vue index f4336db32f..81a3622880 100644 --- a/apps/desktop/src/components/layout/AppToolbar.vue +++ b/apps/desktop/src/components/layout/AppToolbar.vue @@ -40,6 +40,10 @@ const props = defineProps<{ showSettingsPage: boolean; checkingUpdates: boolean; hasUpdateAvailable: boolean; + isDownloadingUpdate: boolean; + downloadProgress: number | null; + updateReadyToInstall: boolean; + updateReady: boolean; agentDriverUpdateCount: number; hasMcpUpdateAvailable: boolean; hasConnections: boolean; @@ -70,6 +74,14 @@ const settingsStore = useSettingsStore(); const toolbarItems = computed(() => settingsStore.editorSettings.toolbarItems); const { isMac, isDesktop, showControls, isMaximized, isFullscreen, minimize, toggleMaximize, close } = useWindowControls(); const checkingUpdates = computed(() => props.checkingUpdates); +const updateTooltip = computed(() => { + if (props.isDownloadingUpdate) return t("updates.downloading", { progress: props.downloadProgress ?? 0 }); + if (props.updateReady) return t("updates.restartRequiredTooltip"); + if (props.updateReadyToInstall) return t("updates.updateReadyTooltip"); + return t("updates.check"); +}); +// ToolbarUpdateIcon takes a 0..1 fraction, with null meaning the download size is unknown. +const updateDownloadProgress = computed(() => (props.downloadProgress == null ? null : Math.min(1, Math.max(0, props.downloadProgress / 100)))); const sqlLibrarySaveFeedbackActive = ref(false); const SQL_LIBRARY_BOOKMARK_PATH = "M10 2 L10 10 L13 7 L16 10 L16 2"; const SQL_LIBRARY_CHECK_PATH = "M9 9.5 L9 9.5 L11 11.5 L15 7.5 L15 7.5"; @@ -586,11 +598,12 @@ const toolbarStyle = computed(() => { - {{ t("updates.check") }} + {{ updateTooltip }} diff --git a/apps/desktop/src/components/layout/ToolbarUpdateIcon.vue b/apps/desktop/src/components/layout/ToolbarUpdateIcon.vue index 03f0175aac..3cbbc5a466 100644 --- a/apps/desktop/src/components/layout/ToolbarUpdateIcon.vue +++ b/apps/desktop/src/components/layout/ToolbarUpdateIcon.vue @@ -1,14 +1,29 @@