import { useCallback, useEffect, useRef, useState } from 'react' import { AlertCircle, Download, RefreshCw, X } from 'lucide-react' import { Button } from './ui/button' import type { AppUpdate } from '../hooks/use-app-update' import './UpdateAvailableModal.css' interface Props { update: AppUpdate isGenerationActive: boolean // onClose receives whether the user ticked "Skip this version". onClose: (skipThisVersion: boolean) => void } function titleForStatus(status: AppUpdate['state']['status']): string { if (status === 'downloaded') return 'Ready to install' if (status === 'downloading') return 'Downloading update' if (status === 'checking') return 'Checking for updates' return 'Update available' } export function UpdateAvailableModal({ update, isGenerationActive, onClose }: Props) { const { state, startDownload, installAndRestart } = update const [skipChecked, setSkipChecked] = useState(false) const [installError, setInstallError] = useState(null) const dialogRef = useRef(null) const downloading = state.status === 'downloading' const downloaded = state.status === 'downloaded' const canDownload = state.status === 'available' const canDismiss = !downloaded const handleClose = useCallback(() => { if (!canDismiss) return onClose(skipChecked && state.status === 'available') }, [canDismiss, onClose, skipChecked, state.status]) useEffect(() => { dialogRef.current?.focus() }, []) useEffect(() => { const onKeyDown = (event: KeyboardEvent) => { if (event.key === 'Escape' && canDismiss) handleClose() } window.addEventListener('keydown', onKeyDown) return () => window.removeEventListener('keydown', onKeyDown) }, [canDismiss, handleClose]) const handleInstall = async () => { try { const res = await installAndRestart() if (!res.success) setInstallError(res.error ?? 'Could not install the update.') } catch (e) { setInstallError(e instanceof Error ? e.message : 'Could not install the update.') } } return (
e.stopPropagation()} > {canDismiss && ( )}

{titleForStatus(state.status)}

{state.currentVersion} → {state.version}

{state.releaseNotes &&
{state.releaseNotes}
} {state.message && (

{state.message}

)} {installError && (

{installError}

)} {downloading && (
{state.percent ?? 0}%
)} {downloaded && isGenerationActive && (

A generation is running. Installing will restart the app — it will be enabled when the generation finishes.

)} {state.status === 'available' && ( )}
{downloaded ? ( ) : downloading ? ( ) : ( <> )}
) }