import { IconX } from "@tabler/icons-react"; import { useState } from "react"; import { useUpdateStatus, installAndRestart, retryUpdateCheck, } from "../lib/updater"; import { DownloadIcon, SpinnerIcon } from "./Icons"; /** * Compact banner that slots into the top of the popover whenever an update * is in flight or ready. Kept tight so it doesn't push the recording * controls off-screen. Hidden in idle / checking / not-available states. */ export function UpdateBanner() { const status = useUpdateStatus(); const [dismissedVersion, setDismissedVersion] = useState(null); // Dismissal is scoped to the specific error message so a new, // different failure still surfaces. Users shouldn't have to see the // same message twice, but they should hear about a new kind of // failure. const [dismissedErrorMessage, setDismissedErrorMessage] = useState< string | null >(null); if (status.state === "idle") return null; if (status.state === "checking") return null; if (status.state === "not-available") return null; if (status.state === "error") { if (status.message === dismissedErrorMessage) return null; return (
Update check failed: {status.message}
); } // User dismissed for this version — don't keep nagging. if ( (status.state === "available" || status.state === "downloading" || status.state === "downloaded") && status.version === dismissedVersion ) { return null; } if (status.state === "available") { return (
Update available — downloading…
); } if (status.state === "downloading") { return (
Downloading update… {status.percent}%
); } // downloaded → actionable restart return (
Update ready — restart to install
); }