import React, { useMemo } from 'react' import { Copy } from 'lucide-react' import { cn } from '@/utils/cn' export interface MessageFooterProps { shouldShowTimestamp: boolean shouldShowCopyButton: boolean timestamp?: string | number isUserInput: boolean isSummary: boolean showSystemAttachments: boolean showUserFile: boolean onCopyMessage: () => void } function parseTimestamp(timestamp: string | number): Date { if (typeof timestamp === 'number') return new Date(timestamp) const num = Number(timestamp) if (!isNaN(num)) return new Date(num) // 截断超过3位的小数秒(Python 微秒精度 → JS 毫秒精度) const normalized = timestamp.replace(/(\.\d{3})\d+/, '$1') return new Date(normalized) } function formatTimestamp(timestamp: string | number): string { const date = parseTimestamp(timestamp) const now = new Date() const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate()) const dateStart = new Date(date.getFullYear(), date.getMonth(), date.getDate()) const diffDays = Math.round( (todayStart.getTime() - dateStart.getTime()) / (1000 * 60 * 60 * 24), ) const hhmm = date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false }) if (diffDays === 0) { return hhmm } else if (diffDays >= 1) { return `${date.getMonth() + 1}/${date.getDate()} ${hhmm}` } else if (now.getFullYear() === date.getFullYear()) { return `${date.getMonth() + 1}/${date.getDate()}` } else { return `${date.getFullYear()}` } } /** * 消息底部 - 显示时间戳和复制按钮,对应 next-agent MessageFooter */ export const MessageFooter: React.FC = ({ shouldShowTimestamp, shouldShowCopyButton, timestamp, isUserInput, isSummary, showSystemAttachments, showUserFile, onCopyMessage, }) => { // hooks 必须在任何 return 之前调用 const displayText = useMemo( () => (timestamp != null ? formatTimestamp(timestamp) : ''), [timestamp], ) const fullTime = useMemo(() => { if (timestamp == null) return '' return parseTimestamp(timestamp).toLocaleString() }, [timestamp]) if (!shouldShowTimestamp) return null return (
{displayText} {shouldShowCopyButton && ( )}
) } export default React.memo(MessageFooter)