"use client";
import { useState, useEffect, useRef } from "react";
import { User, Bot, Send, Loader2 } from "lucide-react";
import { MarkdownRenderer } from "@/components/message/MarkdownRenderer";
import { MessageActions } from "@/components/message/MessageActions";
import { extractCodeBlocks } from "@/hooks/useMarkdown";
import type { Message } from "@/lib/chat";
import { formatTimestamp } from "@/lib/chat";
interface ChatMessageProps {
message: Message;
isStreaming?: boolean;
}
export function ChatMessage({
message,
isStreaming = false,
}: ChatMessageProps) {
const isUser = message.role === "user";
return (
{!isUser && (
)}
{isUser ? (
message.content
) : (
)}
{isStreaming &&
▊}
{!isUser && !isStreaming && (
)}
{formatTimestamp(message.timestamp)}
{isUser && (
)}
);
}
interface ChatInputProps {
onSendMessage: (content: string) => void;
disabled?: boolean;
placeholder?: string;
}
export function ChatInput({
onSendMessage,
disabled = 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 (
);
}
interface StreamingTextProps {
text: string;
isStreaming: boolean;
}
export function StreamingText({ text, isStreaming }: StreamingTextProps) {
return (
{text}
{isStreaming && ▊}
);
}