import React, { useMemo } from "react"; import { motion } from "framer-motion"; import { ChatMessage, MessageBlock } from "./types"; import { bubbleVariants, hhmm } from "./utils"; import { ProgressBar } from "./ProgressBar"; import { Loader2, AlertCircle, CheckCircle2 } from "lucide-react"; import { Image } from 'antd'; import { useDeviceType } from '@/hooks/useDeviceType'; interface MessageRendererProps { msg: ChatMessage; sendMessage: (blocks: MessageBlock[]) => Promise; } export function MessageRenderer({ msg, sendMessage }: MessageRendererProps) { // Decide bubble style const isUser = msg.role === "user"; const isSystem = msg.role === "system"; const { isMobile, isTablet, isDesktop } = useDeviceType(); const bubbleClass = useMemo(() => { if (isSystem) return "bg-[#281c1459] text-white"; if (isUser) return "bg-[#27416c59] text-white"; return "bg-[#281c1459] text-white"; // assistant }, [isSystem, isUser]); const badge = isSystem ? ( 系统流程 ) : msg.role === "assistant" ? ( 助手 ) : null; // 状态图标和颜色 const statusIcon = useMemo(() => { if (!isUser) return null; switch (msg.status) { case 'pending': return ; case 'success': return ; case 'error': return ; default: return null; } }, [isUser, msg.status]); // 消息类型标签 const typeLabel = useMemo(() => { if (!isUser) return null; const isTask = msg.chatType !== 'chat'; if (isTask) { return ( 任务 ); } return ( 聊天 ); }, [isUser, msg.chatType]); return (
{/* Header */} {/*
{badge}
{typeLabel} {hhmm(msg.createdAt)} {statusIcon}
*/} {/* Content blocks */}
{msg.blocks.map((b, idx) => { switch (b.type) { case "text": return (

{b.text}

); case "image": return (
{b.alt document.querySelector('[data-alt="smart-chat-box"]') || document.body, mask:
, maskClassName: "!bg-black/60", rootClassName: "!z-[1000]" }} />
); case "video": return (
); case "audio": return (
); }