Spaces:
Sleeping
Sleeping
'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; | |