From 65cc2cd8b558a3725f8d046847f0283971d03d0c Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Sun, 21 Jun 2026 21:48:05 +0100 Subject: [PATCH] Implement update dismissal functionality in AppUpdateContext to enhance user experience during updates. Added methods to save and check dismissed updates, and modified update prompt logic to respect user preferences. Update modal behavior adjusted to incorporate dismissal actions. --- .../Dashboard/context/AppUpdateContext.jsx | 84 +++++++++++++++---- 1 file changed, 70 insertions(+), 14 deletions(-) diff --git a/src/components/Dashboard/context/AppUpdateContext.jsx b/src/components/Dashboard/context/AppUpdateContext.jsx index 9b4b786..91bf26f 100644 --- a/src/components/Dashboard/context/AppUpdateContext.jsx +++ b/src/components/Dashboard/context/AppUpdateContext.jsx @@ -21,6 +21,42 @@ const { Text } = Typography const UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1000 const DEFAULT_UPDATE_BRANCH = 'main' const CURRENT_BUILD_NUMBER = import.meta.env.VITE_BUILD_NUMBER +const APP_UPDATE_DISMISSED_KEY = 'appUpdateDismissed' + +const getDismissedUpdate = () => { + try { + const stored = sessionStorage.getItem(APP_UPDATE_DISMISSED_KEY) + return stored ? JSON.parse(stored) : null + } catch { + return null + } +} + +const isUpdateDismissed = (update) => { + if (!update) return false + + const dismissed = getDismissedUpdate() + if (!dismissed) return false + + return ( + dismissed.version === update.version && + dismissed.buildNumber === update.buildNumber && + dismissed.branch === update.branch + ) +} + +const saveDismissedUpdate = (update) => { + if (!update) return + + sessionStorage.setItem( + APP_UPDATE_DISMISSED_KEY, + JSON.stringify({ + version: update.version, + buildNumber: update.buildNumber, + branch: update.branch + }) + ) +} const AppUpdateContext = createContext() @@ -77,6 +113,7 @@ export const AppUpdateProvider = ({ children }) => { const [checking, setChecking] = useState(false) const [noUpdateOpen, setNoUpdateOpen] = useState(false) const [availableUpdate, setAvailableUpdate] = useState(null) + const [updatePromptOpen, setUpdatePromptOpen] = useState(false) const [installingUpdate, setInstallingUpdate] = useState(null) const [updateProgress, setUpdateProgress] = useState(null) const runningCheckRef = useRef(null) @@ -136,14 +173,20 @@ export const AppUpdateProvider = ({ children }) => { } }, []) - const showUpdateIfAvailable = useCallback(async () => { - const update = await checkForAvailableUpdate() - if (update) { - setNoUpdateOpen(false) - setAvailableUpdate(update) - } - return update - }, [checkForAvailableUpdate]) + const showUpdateIfAvailable = useCallback( + async ({ forcePrompt = false } = {}) => { + const update = await checkForAvailableUpdate() + if (update) { + setNoUpdateOpen(false) + setAvailableUpdate(update) + if (forcePrompt || !isUpdateDismissed(update)) { + setUpdatePromptOpen(true) + } + } + return update + }, + [checkForAvailableUpdate] + ) const checkForUpdates = useCallback(async () => { if (!isElectron) return null @@ -151,7 +194,7 @@ export const AppUpdateProvider = ({ children }) => { setChecking(true) try { - const update = await showUpdateIfAvailable() + const update = await showUpdateIfAvailable({ forcePrompt: true }) if (!update) { setNoUpdateOpen(true) } @@ -183,15 +226,22 @@ export const AppUpdateProvider = ({ children }) => { }) }, [isElectron, onAppUpdateProgress]) + const dismissUpdatePrompt = () => { + if (availableUpdate) { + saveDismissedUpdate(availableUpdate) + } + setUpdatePromptOpen(false) + } + const closeUpdateModal = () => { - setAvailableUpdate(null) + setUpdatePromptOpen(false) setInstallingUpdate(null) setUpdateProgress(null) } const handleUpdate = async (update) => { setNoUpdateOpen(false) - setAvailableUpdate(null) + setUpdatePromptOpen(false) setInstallingUpdate(update) setModelWidth(550) setUpdateProgress({ @@ -215,7 +265,7 @@ export const AppUpdateProvider = ({ children }) => { } } - const updateModalOpen = Boolean(availableUpdate || installingUpdate) + const updateModalOpen = Boolean(updatePromptOpen || installingUpdate) const updateModalBusy = Boolean(installingUpdate) && updateProgress?.phase !== 'error' @@ -268,7 +318,13 @@ export const AppUpdateProvider = ({ children }) => { centered closable={!updateModalBusy} maskClosable={!updateModalBusy} - onCancel={updateModalBusy ? undefined : closeUpdateModal} + onCancel={ + updateModalBusy + ? undefined + : installingUpdate + ? closeUpdateModal + : dismissUpdatePrompt + } > {installingUpdate ? ( { ) : ( )}