File size: 4,753 Bytes
ee1fc35
88b9eae
 
 
 
f1b8b13
 
 
 
 
 
 
 
 
 
 
 
 
 
bf65a6c
 
c13f601
ee1fc35
c13f601
 
f1b8b13
bf65a6c
ee1fc35
3b5dd8c
ee1fc35
3b5dd8c
f1b8b13
 
3b5dd8c
 
 
 
 
c13f601
 
3b5dd8c
 
f1b8b13
3b5dd8c
 
 
 
 
 
 
f1b8b13
bf65a6c
ee1fc35
 
 
 
c13f601
 
 
 
 
3b5dd8c
 
f1b8b13
 
c13f601
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f1b8b13
 
 
c13f601
f1b8b13
c13f601
 
 
3b5dd8c
f1b8b13
ee1fc35
 
f1b8b13
ee1fc35
3b5dd8c
ee1fc35
 
f1b8b13
3b5dd8c
 
 
 
 
 
ee1fc35
 
 
 
 
bf65a6c
c13f601
 
 
 
 
 
3b5dd8c
ee1fc35
f1b8b13
d1f9048
 
 
 
 
 
 
ee1fc35
f1b8b13
 
ee1fc35
c13f601
88b9eae
f1b8b13
ee1fc35
f1b8b13
88b9eae
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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