import { PreviewMessage, ThinkingMessage } from './message'; import { Greeting } from './greeting'; import { memo, useEffect } from 'react'; import type { Vote } from '@/lib/db/schema'; import equal from 'fast-deep-equal'; import type { UseChatHelpers } from '@ai-sdk/react'; import { useMessages } from '@/hooks/use-messages'; import type { ChatMessage } from '@/lib/types'; import { useDataStream } from './data-stream-provider'; import { Conversation, ConversationContent } from './elements/conversation'; import { ArrowDownIcon } from 'lucide-react'; interface MessagesProps { chatId: string; status: UseChatHelpers['status']; votes: Array | undefined; messages: ChatMessage[]; setMessages: UseChatHelpers['setMessages']; regenerate: UseChatHelpers['regenerate']; isReadonly: boolean; isArtifactVisible: boolean; selectedModelId: string; } function PureMessages({ chatId, status, votes, messages, setMessages, regenerate, isReadonly, isArtifactVisible, selectedModelId, }: MessagesProps) { const { containerRef: messagesContainerRef, endRef: messagesEndRef, isAtBottom, scrollToBottom, hasSentMessage, } = useMessages({ chatId, status, }); useDataStream(); useEffect(() => { if (status === 'submitted') { requestAnimationFrame(() => { const container = messagesContainerRef.current; if (container) { container.scrollTo({ top: container.scrollHeight, behavior: 'smooth', }); } }); } }, [status, messagesContainerRef]); return (
{messages.length === 0 && } {messages.map((message, index) => ( vote.messageId === message.id) : undefined } setMessages={setMessages} regenerate={regenerate} isReadonly={isReadonly} requiresScrollPadding={ hasSentMessage && index === messages.length - 1 } isArtifactVisible={isArtifactVisible} /> ))} {status === 'submitted' && messages.length > 0 && messages[messages.length - 1].role === 'user' && selectedModelId !== 'chat-model-reasoning' && }
{!isAtBottom && ( )}
); } export const Messages = memo(PureMessages, (prevProps, nextProps) => { if (prevProps.isArtifactVisible && nextProps.isArtifactVisible) return true; if (prevProps.status !== nextProps.status) return false; if (prevProps.selectedModelId !== nextProps.selectedModelId) return false; if (prevProps.messages.length !== nextProps.messages.length) return false; if (!equal(prevProps.messages, nextProps.messages)) return false; if (!equal(prevProps.votes, nextProps.votes)) return false; return false; });