File size: 2,663 Bytes
f3a9ef2
a86b547
1f931d5
cfb938a
a86b547
8e3dbd3
58d7e55
92f037b
a1c5622
1f931d5
92f037b
 
 
a1c5622
f3a9ef2
1f931d5
5ec491a
f3a9ef2
 
cfb938a
 
1f931d5
a1c5622
 
f3a9ef2
92f037b
cfb938a
8e3dbd3
92f037b
 
 
 
 
 
 
f80b091
1f931d5
92f037b
1f931d5
 
c232e44
1f931d5
 
 
 
 
 
 
 
 
cfb938a
 
 
 
 
f80b091
cfb938a
1f931d5
a1c5622
 
1f931d5
92f037b
 
a1c5622
 
92f037b
 
1f931d5
 
92f037b
 
 
 
 
 
 
 
 
 
 
1f931d5
f80b091
1f931d5
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
'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;