import { createPortal } from 'react-dom'; import { open } from '@tauri-apps/plugin-shell'; import { ArrowUpCircle, CheckCircle2, ChevronDown, Download, FolderOpen, RefreshCw, ShieldCheck, X } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { version as currentVersion } from '../../package.json'; import { fmtBytes } from '../utils/componentHelpers/appUpdaterHelpers'; import { useAppUpdater } from '../hooks/useAppUpdater'; import Changelog from './appUpdater/Changelog'; export default function AppUpdater() { const { t } = useTranslation(); const { release, dismissed, setDismissed, changelogOpen, setChangelogOpen, dlState, dlProgress, dlError, countdown, asset, showAurHint, useTauriUpdater, showInstallBtn, pct, handleSkip, handleRestartNow, handleDownload, handleShowFolder, } = useAppUpdater(); if (!release || dismissed) return null; return createPortal( <>
setDismissed(true)} style={{ zIndex: 3000 }} />
e.stopPropagation()} > {/* Header */}
{t('common.updaterModalTitle')} v{currentVersion} → v{release.version}
{/* Scrollable body: changelog + download area — single overflow container */}
{/* Collapsible Changelog */} {release.body && (
{changelogOpen && (
)}
)} {/* Download / AUR area */}
{showAurHint ? (
{t('common.updaterAurHint')}
yay -S psysonic-bin sudo pacman -Syu psysonic-bin
) : useTauriUpdater ? ( <> {dlState === 'idle' && (
{t('common.updaterMacReadyTitle', { defaultValue: 'Ready to install' })}
{t('common.updaterMacReady', { defaultValue: 'The update downloads, verifies and applies in place — no DMG needed. The app restarts automatically when done.', })}
{t('common.updaterTrustNotarized', { defaultValue: 'Notarized by Apple' })} {t('common.updaterTrustSignature', { defaultValue: 'Signature verified' })}
)} {dlState === 'downloading' && (
{pct}% {fmtBytes(dlProgress.bytes)} {dlProgress.total > 0 && ` / ${fmtBytes(dlProgress.total)}`}
)} {dlState === 'done' && (
{t('common.updaterMacDoneTitle', { defaultValue: 'Update installed' })}
{countdown !== null ? t('common.updaterRestartingIn', { defaultValue: 'Restarting in {{n}}s…', n: countdown }) : t('common.updaterRestarting', { defaultValue: 'Restarting…' })}
)} {dlState === 'error' && (
{dlError || t('common.updaterErrorMsg')}
)} ) : asset ? ( <> {dlState === 'idle' && (
{asset.name} {fmtBytes(asset.size)}
)} {dlState === 'downloading' && (
{pct}% {fmtBytes(dlProgress.bytes)} {dlProgress.total > 0 && ` / ${fmtBytes(dlProgress.total)}`}
)} {dlState === 'done' && (
{t('common.updaterDone')}
{t('common.updaterInstallHint')}
)} {dlState === 'error' && (
{dlError || t('common.updaterErrorMsg')}
)} ) : (
)}
{/* end update-modal-body */} {/* Footer buttons — state-dependent to avoid redundant/jumping buttons */}
{dlState === 'idle' && ( <>
{showInstallBtn && ( )} )} {dlState === 'downloading' &&
} {dlState === 'done' && useTauriUpdater && ( <>
)} {dlState === 'done' && !useTauriUpdater && ( <>
)} {dlState === 'error' && ( <>
)}
, document.body ); }