diff --git a/frontend-modern/src/App.tsx b/frontend-modern/src/App.tsx index c23ba42..520ce36 100644 --- a/frontend-modern/src/App.tsx +++ b/frontend-modern/src/App.tsx @@ -40,6 +40,8 @@ import BellIcon from 'lucide-solid/icons/bell'; import SettingsIcon from 'lucide-solid/icons/settings'; import { TokenRevealDialog } from './components/TokenRevealDialog'; import { useAlertsActivation } from './stores/alertsActivation'; +import { UpdateProgressModal } from './components/UpdateProgressModal'; +import type { UpdateStatus } from './api/updates'; const Dashboard = lazy(() => import('./components/Dashboard/Dashboard').then((module) => ({ default: module.Dashboard })), @@ -106,6 +108,60 @@ function HostsRoute() { ); } +// Helper to detect if an update is actively in progress (not just checking for updates) +function isUpdateInProgress(status: string | undefined): boolean { + if (!status) return false; + const inProgressStates = ['downloading', 'verifying', 'extracting', 'installing', 'restarting']; + return inProgressStates.includes(status); +} + +// Global update progress watcher - shows modal in ALL tabs when an update is running +function GlobalUpdateProgressWatcher() { + const wsContext = useContext(WebSocketContext); + const navigate = useNavigate(); + const [showProgressModal, setShowProgressModal] = createSignal(false); + const [hasAutoOpened, setHasAutoOpened] = createSignal(false); + + // Watch for update progress events from WebSocket + createEffect(() => { + const progress = wsContext?.updateProgress?.() as UpdateStatus | null; + + if (!progress) { + // Reset when no progress data + setHasAutoOpened(false); + return; + } + + const inProgress = isUpdateInProgress(progress.status); + + if (inProgress && !showProgressModal() && !hasAutoOpened()) { + // Update is starting - auto-open the modal in this tab + logger.info('Update in progress detected via WebSocket, showing progress modal', { + status: progress.status, + message: progress.message, + }); + setShowProgressModal(true); + setHasAutoOpened(true); + } else if (!inProgress && hasAutoOpened()) { + // Update finished - allow the modal to be dismissed + setHasAutoOpened(false); + } + }); + + return ( + setShowProgressModal(false)} + onViewHistory={() => { + setShowProgressModal(false); + navigate('/settings/updates'); + }} + connected={wsContext?.connected} + reconnecting={wsContext?.reconnecting} + /> + ); +} + function App() { const TooltipRoot = createTooltipSystem(); const owner = getOwner(); @@ -644,6 +700,7 @@ function App() { +