Files
Perplexica/ui/components/Chat.tsx
Willie Zutz 467905d9f2 Added compact mode for more concise answers.
Made optimization mode persist between page refreshes.
Added mode switcher to chat so it can be changed while researching.
2025-02-16 15:02:05 -07:00

121 lines
3.2 KiB
TypeScript

'use client';
import { Fragment, useEffect, useRef, useState } from 'react';
import MessageInput from './MessageInput';
import { File, Message } from './ChatWindow';
import MessageBox from './MessageBox';
import MessageBoxLoading from './MessageBoxLoading';
const Chat = ({
loading,
messages,
sendMessage,
messageAppeared,
rewrite,
fileIds,
setFileIds,
files,
setFiles,
isCompact,
setIsCompact,
optimizationMode,
setOptimizationMode,
}: {
messages: Message[];
sendMessage: (
message: string,
messageId?: string,
options?: { isCompact?: boolean },
) => void;
loading: boolean;
messageAppeared: boolean;
rewrite: (messageId: string) => void;
fileIds: string[];
setFileIds: (fileIds: string[]) => void;
files: File[];
setFiles: (files: File[]) => void;
isCompact: boolean;
setIsCompact: (isCompact: boolean) => void;
optimizationMode: string;
setOptimizationMode: (mode: string) => void;
}) => {
const [dividerWidth, setDividerWidth] = useState(0);
const dividerRef = useRef<HTMLDivElement | null>(null);
const messageEnd = useRef<HTMLDivElement | null>(null);
useEffect(() => {
const updateDividerWidth = () => {
if (dividerRef.current) {
setDividerWidth(dividerRef.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.substring(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((msg, i) => {
const isLast = i === messages.length - 1;
return (
<Fragment key={msg.messageId}>
<MessageBox
key={i}
message={msg}
messageIndex={i}
history={messages}
loading={loading}
dividerRef={isLast ? dividerRef : undefined}
isLast={isLast}
rewrite={rewrite}
isCompact={isCompact}
sendMessage={sendMessage}
/>
{!isLast && msg.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"
style={{ width: dividerWidth }}
>
<MessageInput
loading={loading}
sendMessage={sendMessage}
fileIds={fileIds}
setFileIds={setFileIds}
files={files}
setFiles={setFiles}
isCompact={isCompact}
setIsCompact={setIsCompact}
optimizationMode={optimizationMode}
setOptimizationMode={setOptimizationMode}
/>
</div>
)}
</div>
);
};
export default Chat;