From 216c8694c758ad2b393df7a3f256c6b07a255fc8 Mon Sep 17 00:00:00 2001 From: Benjamin Lu Date: Mon, 22 Dec 2025 03:30:08 -0800 Subject: [PATCH] Desktop: wire release toast Update to updater (#7549) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Desktop builds should not send users to git-update docs from the release notification toast; route the toast “Update” action into the Desktop updater flow. On Electron, the release toast “Update” button executes `Comfy-Desktop.CheckForUpdates`; failures surface via `useErrorHandling`. Fixes #7543 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7549-Desktop-wire-release-toast-Update-to-updater-2cb6d73d3650815aadbccc15c724815d) by [Unito](https://www.unito.io) --- .../ReleaseNotificationToast.test.ts | 72 +++++++++++++++++++ .../components/ReleaseNotificationToast.vue | 16 ++++- 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/platform/updates/components/ReleaseNotificationToast.test.ts b/src/platform/updates/components/ReleaseNotificationToast.test.ts index 021772ae2..76a5509da 100644 --- a/src/platform/updates/components/ReleaseNotificationToast.test.ts +++ b/src/platform/updates/components/ReleaseNotificationToast.test.ts @@ -5,6 +5,14 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' import type { ReleaseNote } from '../common/releaseService' import ReleaseNotificationToast from './ReleaseNotificationToast.vue' +const { commandExecuteMock } = vi.hoisted(() => ({ + commandExecuteMock: vi.fn() +})) + +const { toastErrorHandlerMock } = vi.hoisted(() => ({ + toastErrorHandlerMock: vi.fn() +})) + // Mock dependencies vi.mock('vue-i18n', () => ({ useI18n: vi.fn(() => ({ @@ -36,6 +44,18 @@ vi.mock('@/utils/markdownRendererUtil', () => ({ renderMarkdownToHtml: vi.fn((content: string) => `
${content}
`) })) +vi.mock('@/composables/useErrorHandling', () => ({ + useErrorHandling: vi.fn(() => ({ + toastErrorHandler: toastErrorHandlerMock + })) +})) + +vi.mock('@/stores/commandStore', () => ({ + useCommandStore: vi.fn(() => ({ + execute: commandExecuteMock + })) +})) + // Mock release store const mockReleaseStore = { recentRelease: null as ReleaseNote | null, @@ -159,6 +179,58 @@ describe('ReleaseNotificationToast', () => { ) }) + it('executes desktop updater flow when running in Electron', async () => { + mockReleaseStore.recentRelease = { + version: '1.2.3', + content: '# Test Release' + } as ReleaseNote + + commandExecuteMock.mockResolvedValueOnce(undefined) + + const mockWindowOpen = vi.fn() + Object.defineProperty(window, 'open', { + value: mockWindowOpen, + writable: true + }) + ;(window as any).electronAPI = {} + + wrapper = mountComponent() + await wrapper.vm.handleUpdate() + + expect(commandExecuteMock).toHaveBeenCalledWith( + 'Comfy-Desktop.CheckForUpdates' + ) + expect(mockWindowOpen).not.toHaveBeenCalled() + expect(toastErrorHandlerMock).not.toHaveBeenCalled() + + delete (window as any).electronAPI + }) + + it('shows an error toast if the desktop updater flow fails in Electron', async () => { + mockReleaseStore.recentRelease = { + version: '1.2.3', + content: '# Test Release' + } as ReleaseNote + + const error = new Error('Command Comfy-Desktop.CheckForUpdates not found') + commandExecuteMock.mockRejectedValueOnce(error) + + const mockWindowOpen = vi.fn() + Object.defineProperty(window, 'open', { + value: mockWindowOpen, + writable: true + }) + ;(window as any).electronAPI = {} + + wrapper = mountComponent() + await wrapper.vm.handleUpdate() + + expect(toastErrorHandlerMock).toHaveBeenCalledWith(error) + expect(mockWindowOpen).not.toHaveBeenCalled() + + delete (window as any).electronAPI + }) + it('calls handleShowChangelog when learn more link is clicked', async () => { mockReleaseStore.recentRelease = { version: '1.2.3', diff --git a/src/platform/updates/components/ReleaseNotificationToast.vue b/src/platform/updates/components/ReleaseNotificationToast.vue index 3e88a0751..90419f4a1 100644 --- a/src/platform/updates/components/ReleaseNotificationToast.vue +++ b/src/platform/updates/components/ReleaseNotificationToast.vue @@ -69,7 +69,10 @@ import { default as DOMPurify } from 'dompurify' import { computed, onMounted, ref, watch } from 'vue' import { useI18n } from 'vue-i18n' +import { useErrorHandling } from '@/composables/useErrorHandling' import { useExternalLink } from '@/composables/useExternalLink' +import { useCommandStore } from '@/stores/commandStore' +import { isElectron } from '@/utils/envUtil' import { formatVersionAnchor } from '@/utils/formatUtil' import { renderMarkdownToHtml } from '@/utils/markdownRendererUtil' @@ -77,6 +80,7 @@ import type { ReleaseNote } from '../common/releaseService' import { useReleaseStore } from '../common/releaseStore' const { buildDocsUrl } = useExternalLink() +const { toastErrorHandler } = useErrorHandling() const releaseStore = useReleaseStore() const { t } = useI18n() @@ -172,7 +176,17 @@ const handleLearnMore = () => { dismissToast() } -const handleUpdate = () => { +const handleUpdate = async () => { + if (isElectron()) { + try { + await useCommandStore().execute('Comfy-Desktop.CheckForUpdates') + dismissToast() + } catch (error) { + toastErrorHandler(error) + } + return + } + window.open( buildDocsUrl('/installation/update_comfyui', { includeLocale: true }), '_blank'