Feat/add stop conversation button (#76)

* chore add in stop conversation button

* feat: use abort controller

* chore: formatting

---------

Co-authored-by: Simon Holmes <srsholmes@gmail.com>
This commit is contained in:
Mckay Wrigley
2023-03-22 11:01:51 -06:00
committed by GitHub
parent b0f2a0a3ba
commit ec84eb2c49
4 changed files with 37 additions and 6 deletions
+4 -2
View File
@@ -1,5 +1,5 @@
import { Conversation, KeyValuePair, Message, OpenAIModel } from "@/types";
import { FC, useEffect, useRef, useState } from "react";
import { FC, MutableRefObject, useEffect, useRef, useState } from 'react';
import { ChatInput } from "./ChatInput";
import { ChatLoader } from "./ChatLoader";
import { ChatMessage } from "./ChatMessage";
@@ -17,9 +17,10 @@ interface Props {
lightMode: "light" | "dark";
onSend: (message: Message, isResend: boolean) => void;
onUpdateConversation: (conversation: Conversation, data: KeyValuePair) => void;
stopConversationRef: MutableRefObject<boolean>
}
export const Chat: FC<Props> = ({ conversation, models, messageIsStreaming, modelError, messageError, loading, lightMode, onSend, onUpdateConversation }) => {
export const Chat: FC<Props> = ({ conversation, models, messageIsStreaming, modelError, messageError, loading, lightMode, onSend, onUpdateConversation, stopConversationRef }) => {
const [currentMessage, setCurrentMessage] = useState<Message>();
const messagesEndRef = useRef<HTMLDivElement>(null);
@@ -96,6 +97,7 @@ export const Chat: FC<Props> = ({ conversation, models, messageIsStreaming, mode
/>
) : (
<ChatInput
stopConversationRef={stopConversationRef}
messageIsStreaming={messageIsStreaming}
onSend={(message) => {
setCurrentMessage(message);
+22 -3
View File
@@ -1,14 +1,15 @@
import { Message, OpenAIModel, OpenAIModelID } from "@/types";
import { IconSend } from "@tabler/icons-react";
import { FC, KeyboardEvent, useEffect, useRef, useState } from "react";
import { IconHandStop, IconSend } from "@tabler/icons-react";
import { FC, KeyboardEvent, MutableRefObject, useEffect, useRef, useState } from "react";
interface Props {
messageIsStreaming: boolean;
onSend: (message: Message) => void;
model: OpenAIModel;
stopConversationRef: MutableRefObject<boolean>;
}
export const ChatInput: FC<Props> = ({ onSend, messageIsStreaming, model }) => {
export const ChatInput: FC<Props> = ({ onSend, messageIsStreaming, model, stopConversationRef }) => {
const [content, setContent] = useState<string>();
const [isTyping, setIsTyping] = useState<boolean>(false);
@@ -67,6 +68,13 @@ export const ChatInput: FC<Props> = ({ onSend, messageIsStreaming, model }) => {
}
}, [content]);
function handleStopConversation() {
stopConversationRef.current = true;
setTimeout(() => {
stopConversationRef.current = false;
}, 1000);
}
return (
<div className="absolute bottom-0 left-0 w-full border-t md:border-t-0 dark:border-white/20 md:border-transparent md:dark:border-transparent dark:bg-[#444654] md:dark:bg-gradient-to-t from-[#343541] via-[#343541] to-[#343541]/0 bg-white md:dark:!bg-transparent dark:md:bg-vert-dark-gradient pt-2">
<div className="stretch mx-2 md:mt-[52px] mt-4 flex flex-row gap-3 last:mb-2 md:mx-4 md:last:mb-6 lg:mx-auto lg:max-w-3xl">
@@ -98,6 +106,17 @@ export const ChatInput: FC<Props> = ({ onSend, messageIsStreaming, model }) => {
className="opacity-60"
/>
</button>
{messageIsStreaming ? (
<button
className="absolute right-12 focus:outline-none text-neutral-800 hover:text-neutral-900 dark:text-neutral-100 dark:hover:text-neutral-200 dark:bg-opacity-50 hover:bg-neutral-200 p-1 rounded-sm"
onClick={handleStopConversation}
>
<IconHandStop
size={16}
className="opacity-60"
/>
</button>
) : null}
</div>
</div>
<div className="px-3 pt-2 pb-3 text-center text-xs text-black/50 dark:text-white/50 md:px-4 md:pt-3 md:pb-6">