"use client"; import { useState, useEffect, useRef } from "react"; import { User, Bot, Send, Loader2, Square } from "lucide-react"; import { MarkdownRenderer } from "@/components/message/MarkdownRenderer"; import { MessageActions } from "@/components/message/MessageActions"; import type { Message } from "@/lib/chat"; import { formatTimestamp } from "@/lib/chat"; interface ChatMessageProps { message: Message; isStreaming?: boolean; bubbleSize?: "sm" | "md" | "lg"; } export function ChatMessage({ message, isStreaming = false, bubbleSize = "md", }: ChatMessageProps) { const isUser = message.role === "user"; const sizeClass = bubbleSize === "sm" ? "px-3 py-1.5 text-sm" : bubbleSize === "lg" ? "px-5 py-3 text-base" : "px-4 py-2 text-sm"; return (
{!isUser && (
)}
{isUser ? (
{message.content}
) : ( )}
{isStreaming && ▊} {!isUser && !isStreaming && (
)}
{formatTimestamp(message.timestamp)}
{isUser && (
)}
); } interface ChatInputProps { onSendMessage: (content: string) => void; onStop?: () => void; disabled?: boolean; isStreaming?: boolean; placeholder?: string; } export function ChatInput({ onSendMessage, onStop, disabled = false, isStreaming = false, placeholder = "Type a message...", }: ChatInputProps) { const [content, setContent] = useState(""); const textareaRef = useRef(null); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (content.trim() && !disabled) { onSendMessage(content.trim()); setContent(""); } }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); handleSubmit(e); } }; useEffect(() => { if (textareaRef.current) { textareaRef.current.style.height = "auto"; textareaRef.current.style.height = `${Math.min( textareaRef.current.scrollHeight, 120 )}px`; } }, [content]); return (