diff --git a/src/components/ChatBox/index.jsx b/src/components/ChatBox/index.jsx index 4dd12dd..e678fcb 100644 --- a/src/components/ChatBox/index.jsx +++ b/src/components/ChatBox/index.jsx @@ -1,26 +1,19 @@ -import React, { useEffect, useState } from 'react'; +import React from 'react'; +import { useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import Message from '../Message'; import './ChatBox.scss'; // container for all of the messages -const ChatBox = ({ messageList, chatboxContainerRef }) => { - const [isResponseLoading, setResponseLoading] = useState(false); - - useEffect(() => { - if (messageList[messageList.length - 1]?.role === 'user') { - setResponseLoading(true); - } else { - setResponseLoading(false); - } - }, [messageList]); +const ChatBox = ({ chatboxContainerRef }) => { + const { messageList, apiIsLoading } = useSelector(state => state.learningAssistant); return (
{messageList.map(({ role, content, timestamp }) => ( ))} - {isResponseLoading && ( + {apiIsLoading && (
Xpert is thinking
)}
diff --git a/src/components/Sidebar/index.jsx b/src/components/Sidebar/index.jsx index 60168e6..0f43c80 100644 --- a/src/components/Sidebar/index.jsx +++ b/src/components/Sidebar/index.jsx @@ -7,11 +7,13 @@ import './Sidebar.scss'; import { addChatMessage, clearMessages, + getChatResponse, updateCurrentMessage, } from '../../data/thunks'; import { ReactComponent as NewXeySvg } from '../../assets/new_xey.svg'; const Sidebar = ({ + courseId, isOpen, setIsOpen, }) => { @@ -51,7 +53,7 @@ const Sidebar = ({ requestAnimationFrame(scroll); } } - }, [messageList]); + }, [messageList, isOpen]); const handleClick = () => { setIsOpen(false); @@ -65,6 +67,7 @@ const Sidebar = ({ event.preventDefault(); if (currentMessage) { dispatch(addChatMessage('user', currentMessage)); + dispatch(getChatResponse(courseId)); } }; @@ -134,6 +137,7 @@ const Sidebar = ({ }; Sidebar.propTypes = { + courseId: PropTypes.string.isRequired, isOpen: PropTypes.bool.isRequired, setIsOpen: PropTypes.func.isRequired, }; diff --git a/src/data/slice.js b/src/data/slice.js index 5f6b5bb..c4a23cd 100644 --- a/src/data/slice.js +++ b/src/data/slice.js @@ -8,6 +8,7 @@ export const learningAssistantSlice = createSlice({ currentMessage: '', messageList: [], apiError: false, + apiIsLoading: false, conversationId: uuidv4(), }, reducers: { @@ -28,6 +29,9 @@ export const learningAssistantSlice = createSlice({ setApiError: (state) => { state.apiError = true; }, + setApiIsLoading: (state, { payload }) => { + state.apiIsLoading = payload; + }, }, }); @@ -37,6 +41,7 @@ export const { setMessageList, resetMessages, setApiError, + setApiIsLoading, } = learningAssistantSlice.actions; export const { diff --git a/src/data/thunks.js b/src/data/thunks.js index a0d28e5..7b76034 100644 --- a/src/data/thunks.js +++ b/src/data/thunks.js @@ -3,9 +3,10 @@ import fetchChatResponse from './api'; import { setCurrentMessage, clearCurrentMessage, + resetMessages, setMessageList, setApiError, - resetMessages, + setApiIsLoading, } from './slice'; export function addChatMessage(role, content) { @@ -36,11 +37,15 @@ export function addChatMessage(role, content) { export function getChatResponse(courseId) { return async (dispatch, getState) => { const { messageList } = getState().learningAssistant; + + dispatch(setApiIsLoading(true)); try { const message = await fetchChatResponse(courseId, messageList); + dispatch(setApiIsLoading(false)); dispatch(addChatMessage(message.role, message.content)); } catch (error) { dispatch(setApiError()); + dispatch(setApiIsLoading(false)); } }; } diff --git a/src/widgets/Xpert.jsx b/src/widgets/Xpert.jsx index 84f4708..e49c0ce 100644 --- a/src/widgets/Xpert.jsx +++ b/src/widgets/Xpert.jsx @@ -1,25 +1,20 @@ import PropTypes from 'prop-types'; -import { useState, useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useState } from 'react'; import ToggleXpert from '../components/ToggleXpertButton'; import Sidebar from '../components/Sidebar'; -import { getChatResponse } from '../data/thunks'; const Xpert = ({ courseId }) => { - const { messageList } = useSelector(state => state.learningAssistant); const [sidebarIsOpen, setSidebarIsOpen] = useState(false); - const dispatch = useDispatch(); - - useEffect(() => { - if (messageList[messageList.length - 1]?.role === 'user') { - dispatch(getChatResponse(courseId)); - } - }, [dispatch, courseId, messageList]); return (
- +