import { useState, useEffect, useRef, useCallback } from "react"; import { IMessage } from "../interfaces/conversation"; import { conversationWebSocket } from "../services/websockets/conversation"; interface StreamingMessage extends IMessage { isComplete?: boolean; } const useWebSocket = () => { const [messages, setMessages] = useState([]); const [streamingMessage, setStreamingMessage] = useState(""); const [isStreaming, setIsStreaming] = useState(false); const wsRef = useRef(null); const simulateStreaming = (completeMessage: string) => { setIsStreaming(true); setStreamingMessage(""); const cleanMessage = completeMessage.replace(/.*<\/userStyle>/, "").trim(); const chars = cleanMessage.split(""); let currentIndex = -1; setStreamingMessage(""); const streamInterval = setInterval(() => { if (currentIndex < chars.length) { currentIndex++; setStreamingMessage((prev) => prev + chars[currentIndex]); } else { clearInterval(streamInterval); setMessages((prev) => [ ...prev, { text: cleanMessage, sender: "bot", isComplete: true, }, ]); setIsStreaming(false); setStreamingMessage(""); } }, 20); return () => clearInterval(streamInterval); }; const connectWebSocket = useCallback((conversationId: string) => { const ws = conversationWebSocket({ conversationId, modality: "text" }); wsRef.current = ws; ws.onmessage = (event) => { const data = JSON.parse(event.data); if (!data.ai_message) return; simulateStreaming(data.ai_message); }; ws.onclose = () => { wsRef.current = null; }; ws.onerror = (error) => { console.error("WebSocket error:", error); wsRef.current = null; }; }, []); useEffect(() => { return () => { wsRef.current?.close(); wsRef.current = null; }; }, []); const sendMessage = useCallback((message: string) => { if (message.trim()) { setMessages((prev) => [ ...prev, { text: message, sender: "user", isComplete: true, }, ]); if (wsRef.current?.readyState === WebSocket.OPEN) { wsRef.current.send(JSON.stringify({ user_message: message })); } } }, []); const getAllMessages = useCallback(() => { const displayMessages = [...messages]; if (isStreaming) { displayMessages.push({ text: streamingMessage, sender: "bot", isComplete: false, }); } return displayMessages; }, [messages, isStreaming, streamingMessage]); return { messages: getAllMessages(), sendMessage, connectWebSocket, isStreaming, }; }; export default useWebSocket;