diff --git a/client/src/hooks/useCheckTimePassed.js b/client/src/hooks/useCheckTimePassed.js index 9c7cf5dc9..b984b6ccb 100644 --- a/client/src/hooks/useCheckTimePassed.js +++ b/client/src/hooks/useCheckTimePassed.js @@ -1,38 +1,63 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useState, useCallback } from 'react'; -/* - * {timeInMilliseconds} is the time to track e.g 5 o'clock - * {timeToCheck} is the time to track against also in ms e.g 3 minutes - */ -export default (timeInMilliseconds, timeToCheck) => { +export default (timeInMilliseconds, timeToCheck, onTimePass, interval = 1000) => { const [timePassed, setTimePassed] = useState(false); const [timer, setTimer] = useState(null); // Function to clear the timer externally - const clearTimer = () => { + const clearTimer = useCallback(() => { clearInterval(timer); - return { timePassed: false, clearTimer }; - }; + setTimer(null); + setTimePassed(false); + }, [timer]); + + // Function to pause the timer + const pauseTimer = useCallback(() => { + clearInterval(timer); + setTimer(null); + }, [timer]); + + // Function to resume the timer + const resumeTimer = useCallback(() => { + if (!timer) { + setTimer(setInterval(checkTime, interval)); + } + }, [timer, interval]); + + // Function to reset the timer + const resetTimer = useCallback(() => { + clearInterval(timer); + setTimer(null); + setTimePassed(false); + if (timeInMilliseconds) { + setTimer(setInterval(checkTime, interval)); + } + }, [timer, timeInMilliseconds, interval]); + + // Function to check the time difference + const checkTime = useCallback(() => { + const currentTime = Date.now(); + const timeDifference = currentTime - timeInMilliseconds; + const hasTimePassed = timeDifference >= timeToCheck; + setTimePassed(hasTimePassed); + if (hasTimePassed && onTimePass) { + onTimePass(); + } + }, [timeInMilliseconds, timeToCheck, onTimePass]); useEffect(() => { if (!timeInMilliseconds) { return; } - // check if the time if it's greater or equal to the `timeToCheck` - const checkTime = () => { - const currentTime = Date.now(); - const timeDifference = currentTime - timeInMilliseconds; - setTimePassed(timeDifference >= timeToCheck); - }; + setTimer(setInterval(checkTime, interval)); - // set the interval to state - setTimer(setInterval(checkTime, 1000)); - }, [timeInMilliseconds]); + return () => clearInterval(timer); + }, [timeInMilliseconds, checkTime, interval]); if (!timeInMilliseconds) { - return { timePassed: false, clearTimer }; + return { timePassed: false, clearTimer, pauseTimer, resumeTimer, resetTimer }; } - return { timePassed, clearTimer }; + return { timePassed, clearTimer, pauseTimer, resumeTimer, resetTimer }; }; diff --git a/server/sockets/sendMessage.js b/server/sockets/sendMessage.js index c102a5c47..de076eff7 100644 --- a/server/sockets/sendMessage.js +++ b/server/sockets/sendMessage.js @@ -2,57 +2,59 @@ const { NEW_EVENT_SEND_MESSAGE, NEW_EVENT_SEND_FAILED, NEW_EVENT_RECEIVE_MESSAGE, + NEW_EVENT_TYPING, + NEW_EVENT_STOP_TYPING } = require('../../constants.json'); const { addMessage, getActiveUser } = require('../utils/lib'); -// Create an object to store message counts per user const messageCounts = {}; +const typingUsers = {}; module.exports = (socket) => { + socket.on(NEW_EVENT_TYPING, ({ chatId }) => { + const user = getActiveUser({ socketId: socket.id }); + if (user) { + typingUsers[user.id] = true; + socket.broadcast.to(chatId).emit(NEW_EVENT_TYPING, { userId: user.id }); + } + }); + + socket.on(NEW_EVENT_STOP_TYPING, ({ chatId }) => { + const user = getActiveUser({ socketId: socket.id }); + if (user) { + delete typingUsers[user.id]; + socket.broadcast.to(chatId).emit(NEW_EVENT_STOP_TYPING, { userId: user.id }); + } + }); + socket.on( NEW_EVENT_SEND_MESSAGE, async ({ senderId, message, time, chatId, containsBadword, replyTo }, returnMessageToSender) => { - // Below line is just a failed message simulator for testing purposes. - - // const rndInt = Math.floor(Math.random() * 6) + 1; - // if (rndInt % 2 !== 0) { - // return; - // } - const user = getActiveUser({ - socketId: socket.id, - }); + const user = getActiveUser({ socketId: socket.id }); if (!user) { socket.emit(NEW_EVENT_SEND_FAILED, { - message: - 'Hmmm. It seems your login session has expired. ' + - 'Re-login and try again', + message: 'Hmmm. It seems your login session has expired. Re-login and try again', }); return; } - // Check the message count for the user const userMessageCount = messageCounts[senderId] || 0; if (userMessageCount >= 25) { - // User has exceeded the message limit socket.emit(NEW_EVENT_SEND_FAILED, { - message: - 'You have exceeded the message limit. Please try again later.', + message: 'You have exceeded the message limit. Please try again later.', }); return; } - /** - * Cache the sent message in memory a nd persist to db - */ const sentMessage = await addMessage(chatId, { message, time, senderId, type: 'message', containsBadword, - replyTo + replyTo, }); const messageDetails = { @@ -63,14 +65,10 @@ module.exports = (socket) => { returnMessageToSender(messageDetails); - socket.broadcast - .to(chatId) - .emit(NEW_EVENT_RECEIVE_MESSAGE, messageDetails); + socket.broadcast.to(chatId).emit(NEW_EVENT_RECEIVE_MESSAGE, messageDetails); - // Update the message count for the user messageCounts[senderId] = userMessageCount + 1; - // Reset the count after 1 minute setTimeout(() => { messageCounts[senderId] = 0; }, 60 * 1000);