Skip to content

Commit

Permalink
Finished socket
Browse files Browse the repository at this point in the history
  • Loading branch information
Keagan Aromin authored and Keagan Aromin committed Jan 12, 2025
1 parent 5cafe5f commit 7d2ee3a
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 7 deletions.
15 changes: 9 additions & 6 deletions backend/controllers/message.controller.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Conversation from "../models/conversation.model.js";
import Message from "../models/message.model.js";
//import { getReceiverSocketId, io } from "../socket/socket.js";
import { getReceiverSocketId, io } from "../socket/socket.js";

export const sendMessage = async (req, res) => {
try {
Expand Down Expand Up @@ -33,15 +33,18 @@ export const sendMessage = async (req, res) => {
conversation.messages.push(newMessage._id);
}

// SOCKET IO FUNCTIONALITY WILL GO HERE

// await conversation.save();
// await newMessage.save();

// saves the message to db, access by going to MongoDB website > cluster > chat-app-db > conversations/messages
// the Promise.all() allows us to run conversation.save() and newMessage.save() in parallel
await Promise.all([conversation.save(), newMessage.save()]);

// socket.io functionality
// now that message in db, send to other user
const receiverSocketId = getReceiverSocketId(receiverId);
if (receiverSocketId) {
//io.to sends message to one specific client, not everyone
io.to(receiverSocketId).emit("newMessage", newMessage);
}

res.status(201).json(newMessage);
} catch (error) {
console.log("Error in sendMessage controller: ", error.message);
Expand Down
4 changes: 4 additions & 0 deletions backend/socket/socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ const io = new Server(server, {
}
})

export const getReceiverSocketId = (receiverId) => {
return userSocketMap[receiverId];
}

const userSocketMap = {}; // {userId: socketId}

io.on('connection', (socket) => {
Expand Down
Binary file added frontend/src/assets/sounds/notification.mp3
Binary file not shown.
3 changes: 2 additions & 1 deletion frontend/src/components/messages/Message.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const Message = ({message}) => {
const profilePic = fromMe ? authUser.profilePic : selectedConversation?.profilePic;
const bubbleBgColor = fromMe ? 'bg-blue-500' : "";

const shakeClass = message.shouldShake ? 'shake' : "";

return (
<div className={`chat ${chatClassName}`}>
Expand All @@ -23,7 +24,7 @@ const Message = ({message}) => {
/>
</div>
</div>
<div className={`chat-bubble text-white ${bubbleBgColor} pb-2`}>{message.message}</div>
<div className={`chat-bubble text-white ${bubbleBgColor} ${shakeClass} pb-2`}>{message.message}</div>
<div className="chat-footer opacity-50 text-xs flex gap-1 items-center">
1:12
</div>
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/messages/Messages.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import React, { useEffect, useRef } from "react";
import Message from "./Message";
import useGetMessages from "../../hooks/useGetMessages";
import MessageSkeleton from "../skeletons/MessageSkeleton";
import useListenMessages from "../../hooks/useListenMessages"

const Messages = () => {
const {messages, loading}= useGetMessages();
//listen to any incoming messages from socket
useListenMessages();
const lastMessageRef = useRef();

useEffect(() => {
Expand Down
23 changes: 23 additions & 0 deletions frontend/src/hooks/useListenMessages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useSocketContext } from '../context/SocketContext'
import useConversation from '../zustand/useConversation'
import { useEffect } from 'react'
import notificationSound from '../assets/sounds/notification.mp3'

const useListenMessages = () => {
const { socket } = useSocketContext();
const { messages, setMessages } = useConversation();

useEffect(() => {
socket?.on('newMessage', (newMessage) => {
newMessage.shouldShake = true;
const sound = new Audio(notificationSound);
sound.play();
setMessages([...messages, newMessage])
})

//this line is important so we don't stack calls (this will stack notification sounds)
return () => socket?.off('newMessage')
}, [socket, setMessages, messages])
}

export default useListenMessages;
31 changes: 31 additions & 0 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,34 @@ body {
::-webkit-scrollbar-thumb:hover {
background: #242424;
}

/* SHAKE ANIMATION ON HORIZONTAL DIRECTION */
.shake {
animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) 0.2s both;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
perspective: 1000px;
}

@keyframes shake {
10%,
90% {
transform: translate3d(-1px, 0, 0);
}

20%,
80% {
transform: translate3d(2px, 0, 0);
}

30%,
50%,
70% {
transform: translate3d(-4px, 0, 0);
}

40%,
60% {
transform: translate3d(4px, 0, 0);
}
}

0 comments on commit 7d2ee3a

Please sign in to comment.