import { useEffect, useState, useRef } from "react"; import { conversationService } from "../api/conversationService"; import { QuestionBubble } from "./QuestionBubble"; import { AnswerBubble } from "./AnswerBubble"; import { MessageInput } from "./MessageInput"; import { ConversationList } from "./ConversationList"; import catIcon from "../assets/cat.png"; type Message = { text: string; speaker: "simba" | "user"; }; type QuestionAnswer = { question: string; answer: string; }; type Conversation = { title: string; id: string; }; type ChatScreenProps = { setAuthenticated: (isAuth: boolean) => void; }; export const ChatScreen = ({ setAuthenticated }: ChatScreenProps) => { const [query, setQuery] = useState(""); const [answer, setAnswer] = useState(""); const [simbaMode, setSimbaMode] = useState(false); const [questionsAnswers, setQuestionsAnswers] = useState( [], ); const [messages, setMessages] = useState([]); const [conversations, setConversations] = useState([ { title: "simba meow meow", id: "uuid" }, ]); const [showConversations, setShowConversations] = useState(false); const [selectedConversation, setSelectedConversation] = useState(null); const [sidebarCollapsed, setSidebarCollapsed] = useState(false); const [isLoading, setIsLoading] = useState(false); const messagesEndRef = useRef(null); const simbaAnswers = ["meow.", "hiss...", "purrrrrr", "yowOWROWWowowr"]; const scrollToBottom = () => { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); }; const handleSelectConversation = (conversation: Conversation) => { setShowConversations(false); setSelectedConversation(conversation); const loadMessages = async () => { try { const fetchedConversation = await conversationService.getConversation( conversation.id, ); setMessages( fetchedConversation.messages.map((message) => ({ text: message.text, speaker: message.speaker, })), ); } catch (error) { console.error("Failed to load messages:", error); } }; loadMessages(); }; const loadConversations = async () => { try { const fetchedConversations = await conversationService.getAllConversations(); const parsedConversations = fetchedConversations.map((conversation) => ({ id: conversation.id, title: conversation.name, })); setConversations(parsedConversations); setSelectedConversation(parsedConversations[0]); console.log(parsedConversations); console.log("JELLYFISH@"); } catch (error) { console.error("Failed to load messages:", error); } }; const handleCreateNewConversation = async () => { const newConversation = await conversationService.createConversation(); await loadConversations(); setSelectedConversation({ title: newConversation.name, id: newConversation.id, }); }; useEffect(() => { loadConversations(); }, []); useEffect(() => { scrollToBottom(); }, [messages]); useEffect(() => { const loadMessages = async () => { console.log(selectedConversation); console.log("JELLYFISH"); if (selectedConversation == null) return; try { const conversation = await conversationService.getConversation( selectedConversation.id, ); // Update the conversation title in case it changed setSelectedConversation({ id: conversation.id, title: conversation.name, }); setMessages( conversation.messages.map((message) => ({ text: message.text, speaker: message.speaker, })), ); } catch (error) { console.error("Failed to load messages:", error); } }; loadMessages(); }, [selectedConversation?.id]); const handleQuestionSubmit = async () => { if (!query.trim() || isLoading) return; // Don't submit empty messages or while loading const currMessages = messages.concat([{ text: query, speaker: "user" }]); setMessages(currMessages); setQuery(""); // Clear input immediately after submission setIsLoading(true); if (simbaMode) { console.log("simba mode activated"); const randomIndex = Math.floor(Math.random() * simbaAnswers.length); const randomElement = simbaAnswers[randomIndex]; setAnswer(randomElement); setQuestionsAnswers( questionsAnswers.concat([ { question: query, answer: randomElement, }, ]), ); setIsLoading(false); return; } try { const result = await conversationService.sendQuery( query, selectedConversation.id, ); setQuestionsAnswers( questionsAnswers.concat([{ question: query, answer: result.response }]), ); setMessages( currMessages.concat([{ text: result.response, speaker: "simba" }]), ); } catch (error) { console.error("Failed to send query:", error); // If session expired, redirect to login if (error instanceof Error && error.message.includes("Session expired")) { setAuthenticated(false); } } finally { setIsLoading(false); } }; const handleQueryChange = (event: React.ChangeEvent) => { setQuery(event.target.value); }; const handleKeyDown = (event: React.KeyboardEvent) => { // Submit on Enter, but allow Shift+Enter for new line if (event.key === "Enter" && !event.shiftKey) { event.preventDefault(); handleQuestionSubmit(); } }; return (
{/* Sidebar - Expanded */} {/* Main chat area */}
{/* Mobile header */}
Simba

asksimba!

{/* Messages area */} {selectedConversation && (

{selectedConversation.title || "Untitled Conversation"}

)}
{/* Floating conversation name */}
{showConversations && (
)} {messages.map((msg, index) => { if (msg.speaker === "simba") { return ; } return ; })} {isLoading && }
{/* Input area */}
); };