leothesouthafrican's picture
docker local
b978eed
import { useState } from 'react';
import axios from 'axios';
/**
* Custom hook for managing chat-related state and functionality.
* It handles input text, chat history, loading state, history navigation, and form submission.
*
* returns {object} An object containing the state and functions related to chat handling.
*/
export default function useChatHandler() {
// State variables
const [inputText, setInputText] = useState('');
const initialChatHistory = localStorage.getItem('chatHistory');
const [chatHistory, setChatHistory] = useState(
initialChatHistory ? JSON.parse(initialChatHistory) : []
);
const [loading, setLoading] = useState(false);
const [historyIndex, setHistoryIndex] = useState(-1);
const [isHistoryNavigation, setIsHistoryNavigation] = useState(false);
// Function to handle form submission
const handleSubmit = async (text) => {
setLoading(true);
let success = false;
try {
const sendTextResponse = await axios.post('http://127.0.0.1:5000/sendText', { text });
const sendQuestionsResponse = await axios.post('http://127.0.0.1:5000/sendQuestions', { text });
const newChatItem = {
question: text,
response: sendTextResponse.data.output,
followUps: sendQuestionsResponse.data.output.followUps.map(followUp => ({
text: followUp,
response: null,
loading: false
})),
};
setChatHistory((oldChatHistory) => {
const newChatHistory = [...oldChatHistory, newChatItem];
localStorage.setItem('chatHistory', JSON.stringify(newChatHistory));
return newChatHistory;
});
setInputText('');
success = true;
} catch (error) {
console.error(error);
}
setLoading(false);
return success;
};
// Function to handle follow-up questions
const handleFollowUp = async (chatItemIndex, followUpIndex) => {
// set loading to true
chatHistory[chatItemIndex].followUps[followUpIndex].loading = true;
setChatHistory([...chatHistory]);
try {
const response = await axios.post('http://127.0.0.1:5000/sendText', {
text: chatHistory[chatItemIndex].followUps[followUpIndex].text
});
// Update the response and loading state
chatHistory[chatItemIndex].followUps[followUpIndex].response = response.data.output;
chatHistory[chatItemIndex].followUps[followUpIndex].loading = false;
// Get new follow-up questions based on the follow-up response.
const sendQuestionsResponse = await axios.post('http://127.0.0.1:5000/sendQuestions', { text: response.data.output });
// Add to FollowUp array
const newFollowUps = sendQuestionsResponse.data.output.followUps.map(followUp => ({
text: followUp,
response: null,
loading: false
}));
// Insert new follow ups after the current one
chatHistory[chatItemIndex].followUps.splice(followUpIndex + 1, 0, ...newFollowUps);
setChatHistory([...chatHistory]);
} catch (error) {
console.error(error);
// handle error
// set loading to false
chatHistory[chatItemIndex].followUps[followUpIndex].loading = false;
setChatHistory([...chatHistory]);
}
};
// Function to handle special keys (Command+Enter, Up Arrow, Down Arrow)
const handleKeyDown = (e, handleFormSubmit) => {
// If command+enter, submit form
if (e.metaKey && e.keyCode === 13) {
e.preventDefault();
handleFormSubmit(e);
}
// If up arrow, navigate one step up in chat history
else if (e.keyCode === 38) {
e.preventDefault();
if (chatHistory.length > 0) {
setIsHistoryNavigation(true);
setHistoryIndex((prevHistoryIndex) => {
let newHistoryIndex = Math.min(prevHistoryIndex + 1, chatHistory.length - 1);
setInputText(chatHistory[chatHistory.length - newHistoryIndex - 1].question);
return newHistoryIndex;
});
}
}
// If down arrow, navigate one step down in chat history
else if (e.keyCode === 40) {
e.preventDefault();
if (chatHistory.length > 0 && historyIndex !== -1) {
setIsHistoryNavigation(true);
setHistoryIndex((prevHistoryIndex) => {
let newHistoryIndex = Math.max(prevHistoryIndex - 1, -1);
if (newHistoryIndex === -1) setInputText('');
else setInputText(chatHistory[chatHistory.length - newHistoryIndex - 1].question);
return newHistoryIndex;
});
}
}
};
// Function to clear chat history
const clearChatHistory = () => {
setChatHistory([]);
localStorage.removeItem('chatHistory');
};
// Function to handle input text change
const handleInputChange = (e) => {
setInputText(e.target.value);
setIsHistoryNavigation(false);
};
// Return the state and functions related to chat handling
return {
inputText,
handleInputChange,
setInputText,
chatHistory,
setChatHistory,
loading,
handleSubmit,
handleKeyDown,
clearChatHistory,
handleFollowUp,
};
}