pygmalion-web-frontend/src/routes/chat.jsx

79 lines
2.9 KiB
JavaScript

import { useState, useEffect } from "react";
import { useLoaderData } from "react-router-dom";
import { getCharacter, getChats } from "../api/characters";
import { Flex, Divider, Text, Box } from "@chakra-ui/react";
import NavBar from "../components/NavBar";
import Messages from "../components/chat/Messages";
import MessageInput from "../components/chat/MessageInput";
export async function loader({ params }){
return getCharacter(params.char);
}
// Followed https://ordinarycoders.com/blog/article/react-chakra-ui for most of this page.
const Chat = () => {
const character = useLoaderData();
const [messages, setMessages] = useState([]);
const [inputMessage, setInputMessage] = useState("");
const handleSendMessage = () => {
if (!inputMessage.trim().length) {
return;
}
const data = inputMessage;
setMessages((old) => [{ sender: "YOU", text: data }, ...old]);
setInputMessage("");
setMessages((old) => [{ sender: "CHARACTER", text: "This is a placeholder response to your message.", }, ...old]);
};
useEffect(() => {
let mounted = true;
getChats(character.id)
.then(
(response) => {
if(mounted){
if(response.messages){
let messagesList = response.messages.reverse(); // Reversed because the messages section uses flex-direction="column-reverse"
setMessages(messagesList);
}
else{
// If no messages found, default to the description.
setMessages([{ sender: "CHARACTER", text: character.description }]);
}
}
}
)
.catch((error) => {
console.log(error);
setMessages([{ sender: "", text: "An error occurred when fetching messages."}]); // TODO this isn't the best way to show an error.
});
return () => mounted = false;
}, []);
return (
<Box
height="100vh"
>
<NavBar />
{messages ? (
<Flex flexDir="column" height="100%" maxHeight="86vh">
<Flex width="100%" maxHeight="100%" justify="center" align="center" flexGrow="1">
<Flex width="60%" height="100%" maxHeight="100%" flexDir="column">
<Divider />
<Messages messages={messages} character={character} />
<Divider />
<MessageInput inputMessage={inputMessage} setInputMessage={setInputMessage} handleSendMessage={handleSendMessage} />
</Flex>
</Flex>
</Flex>
) : (
<Text ml="4">An error occured when trying to fetch messages.</Text>
)}
</Box>
);
}
export default Chat;