import React, { memo, useCallback, useRef, useState } from "react"; import { Transition } from "@headlessui/react"; import axios from "axios"; import ReactMarkdown from "react-markdown"; import FileViewerList from "./FileViewerList"; import LoadingText from "./LoadingText"; import { isFileNameInString } from "../services/utils"; import { FileChunk, FileLite } from "../types/file"; import { SERVER_ADDRESS } from "../types/constants"; type FileQandAAreaProps = { files: FileLite[]; }; function FileQandAArea(props: FileQandAAreaProps) { const searchBarRef = useRef(null); const [answerError, setAnswerError] = useState(""); const [searchResultsLoading, setSearchResultsLoading] = useState(false); const [answer, setAnswer] = useState(""); const handleSearch = useCallback(async () => { if (searchResultsLoading) { return; } const question = (searchBarRef?.current as any)?.value ?? ""; setAnswer(""); if (!question) { setAnswerError("Please ask a question."); return; } if (props.files.length === 0) { setAnswerError("Please upload files before asking a question."); return; } setSearchResultsLoading(true); setAnswerError(""); let results: FileChunk[] = []; try { const answerResponse = await axios.post( `${SERVER_ADDRESS}/answer_question`, { question, } ); if (answerResponse.status === 200) { setAnswer(answerResponse.data.answer); } else { setAnswerError("Sorry, something went wrong!"); } } catch (err: any) { setAnswerError("Sorry, something went wrong!"); } setSearchResultsLoading(false); }, [props.files, searchResultsLoading]); const handleEnterInSearchBar = useCallback( async (event: React.SyntheticEvent) => { if ((event as any).key === "Enter") { await handleSearch(); } }, [handleSearch] ); return (
Ask a question based on the content of your files:
{searchResultsLoading ? ( ) : ( "Ask question" )}
{answerError &&
{answerError}
} {/* answer from files */} {answer && (
{answer}
)} isFileNameInString(file.name, answer) ).length > 0 } enter="transition duration-600 ease-out" enterFrom="transform opacity-0" enterTo="transform opacity-100" leave="transition duration-125 ease-out" leaveFrom="transform opacity-100" leaveTo="transform opacity-0" className="mb-8" > isFileNameInString(file.name, answer) )} title="Sources" listExpanded={true} />
); } export default memo(FileQandAArea);