import { Modal } from "antd"; import { Button } from "~/components/ui/button"; import type { CheckVersionResponse } from "~/service/api/version/state"; const IGNORED_VERSIONS_KEY = "GOWVP_IGNORED_VERSIONS"; const MAX_IGNORED_VERSIONS = 3; interface VersionUpdateModalProps { versionInfo: CheckVersionResponse | null; onClose: () => void; } // 获取已忽略的版本列表 function getIgnoredVersions(): string[] { try { const stored = localStorage.getItem(IGNORED_VERSIONS_KEY); if (stored) { return JSON.parse(stored); } } catch { // ignore } return []; } // 添加忽略的版本 function addIgnoredVersion(version: string): void { const versions = getIgnoredVersions(); if (!versions.includes(version)) { versions.push(version); // 保持最多 3 个 while (versions.length > MAX_IGNORED_VERSIONS) { versions.shift(); } localStorage.setItem(IGNORED_VERSIONS_KEY, JSON.stringify(versions)); } } // 检查版本是否被忽略 export function isVersionIgnored(version: string): boolean { return getIgnoredVersions().includes(version); } // 简单的 Markdown 渲染(支持基本格式) function renderMarkdown(text: string): React.ReactNode { if (!text) return null; const lines = text.split("\n"); const elements: React.ReactNode[] = []; for (let i = 0; i < lines.length; i++) { const line = lines[i]; // 处理标题 if (line.startsWith("### ")) { elements.push(

{line.slice(4)}

, ); continue; } if (line.startsWith("## ")) { elements.push(

{line.slice(3)}

, ); continue; } if (line.startsWith("# ")) { elements.push(

{line.slice(2)}

, ); continue; } // 处理分隔线 if (line.match(/^-{3,}$/)) { elements.push(
); continue; } // 处理列表项 if (line.match(/^\d+\.\s/)) { const content = line.replace(/^\d+\.\s/, ""); elements.push(
{renderInlineMarkdown(content)}
, ); continue; } if (line.startsWith("- ")) { elements.push(
{renderInlineMarkdown(line.slice(2))}
, ); continue; } // 空行 if (line.trim() === "") { elements.push(
); continue; } // 普通段落 elements.push(

{renderInlineMarkdown(line)}

, ); } return
{elements}
; } // 处理行内 Markdown(粗体、斜体、代码) function renderInlineMarkdown(text: string): React.ReactNode { // 简单处理:粗体 **text** 和代码 `code` const parts: React.ReactNode[] = []; let remaining = text; let key = 0; while (remaining.length > 0) { // 处理粗体 const boldMatch = remaining.match(/\*\*(.+?)\*\*/); // 处理代码 const codeMatch = remaining.match(/`(.+?)`/); if (boldMatch && (!codeMatch || boldMatch.index! <= codeMatch.index!)) { if (boldMatch.index! > 0) { parts.push(remaining.slice(0, boldMatch.index)); } parts.push( {boldMatch[1]} , ); remaining = remaining.slice(boldMatch.index! + boldMatch[0].length); } else if (codeMatch) { if (codeMatch.index! > 0) { parts.push(remaining.slice(0, codeMatch.index)); } parts.push( {codeMatch[1]} , ); remaining = remaining.slice(codeMatch.index! + codeMatch[0].length); } else { parts.push(remaining); break; } } return parts.length === 1 ? parts[0] : <>{parts}; } export default function VersionUpdateModal({ versionInfo, onClose, }: VersionUpdateModalProps) { if (!versionInfo) return null; const handleIgnore = () => { addIgnoredVersion(versionInfo.new_version); onClose(); }; const handleConfirm = (): void => { // 直接关闭弹窗,不触发任何请求 onClose(); }; return ( 🎉 发现新版本
} width={520} >
{/* 版本信息 */}
当前版本: {versionInfo.current_version}
新版本: {versionInfo.new_version}
{/* 更新说明 */}

更新说明

{renderMarkdown(versionInfo.description)}
{/* 操作按钮 */}
); }