import type { CSSProperties } from 'react' import { ArrowSquareOut as ExternalLink, ArrowsClockwise as RefreshCw, Download, X } from '@phosphor-icons/react' import type { UpdateStatus, UpdateActions } from '../hooks/useUpdater' import { restartApp } from '../hooks/useUpdater' import { Button } from './ui/button' import { translate, type AppLocale } from '../lib/i18n' interface UpdateBannerProps { status: UpdateStatus actions: UpdateActions locale?: AppLocale } type VisibleUpdateStatus = Exclude function isUpdateBannerVisible(status: UpdateStatus): status is VisibleUpdateStatus { return status.state !== 'idle' && status.state !== 'error' } const bannerStyle = { display: 'flex', alignItems: 'center', gap: 10, padding: '6px 12px', background: 'var(--accent-blue)', borderBottom: 'none', fontSize: 13, color: 'var(--text-inverse)', flexShrink: 0, } satisfies CSSProperties const iconStyle = { color: 'var(--text-inverse)', flexShrink: 0, } satisfies CSSProperties const primaryActionStyle = { marginLeft: 'auto', padding: '3px 10px', background: 'var(--text-inverse)', color: 'var(--accent-blue)', fontSize: 12, fontWeight: 500, } satisfies CSSProperties const dismissButtonStyle = { color: 'var(--text-inverse)', display: 'flex', padding: 2, } satisfies CSSProperties const progressTrackStyle = { flex: 1, maxWidth: 200, height: 4, background: 'color-mix(in srgb, var(--text-inverse) 30%, transparent)', borderRadius: 2, overflow: 'hidden', } satisfies CSSProperties const progressTextStyle = { fontSize: 11, color: 'color-mix(in srgb, var(--text-inverse) 85%, transparent)', } satisfies CSSProperties const readyIconStyle = { color: 'var(--accent-green)', flexShrink: 0, } satisfies CSSProperties function renderAvailableContent(status: Extract, actions: UpdateActions, locale: AppLocale) { return ( <> HoloLake Era {status.displayVersion} {translate(locale, 'update.available')} ) } function renderCheckingContent(locale: AppLocale) { return ( <> {translate(locale, 'update.checking')} ) } function renderDownloadingContent(status: Extract, locale: AppLocale) { return ( <> {translate(locale, 'update.downloading', { version: status.displayVersion })}
{Math.round(status.progress * 100)}% ) } function renderReadyContent(status: Extract, locale: AppLocale) { return ( <> HoloLake Era {status.displayVersion} {translate(locale, 'update.readyRestart')} ) } function renderBannerContent(status: VisibleUpdateStatus, actions: UpdateActions, locale: AppLocale) { switch (status.state) { case 'checking': return renderCheckingContent(locale) case 'available': return renderAvailableContent(status, actions, locale) case 'downloading': return renderDownloadingContent(status, locale) case 'ready': return renderReadyContent(status, locale) } } export function UpdateBanner({ status, actions, locale = 'en' }: UpdateBannerProps) { if (!isUpdateBannerVisible(status)) return null return
{renderBannerContent(status, actions, locale)}
}