Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 41 additions & 26 deletions src/components/Chat.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useEffect, useRef, useState } from "react";
import { useParams } from "react-router-dom";
import { createSocketConnection } from "../utils/socket";
import { useSelector } from "react-redux";
Expand All @@ -9,16 +9,14 @@ const Chat = () => {
const { targetUserId } = useParams();
const [messages, setMessages] = useState([]);
const [newMessage, setNewMessage] = useState("");
const chatEndRef = useRef(null);
const user = useSelector((store) => store.user);
const userId = user?._id;

const fetchChatMessages = async () => {
const chat = await axios.get(BASE_URL + "/chat/" + targetUserId, {
withCredentials: true,
});

console.log(chat.data.messages);

const chatMessages = chat?.data?.messages.map((msg) => {
const { senderId, text } = msg;
return {
Expand All @@ -29,24 +27,31 @@ const Chat = () => {
});
setMessages(chatMessages);
};

const scrollToBottom = () => {
chatEndRef.current?.scrollIntoView({ behavior: "smooth" });
};

useEffect(() => {
fetchChatMessages();
}, []);

useEffect(() => {
scrollToBottom();
}, [messages]);

useEffect(() => {
if (!userId) {
return;
}
const socket = createSocketConnection();
// As soon as the page loaded, the socket connection is made and joinChat event is emitted
socket.emit("joinChat", {
firstName: user.firstName,
userId,
targetUserId,
});

socket.on("messageReceived", ({ firstName, lastName, text }) => {
console.log(firstName + " : " + text);
setMessages((messages) => [...messages, { firstName, lastName, text }]);
});

Expand All @@ -56,6 +61,7 @@ const Chat = () => {
}, [userId, targetUserId]);

const sendMessage = () => {
if (newMessage.trim() === "") return;
const socket = createSocketConnection();
socket.emit("sendMessage", {
firstName: user.firstName,
Expand All @@ -67,35 +73,44 @@ const Chat = () => {
setNewMessage("");
};

const handleKeyDown = (e) => {
if (e.key === "Enter") {
sendMessage();
}
};

return (
<div className="w-3/4 mx-auto border border-gray-600 m-5 h-[70vh] flex flex-col">
<h1 className="p-5 border-b border-gray-600">Chat</h1>
<h1 className="p-5 border-b border-gray-600 text-xl font-semibold">
Chat
</h1>
<div className="flex-1 overflow-scroll p-5">
{messages.map((msg, index) => {
return (
<div
key={index}
className={
"chat " +
(user.firstName === msg.firstName ? "chat-end" : "chat-start")
}
>
<div className="chat-header">
{`${msg.firstName} ${msg.lastName}`}
<time className="text-xs opacity-50"> 2 hours ago</time>
</div>
<div className="chat-bubble">{msg.text}</div>
<div className="chat-footer opacity-50">Seen</div>
{messages.map((msg, index) => (
<div
key={index}
className={
"chat " +
(user.firstName === msg.firstName ? "chat-end" : "chat-start")
}
>
<div className="chat-header text-sm font-medium">
{`${msg.firstName} ${msg.lastName}`}
<time className="text-xs opacity-50 ml-2">2 hours ago</time>
</div>
);
})}
<div className="chat-bubble bg-blue-600 text-white">{msg.text}</div>
<div className="chat-footer text-xs opacity-50">Seen</div>
</div>
))}
<div ref={chatEndRef}></div>
</div>
<div className="p-5 border-t border-gray-600 flex items-center gap-2">
<input
value={newMessage}
onChange={(e) => setNewMessage(e.target.value)}
className="flex-1 border border-gray-500 text-white rounded p-2"
></input>
onKeyDown={handleKeyDown}
placeholder="Type a message..."
className="flex-1 border border-gray-500 text-white rounded p-2 bg-gray-800"
/>
<button onClick={sendMessage} className="btn btn-secondary">
Send
</button>
Expand Down