Spaces:
Runtime error
Runtime error
| import React, { useContext, useEffect, useState, useRef } from 'react'; | |
| import "./Chat.css"; | |
| import ChatHeader from '../ChatHeader'; | |
| import ChatMain from '../ChatMain'; | |
| import ChatFooter from '../ChatFooter'; | |
| import { SocketContext } from '../../contexts/SocketProvider'; | |
| import { ChatContext } from '../../contexts/ChatProvider'; | |
| import { UserContext } from '../../contexts/UserProvider'; | |
| function Chat({ }) { | |
| const { | |
| contacts, | |
| setContacts, | |
| lastMessages, | |
| setLastMessages, | |
| currentChat, | |
| } = useContext(ChatContext); | |
| const [messages, setMessages] = useState([]); | |
| const socket = useContext(SocketContext); | |
| const { user } = useContext(UserContext); | |
| const chatMainRef = useRef(); | |
| // to get Messages of currently opened chat | |
| //--------------------------------------------------------------------------------------------------------------// | |
| useEffect(() => { | |
| if (Object.keys(currentChat).length === 0) return; | |
| const fetchData = async () => { | |
| if (!socket) return; | |
| // console.log() | |
| socket.on("messages", (messages) => { | |
| console.log("on-messages", messages); | |
| setMessages(messages.reverse()); | |
| }); | |
| socket.emit("get_messages", currentChat.id); | |
| } | |
| fetchData(); | |
| return () => { | |
| if (!socket) return; | |
| socket.off("messages"); | |
| } | |
| }, [currentChat, socket]); | |
| // to add receive_message listener | |
| useEffect(() => { | |
| if (socket) { | |
| socket.on("receive_message", (message) => { | |
| console.log("receive_message:", message); | |
| // if message is received in the current open chat | |
| if (message.sender_id == currentChat.id || message.sender_id == user.id) { | |
| setMessages((prev) => [...prev, message]); | |
| } | |
| const isMsgOfOpenedChat = (contact) => (contact.id == message.receiver_id) || (contact.id == message.sender_id); | |
| const updateUnseenCount = (contact) => { | |
| if (isMsgOfOpenedChat(contact)) { | |
| return contact.unseen_count; | |
| } | |
| else { | |
| return contact.unseen_count + 1; | |
| } | |
| }; | |
| var updatedContacts = contacts.map((contact) => { | |
| var chat_data = { ...contact.chat_data }; | |
| // console.log(contact); | |
| if (contact.id == message.receiver_id || contact.id == message.sender_id) { | |
| chat_data.last_message = message; | |
| } | |
| chat_data.unseen_count = updateUnseenCount(contact); | |
| return { ...contact, chat_data }; | |
| }); | |
| updatedContacts.sort((a, b) => Date.parse(b.chat_data.last_message.timestamp) - Date.parse(a.chat_data.last_message.timestamp)); | |
| // console.log(updatedContacts); | |
| setContacts(updatedContacts); | |
| // if message from a new Contact | |
| const contact = contacts.find(contact => contact.id == message.sender_id); | |
| if (!contact && message.sender_id != user.id) { | |
| socket.emit("get_contact", message.sender_id); | |
| } | |
| }); | |
| return () => { | |
| socket.off("receive_message"); | |
| }; | |
| } | |
| }, [socket, contacts, currentChat]); | |
| const scrollToBottom = () => { | |
| if (chatMainRef.current) { | |
| chatMainRef.current.scrollTo(0, chatMainRef.current.scrollHeight); | |
| } | |
| }; | |
| // when ever a chat's messages are updated, scrollToBottom | |
| useEffect(() => { | |
| scrollToBottom(); | |
| }, [messages]); | |
| useEffect(() => { | |
| if (messages.length === 0) return; | |
| const unseen_messages = messages.filter(message => message.is_seen == 0); | |
| console.log(unseen_messages); | |
| socket.emit("mark_messages_seen", unseen_messages.map(msg => msg.id)); | |
| }, [messages]); | |
| // Until no chat is selected | |
| if (Object.keys(currentChat).length === 0) { | |
| return ( | |
| <div className='chat_dummy'> | |
| <h2>Choose a chat</h2> | |
| </div> | |
| ) | |
| } | |
| // console.log("currentChat",currentChat); | |
| // console.log("currentChat",currentChat.id); | |
| // once a chat is selected | |
| return ( | |
| <div className='chat'> | |
| <ChatHeader name={currentChat.username} /> | |
| <ChatMain messages={messages} ref={chatMainRef} /> | |
| <ChatFooter currentChatId={currentChat.id} /> | |
| </div> | |
| ) | |
| } | |
| export default Chat |