next-chat / components /messages.tsx
NeoPy's picture
Upload folder using huggingface_hub
867b17d verified
raw
history blame
3.1 kB
import { PreviewMessage, ThinkingMessage } from './message';
import { Greeting } from './greeting';
import { memo } from 'react';
import type { Vote } from '@/lib/db/schema';
import equal from 'fast-deep-equal';
import type { UseChatHelpers } from '@ai-sdk/react';
import { motion } from 'framer-motion';
import { useMessages } from '@/hooks/use-messages';
import type { ChatMessage } from '@/lib/types';
import { useDataStream } from './data-stream-provider';
import { Conversation, ConversationContent, ConversationScrollButton } from './elements/conversation';
interface MessagesProps {
chatId: string;
status: UseChatHelpers<ChatMessage>['status'];
votes: Array<Vote> | undefined;
messages: ChatMessage[];
setMessages: UseChatHelpers<ChatMessage>['setMessages'];
regenerate: UseChatHelpers<ChatMessage>['regenerate'];
isReadonly: boolean;
isArtifactVisible: boolean;
}
function PureMessages({
chatId,
status,
votes,
messages,
setMessages,
regenerate,
isReadonly,
}: MessagesProps) {
const {
containerRef: messagesContainerRef,
endRef: messagesEndRef,
onViewportEnter,
onViewportLeave,
hasSentMessage,
} = useMessages({
chatId,
status,
});
useDataStream();
return (
<div ref={messagesContainerRef} className="flex-1 overflow-y-auto">
<Conversation className="flex flex-col min-w-0 gap-6 py-4 px-2 md:px-4">
<ConversationContent className="flex flex-col gap-6">
{messages.length === 0 && <Greeting />}
{messages.map((message, index) => (
<PreviewMessage
key={message.id}
chatId={chatId}
message={message}
isLoading={status === 'streaming' && messages.length - 1 === index}
vote={
votes
? votes.find((vote) => 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' && <ThinkingMessage />}
<motion.div
ref={messagesEndRef}
className="shrink-0 min-w-[24px] min-h-[24px]"
onViewportLeave={onViewportLeave}
onViewportEnter={onViewportEnter}
/>
</ConversationContent>
<ConversationScrollButton />
</Conversation>
</div>
);
}
export const Messages = memo(PureMessages, (prevProps, nextProps) => {
if (prevProps.isArtifactVisible && nextProps.isArtifactVisible) return true;
if (prevProps.status !== nextProps.status) 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;
});