85 lines
2.4 KiB
TypeScript
85 lines
2.4 KiB
TypeScript
"use client";
|
|
|
|
import { Fragment, useEffect, useRef, useState } from "react";
|
|
import MessageInput from "./MessageInput";
|
|
import { Message } from "./ChatWindow";
|
|
import MessageBox from "./MessageBox";
|
|
import MessageBoxLoading from "./MessageBoxLoading";
|
|
|
|
const Chat = ({
|
|
loading,
|
|
messages,
|
|
sendMessage,
|
|
messageAppeared,
|
|
rewrite,
|
|
}: {
|
|
messages: Message[];
|
|
sendMessage: (message: string) => void;
|
|
loading: boolean;
|
|
messageAppeared: boolean;
|
|
rewrite: (messageId: string) => void;
|
|
}) => {
|
|
const [dividerWidth, setDividerWidth] = useState(0);
|
|
const dividerReference = useRef<HTMLDivElement | null>(null);
|
|
const messageEnd = useRef<HTMLDivElement | null>(null);
|
|
|
|
useEffect(() => {
|
|
const updateDividerWidth = () => {
|
|
if (dividerReference.current) {
|
|
setDividerWidth(dividerReference.current.scrollWidth);
|
|
}
|
|
};
|
|
|
|
updateDividerWidth();
|
|
|
|
window.addEventListener("resize", updateDividerWidth);
|
|
|
|
return () => {
|
|
window.removeEventListener("resize", updateDividerWidth);
|
|
};
|
|
});
|
|
|
|
useEffect(() => {
|
|
messageEnd.current?.scrollIntoView({ behavior: "smooth" });
|
|
|
|
if (messages.length === 1) {
|
|
document.title = `${messages[0].content.slice(0, 30)} - Perplexica`;
|
|
}
|
|
}, [messages]);
|
|
|
|
return (
|
|
<div className="flex flex-col space-y-6 pt-8 pb-44 lg:pb-32 sm:mx-4 md:mx-8">
|
|
{messages.map((message, index) => {
|
|
const isLast = index === messages.length - 1;
|
|
|
|
return (
|
|
<Fragment key={message.messageId}>
|
|
<MessageBox
|
|
key={index}
|
|
message={message}
|
|
messageIndex={index}
|
|
history={messages}
|
|
loading={loading}
|
|
dividerRef={isLast ? dividerReference : undefined}
|
|
isLast={isLast}
|
|
rewrite={rewrite}
|
|
sendMessage={sendMessage}
|
|
/>
|
|
{!isLast && message.role === "assistant" && (
|
|
<div className="h-px w-full bg-light-secondary dark:bg-dark-secondary" />
|
|
)}
|
|
</Fragment>
|
|
);
|
|
})}
|
|
{loading && !messageAppeared && <MessageBoxLoading />}
|
|
<div ref={messageEnd} className="h-0" />
|
|
{dividerWidth > 0 && (
|
|
<div className="bottom-24 lg:bottom-10 fixed z-40" style={{ width: dividerWidth }}>
|
|
<MessageInput loading={loading} sendMessage={sendMessage} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Chat;
|