import type { ReactNode } from "react"; import { useEffect, useMemo, useRef } from "react"; import IconMessage from "virtual:icons/mdi/message"; import Message from "./Message"; import MessageTyping from "./MessageTyping"; import { useChat } from "../composables"; import type { ChatMessage } from "../types"; import "./MessagesList.scss"; interface MessagesListProps { messages: ChatMessage[]; emptyText?: string; initialMessages?: ChatMessage[]; renderBeforeMessages?: ReactNode; } export default function MessagesList({ messages, emptyText, initialMessages, renderBeforeMessages, }: MessagesListProps) { const { initialMessages: storeInitialMessages, waitingForResponse } = useChat(); const derivedInitialMessages = useMemo( () => initialMessages ?? storeInitialMessages, [initialMessages, storeInitialMessages], ); const lastMessageRef = useRef(null); const hasNoMessages = (derivedInitialMessages?.length ?? 0) === 0 && messages.length === 0 && Boolean(emptyText); useEffect(() => { const scrollTarget = lastMessageRef.current; if (scrollTarget && typeof scrollTarget.scrollIntoView === "function") { scrollTarget.scrollIntoView({ block: "start" }); } }, [messages.length, waitingForResponse, derivedInitialMessages.length]); if (hasNoMessages) { return (

{emptyText}

); } return (
{renderBeforeMessages} {derivedInitialMessages.map((message) => ( ))} {messages.map((message, index) => { const isLast = index === messages.length - 1; return (
); })} {waitingForResponse && }
); }