"use client" import { useState, useEffect, useRef } from "react" import { Loader2 } from "lucide-react" import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" import { Label } from "@/components/ui/label" import { useTheme } from "next-themes" import { useToast } from "@/components/ui/use-toast" interface Message { id: string from_address?: string to_address?: string subject: string content: string html?: string received_at?: number sent_at?: number } interface MessageViewProps { emailId: string messageId: string messageType?: 'received' | 'sent' onClose: () => void } type ViewMode = "html" | "text" export function MessageView({ emailId, messageId, messageType = 'received' }: MessageViewProps) { const [message, setMessage] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [viewMode, setViewMode] = useState("html") const iframeRef = useRef(null) const { theme } = useTheme() const { toast } = useToast() useEffect(() => { const fetchMessage = async () => { try { setLoading(true) setError(null) const url = `/api/emails/${emailId}/${messageId}${messageType === 'sent' ? '?type=sent' : ''}`; const response = await fetch(url) if (!response.ok) { const errorData = await response.json() const errorMessage = (errorData as { error?: string }).error || '获取邮件详情失败' setError(errorMessage) toast({ title: "错误", description: errorMessage, variant: "destructive" }) return } const data = await response.json() as { message: Message } setMessage(data.message) if (!data.message.html) { setViewMode("text") } } catch (error) { const errorMessage = "网络错误,请稍后重试" setError(errorMessage) toast({ title: "错误", description: errorMessage, variant: "destructive" }) console.error("Failed to fetch message:", error) } finally { setLoading(false) } } fetchMessage() }, [emailId, messageId, messageType, toast]) const updateIframeContent = () => { if (viewMode === "html" && message?.html && iframeRef.current) { const iframe = iframeRef.current const doc = iframe.contentDocument || iframe.contentWindow?.document if (doc) { doc.open() doc.write(` ${message.html} `) doc.close() // 更新高度以填充容器 const updateHeight = () => { const container = iframe.parentElement if (container) { iframe.style.height = `${container.clientHeight}px` } } updateHeight() window.addEventListener('resize', updateHeight) // 监听内容变化 const resizeObserver = new ResizeObserver(updateHeight) resizeObserver.observe(doc.body) // 监听图片加载 doc.querySelectorAll('img').forEach((img: HTMLImageElement) => { img.onload = updateHeight }) return () => { window.removeEventListener('resize', updateHeight) resizeObserver.disconnect() } } } } // 监听主题变化和内容变化 useEffect(() => { updateIframeContent() }, [message?.html, viewMode, theme]) if (loading) { return (
加载邮件详情...
) } if (error) { return (

{error}

) } if (!message) return null return (

{message.subject}

{message.from_address && (

发件人:{message.from_address}

)} {message.to_address && (

收件人:{message.to_address}

)}

时间:{new Date(message.sent_at || message.received_at || 0).toLocaleString()}

{message.html && message.content && (
setViewMode(value as ViewMode)} className="flex items-center gap-4" >
)}
{viewMode === "html" && message.html ? (