import { useEffect } from 'react' import { IconDownload } from '@tabler/icons-react' import { Button } from '@/client/components/ui/button' import { Spinner } from '@/client/components/ui/spinner' import { Tooltip, TooltipContent, TooltipTrigger } from '@/client/components/ui/tooltip' import { hasRunningActivity, useLive } from '@/client/features/chat/chat-store' import { UPDATE_ACTIVE_AGENT_MESSAGE } from '@/lib/update' import type { UpdateStatus } from '@/lib/types' import { useUpdate, useUpdateStatus } from './api' export function shouldReloadAfterUpdate( status: UpdateStatus | undefined, targetVersion: string | null ): boolean { return !!targetVersion && status?.runningVersion === targetVersion } export function getUpdateButtonState( agentRunning: boolean, updating: boolean, restarting: boolean ) { const busy = updating || restarting const blocked = agentRunning && !busy const label = updating ? 'Updating' : restarting ? 'Restarting' : blocked ? UPDATE_ACTIVE_AGENT_MESSAGE : 'Update' return { busy, blocked, label } } export function Update() { const update = useUpdate() const statusQuery = useUpdateStatus(update.isSuccess) const agentRunning = useLive(state => hasRunningActivity(state.activity)) const status = statusQuery.data const restartTarget = update.data?.installedVersion ?? null useEffect(() => { if (shouldReloadAfterUpdate(status, restartTarget)) window.location.reload() }, [restartTarget, status]) if (!status?.availableVersion) return null const restarting = update.isSuccess const button = getUpdateButtonState(agentRunning, update.isPending, restarting) // The div gives TooltipTrigger an enabled event target when the button is disabled. return ( } /> {button.blocked ? UPDATE_ACTIVE_AGENT_MESSAGE : (update.error?.message ?? button.label)} ) }