From d7b70922618b66b3375c3b159ec710c253392b4a Mon Sep 17 00:00:00 2001 From: Bobby Gifford Date: Tue, 18 Jul 2023 12:34:59 -0700 Subject: [PATCH 1/3] rerendering for new messages and seen status --- client/src/components/Home.js | 57 ++++++++++++++++++------------ server/db/models/message.js | 4 +++ server/routes/api/conversations.js | 7 ++-- 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/client/src/components/Home.js b/client/src/components/Home.js index d301ab2..0b43925 100644 --- a/client/src/components/Home.js +++ b/client/src/components/Home.js @@ -62,9 +62,9 @@ const Home = ({ user, logout }) => { }); }; - const postMessage = (body) => { + const postMessage = async (body) => { try { - const data = saveMessage(body); + const data = await saveMessage(body); if (!body.conversationId) { addNewConvo(body.recipientId, data.message); @@ -80,41 +80,54 @@ const Home = ({ user, logout }) => { const addNewConvo = useCallback( (recipientId, message) => { - conversations.forEach((convo) => { - if (convo.otherUser.id === recipientId) { - convo.messages.push(message); - convo.latestMessageText = message.text; - convo.id = message.conversationId; - } - }); - setConversations(conversations); + setConversations((prevConversations) => + prevConversations.map((convo) => { + if (convo.otherUser.id === recipientId) { + return { + ...convo, + messages: [...convo.messages, message], + latestMessageText: message.text, + id: message.conversationId, + }; + } else { + return convo; + } + }) + ); }, - [setConversations, conversations] + [setConversations] ); const addMessageToConversation = useCallback( (data) => { - // if sender isn't null, that means the message needs to be put in a brand new convo const { message, sender = null } = data; + + // if sender isn't null, that means the message needs to be put in a brand new convo if (sender !== null) { const newConvo = { id: message.conversationId, otherUser: sender, messages: [message], + latestMessageText: message.text, }; - newConvo.latestMessageText = message.text; setConversations((prev) => [newConvo, ...prev]); + } else { + setConversations((prevConversations) => + prevConversations.map((convo) => { + if (convo.id === message.conversationId) { + return { + ...convo, + messages: [...convo.messages, message], + latestMessageText: message.text, + }; + } else { + return convo; + } + }) + ); } - - conversations.forEach((convo) => { - if (convo.id === message.conversationId) { - convo.messages.push(message); - convo.latestMessageText = message.text; - } - }); - setConversations(conversations); }, - [setConversations, conversations] + [setConversations] ); const setActiveChat = (username) => { diff --git a/server/db/models/message.js b/server/db/models/message.js index 576a2a3..4e5f676 100644 --- a/server/db/models/message.js +++ b/server/db/models/message.js @@ -10,6 +10,10 @@ const Message = db.define("message", { type: Sequelize.INTEGER, allowNull: false, }, + seen: { + type: Sequelize.BOOLEAN, + defaultValue: false, + }, }); module.exports = Message; diff --git a/server/routes/api/conversations.js b/server/routes/api/conversations.js index 82124d5..c16a6cb 100644 --- a/server/routes/api/conversations.js +++ b/server/routes/api/conversations.js @@ -19,9 +19,9 @@ router.get("/", async (req, res, next) => { }, }, attributes: ["id"], - order: [[Message, "createdAt", "DESC"]], + order: [[Message, "createdAt", "ASC"]], include: [ - { model: Message, order: ["createdAt", "DESC"] }, + { model: Message, order: [["createdAt", "ASC"]] }, { model: User, as: "user1", @@ -68,7 +68,8 @@ router.get("/", async (req, res, next) => { } // set properties for notification count and latest message preview - convoJSON.latestMessageText = convoJSON.messages[0].text; + convoJSON.latestMessageText = + convoJSON.messages[convoJSON.messages.length - 1].text; conversations[i] = convoJSON; } From fd30407b74ce63676aa9622a39ca10147801e4ae Mon Sep 17 00:00:00 2001 From: Bobby Gifford Date: Tue, 18 Jul 2023 13:11:34 -0700 Subject: [PATCH 2/3] unread badge on conversations --- client/src/components/Sidebar/ChatContent.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/client/src/components/Sidebar/ChatContent.js b/client/src/components/Sidebar/ChatContent.js index 1babcb5..221190e 100644 --- a/client/src/components/Sidebar/ChatContent.js +++ b/client/src/components/Sidebar/ChatContent.js @@ -1,5 +1,5 @@ import React from "react"; -import { Box, Typography } from "@material-ui/core"; +import { Box, Typography, Badge } from "@material-ui/core"; import { makeStyles } from "@material-ui/core/styles"; const useStyles = makeStyles((theme) => ({ @@ -26,6 +26,11 @@ const ChatContent = ({ conversation }) => { const { otherUser } = conversation; const latestMessageText = conversation.id && conversation.latestMessageText; + const unseenMessages = conversation.messages.filter( + (message) => message.seen === false + ); + + console.log(unseenMessages.length); return ( @@ -36,6 +41,12 @@ const ChatContent = ({ conversation }) => { {latestMessageText} + ); }; From a41e99a3f7114efcbbe66db7cb78aa60b3b93169 Mon Sep 17 00:00:00 2001 From: Bobby Gifford Date: Tue, 18 Jul 2023 16:18:08 -0700 Subject: [PATCH 3/3] read status updates. controls unread messages number badge --- .../src/components/ActiveChat/ActiveChat.js | 33 ++++++++++++++++++- client/src/components/ActiveChat/Input.js | 1 + client/src/components/Home.js | 1 + server/routes/api/messages.js | 33 +++++++++++++++++-- 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/client/src/components/ActiveChat/ActiveChat.js b/client/src/components/ActiveChat/ActiveChat.js index 2f1aed7..3bd808d 100644 --- a/client/src/components/ActiveChat/ActiveChat.js +++ b/client/src/components/ActiveChat/ActiveChat.js @@ -1,4 +1,5 @@ -import React from "react"; +import React, { useEffect } from "react"; +import axios from "axios"; import { makeStyles } from "@material-ui/core/styles"; import { Box } from "@material-ui/core"; import { Input, Header, Messages } from "./index"; @@ -24,6 +25,7 @@ const ActiveChat = ({ conversations, activeConversation, postMessage, + setConversations, }) => { const classes = useStyles(); @@ -37,6 +39,35 @@ const ActiveChat = ({ return obj !== {} && obj !== undefined; }; + useEffect(() => { + const seeMessages = async () => { + const { data } = await axios.post("/api/messages/read", { + conversationId: conversation?.id, + }); + // console.log(data); + }; + + const fetchConversations = async () => { + try { + const { data } = await axios.get("/api/conversations"); + setConversations(data); + } catch (error) { + console.error(error); + } + }; + + // update messages.seen to be true here + // send conversation id to /read + + if (!!conversation) { + seeMessages(); + + if (!user.isFetching) { + fetchConversations(); + } + } + }, [activeConversation, setConversations, user]); + return ( {isConversation(conversation) && conversation.otherUser && ( diff --git a/client/src/components/ActiveChat/Input.js b/client/src/components/ActiveChat/Input.js index e1927d7..4dfecc2 100644 --- a/client/src/components/ActiveChat/Input.js +++ b/client/src/components/ActiveChat/Input.js @@ -33,6 +33,7 @@ const Input = ({ otherUser, conversationId, user, postMessage }) => { recipientId: otherUser.id, conversationId, sender: conversationId ? null : user, + seen: true, }; await postMessage(reqBody); setText(""); diff --git a/client/src/components/Home.js b/client/src/components/Home.js index 0b43925..9b74c26 100644 --- a/client/src/components/Home.js +++ b/client/src/components/Home.js @@ -225,6 +225,7 @@ const Home = ({ user, logout }) => { setActiveChat={setActiveChat} /> { return res.sendStatus(401); } const senderId = req.user.id; - const { recipientId, text, conversationId, sender } = req.body; + const { recipientId, text, conversationId, sender, seen } = req.body; // if we already know conversation id, we can save time and just add it to message and return if (conversationId) { - const message = await Message.create({ senderId, text, conversationId }); + const message = await Message.create({ + senderId, + text, + conversationId, + seen, + }); return res.json({ message, sender }); } // if we don't have conversation id, find a conversation to make sure it doesn't already exist @@ -36,6 +41,7 @@ router.post("/", async (req, res, next) => { senderId, text, conversationId: conversation.id, + seen: seen, }); res.json({ message, sender }); } catch (error) { @@ -43,4 +49,27 @@ router.post("/", async (req, res, next) => { } }); +router.post("/read", async (req, res, next) => { + try { + if (!req.user) { + return res.sendStatus(401); + } + + const { conversationId } = req.body; + + const message = await Message.update( + { seen: true }, + { + where: { + conversationId: conversationId, + }, + } + ); + + res.json({ message }); + } catch (error) { + next(error); + } +}); + module.exports = router;