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.

This commit is contained in:
Tom Butcher 2026-06-21 21:48:05 +01:00
parent 4501f9936f
commit 65cc2cd8b5

View File

@ -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 showUpdateIfAvailable = useCallback(
async ({ forcePrompt = false } = {}) => {
const update = await checkForAvailableUpdate()
if (update) {
setNoUpdateOpen(false)
setAvailableUpdate(update)
if (forcePrompt || !isUpdateDismissed(update)) {
setUpdatePromptOpen(true)
}
}
return update
}, [checkForAvailableUpdate])
},
[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 ? (
<AppUpdateProgress
@ -279,7 +335,7 @@ export const AppUpdateProvider = ({ children }) => {
) : (
<NewAppUpdate
update={availableUpdate}
onCancel={closeUpdateModal}
onCancel={dismissUpdatePrompt}
onUpdate={handleUpdate}
/>
)}