diff --git a/embedded-app/src/App.jsx b/embedded-app/src/App.jsx index 5e689500..8b077706 100644 --- a/embedded-app/src/App.jsx +++ b/embedded-app/src/App.jsx @@ -6,9 +6,9 @@ import { fetchEventSource } from "@microsoft/fetch-event-source"; export default function App() { const [isOpen, setIsOpen] = useState(false); - const [message, setMessage] = useState(""); const [userId, setUserId] = useState(""); - const [chatMessages, setChatMessages] = useState([]); + const [messages, setMessages] = useState([]); + const [chatLoading, setChatLoading] = useState(false); const eventSourceRef = useRef(null); useEffect(() => { @@ -22,150 +22,179 @@ export default function App() { const toggleOpen = () => { setIsOpen(!isOpen); - // if (!isOpen) { - // streamMessages(); - // } }; - const handleChat = (chatResult) => { - setChatMessages((prev) => [...prev, chatResult]); - if (chatResult.close) { - eventSourceRef.current?.abort(); - console.log("message stream completed"); - } + const addMessage = (newMessage, sender) => { + setMessages((prev) => [...prev, { ...newMessage, id: v4(), sender }]); }; - const streamMessages = async () => { + const addChunkToLastMessage = (textChunk, sender) => { + setMessages((prev) => { + const lastMessage = prev.length > 0 ? prev[prev.length - 1] : null; + if (lastMessage && lastMessage.sender === sender && !lastMessage.close) { + return [ + ...prev.slice(0, -1), + { + ...lastMessage, + textResponse: lastMessage.textResponse + textChunk, + }, + ]; + } else { + return [...prev, { id: v4(), textResponse: textChunk, sender }]; + } + }); + }; + + const streamMessages = async (message) => { + addMessage({ textResponse: message, close: false }, "user"); + setChatLoading(true); + const ctrl = new AbortController(); eventSourceRef.current = ctrl; await fetchEventSource( - `http://localhost:3001/api/workspace/hello/stream-chat`, + `http://localhost:3001/api/workspace/hello/stream-embedded-chat`, { method: "POST", body: JSON.stringify({ message, mode: "chat" }), - // headers: baseHeaders(), signal: ctrl.signal, openWhenHidden: true, onopen(response) { - if (response.ok) { - // everything's good - } else { - handleChat({ - id: v4(), - type: "abort", - textResponse: null, - sources: [], - close: true, - error: `An error occurred while streaming response. Code ${response.status}`, - }); + if (!response.ok) { + addMessage( + { + textResponse: `Error: Response code ${response.status}`, + close: true, + }, + "system" + ); ctrl.abort(); } }, onmessage(msg) { try { const chatResult = JSON.parse(msg.data); - console.log("chatResult: ", chatResult); - handleChat(chatResult); + addChunkToLastMessage(chatResult.textResponse, "system"); + if (chatResult.close) { + setChatLoading(false); + finalizeLastMessage(); + } } catch (error) { - console.error("Error parsing message:", error); + addMessage( + { textResponse: `Error: ${error.message}`, close: true }, + "system" + ); + setChatLoading(false); } }, onerror(err) { - handleChat({ - id: v4(), - type: "abort", - textResponse: null, - sources: [], - close: true, - error: `An error occurred while streaming response. ${err.message}`, - }); + addMessage( + { textResponse: `Error: ${err.message}`, close: true }, + "system" + ); ctrl.abort(); + setChatLoading(false); }, } ); }; - const sendMessage = async () => { - console.log("EMBEDDED MESSAGE: ", message); - await streamMessages(); - fetch(`http://localhost:3001/api/workspace/${userId}/embedded-chat`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - message: message, - }), - }) - .then((response) => { - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - return response.json(); - }) - .then((data) => { - console.log("Success:", data); - }) - .catch((error) => { - console.error("Error:", error); - }); + const finalizeLastMessage = () => { + setMessages((prev) => { + const lastMessage = prev.length > 0 ? prev[prev.length - 1] : null; + if (lastMessage) { + return [...prev.slice(0, -1), { ...lastMessage, close: true }]; + } + return prev; + }); }; - console.log("chatMessages: ", chatMessages); - console.log("isOpen: ", isOpen); + const handleSubmit = async (e) => { + e.preventDefault(); + const message = e.target.message.value; + e.target.message.value = ""; + await streamMessages(message); + }; return ( -
{msg.textResponse || msg.error}
- ))} -- Learn more -
- > - )} -