import { PreviewMessage, ThinkingMessage } from './message'; import type { Vote } from '@/lib/db/schema'; import { memo } from 'react'; import equal from 'fast-deep-equal'; import type { UIArtifact } from './artifact'; import type { UseChatHelpers } from '@ai-sdk/react'; import { motion } from 'framer-motion'; import { useMessages } from '@/hooks/use-messages'; import type { ChatMessage } from '@/lib/types'; interface ArtifactMessagesProps { chatId: string; status: UseChatHelpers['status']; votes: Array | undefined; messages: ChatMessage[]; setMessages: UseChatHelpers['setMessages']; regenerate: UseChatHelpers['regenerate']; isReadonly: boolean; artifactStatus: UIArtifact['status']; } function PureArtifactMessages({ chatId, status, votes, messages, setMessages, regenerate, isReadonly, }: ArtifactMessagesProps) { const { containerRef: messagesContainerRef, endRef: messagesEndRef, onViewportEnter, onViewportLeave, hasSentMessage, } = useMessages({ chatId, status, }); return (
{messages.map((message, index) => ( vote.messageId === message.id) : undefined } setMessages={setMessages} regenerate={regenerate} isReadonly={isReadonly} requiresScrollPadding={ hasSentMessage && index === messages.length - 1 } /> ))} {status === 'submitted' && messages.length > 0 && messages[messages.length - 1].role === 'user' && }
); } function areEqual( prevProps: ArtifactMessagesProps, nextProps: ArtifactMessagesProps, ) { if ( prevProps.artifactStatus === 'streaming' && nextProps.artifactStatus === 'streaming' ) return true; if (prevProps.status !== nextProps.status) return false; if (prevProps.status && nextProps.status) return false; if (prevProps.messages.length !== nextProps.messages.length) return false; if (!equal(prevProps.votes, nextProps.votes)) return false; return true; } export const ArtifactMessages = memo(PureArtifactMessages, areEqual);