import { Modal, Timeline, Tag, Avatar, Empty, Spin, Button, Space } from 'antd'; import { useState, useEffect } from 'react'; import { BugOutlined, StarOutlined, FileTextOutlined, BgColorsOutlined, ThunderboltOutlined, ExperimentOutlined, ToolOutlined, QuestionCircleOutlined, GithubOutlined, ReloadOutlined, ClockCircleOutlined, SyncOutlined, } from '@ant-design/icons'; import { fetchChangelog, groupChangelogByDate, cacheChangelog, clearChangelogCache, type ChangelogEntry, } from '../services/changelogService'; interface ChangelogModalProps { visible: boolean; onClose: () => void; } // 提交类型图标和颜色配置 const typeConfig: Record = { feature: { icon: , color: 'green', label: '新功能' }, update: { icon: , color: 'geekblue', label: '更新' }, fix: { icon: , color: 'red', label: '修复' }, docs: { icon: , color: 'blue', label: '文档' }, style: { icon: , color: 'purple', label: '样式' }, refactor: { icon: , color: 'orange', label: '重构' }, perf: { icon: , color: 'gold', label: '性能' }, test: { icon: , color: 'cyan', label: '测试' }, chore: { icon: , color: 'default', label: '杂项' }, other: { icon: , color: 'default', label: '其他' }, }; export default function ChangelogModal({ visible, onClose }: ChangelogModalProps) { const [changelog, setChangelog] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [page, setPage] = useState(1); const [hasMore, setHasMore] = useState(true); // 加载更新日志 // 每次用户打开窗口时才同步获取最新数据,不自动刷新 const loadChangelog = async (pageNum: number = 1, append: boolean = false) => { setLoading(true); setError(null); try { // 每次打开都从网络获取最新数据 const entries = await fetchChangelog(pageNum, 30); if (entries.length === 0) { setHasMore(false); } else { if (append) { setChangelog(prev => [...prev, ...entries]); } else { setChangelog(entries); // 缓存第一页数据(用于分页加载时的数据持久化) if (pageNum === 1) { cacheChangelog(entries); } } } } catch (err) { setError(err instanceof Error ? err.message : '获取更新日志失败'); } finally { setLoading(false); } }; // 初始加载 useEffect(() => { if (visible) { loadChangelog(1, false); setPage(1); setHasMore(true); } }, [visible]); // 加载更多 const handleLoadMore = () => { const nextPage = page + 1; setPage(nextPage); loadChangelog(nextPage, true); }; // 刷新(清除缓存并重新加载) const handleRefresh = () => { clearChangelogCache(); setPage(1); setHasMore(true); loadChangelog(1, false); }; // 按日期分组 const groupedChangelog = groupChangelogByDate(changelog); const sortedDates = Array.from(groupedChangelog.keys()).sort((a, b) => b.localeCompare(a)); // 格式化日期 const formatDate = (dateStr: string) => { const date = new Date(dateStr); const now = new Date(); const diffDays = Math.floor((now.getTime() - date.getTime()) / (1000 * 60 * 60 * 24)); if (diffDays === 0) return '今天'; if (diffDays === 1) return '昨天'; if (diffDays < 7) return `${diffDays} 天前`; return date.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' }); }; // 格式化时间 const formatTime = (dateStr: string) => { return new Date(dateStr).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }); }; return ( 更新日志 ) } { !hasMore && changelog.length > 0 && (
已显示所有更新日志
) } )}
💡 提示:每次打开窗口时自动获取最新更新日志,数据来源于 GitHub 提交历史
); }