diff --git a/client/src/components/Conversations/Conversation.jsx b/client/src/components/Conversations/Conversation.jsx index ce4cf3c6be..470206cb51 100644 --- a/client/src/components/Conversations/Conversation.jsx +++ b/client/src/components/Conversations/Conversation.jsx @@ -3,8 +3,8 @@ import RenameButton from './RenameButton'; import DeleteButton from './DeleteButton'; import { useSelector, useDispatch } from 'react-redux'; import { setConversation } from '~/store/convoSlice'; -import { setCustomGpt, setModel, setCustomModel } from '~/store/submitSlice'; -import { setMessages } from '~/store/messageSlice'; +import { setStopStream, setCustomGpt, setModel, setCustomModel } from '~/store/submitSlice'; +import { setMessages, setEmptyMessage } from '~/store/messageSlice'; import { setText } from '~/store/textSlice'; import manualSWR from '~/utils/fetchers'; import ConvoIcon from '../svg/ConvoIcon'; @@ -23,7 +23,7 @@ export default function Conversation({ const { modelMap } = useSelector((state) => state.models); const inputRef = useRef(null); const dispatch = useDispatch(); - const { trigger } = manualSWR(`/api/messages/${id}`, 'get'); + const { trigger, isMutating } = manualSWR(`/api/messages/${id}`, 'get'); const rename = manualSWR(`/api/convos/update`, 'post'); const clickHandler = async () => { @@ -31,6 +31,9 @@ export default function Conversation({ return; } + dispatch(setStopStream(true)); + dispatch(setEmptyMessage()); + const convo = { title, error: false, conversationId: id, chatGptLabel, promptPrefix }; if (bingData) { @@ -64,6 +67,12 @@ export default function Conversation({ ); } const data = await trigger(); + // while (isMutating) { + // await new Promise((resolve) => setTimeout(() => { + // dispatch(setMessages([])); + // resolve(); + // }, 50)); + // } if (chatGptLabel) { dispatch(setModel('chatgptCustom')); @@ -81,6 +90,7 @@ export default function Conversation({ dispatch(setMessages(data)); dispatch(setCustomGpt(convo)); dispatch(setText('')); + dispatch(setStopStream(false)); }; const renameHandler = (e) => { diff --git a/client/src/components/Main/TextChat.jsx b/client/src/components/Main/TextChat.jsx index 9cf474357b..9fe119adef 100644 --- a/client/src/components/Main/TextChat.jsx +++ b/client/src/components/Main/TextChat.jsx @@ -16,7 +16,7 @@ export default function TextChat({ messages }) { const dispatch = useDispatch(); const convo = useSelector((state) => state.convo); const { initial } = useSelector((state) => state.models); - const { isSubmitting, disabled, model, chatGptLabel, promptPrefix } = useSelector( + const { isSubmitting, stopStream, disabled, model, chatGptLabel, promptPrefix } = useSelector( (state) => state.submit ); const { text } = useSelector((state) => state.text); @@ -38,7 +38,12 @@ export default function TextChat({ messages }) { const initialResponse = { sender, text: '' }; dispatch(setMessages([...messages, currentMsg, initialResponse])); dispatch(setText('')); - const messageHandler = (data) => { + const messageHandler = (data, events) => { + if (stopStream) { + console.log('Stopping stream'); + events.close(); + return; + } dispatch(setMessages([...messages, currentMsg, { sender, text: data }])); }; const convoHandler = (data) => { diff --git a/client/src/components/Messages/Message.jsx b/client/src/components/Messages/Message.jsx index ecb929b902..37f7a5c63b 100644 --- a/client/src/components/Messages/Message.jsx +++ b/client/src/components/Messages/Message.jsx @@ -4,6 +4,7 @@ import { useSelector } from 'react-redux'; import GPTIcon from '../svg/GPTIcon'; import BingIcon from '../svg/BingIcon'; import HoverButtons from './HoverButtons'; +import Spinner from '../svg/Spinner'; export default function Message({ sender, @@ -22,6 +23,10 @@ export default function Message({ scrollToBottom(); } }, [isSubmitting, text, blinker, scrollToBottom, abortScroll]); + + if (sender === '') { + return ; + } const handleWheel = () => { if (blinker) { diff --git a/client/src/store/messageSlice.js b/client/src/store/messageSlice.js index 4f51fc5022..c93f70048e 100644 --- a/client/src/store/messageSlice.js +++ b/client/src/store/messageSlice.js @@ -11,9 +11,20 @@ const currentSlice = createSlice({ setMessages: (state, action) => { state.messages = action.payload; }, + setEmptyMessage: (state) => { + state.messages = [ + { + id: '1', + conversationId: '1', + parentMessageId: '1', + sender: '', + text: '' + } + ] + }, } }); -export const { setMessages, setSubmitState } = currentSlice.actions; +export const { setMessages, setEmptyMessage } = currentSlice.actions; export default currentSlice.reducer; diff --git a/client/src/store/submitSlice.js b/client/src/store/submitSlice.js index b659ddcc7d..cdcc230224 100644 --- a/client/src/store/submitSlice.js +++ b/client/src/store/submitSlice.js @@ -2,6 +2,7 @@ import { createSlice } from '@reduxjs/toolkit'; const initialState = { isSubmitting: false, + stopStream: false, disabled: false, model: 'chatgpt', promptPrefix: '', @@ -16,6 +17,9 @@ const currentSlice = createSlice({ setSubmitState: (state, action) => { state.isSubmitting = action.payload; }, + setStopStream: (state, action) => { + state.stopStream = action.payload; + }, setDisabled: (state, action) => { state.disabled = action.payload; }, @@ -32,7 +36,7 @@ const currentSlice = createSlice({ } }); -export const { setSubmitState, setDisabled, setModel, setCustomGpt, setCustomModel } = +export const { setSubmitState, setStopStream, setDisabled, setModel, setCustomGpt, setCustomModel } = currentSlice.actions; export default currentSlice.reducer; diff --git a/client/src/utils/handleSubmit.js b/client/src/utils/handleSubmit.js index 4ba262ac08..1f6dfca027 100644 --- a/client/src/utils/handleSubmit.js +++ b/client/src/utils/handleSubmit.js @@ -51,7 +51,7 @@ export default function handleSubmit({ const data = JSON.parse(e.data); let text = data.text || data.response; if (data.message) { - messageHandler(text); + messageHandler(text, events); } if (data.final) {