import React, { useState, useEffect, useRef } from 'react'; import { useAuth } from '../services/AuthContext'; import { useNavigate } from 'react-router-dom'; const processMessages = (messageObject) => { return (previousMessages) => { if (previousMessages.length > 0 && previousMessages[previousMessages.length - 1].sender === messageObject.sender) { const newMessage = {text:previousMessages[previousMessages.length - 1].text+ ' ' + messageObject.text, sender: messageObject.sender}; return [...previousMessages.slice(0, -1), newMessage]; } else { return [...previousMessages, messageObject]; } } } const Chat = () => { const { token, logout } = useAuth(); const navigate = useNavigate(); const [messages, setMessages] = useState([]); const [input, setInput] = useState(''); const [isConnected, setIsConnected] = useState(false); const [connectionAttempts, setConnectionAttempts] = useState(0); const [isReconnecting, setIsReconnecting] = useState(false); const websocket = useRef(null); const maxReconnectAttempts = 5; const connectWebSocket = () => { if (websocket.current?.readyState === WebSocket.OPEN) { console.log('WebSocket is already connected'); return; } console.log('Attempting to connect WebSocket...'); const ws = new WebSocket('ws://localhost:8000/ws'); websocket.current = ws; ws.onopen = async () => { console.log('WebSocket connected, sending auth token...'); // Send authentication token ws.send(JSON.stringify({ type: 'authentication', token: token })); }; ws.onmessage = (event) => { try { const data = JSON.parse(event.data); console.log('Received message:', data); switch (data.type) { case 'connection_established': setIsConnected(true); setConnectionAttempts(0); setIsReconnecting(false); break; case 'message': setMessages(processMessages({ text:data.message, sender: data.sender })); break; case 'error': console.error('Server error:', data.message); if (data.message.includes('Authentication failed')) { logout(); navigate('/login'); } break; default: console.log('Unhandled message type:', data.type); } } catch (error) { console.error('Error processing message:', error); setMessages(processMessages({ text: event.data, sender: 'ai' })); } }; ws.onclose = (event) => { console.log('WebSocket closed:', event); setIsConnected(false); if (event.code === 1008) { // Authentication failed console.error('WebSocket authentication failed'); logout(); navigate('/login'); } else if (connectionAttempts < maxReconnectAttempts) { // Normal closure or error, attempt to reconnect setIsReconnecting(true); setConnectionAttempts(prev => prev + 1); setTimeout(connectWebSocket, 2000 * Math.min(connectionAttempts + 1, 5)); } }; ws.onerror = (error) => { console.error('WebSocket error:', error); }; }; useEffect(() => { connectWebSocket(); return () => { if (websocket.current) { websocket.current.close(); } }; }, [token]); const sendMessage = (e) => { e.preventDefault(); if (!input.trim() || !isConnected) return; const message = { type: 'message', content: input }; setMessages(processMessages({ text: input, sender: 'user' })); websocket.current.send(JSON.stringify(message)); setInput(''); }; console.log('MESSAGES****', messages); // Rest of your component (file upload handler, UI rendering, etc.) return (
{/* Messages area */}
{isReconnecting && Reconnecting...} {(messages || []).map((message, index) => (
{message.text}
))}
{/* Input area */}
setInput(e.target.value)} placeholder="Type your message..." className="flex-1 p-2 border rounded" disabled={!isConnected} />
); }; export default Chat;