diff --git a/apps/desktop/src/App.vue b/apps/desktop/src/App.vue index a9ef3af5e3..e99227ee27 100644 --- a/apps/desktop/src/App.vue +++ b/apps/desktop/src/App.vue @@ -172,11 +172,13 @@ const { updateDownloaded, isInstallingUpdate, updateReady, + isIgnoringUpdate, activeTaskCount: activeUpdateTaskCount, hasUpdateAvailable, openUrl, checkUpdates, openLatestRelease, + ignoreCurrentVersion, downloadAndInstallUpdate, cancelDownload, installDownloadedUpdate, @@ -2857,12 +2859,14 @@ onUnmounted(() => { :update-downloaded="updateDownloaded" :is-installing-update="isInstallingUpdate" :update-ready="updateReady" + :is-ignoring-update="isIgnoringUpdate" :active-task-count="activeUpdateTaskCount" @open-latest-release="openLatestRelease" @download-and-install="downloadAndInstallUpdate" @cancel-download="cancelDownload" @install-downloaded="installDownloadedUpdate" @restart="restartApp" + @ignore-version="ignoreCurrentVersion" /> diff --git a/apps/desktop/src/components/layout/UpdateDialog.spec.ts b/apps/desktop/src/components/layout/UpdateDialog.spec.ts index d6499c860c..d198329a72 100644 --- a/apps/desktop/src/components/layout/UpdateDialog.spec.ts +++ b/apps/desktop/src/components/layout/UpdateDialog.spec.ts @@ -20,6 +20,7 @@ interface DialogState { updateDownloaded: boolean; isInstallingUpdate: boolean; updateReady: boolean; + isIgnoringUpdate: boolean; } async function flushDialog() { @@ -37,10 +38,12 @@ async function mountDialog(activeTaskCount: number, initialState: Partial { expect(downloadAndInstall).not.toHaveBeenCalled(); }); }); + +describe("UpdateDialog ignore version", () => { + it("emits ignore-version when the ignore button is clicked", async () => { + const { ignoreVersion } = await mountDialog(0); + + const ignoreButton = buttonWithText("Ignore this version"); + expect(ignoreButton).toBeDefined(); + ignoreButton?.click(); + await flushDialog(); + + expect(ignoreVersion).toHaveBeenCalledOnce(); + }); + + it("hides the ignore button once an update has been downloaded", async () => { + await mountDialog(0, { updateDownloaded: true, downloadProgress: 100 }); + + expect(buttonWithText("Ignore this version")).toBeUndefined(); + }); + + it("disables the ignore button while the setting is being persisted", async () => { + await mountDialog(0, { isIgnoringUpdate: true }); + + expect(buttonWithText("Ignore this version")?.disabled).toBe(true); + }); +}); diff --git a/apps/desktop/src/components/layout/UpdateDialog.vue b/apps/desktop/src/components/layout/UpdateDialog.vue index b2d2c241c2..6cf189f047 100644 --- a/apps/desktop/src/components/layout/UpdateDialog.vue +++ b/apps/desktop/src/components/layout/UpdateDialog.vue @@ -18,6 +18,7 @@ const props = defineProps<{ updateDownloaded: boolean; isInstallingUpdate: boolean; updateReady: boolean; + isIgnoringUpdate: boolean; activeTaskCount: number; }>(); @@ -27,6 +28,7 @@ const emit = defineEmits<{ "cancel-download": []; "install-downloaded": []; restart: []; + "ignore-version": []; }>(); const { t } = useI18n(); @@ -35,6 +37,7 @@ const isDesktop = isTauriRuntime(); const renderedNotes = ref(""); // Only active file replacement (installation) must trap the dialog. const isCloseBlocked = computed(() => props.isInstallingUpdate); +const canIgnoreVersion = computed(() => props.updateInfo?.update_available === true && !props.updateDownloaded && !props.isDownloadingUpdate && !props.isInstallingUpdate && !props.updateReady); function handleCancel() { handleOpenChange(false); @@ -136,6 +139,10 @@ watch( +