theo-agent-dashboard

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

MessageList.tsx (1971B)


      1 import { useRef, useEffect } from "react";
      2 import type { Message as MessageType } from "../../store/chat";
      3 import { Message } from "../Message/Message";
      4 
      5 interface MessageListProps {
      6   messages: MessageType[];
      7   onForkMessage?: (messageId: string) => void;
      8   showForkButton?: boolean;
      9   thinking?: boolean;
     10 }
     11 
     12 function TypingIndicator() {
     13   return (
     14     <div className="flex items-center gap-2 px-4 py-3">
     15       <div className="flex gap-1">
     16         <span className="inline-block h-2 w-2 animate-bounce rounded-full bg-gray-500 [animation-delay:0ms]" />
     17         <span className="inline-block h-2 w-2 animate-bounce rounded-full bg-gray-500 [animation-delay:150ms]" />
     18         <span className="inline-block h-2 w-2 animate-bounce rounded-full bg-gray-500 [animation-delay:300ms]" />
     19       </div>
     20       <span className="text-xs text-gray-500">Thinking...</span>
     21     </div>
     22   );
     23 }
     24 
     25 export function MessageList({
     26   messages,
     27   onForkMessage,
     28   showForkButton = false,
     29   thinking = false,
     30 }: MessageListProps) {
     31   const bottomRef = useRef<HTMLDivElement>(null);
     32 
     33   useEffect(() => {
     34     const container = bottomRef.current?.parentElement?.parentElement;
     35     if (container && container.classList.contains('overflow-y-auto')) {
     36       container.scrollTop = container.scrollHeight;
     37     }
     38   }, [messages, thinking]);
     39 
     40   if (messages.length === 0 && !thinking) {
     41     return (
     42       <div className="flex flex-1 items-center justify-center text-gray-500">
     43         Send a message to start
     44       </div>
     45     );
     46   }
     47 
     48   return (
     49     <div className="flex-1 overflow-y-auto px-4 py-6">
     50       <div className="mx-auto max-w-3xl space-y-6">
     51         {messages.map((msg) => (
     52           <Message
     53             key={msg.id}
     54             message={msg}
     55             showForkButton={showForkButton}
     56             onFork={onForkMessage ? () => onForkMessage(msg.id) : undefined}
     57           />
     58         ))}
     59         {thinking && <TypingIndicator />}
     60         <div ref={bottomRef} />
     61       </div>
     62     </div>
     63   );
     64 }