vision-agent / components /chat /ChatClient.tsx
MingruiZhang's picture
feat: DB change - combine user and assistant message (#70)
a1c5622 unverified
raw
history blame
2.66 kB
'use client';
// import { ChatList } from '@/components/chat/ChatList';
import Composer from '@/components/chat/Composer';
import useVisionAgent from '@/lib/hooks/useVisionAgent';
import { useScrollAnchor } from '@/lib/hooks/useScrollAnchor';
import { Session } from 'next-auth';
import { useEffect } from 'react';
import { ChatWithMessages, MessageUserInput } from '@/lib/types';
import { ChatMessage } from './ChatMessage';
import { Button } from '../ui/Button';
import { cn } from '@/lib/utils';
import { IconArrowDown } from '../ui/Icons';
import { dbPostCreateMessage } from '@/lib/db/functions';
export interface ChatClientProps {
chat: ChatWithMessages;
}
export const SCROLL_BOTTOM = 120;
const ChatClient: React.FC<ChatClientProps> = ({ chat }) => {
const { id, messages: dbMessages } = chat;
const { messages, append, isLoading } = useVisionAgent(chat);
const { messagesRef, scrollRef, visibilityRef, isVisible, scrollToBottom } =
useScrollAnchor(SCROLL_BOTTOM);
// Scroll to bottom when messages are loading
useEffect(() => {
if (isLoading && messages.length) {
scrollToBottom();
}
}, [isLoading, scrollToBottom, messages]);
return (
<div
className="h-full overflow-auto mx-auto w-[1024px] max-w-full border rounded-lg relative"
ref={scrollRef}
>
<div className="overflow-auto h-full pt-6 px-6 z-10" ref={messagesRef}>
{messages
// .filter(message => message.role !== 'system')
.map((message, index) => (
<ChatMessage
key={index}
message={message}
isLoading={isLoading && index === messages.length - 1}
/>
))}
<div
className="w-full"
style={{ height: SCROLL_BOTTOM }}
ref={visibilityRef}
/>
</div>
<div className="absolute bottom-4 w-full">
<Composer
// Use the last message mediaUrl as the initial mediaUrl
initMediaUrl={dbMessages[dbMessages.length - 1]?.mediaUrl}
isLoading={isLoading}
onSubmit={async ({ input, mediaUrl: newMediaUrl }) => {
append({
prompt: input,
mediaUrl: newMediaUrl,
});
}}
/>
</div>
{/* Scroll to bottom Icon */}
<Button
size="icon"
className={cn(
'absolute bottom-3 right-3 transition-opacity duration-300 size-6',
isVisible ? 'opacity-0' : 'opacity-100',
)}
onClick={() => scrollToBottom()}
>
<IconArrowDown className="size-3" />
</Button>
</div>
);
};
export default ChatClient;