import { useEffect, useRef, useState } from "react";
import { FileUpload } from "./FileUpload";
function Message({ message, role }: Message) {
return (
{message}
);
}
interface Message {
message: string;
role: "user" | "assistant";
}
function App() {
const scrollUpRef = useRef(false);
const [result, setResult] = useState("");
const [error, setError] = useState("");
const [isStreaming, setIsStreaming] = useState(false);
const [messages, setMessages] = useState([]);
const [isFileUploaded, setIsFileUploaded] = useState(false);
useEffect(() => {
function handleWheel(event: WheelEvent) {
if (isStreaming && event.deltaY < 0) {
scrollUpRef.current = true;
}
}
document.body.addEventListener("wheel", handleWheel);
return () => {
document.body.removeEventListener("wheel", handleWheel);
};
}, [isStreaming]);
const onKeyDown = (e: React.KeyboardEvent) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
e.currentTarget.form?.requestSubmit();
}
};
async function onSubmit(e: React.FormEvent) {
e.preventDefault();
const form = e.currentTarget;
const formData = new FormData(form);
const msg = formData.get("msg") as string;
const scrollingElement = document.scrollingElement;
if (msg.trim() === "") return;
scrollUpRef.current = false;
scrollingElement?.scrollTo({
behavior: "smooth",
top: scrollingElement?.scrollHeight,
});
setIsStreaming(true);
setMessages((prev) => [
...prev,
{
message: msg,
role: "user",
},
]);
try {
const session_id = sessionStorage.getItem("session_id");
const response = await fetch(form.action, {
method: "POST",
headers: session_id
? {
"X-Session-ID": session_id,
}
: undefined,
body: msg,
});
let result = "";
const reader = response.body?.getReader();
const decoder = new TextDecoder();
form.msg.value = "";
await reader?.read().then(function processText(msg): Promise {
const { value, done } = msg;
const chunk = decoder.decode(value, { stream: true });
const scrollingElement = document.scrollingElement;
if (done) {
setResult("");
setMessages((prev) => [
...prev,
{
message: result,
role: "assistant",
},
]);
if (scrollingElement) {
scrollingElement.scrollTop = scrollingElement?.scrollHeight;
}
return Promise.resolve();
}
result += chunk;
setResult(result);
if (!scrollUpRef.current && scrollingElement) {
scrollingElement.scrollTop = scrollingElement.scrollHeight;
}
// Read some more, and call this function again
return reader.read().then(processText);
});
} catch (error) {
setError("Error submitting message");
console.error("Error submitting message", error);
} finally {
setIsStreaming(false);
}
}
return (
{!isFileUploaded && (
DocTalk
Talk to your documents.
)}
{messages.map(({ message, role }) => (
))}
{result &&
}
{error &&
{error}
}
{isFileUploaded && (
)}
);
}
export default App;