Spaces:
Runtime error
Runtime error
Commit
·
f1b8b13
1
Parent(s):
35f15f5
added new contact update feature
Browse files- client/src/App.js +1 -1
- client/src/ChatPage/ChatPage.jsx +6 -6
- client/src/PrivateRoutes.jsx +1 -1
- client/src/components/Chat/Chat.jsx +48 -32
- client/src/components/ChatFooter/ChatFooter.jsx +4 -7
- client/src/components/ChatMain/ChatMain.jsx +2 -5
- client/src/components/Contacts/Contacts.jsx +37 -11
- client/src/components/SideBar/SideBar.jsx +22 -16
- client/src/contexts/ChatProvider.jsx +19 -0
- client/src/{SocketProvider.jsx → contexts/SocketProvider.jsx} +0 -0
- client/src/{UserProvider.jsx → contexts/UserProvider.jsx} +0 -0
- server/index.ts +20 -8
client/src/App.js
CHANGED
|
@@ -4,7 +4,7 @@ import ChatPage from './ChatPage';
|
|
| 4 |
import LoginPage from './LoginPage';
|
| 5 |
import SignupPage from './SignupPage';
|
| 6 |
import PrivateRoutes from './PrivateRoutes';
|
| 7 |
-
import { UserProvider } from './UserProvider';
|
| 8 |
|
| 9 |
function App() {
|
| 10 |
|
|
|
|
| 4 |
import LoginPage from './LoginPage';
|
| 5 |
import SignupPage from './SignupPage';
|
| 6 |
import PrivateRoutes from './PrivateRoutes';
|
| 7 |
+
import { UserProvider } from './contexts/UserProvider';
|
| 8 |
|
| 9 |
function App() {
|
| 10 |
|
client/src/ChatPage/ChatPage.jsx
CHANGED
|
@@ -1,17 +1,17 @@
|
|
| 1 |
import React, { useEffect, useState } from 'react';
|
| 2 |
import Chat from '../components/Chat';
|
| 3 |
import SideBar from '../components/SideBar';
|
| 4 |
-
import { SocketProvider } from '../SocketProvider';
|
|
|
|
| 5 |
|
| 6 |
function ChatPage() {
|
| 7 |
-
|
| 8 |
-
const [contacts, setContacts] = useState([]);
|
| 9 |
-
const [currentContact, setCurrentContact] = useState({});
|
| 10 |
return (
|
| 11 |
<>
|
| 12 |
<SocketProvider>
|
| 13 |
-
<
|
| 14 |
-
|
|
|
|
|
|
|
| 15 |
</SocketProvider>
|
| 16 |
</>
|
| 17 |
);
|
|
|
|
| 1 |
import React, { useEffect, useState } from 'react';
|
| 2 |
import Chat from '../components/Chat';
|
| 3 |
import SideBar from '../components/SideBar';
|
| 4 |
+
import { SocketProvider } from '../contexts/SocketProvider';
|
| 5 |
+
import { ChatProvider } from '../contexts/ChatProvider';
|
| 6 |
|
| 7 |
function ChatPage() {
|
|
|
|
|
|
|
|
|
|
| 8 |
return (
|
| 9 |
<>
|
| 10 |
<SocketProvider>
|
| 11 |
+
<ChatProvider>
|
| 12 |
+
<SideBar />
|
| 13 |
+
<Chat />
|
| 14 |
+
</ChatProvider>
|
| 15 |
</SocketProvider>
|
| 16 |
</>
|
| 17 |
);
|
client/src/PrivateRoutes.jsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
import React, { useState, useEffect, useContext } from 'react'
|
| 2 |
import { Outlet, Navigate } from "react-router-dom";
|
| 3 |
-
import { UserContext } from './UserProvider';
|
| 4 |
|
| 5 |
function PrivateRoutes() {
|
| 6 |
|
|
|
|
| 1 |
import React, { useState, useEffect, useContext } from 'react'
|
| 2 |
import { Outlet, Navigate } from "react-router-dom";
|
| 3 |
+
import { UserContext } from './contexts/UserProvider';
|
| 4 |
|
| 5 |
function PrivateRoutes() {
|
| 6 |
|
client/src/components/Chat/Chat.jsx
CHANGED
|
@@ -3,23 +3,34 @@ import "./Chat.css";
|
|
| 3 |
import ChatHeader from '../ChatHeader';
|
| 4 |
import ChatMain from '../ChatMain';
|
| 5 |
import ChatFooter from '../ChatFooter';
|
| 6 |
-
import { SocketContext } from '../../SocketProvider';
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
const [messages, setMessages] = useState([]);
|
| 15 |
const socket = useContext(SocketContext);
|
|
|
|
| 16 |
const chatMainRef = useRef();
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
// to get Messages of currently opened chat
|
| 19 |
//--------------------------------------------------------------------------------------------------------------//
|
| 20 |
useEffect(() => {
|
| 21 |
|
| 22 |
-
if (Object.keys(
|
|
|
|
| 23 |
const fetchData = async () => {
|
| 24 |
|
| 25 |
if (!socket) return;
|
|
@@ -29,7 +40,7 @@ function Chat({
|
|
| 29 |
setMessages(messages);
|
| 30 |
});
|
| 31 |
|
| 32 |
-
socket.emit("get_messages",
|
| 33 |
}
|
| 34 |
fetchData();
|
| 35 |
|
|
@@ -37,38 +48,41 @@ function Chat({
|
|
| 37 |
if (!socket) return;
|
| 38 |
socket.off("messages");
|
| 39 |
}
|
| 40 |
-
}, [
|
| 41 |
|
| 42 |
// to add receive_message listener
|
| 43 |
useEffect(() => {
|
| 44 |
if (socket) {
|
| 45 |
socket.on("receive_message", (message) => {
|
| 46 |
-
|
| 47 |
-
// console.log(message.send_from,currentContact.id);
|
| 48 |
-
// console.log(message.send_from == currentContact.id);
|
| 49 |
-
if (currentContact && message.send_from == currentContact.id) {
|
| 50 |
setMessages((prev) => [...prev, message]);
|
| 51 |
}
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
}
|
|
|
|
| 65 |
});
|
| 66 |
|
|
|
|
| 67 |
return () => {
|
| 68 |
socket.off("receive_message");
|
| 69 |
};
|
| 70 |
}
|
| 71 |
-
}, [socket,contacts,
|
| 72 |
|
| 73 |
const scrollToBottom = () => {
|
| 74 |
if (chatMainRef.current) {
|
|
@@ -84,7 +98,7 @@ function Chat({
|
|
| 84 |
|
| 85 |
|
| 86 |
// Until no chat is selected
|
| 87 |
-
if (Object.keys(
|
| 88 |
|
| 89 |
return (
|
| 90 |
<div className='chat_dummy'>
|
|
@@ -93,12 +107,14 @@ function Chat({
|
|
| 93 |
)
|
| 94 |
}
|
| 95 |
|
|
|
|
|
|
|
| 96 |
// once a chat is selected
|
| 97 |
-
return (
|
| 98 |
<div className='chat'>
|
| 99 |
-
<ChatHeader name={
|
| 100 |
<ChatMain messages={messages} ref={chatMainRef} />
|
| 101 |
-
<ChatFooter
|
| 102 |
</div>
|
| 103 |
)
|
| 104 |
}
|
|
|
|
| 3 |
import ChatHeader from '../ChatHeader';
|
| 4 |
import ChatMain from '../ChatMain';
|
| 5 |
import ChatFooter from '../ChatFooter';
|
| 6 |
+
import { SocketContext } from '../../contexts/SocketProvider';
|
| 7 |
+
import { ChatContext } from '../../contexts/ChatProvider';
|
| 8 |
+
import { UserContext } from '../../contexts/UserProvider';
|
| 9 |
+
|
| 10 |
+
function Chat({ }) {
|
| 11 |
+
|
| 12 |
+
const {
|
| 13 |
+
contacts,
|
| 14 |
+
setContacts,
|
| 15 |
+
lastMessages,
|
| 16 |
+
setLastMessages,
|
| 17 |
+
currentChat,
|
| 18 |
+
} = useContext(ChatContext);
|
| 19 |
+
|
| 20 |
const [messages, setMessages] = useState([]);
|
| 21 |
const socket = useContext(SocketContext);
|
| 22 |
+
const {user} = useContext(UserContext);
|
| 23 |
const chatMainRef = useRef();
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
|
| 27 |
|
| 28 |
// to get Messages of currently opened chat
|
| 29 |
//--------------------------------------------------------------------------------------------------------------//
|
| 30 |
useEffect(() => {
|
| 31 |
|
| 32 |
+
if (Object.keys(currentChat).length === 0) return;
|
| 33 |
+
|
| 34 |
const fetchData = async () => {
|
| 35 |
|
| 36 |
if (!socket) return;
|
|
|
|
| 40 |
setMessages(messages);
|
| 41 |
});
|
| 42 |
|
| 43 |
+
socket.emit("get_messages", currentChat.id);
|
| 44 |
}
|
| 45 |
fetchData();
|
| 46 |
|
|
|
|
| 48 |
if (!socket) return;
|
| 49 |
socket.off("messages");
|
| 50 |
}
|
| 51 |
+
}, [currentChat, socket]);
|
| 52 |
|
| 53 |
// to add receive_message listener
|
| 54 |
useEffect(() => {
|
| 55 |
if (socket) {
|
| 56 |
socket.on("receive_message", (message) => {
|
| 57 |
+
if (message.send_from == currentChat.id || message.send_from == user.id) {
|
|
|
|
|
|
|
|
|
|
| 58 |
setMessages((prev) => [...prev, message]);
|
| 59 |
}
|
| 60 |
+
|
| 61 |
+
const ismessageOfContact = (contact) => (contact.id == message.send_to) || (contact.id == message.send_from);
|
| 62 |
+
var updatedContacts = contacts.map((contact) => (
|
| 63 |
+
ismessageOfContact(contact) ?
|
| 64 |
+
{ ...contact, last_message: message } : contact
|
| 65 |
+
));
|
| 66 |
+
|
| 67 |
+
updatedContacts.sort((a,b)=>b.last_message.send_at - a.last_message.send_at);
|
| 68 |
+
// console.log(updatedContacts);
|
| 69 |
+
|
| 70 |
+
setContacts(updatedContacts);
|
| 71 |
+
|
| 72 |
+
// if message from a new Contact
|
| 73 |
+
const contact = contacts.find(contact=>contact.id==message.send_from);
|
| 74 |
+
if(!contact && message.send_from !=user.id){
|
| 75 |
+
socket.emit("get_contact",message.send_from);
|
| 76 |
}
|
| 77 |
+
|
| 78 |
});
|
| 79 |
|
| 80 |
+
|
| 81 |
return () => {
|
| 82 |
socket.off("receive_message");
|
| 83 |
};
|
| 84 |
}
|
| 85 |
+
}, [socket, contacts, currentChat]);
|
| 86 |
|
| 87 |
const scrollToBottom = () => {
|
| 88 |
if (chatMainRef.current) {
|
|
|
|
| 98 |
|
| 99 |
|
| 100 |
// Until no chat is selected
|
| 101 |
+
if (Object.keys(currentChat).length === 0) {
|
| 102 |
|
| 103 |
return (
|
| 104 |
<div className='chat_dummy'>
|
|
|
|
| 107 |
)
|
| 108 |
}
|
| 109 |
|
| 110 |
+
// console.log("currentChat",currentChat);
|
| 111 |
+
// console.log("currentChat",currentChat.id);
|
| 112 |
// once a chat is selected
|
| 113 |
+
return (
|
| 114 |
<div className='chat'>
|
| 115 |
+
<ChatHeader name={currentChat.username} />
|
| 116 |
<ChatMain messages={messages} ref={chatMainRef} />
|
| 117 |
+
<ChatFooter currentChatId={currentChat.id} />
|
| 118 |
</div>
|
| 119 |
)
|
| 120 |
}
|
client/src/components/ChatFooter/ChatFooter.jsx
CHANGED
|
@@ -1,13 +1,12 @@
|
|
| 1 |
import React, { useContext, useEffect, useRef } from 'react'
|
| 2 |
import "./ChatFooter.css";
|
| 3 |
import { PaperAirplaneIcon, PhotoIcon, PaperClipIcon, FaceSmileIcon } from "@heroicons/react/24/solid";
|
| 4 |
-
import { SocketContext } from '../../SocketProvider';
|
| 5 |
|
| 6 |
function ChatFooter({
|
| 7 |
-
|
| 8 |
-
currentContactId,
|
| 9 |
}) {
|
| 10 |
-
|
| 11 |
const socket = useContext(SocketContext);
|
| 12 |
const messageRef = useRef();
|
| 13 |
|
|
@@ -27,10 +26,8 @@ function ChatFooter({
|
|
| 27 |
const message_bundle= {
|
| 28 |
message,
|
| 29 |
send_at:curr_time,
|
| 30 |
-
send_to:
|
| 31 |
}
|
| 32 |
-
|
| 33 |
-
setMessages((prev) => [...prev, message_bundle]);
|
| 34 |
|
| 35 |
if(socket){
|
| 36 |
socket.emit("send_message",message_bundle);
|
|
|
|
| 1 |
import React, { useContext, useEffect, useRef } from 'react'
|
| 2 |
import "./ChatFooter.css";
|
| 3 |
import { PaperAirplaneIcon, PhotoIcon, PaperClipIcon, FaceSmileIcon } from "@heroicons/react/24/solid";
|
| 4 |
+
import { SocketContext } from '../../contexts/SocketProvider';
|
| 5 |
|
| 6 |
function ChatFooter({
|
| 7 |
+
currentChatId,
|
|
|
|
| 8 |
}) {
|
| 9 |
+
// console.log(currentChatId)
|
| 10 |
const socket = useContext(SocketContext);
|
| 11 |
const messageRef = useRef();
|
| 12 |
|
|
|
|
| 26 |
const message_bundle= {
|
| 27 |
message,
|
| 28 |
send_at:curr_time,
|
| 29 |
+
send_to:currentChatId,
|
| 30 |
}
|
|
|
|
|
|
|
| 31 |
|
| 32 |
if(socket){
|
| 33 |
socket.emit("send_message",message_bundle);
|
client/src/components/ChatMain/ChatMain.jsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
import React, { useContext } from 'react'
|
| 2 |
import Message from '../Message';
|
| 3 |
import "./ChatMain.css";
|
| 4 |
-
import { UserContext } from '../../UserProvider';
|
| 5 |
|
| 6 |
const ChatMain = React.forwardRef(({
|
| 7 |
messages,
|
| 8 |
-
},ref) => {
|
| 9 |
|
| 10 |
const { user } = useContext(UserContext);
|
| 11 |
|
|
@@ -16,9 +16,6 @@ const ChatMain = React.forwardRef(({
|
|
| 16 |
}
|
| 17 |
|
| 18 |
const isReceived = (message) => {
|
| 19 |
-
// console.log("message",message.send_to);
|
| 20 |
-
// console.log("user",user.id);
|
| 21 |
-
// && user.id==message.from
|
| 22 |
return user && message.send_to == user.id;
|
| 23 |
};
|
| 24 |
|
|
|
|
| 1 |
import React, { useContext } from 'react'
|
| 2 |
import Message from '../Message';
|
| 3 |
import "./ChatMain.css";
|
| 4 |
+
import { UserContext } from '../../contexts/UserProvider';
|
| 5 |
|
| 6 |
const ChatMain = React.forwardRef(({
|
| 7 |
messages,
|
| 8 |
+
}, ref) => {
|
| 9 |
|
| 10 |
const { user } = useContext(UserContext);
|
| 11 |
|
|
|
|
| 16 |
}
|
| 17 |
|
| 18 |
const isReceived = (message) => {
|
|
|
|
|
|
|
|
|
|
| 19 |
return user && message.send_to == user.id;
|
| 20 |
};
|
| 21 |
|
client/src/components/Contacts/Contacts.jsx
CHANGED
|
@@ -1,36 +1,62 @@
|
|
| 1 |
-
import React, { useContext, useState } from 'react'
|
| 2 |
import Contact from '../Contact';
|
| 3 |
import "./Contacts.css";
|
| 4 |
-
import { UserContext } from '../../UserProvider';
|
|
|
|
|
|
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
-
function Contacts({
|
| 9 |
-
allContacts,
|
| 10 |
-
currentContact,
|
| 11 |
-
setCurrentContact,
|
| 12 |
-
}) {
|
| 13 |
|
| 14 |
// const [activeContact, setActiveContact] = useState({});
|
| 15 |
-
const {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
// handleClick
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
return (
|
| 19 |
<div className='contacts'>
|
| 20 |
|
| 21 |
|
| 22 |
{
|
| 23 |
-
|
| 24 |
// console.log("contact.last_message",contact,contact.last_message),
|
| 25 |
// console.log(user.id),
|
| 26 |
<Contact
|
| 27 |
key={contact.id}
|
| 28 |
-
onClick={() => {
|
| 29 |
profile_pic={"logo512.png"}
|
| 30 |
name={contact.username}
|
| 31 |
lastmessage={contact.last_message.message}
|
| 32 |
is_new={user.id == contact.last_message.send_to && contact.last_message.is_seen == 0}
|
| 33 |
-
isActive={
|
| 34 |
/>
|
| 35 |
))
|
| 36 |
}
|
|
|
|
| 1 |
+
import React, { useContext, useEffect, useState } from 'react'
|
| 2 |
import Contact from '../Contact';
|
| 3 |
import "./Contacts.css";
|
| 4 |
+
import { UserContext } from '../../contexts/UserProvider';
|
| 5 |
+
import { ChatContext } from '../../contexts/ChatProvider';
|
| 6 |
+
import { SocketContext } from '../../contexts/SocketProvider';
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
+
function Contacts({ }) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
// const [activeContact, setActiveContact] = useState({});
|
| 13 |
+
const {
|
| 14 |
+
contacts,
|
| 15 |
+
setContacts,
|
| 16 |
+
currentChat,
|
| 17 |
+
setCurrentChat,
|
| 18 |
+
lastMessages,
|
| 19 |
+
} = useContext(ChatContext);
|
| 20 |
+
const { user } = useContext(UserContext);
|
| 21 |
+
const socket = useContext(SocketContext);
|
| 22 |
// handleClick
|
| 23 |
|
| 24 |
+
|
| 25 |
+
useEffect(() => {
|
| 26 |
+
if (!socket) return;
|
| 27 |
+
socket.on("contact", (contact) => {
|
| 28 |
+
var newContacts = [...contacts, contact];
|
| 29 |
+
|
| 30 |
+
newContacts.sort((a,b)=>b.last_message.send_at - a.last_message.send_at);
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
setContacts(newContacts);
|
| 34 |
+
});
|
| 35 |
+
|
| 36 |
+
const cleanUp = () => {
|
| 37 |
+
if (!socket) return;
|
| 38 |
+
socket.off("contact");
|
| 39 |
+
}
|
| 40 |
+
return cleanUp;
|
| 41 |
+
}, [socket])
|
| 42 |
+
|
| 43 |
+
|
| 44 |
return (
|
| 45 |
<div className='contacts'>
|
| 46 |
|
| 47 |
|
| 48 |
{
|
| 49 |
+
contacts.map((contact) => (
|
| 50 |
// console.log("contact.last_message",contact,contact.last_message),
|
| 51 |
// console.log(user.id),
|
| 52 |
<Contact
|
| 53 |
key={contact.id}
|
| 54 |
+
onClick={() => { setCurrentChat(contact) }}
|
| 55 |
profile_pic={"logo512.png"}
|
| 56 |
name={contact.username}
|
| 57 |
lastmessage={contact.last_message.message}
|
| 58 |
is_new={user.id == contact.last_message.send_to && contact.last_message.is_seen == 0}
|
| 59 |
+
isActive={currentChat.id == contact.id}
|
| 60 |
/>
|
| 61 |
))
|
| 62 |
}
|
client/src/components/SideBar/SideBar.jsx
CHANGED
|
@@ -1,36 +1,42 @@
|
|
| 1 |
-
import React, { useContext, useEffect
|
| 2 |
import Search from '../Search';
|
| 3 |
import Contacts from '../Contacts';
|
| 4 |
import "./SideBar.css";
|
| 5 |
-
import { SocketContext } from '../../SocketProvider';
|
|
|
|
| 6 |
|
| 7 |
|
| 8 |
-
function SideBar({
|
| 9 |
-
contacts,
|
| 10 |
-
setContacts,
|
| 11 |
-
setCurrentContact,
|
| 12 |
-
currentContact,
|
| 13 |
-
}) {
|
| 14 |
|
| 15 |
const socket = useContext(SocketContext);
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
useEffect(() => {
|
| 18 |
|
| 19 |
const fetchData = async () => {
|
| 20 |
-
|
| 21 |
-
if(!socket) return;
|
| 22 |
-
|
| 23 |
-
socket.on("contacts",(contacts)=>{
|
| 24 |
// console.log(contacts);
|
| 25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
});
|
| 27 |
|
| 28 |
socket.emit("get_contacts");
|
| 29 |
}
|
|
|
|
| 30 |
fetchData();
|
| 31 |
|
| 32 |
-
return ()=>{
|
| 33 |
-
if(!socket) return;
|
| 34 |
socket.off("contacts");
|
| 35 |
}
|
| 36 |
}, [socket]);
|
|
@@ -39,7 +45,7 @@ function SideBar({
|
|
| 39 |
|
| 40 |
<div className='side_bar'>
|
| 41 |
<Search />
|
| 42 |
-
<Contacts
|
| 43 |
</div>
|
| 44 |
)
|
| 45 |
}
|
|
|
|
| 1 |
+
import React, { useContext, useEffect } from 'react'
|
| 2 |
import Search from '../Search';
|
| 3 |
import Contacts from '../Contacts';
|
| 4 |
import "./SideBar.css";
|
| 5 |
+
import { SocketContext } from '../../contexts/SocketProvider';
|
| 6 |
+
import { ChatContext } from '../../contexts/ChatProvider';
|
| 7 |
|
| 8 |
|
| 9 |
+
function SideBar() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
const socket = useContext(SocketContext);
|
| 12 |
|
| 13 |
+
const {
|
| 14 |
+
setContacts,
|
| 15 |
+
// setLastMessages,
|
| 16 |
+
} = useContext(ChatContext);
|
| 17 |
+
|
| 18 |
useEffect(() => {
|
| 19 |
|
| 20 |
const fetchData = async () => {
|
| 21 |
+
|
| 22 |
+
if (!socket) return;
|
| 23 |
+
socket.on("contacts", (contacts) => {
|
|
|
|
| 24 |
// console.log(contacts);
|
| 25 |
+
var newContacts = contacts;
|
| 26 |
+
|
| 27 |
+
newContacts.sort((a,b)=>b.last_message.send_at - a.last_message.send_at);
|
| 28 |
+
|
| 29 |
+
setContacts(newContacts); // set Contacts
|
| 30 |
+
// setLastMessages(contacts.map((contact) => contact.last_message)); // set Last messages
|
| 31 |
});
|
| 32 |
|
| 33 |
socket.emit("get_contacts");
|
| 34 |
}
|
| 35 |
+
|
| 36 |
fetchData();
|
| 37 |
|
| 38 |
+
return () => {
|
| 39 |
+
if (!socket) return;
|
| 40 |
socket.off("contacts");
|
| 41 |
}
|
| 42 |
}, [socket]);
|
|
|
|
| 45 |
|
| 46 |
<div className='side_bar'>
|
| 47 |
<Search />
|
| 48 |
+
<Contacts />
|
| 49 |
</div>
|
| 50 |
)
|
| 51 |
}
|
client/src/contexts/ChatProvider.jsx
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React, { createContext, useState } from "react";
|
| 2 |
+
|
| 3 |
+
export const ChatContext = createContext();
|
| 4 |
+
|
| 5 |
+
export const ChatProvider = ({ children }) => {
|
| 6 |
+
const [contacts, setContacts] = useState([]);
|
| 7 |
+
const [currentChat, setCurrentChat] = useState({});
|
| 8 |
+
const [lastMessages, setLastMessages] = useState([]);
|
| 9 |
+
|
| 10 |
+
return (
|
| 11 |
+
<ChatContext.Provider value={{
|
| 12 |
+
contacts, setContacts,
|
| 13 |
+
currentChat, setCurrentChat,
|
| 14 |
+
lastMessages, setLastMessages,
|
| 15 |
+
}}>
|
| 16 |
+
{children}
|
| 17 |
+
</ChatContext.Provider>
|
| 18 |
+
);
|
| 19 |
+
}
|
client/src/{SocketProvider.jsx → contexts/SocketProvider.jsx}
RENAMED
|
File without changes
|
client/src/{UserProvider.jsx → contexts/UserProvider.jsx}
RENAMED
|
File without changes
|
server/index.ts
CHANGED
|
@@ -352,22 +352,34 @@ io.on("connection", async (socket) => {
|
|
| 352 |
console.log("saved message:", data.message);
|
| 353 |
|
| 354 |
const sockets = await io.fetchSockets();
|
| 355 |
-
|
| 356 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 357 |
sockets.forEach((client) => {
|
| 358 |
if (client.data.user.id == data.send_to) {
|
| 359 |
// console.log("heyy");
|
| 360 |
-
return socket.to(client.id).emit("receive_message",
|
| 361 |
-
...data,
|
| 362 |
-
"send_to": data.send_to,
|
| 363 |
-
"send_from": socket.data.user.id,
|
| 364 |
-
"is_seen": 0,
|
| 365 |
-
});
|
| 366 |
}
|
| 367 |
})
|
| 368 |
|
| 369 |
});
|
| 370 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 371 |
// upon disconnection
|
| 372 |
socket.on("disconnect", (reason) => {
|
| 373 |
console.log(`socket ${socket.id} disconnected due to ${reason}`);
|
|
|
|
| 352 |
console.log("saved message:", data.message);
|
| 353 |
|
| 354 |
const sockets = await io.fetchSockets();
|
| 355 |
+
const message_bundle = {
|
| 356 |
+
...data,
|
| 357 |
+
"id":msg_id,
|
| 358 |
+
"send_to": data.send_to,
|
| 359 |
+
"send_from": socket.data.user.id,
|
| 360 |
+
"is_seen": 0,
|
| 361 |
+
};
|
| 362 |
+
|
| 363 |
+
socket.emit("receive_message",message_bundle);
|
| 364 |
sockets.forEach((client) => {
|
| 365 |
if (client.data.user.id == data.send_to) {
|
| 366 |
// console.log("heyy");
|
| 367 |
+
return socket.to(client.id).emit("receive_message", message_bundle);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 368 |
}
|
| 369 |
})
|
| 370 |
|
| 371 |
});
|
| 372 |
|
| 373 |
+
socket.on("get_contact",async contact_id=>{
|
| 374 |
+
const contact = await db.prepare("select * from users where id = ?").get(contact_id);
|
| 375 |
+
|
| 376 |
+
|
| 377 |
+
socket.emit("contact",{
|
| 378 |
+
...contact,
|
| 379 |
+
last_message: await getLastMessage({ user_id: socket.data.user.id, contact_id: contact_id }),
|
| 380 |
+
});
|
| 381 |
+
})
|
| 382 |
+
|
| 383 |
// upon disconnection
|
| 384 |
socket.on("disconnect", (reason) => {
|
| 385 |
console.log(`socket ${socket.id} disconnected due to ${reason}`);
|