'use client'; import { marked } from 'marked'; import { useEffect, useState } from 'react'; import { EmptyState } from '@/components/feedback/empty-state'; import { ErrorState } from '@/components/feedback/error-state'; import { LoadingState } from '@/components/feedback/loading-state'; import { AppCard } from '@/components/ui/app-card'; import { AppModal } from '@/components/ui/app-modal'; import { StatusBadge } from '@/components/ui/status-badge'; import type { LatestReleaseInfo, ReleaseChannel, UploadedServerBinaryInfo, } from '@/features/update/types'; import { PrimaryButton, ResourceField, ResourceInput, SecondaryButton, } from '@/features/shared/components/resource-primitives'; import { formatDateTime, formatRelativeTime } from '@/lib/utils/date'; interface VersionUpgradeModalProps { isOpen: boolean; onClose: () => void; currentVersion: string; frontendVersion: string; release: LatestReleaseInfo | null | undefined; selectedChannel: ReleaseChannel; uploadedBinary: UploadedServerBinaryInfo | null; isLoading: boolean; releaseErrorMessage?: string; manualStatusMessage?: string; manualErrorMessage?: string; canUpgrade: boolean; isChecking: boolean; isUpgrading: boolean; isUploadingBinary: boolean; isConfirmingManualUpgrade: boolean; onChannelChange: (channel: ReleaseChannel) => void; onCheck: () => void; onUpgrade: () => void; onUploadBinary: (file: File) => void; onConfirmManualUpgrade: () => void; } function getUpgradeBadge(release: LatestReleaseInfo | null | undefined) { if (!release) { return { label: '未检查', variant: 'info' as const }; } if (release.in_progress) { return { label: '升级中', variant: 'warning' as const }; } if (release.has_update) { return { label: '可升级', variant: 'warning' as const }; } return { label: '最新', variant: 'success' as const }; } export function VersionUpgradeModal({ isOpen, onClose, currentVersion, frontendVersion, release, selectedChannel, uploadedBinary, isLoading, releaseErrorMessage, manualStatusMessage, manualErrorMessage, canUpgrade, isChecking, isUpgrading, isUploadingBinary, isConfirmingManualUpgrade, onChannelChange, onCheck, onUpgrade, onUploadBinary, onConfirmManualUpgrade, }: VersionUpgradeModalProps) { const upgradeBadge = getUpgradeBadge(release); const [selectedBinary, setSelectedBinary] = useState(null); const selectedChannelLabel = selectedChannel === 'preview' ? '预览版' : '正式版'; const toggleChannel = () => { onChannelChange(selectedChannel === 'preview' ? 'stable' : 'preview'); }; const canConfirmManualUpgrade = Boolean( uploadedBinary?.ready_to_upgrade && uploadedBinary.upload_token, ); const showConfirmManualUpgradeAction = canConfirmManualUpgrade; useEffect(() => { if (!isOpen) { setSelectedBinary(null); } }, [isOpen]); return (

{frontendVersion}

{currentVersion || 'unknown'}

{release?.tag_name || '未检查'}

{canUpgrade ? (
点击标签切换通道
{isChecking ? '检查中...' : '检查'}
) : null}
{isLoading ? : null} {!isLoading && releaseErrorMessage ? ( ) : null} {!isLoading && !releaseErrorMessage && !release ? ( ) : null} {!isLoading && !releaseErrorMessage && release ? (
{release.prerelease ? ( ) : ( )} {!release.upgrade_supported ? ( ) : null} {release.in_progress ? ( ) : null}
查看发布详情 {canUpgrade ? (
{isUpgrading ? '升级中...' : release.in_progress ? '升级中...' : selectedChannel === 'preview' ? '升级到预览版' : '升级到正式版'}
) : null}
) : null} {canUpgrade ? (
{ const file = event.target.files?.[0] ?? null; setSelectedBinary(file); }} disabled={isUploadingBinary || isConfirmingManualUpgrade} />
{showConfirmManualUpgradeAction ? ( {isConfirmingManualUpgrade ? '升级中...' : '升级'} ) : ( { if (selectedBinary) { onUploadBinary(selectedBinary); } }} disabled={ !selectedBinary || isUploadingBinary || isConfirmingManualUpgrade } > {isUploadingBinary ? '上传检查中...' : '上传并检查'} )}
{manualErrorMessage ? ( ) : null} {!manualErrorMessage && manualStatusMessage ? (
{manualStatusMessage}
) : null} {uploadedBinary ? (
{!uploadedBinary.upgrade_supported ? ( ) : null}

文件名

{uploadedBinary.file_name}

上传时间

{uploadedBinary.uploaded_at ? formatDateTime(uploadedBinary.uploaded_at) : '未知'}

当前版本

{uploadedBinary.current_version}

上传版本

{uploadedBinary.detected_version}

{uploadedBinary.comparison_message}

) : ( )}
) : null}
); }