[AutoGen Studio] Allow multiline strings in chat input (#1105)

* [AutoGen Studio] Allow multiline strings in chat input

* make cogicon spin/animate during loading. minor fix to header issue.

---------

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
This commit is contained in:
Dragos Campean 2024-01-03 02:24:24 +02:00 committed by GitHub
parent 8a26d3b3cd
commit 98d148046b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 49 deletions

View File

@ -95,7 +95,7 @@ const Header = ({ meta, link }: any) => {
return (
<div
key={index + "linkrow"}
className={`text-primary items-center hover:text-accent hover:bg-secondary px-1 pt-1 block text-sm font-medium `}
className={`text-primary items-center hover:text-accent px-1 pt-1 block text-sm font-medium `}
>
<Link
className="hover:text-accent h-full flex flex-col"

View File

@ -29,7 +29,7 @@ const ChatBox = ({
editable?: boolean;
}) => {
const session: IChatSession | null = useConfigStore((state) => state.session);
const queryInputRef = React.useRef<HTMLInputElement>(null);
const textAreaInputRef = React.useRef<HTMLTextAreaElement>(null);
const messageBoxInputRef = React.useRef<HTMLDivElement>(null);
const { user } = React.useContext(appContext);
@ -37,6 +37,7 @@ const ChatBox = ({
const deleteMsgUrl = `${serverUrl}/messages/delete`;
const [loading, setLoading] = React.useState(false);
const [text, setText] = React.useState("");
const [error, setError] = React.useState<IStatus | null>({
status: true,
message: "All good",
@ -51,7 +52,7 @@ const ChatBox = ({
let pageHeight, chatMaxHeight;
if (typeof window !== "undefined") {
pageHeight = window.innerHeight;
chatMaxHeight = pageHeight - 300 + "px";
chatMaxHeight = pageHeight - 350 + "px";
}
const parseMessages = (messages: any) => {
@ -265,28 +266,26 @@ const ChatBox = ({
}, 200);
}, [messages]);
const textAreaDefaultHeight = "50px";
// clear text box if loading has just changed to false and there is no error
React.useEffect(() => {
if (loading === false && queryInputRef.current) {
if (queryInputRef.current) {
// console.log("loading changed", loading, error);
if (loading === false && textAreaInputRef.current) {
if (textAreaInputRef.current) {
if (error === null || (error && error.status === false)) {
queryInputRef.current.value = "";
textAreaInputRef.current.value = "";
textAreaInputRef.current.style.height = textAreaDefaultHeight;
}
}
}
}, [loading]);
// scroll to queryInputRef on load
React.useEffect(() => {
// console.log("scrolling to query input");
// if (queryInputRef.current) {
// queryInputRef.current.scrollIntoView({
// behavior: "smooth",
// block: "center",
// });
// }
}, []);
if (textAreaInputRef.current) {
textAreaInputRef.current.style.height = textAreaDefaultHeight; // Reset height to shrink if text is deleted
const scrollHeight = textAreaInputRef.current.scrollHeight;
textAreaInputRef.current.style.height = `${scrollHeight}px`;
}
}, [text]);
const chatHistory = (messages: IChatMessage[] | null) => {
let history = "";
@ -378,6 +377,23 @@ const ChatBox = ({
});
};
const handleTextChange = (
event: React.ChangeEvent<HTMLTextAreaElement>
): void => {
setText(event.target.value);
};
const handleKeyDown = (
event: React.KeyboardEvent<HTMLTextAreaElement>
): void => {
if (event.key === "Enter" && !event.shiftKey) {
if (textAreaInputRef.current && !loading) {
event.preventDefault();
getCompletion(textAreaInputRef.current.value);
}
}
};
return (
<div className="text-primary relative h-full rounded ">
<div
@ -414,55 +430,53 @@ const ChatBox = ({
{editable && (
<div className="mt-2 p-2 absolute bg-primary bottom-0 w-full">
<div
className={`mt-2 rounded p-2 shadow-lg flex mb-1 gap-2 ${
className={`rounded p-2 shadow-lg flex mb-1 gap-2 ${
loading ? " opacity-50 pointer-events-none" : ""
}`}
>
{/* <input className="flex-1 p-2 ring-2" /> */}
<form
autoComplete="on"
className="flex-1 "
className="flex-1 relative"
onSubmit={(e) => {
e.preventDefault();
// if (queryInputRef.current && !loading) {
// getCompletion(queryInputRef.current?.value);
// }
}}
>
<input
<textarea
id="queryInput"
name="queryInput"
autoComplete="on"
onKeyDown={(e) => {
if (e.key === "Enter" && queryInputRef.current && !loading) {
getCompletion(queryInputRef.current?.value);
onKeyDown={handleKeyDown}
onChange={handleTextChange}
placeholder="Write message here..."
ref={textAreaInputRef}
className="flex items-center w-full resize-none text-gray-600 bg-white p-2 ring-2 rounded-sm pl-5 pr-16"
style={{ maxHeight: "120px", overflowY: "auto" }}
/>
<div
role={"button"}
style={{ width: "45px", height: "35px" }}
title="Send message"
onClick={() => {
if (textAreaInputRef.current && !loading) {
getCompletion(textAreaInputRef.current.value);
}
}}
ref={queryInputRef}
className="w-full text-gray-600 bg-white p-2 ring-2 rounded-sm"
/>
className="absolute right-3 bottom-2 bg-accent hover:brightness-75 transition duration-300 rounded cursor-pointer flex justify-center items-center"
>
{" "}
{!loading && (
<div className="inline-block ">
<PaperAirplaneIcon className="h-6 w-6 text-white " />{" "}
</div>
)}
{loading && (
<div className="inline-block ">
<Cog6ToothIcon className="text-white animate-spin rounded-full h-6 w-6" />
</div>
)}
</div>
</form>
<div
role={"button"}
onClick={() => {
if (queryInputRef.current && !loading) {
getCompletion(queryInputRef.current?.value);
}
}}
className="bg-accent hover:brightness-75 transition duration-300 rounded pt-2 px-5 "
>
{" "}
{!loading && (
<div className="inline-block ">
<PaperAirplaneIcon className="h-6 text-white inline-block" />{" "}
</div>
)}
{loading && (
<div className="inline-block ">
<Cog6ToothIcon className="relative -pb-2 text-white animate-spin inline-flex rounded-full h-6 w-6" />
</div>
)}
</div>
</div>{" "}
<div>
<div className="mt-2 text-xs text-secondary">