import React, { useState, useEffect } from 'react'; import { motion } from 'framer-motion'; import { User, Copy, Check } from 'lucide-react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism'; export interface MessageProps { id: string; role: 'user' | 'bot'; content: string; isNew?: boolean; } const CodeBlock = ({ inline, className, children, ...props }: { inline?: boolean; className?: string; children?: React.ReactNode } & React.HTMLAttributes) => { const match = /language-(\w+)/.exec(className || ''); const [copied, setCopied] = useState(false); const handleCopy = () => { navigator.clipboard.writeText(String(children).replace(/\n$/, '')); setCopied(true); setTimeout(() => setCopied(false), 2000); }; return !inline && match ? (
{match[1]}
{String(children).replace(/\n$/, '')}
) : ( {children} ); }; export const ChatMessage: React.FC<{ message: MessageProps }> = ({ message }) => { const isUser = message.role === 'user'; const [displayedContent, setDisplayedContent] = useState( !isUser && message.isNew ? '' : message.content ); useEffect(() => { if (isUser || !message.isNew) { setDisplayedContent(message.content); return; } let index = 0; setDisplayedContent(''); const timer = setInterval(() => { if (index < message.content.length) { setDisplayedContent(message.content.substring(0, index + 1)); index++; } else { clearInterval(timer); } }, 15); return () => clearInterval(timer); }, [message.content, isUser, message.isNew]); return (
{/* Avatar */}
{isUser ? ( ) : (
)}
{/* Message Bubble */}
{isUser ? ( message.content ) : (

{children}

, ul: ({ children }) =>
    {children}
, ol: ({ children }) =>
    {children}
, li: ({ children }) =>
  • {children}
  • , a: ({ href, children }) => {children}, h1: ({ children }) =>

    {children}

    , h2: ({ children }) =>

    {children}

    , h3: ({ children }) =>

    {children}

    , strong: ({ children }) => {children}, blockquote: ({ children }) =>
    {children}
    }} > {displayedContent}
    {!displayedContent && !isUser && message.isNew && (
    )}
    )}
    ); };