Skip to content

Commit

Permalink
Seen message feature added
Browse files Browse the repository at this point in the history
  • Loading branch information
burakorkmez committed Sep 17, 2023
1 parent 3d206b0 commit 807dcf1
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 9 deletions.
4 changes: 4 additions & 0 deletions backend/models/conversationModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ const conversationSchema = new mongoose.Schema(
lastMessage: {
text: String,
sender: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
seen: {
type: Boolean,
default: false,
},
},
},
{ timestamps: true }
Expand Down
4 changes: 4 additions & 0 deletions backend/models/messageModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ const messageSchema = new mongoose.Schema(
conversationId: { type: mongoose.Schema.Types.ObjectId, ref: "Conversation" },
sender: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
text: String,
seen: {
type: Boolean,
default: false,
},
},
{ timestamps: true }
);
Expand Down
12 changes: 12 additions & 0 deletions backend/socket/socket.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Server } from "socket.io";
import http from "http";
import express from "express";
import Message from "../models/messageModel.js";
import Conversation from "../models/conversationModel.js";

const app = express();
const server = http.createServer(app);
Expand All @@ -24,6 +26,16 @@ io.on("connection", (socket) => {
if (userId != "undefined") userSocketMap[userId] = socket.id;
io.emit("getOnlineUsers", Object.keys(userSocketMap));

socket.on("markMessagesAsSeen", async ({ conversationId, userId }) => {
try {
await Message.updateMany({ conversationId: conversationId, seen: false }, { $set: { seen: true } });
await Conversation.updateOne({ _id: conversationId }, { $set: { "lastMessage.seen": true } });
io.to(userSocketMap[userId]).emit("messagesSeen", { conversationId });
} catch (error) {
console.log(error);
}
});

socket.on("disconnect", () => {
console.log("user disconnected");
delete userSocketMap[userId];
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/components/Conversation.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Avatar,
AvatarBadge,
Box,
Flex,
Image,
Stack,
Expand Down Expand Up @@ -64,7 +65,13 @@ const Conversation = ({ conversation, isOnline }) => {
{user.username} <Image src='/verified.png' w={4} h={4} ml={1} />
</Text>
<Text fontSize={"xs"} display={"flex"} alignItems={"center"} gap={1}>
{currentUser._id === lastMessage.sender ? <BsCheck2All size={16} /> : ""}
{currentUser._id === lastMessage.sender ? (
<Box color={lastMessage.seen ? "blue.400" : ""}>
<BsCheck2All size={16} />
</Box>
) : (
""
)}
{lastMessage.text.length > 18 ? lastMessage.text.substring(0, 18) + "..." : lastMessage.text}
</Text>
</Stack>
Expand Down
12 changes: 8 additions & 4 deletions frontend/src/components/Message.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Avatar, Flex, Text } from "@chakra-ui/react";
import { Avatar, Box, Flex, Text } from "@chakra-ui/react";
import { selectedConversationAtom } from "../atoms/messagesAtom";
import { useRecoilValue } from "recoil";
import userAtom from "../atoms/userAtom";
import { BsCheck2All } from "react-icons/bs";

const Message = ({ ownMessage, message }) => {
const selectedConversation = useRecoilValue(selectedConversationAtom);
Expand All @@ -11,9 +12,12 @@ const Message = ({ ownMessage, message }) => {
<>
{ownMessage ? (
<Flex gap={2} alignSelf={"flex-end"}>
<Text maxW={"350px"} bg={"blue.400"} p={1} borderRadius={"md"}>
{message.text}
</Text>
<Flex bg={"green.800"} maxW={"350px"} p={1} borderRadius={"md"}>
<Text color={"white"}>{message.text}</Text>
<Box alignSelf={"flex-end"} ml={1} color={message.seen ? "blue.400" : ""} fontWeight={"bold"}>
<BsCheck2All size={16} />
</Box>
</Flex>
<Avatar src={user.profilePic} w='7' h={7} />
</Flex>
) : (
Expand Down
35 changes: 31 additions & 4 deletions frontend/src/components/MessageContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import MessageInput from "./MessageInput";
import { useEffect, useRef, useState } from "react";
import useShowToast from "../hooks/useShowToast";
import { conversationsAtom, selectedConversationAtom } from "../atoms/messagesAtom";
import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
import { useRecoilValue, useSetRecoilState } from "recoil";
import userAtom from "../atoms/userAtom";
import { useSocket } from "../context/SocketContext.jsx";

const MessageContainer = () => {
const showToast = useShowToast();
const [selectedConversation, setSelectedConversation] = useRecoilState(selectedConversationAtom);
const selectedConversation = useRecoilValue(selectedConversationAtom);
const [loadingMessages, setLoadingMessages] = useState(true);
const [messages, setMessages] = useState([]);
const currentUser = useRecoilValue(userAtom);
Expand Down Expand Up @@ -42,7 +42,34 @@ const MessageContainer = () => {
});

return () => socket.off("newMessage");
}, [socket]);
}, [socket, selectedConversation, setConversations]);

useEffect(() => {
const lastMessageIsFromOtherUser = messages.length && messages[messages.length - 1].sender !== currentUser._id;
if (lastMessageIsFromOtherUser) {
socket.emit("markMessagesAsSeen", {
conversationId: selectedConversation._id,
userId: selectedConversation.userId,
});
}

socket.on("messagesSeen", ({ conversationId }) => {
if (selectedConversation._id === conversationId) {
setMessages((prev) => {
const updatedMessages = prev.map((message) => {
if (!message.seen) {
return {
...message,
seen: true,
};
}
return message;
});
return updatedMessages;
});
}
});
}, [socket, currentUser._id, messages, selectedConversation]);

useEffect(() => {
messageEndRef.current?.scrollIntoView({ behavior: "smooth" });
Expand All @@ -69,7 +96,7 @@ const MessageContainer = () => {
};

getMessages();
}, [showToast, selectedConversation.userId]);
}, [showToast, selectedConversation.userId, selectedConversation.mock]);

return (
<Flex
Expand Down
20 changes: 20 additions & 0 deletions frontend/src/pages/ChatPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,26 @@ const ChatPage = () => {
const showToast = useShowToast();
const { socket, onlineUsers } = useSocket();

useEffect(() => {
socket?.on("messagesSeen", ({ conversationId }) => {
setConversations((prev) => {
const updatedConversations = prev.map((conversation) => {
if (conversation._id === conversationId) {
return {
...conversation,
lastMessage: {
...conversation.lastMessage,
seen: true,
},
};
}
return conversation;
});
return updatedConversations;
});
});
}, [socket, setConversations]);

useEffect(() => {
const getConversations = async () => {
try {
Expand Down

0 comments on commit 807dcf1

Please sign in to comment.