// AboutVersion:展示当前版本的更新内容。 // 数据源:getReleaseNotes()(GitHub release-notes.md,主进程自动切加速源,回退最新版)。 // 不直接渲染 Markdown —— 解析后按提交类型(新增/修复/优化/重构/文档/其他)分组, // 每组配图标,用卡片展示。 import { useCallback, useEffect, useState } from "react"; import { Sparkles, Bug, Gauge, RefreshCw, FileText, Wrench, ExternalLink, GitCommitHorizontal } from "lucide-react"; import { getReleaseNotes, type ReleaseNotesResult } from "@/api/update"; import { VERSION } from "@/lib/version"; import { parseReleaseNotes, type ChangeType, type VersionChange } from "./parse"; const GITHUB_RELEASES = "https://github.com/dream-pep/koring-launcher/releases"; const CATEGORY_ORDER: ChangeType[] = ["feat", "fix", "perf", "refactor", "docs", "other"]; const CATEGORY_META: Record; iconCls: string; dotCls: string }> = { feat: { label: "新增功能", icon: Sparkles, iconCls: "text-sky-600 dark:text-sky-400 bg-sky-500/10", dotCls: "bg-sky-500" }, fix: { label: "修复", icon: Bug, iconCls: "text-red-600 dark:text-red-400 bg-red-500/10", dotCls: "bg-red-500" }, perf: { label: "性能优化", icon: Gauge, iconCls: "text-emerald-600 dark:text-emerald-400 bg-emerald-500/10", dotCls: "bg-emerald-500" }, refactor: { label: "重构", icon: RefreshCw, iconCls: "text-violet-600 dark:text-violet-400 bg-violet-500/10", dotCls: "bg-violet-500" }, docs: { label: "文档", icon: FileText, iconCls: "text-amber-600 dark:text-amber-400 bg-amber-500/10", dotCls: "bg-amber-500" }, other: { label: "其他", icon: Wrench, iconCls: "text-foreground/60 bg-foreground/[0.06]", dotCls: "bg-foreground/40" }, }; /** 一条变更(含 commit 标)+ 短分隔条 */ function ChangeItem({ change }: { change: VersionChange }) { return (
{change.commit && ( {change.commit} )}

{change.title}

{change.description && (

{change.description}

)}
); } /** 一个分类卡片:图标头部 + 该类型的变更列表 */ function CategoryCard({ type, items }: { type: ChangeType; items: VersionChange[] }) { const meta = CATEGORY_META[type]; const Icon = meta.icon; return (
{meta.label} {items.length} 项
{items.map((c, i) => ( ))}
); } function EmptyCard({ text }: { text: string }) { return (

{text}

); } export function AboutVersion({ className }: { className?: string }) { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [result, setResult] = useState(null); const load = useCallback(async () => { setLoading(true); setError(null); try { const r = await getReleaseNotes(); setResult(r); } catch (e) { setError(e instanceof Error ? e.message : String(e)); } finally { setLoading(false); } }, []); useEffect(() => { load(); }, [load]); const parsed = result ? parseReleaseNotes(result.notes, result.version, result.tag) : null; const grouped = parsed ? CATEGORY_ORDER.map((t) => ({ type: t, items: parsed.changes.filter((c) => c.type === t) })).filter( (g) => g.items.length > 0, ) : []; return (
{/* 头部:版本 + 来源 */}
{parsed ? ( <> 版本 v{parsed.version} {result?.isLatest && parsed.version !== VERSION && ( (当前版本暂无说明,展示最新版本内容) )} ) : ( <>版本 v{VERSION} )}
{loading ? (
{[0, 1, 2].map((i) => (
))}
) : error ? ( ) : !result || !parsed ? ( ) : (
{parsed.noCommits && parsed.changes.length === 0 ? ( ) : grouped.length === 0 ? ( ) : ( grouped.map((g) => ) )}
)} {/* 底部操作 */}
{error && ( <>

{error}

)}
); }