diff --git a/src/services/chatService.js b/src/services/chatService.js index c76afab..79bc00d 100644 --- a/src/services/chatService.js +++ b/src/services/chatService.js @@ -2,8 +2,8 @@ * @module community/service/chat */ -import ChatModel from "../db/models/ChatModel.js"; -import MessageModel from "../db/models/MessageModel.js"; +import ChatModel from "../db/models/ChatModel.js" +import MessageModel from "../db/models/MessageModel.js" import { User } from "../db/models/User.js"; // TODO: Uncomment. @@ -27,40 +27,20 @@ const sendMessage = async (sender, receiverUsername, message) => { try { receiver = await User.findOne({ username: receiverUsername }); } catch (error) { - return { - err: { - status: 500, - message: `Error finding receiver with username: ${receiverUsername}`, - }, - }; + return { err: { status: 500, message: `Error finding receiver with username: ${receiverUsername}` } }; } if (!receiver || !sender) { - return { - err: { - status: 404, - message: "Either the receiver or sender does not exist in the system", - }, - }; + return { err: { status: 404, message: 'Either the receiver or sender does not exist in the system' } }; } if (receiver.username === sender.username) { - return { - err: { - status: 400, - message: "A user cannot send a message to themselves", - }, - }; + return { err: { status: 400, message: 'A user cannot send a message to themselves' } }; } // Validating the message if (!message) { - return { - err: { - status: 400, - message: "The message attribute must be provided in the request body.", - }, - }; + return { err: { status: 400, message: 'The message attribute must be provided in the request body.' } }; } // Create a new message and add it to the chat. @@ -68,15 +48,10 @@ const sendMessage = async (sender, receiverUsername, message) => { senderId: sender._id, receiverId: receiver._id, message, - }); + }) if (!newMessage) { - return { - err: { - status: 500, - message: "An error occurred while creating the new message", - }, - }; + return { err: { status: 500, message: 'An error occurred while creating the new message' } }; } // Check if the chat already exists. If not, create a new chat. @@ -86,17 +61,12 @@ const sendMessage = async (sender, receiverUsername, message) => { { participants: { $all: [sender._id, receiver._id] } }, { $set: { lastMessage: newMessage._id }, - $push: { messages: newMessage._id }, + $push: { messages: newMessage._id } }, { new: true } ); } catch (error) { - return { - err: { - status: 500, - message: "An error occurred while trying to find or update the chat", - }, - }; + return { err: { status: 500, message: 'An error occurred while trying to find or update the chat' } }; } if (!chat) { @@ -107,28 +77,15 @@ const sendMessage = async (sender, receiverUsername, message) => { lastMessage: newMessage._id, }); } catch (error) { - return { - err: { - status: 500, - message: "An error occurred while creating a new chat", - }, - }; + return { err: { status: 500, message: 'An error occurred while creating a new chat' } }; } } let savedChat, savedMessage; try { - [savedChat, savedMessage] = await Promise.all([ - chat.save(), - newMessage.save(), - ]); + [savedChat, savedMessage] = await Promise.all([chat.save(), newMessage.save()]); } catch (error) { - return { - err: { - status: 500, - message: "An error occurred while saving the chat or message", - }, - }; + return { err: { status: 500, message: 'An error occurred while saving the chat or message' } }; } const receiverSocketId = getReceiverSocketId(receiver._id); @@ -140,6 +97,7 @@ const sendMessage = async (sender, receiverUsername, message) => { return { newMessage }; }; + /** * Retrieves all messages between a sender and a receiver. * @@ -157,31 +115,15 @@ const getMessages = async (sender, receiverUsername) => { try { receiver = await User.findOne({ username: receiverUsername }); } catch (error) { - return { - err: { - status: 500, - message: `Error occurred while trying to find the receiver with username: ${receiverUsername}`, - }, - }; + return { err: { status: 500, message: `Error occurred while trying to find the receiver with username: ${receiverUsername}` } }; } if (!sender || !receiver) { - return { - err: { - status: 404, - message: - "Either the sender or the receiver does not exist in the system", - }, - }; + return { err: { status: 404, message: 'Either the sender or the receiver does not exist in the system' } }; } if (sender._id.toString() === receiver._id.toString()) { - return { - err: { - status: 400, - message: "A user cannot retrieve messages with themselves", - }, - }; + return { err: { status: 400, message: 'A user cannot retrieve messages with themselves' } }; } // Find chat @@ -192,27 +134,17 @@ const getMessages = async (sender, receiverUsername) => { }).populate({ path: "messages", populate: [ - { path: "senderId", select: "username profile_picture" }, - { path: "receiverId", select: "username profile_picture" }, - ], + { path: 'senderId', select: 'username profile_picture' }, + { path: 'receiverId', select: 'username profile_picture' } + ] }); + } catch (error) { - return { - err: { - status: 500, - message: - "An error occurred while trying to find the chat between the sender and receiver", - }, - }; + return { err: { status: 500, message: 'An error occurred while trying to find the chat between the sender and receiver' } }; } if (!chat) { - return { - err: { - status: 404, - message: "No chat exists between the sender and the receiver", - }, - }; + return { err: { status: 404, message: 'No chat exists between the sender and the receiver' } }; } const messages = chat.messages; @@ -220,15 +152,16 @@ const getMessages = async (sender, receiverUsername) => { return { messages }; }; + /** - * Retrieves all chats for a logged-in user, formatted for display in a sidebar. - * - * @param {string} loggedInUserId - The ID of the logged-in user. - * - * @returns {Promise} - A promise that resolves to an object. If the function is successful, the object contains a 'sideBarChats' property with all the chats for the logged-in user, formatted for display in a sidebar. Each chat includes the chat ID, the username and profile picture of the other participant, and the sender, text, and timestamp of the last message. If an error occurs, the object contains an 'err' property with the status code and error message. - * - * @throws {Object} - If an error occurs, an object is thrown with an 'err' property containing the status code and error message. - */ + * Retrieves all chats for a logged-in user, formatted for display in a sidebar. + * + * @param {string} loggedInUserId - The ID of the logged-in user. + * + * @returns {Promise} - A promise that resolves to an object. If the function is successful, the object contains a 'sideBarChats' property with all the chats for the logged-in user, formatted for display in a sidebar. Each chat includes the chat ID, the username and profile picture of the other participant, and the sender, text, and timestamp of the last message. If an error occurs, the object contains an 'err' property with the status code and error message. + * + * @throws {Object} - If an error occurs, an object is thrown with an 'err' property containing the status code and error message. + */ const getSideBarChats = async (loggedInUserId) => { let chats; @@ -246,13 +179,7 @@ const getSideBarChats = async (loggedInUserId) => { }) .exec(); } catch (error) { - return { - err: { - status: 500, - message: - "An error occurred while trying to find the chats for the logged in user", - }, - }; + return { err: { status: 500, message: 'An error occurred while trying to find the chats for the logged in user' } }; } // Format chat data @@ -263,19 +190,14 @@ const getSideBarChats = async (loggedInUserId) => { // Handle case where there might not be another participant (e.g., private message to yourself) if (!otherParticipant) { - return { - err: { status: 404, message: "No other participant found in the chat" }, - }; + return { err: { status: 404, message: 'No other participant found in the chat' } } } const lastMessage = chat.lastMessage; let lastMessageSender, lastMessageText, lastMessageTimestamp; if (lastMessage) { - lastMessageSender = - lastMessage.senderId.toString() === loggedInUserId.toString() - ? "You" - : otherParticipant.username; + lastMessageSender = lastMessage.senderId.toString() === loggedInUserId.toString() ? "You" : otherParticipant.username; lastMessageText = lastMessage.message; lastMessageTimestamp = lastMessage.createdAt; } else { @@ -295,10 +217,11 @@ const getSideBarChats = async (loggedInUserId) => { }; }); - const sideBarChats = formattedChats.filter((chat) => chat !== null); // Remove any null values - return { sideBarChats }; + const sideBarChats = formattedChats.filter(chat => chat !== null); // Remove any null values + return { sideBarChats } }; + /** * Reports a message for a given reason by a user. * @@ -313,62 +236,32 @@ const getSideBarChats = async (loggedInUserId) => { const reportMessage = async (messageId, reason, reportingUserId) => { if (!messageId || !reason || !reportingUserId) { - return { - err: { - status: 400, - message: - "Message ID, reason for reporting, or reporting user ID is missing", - }, - }; + return { err: { status: 400, message: 'Message ID, reason for reporting, or reporting user ID is missing' } }; } // Check if the reason is valid - const validReasons = MessageModel.schema - .path("reported.reason") - .enumValues.map((value) => value.toLowerCase()); + const validReasons = MessageModel.schema.path('reported.reason').enumValues.map(value => value.toLowerCase()); if (!validReasons.includes(reason.toLowerCase())) { - return { - err: { - status: 400, - message: `Invalid report reason. Valid reasons are: ${validReasons.join( - ", " - )}`, - }, - }; + return { err: { status: 400, message: `Invalid report reason. Valid reasons are: ${validReasons.join(', ')}` } }; } // Find the message let message; try { message = await MessageModel.findOne({ _id: messageId }); - } catch (error) { - return { - err: { - status: 500, - message: `Error occurred while trying to find the message with ID: ${messageId}`, - }, - }; + } + catch (error) { + return { err: { status: 500, message: `Error occurred while trying to find the message with ID: ${messageId}` } }; } if (!message) { - return { - err: { - status: 404, - message: `No message found with the ID: ${messageId}`, - }, - }; + return { err: { status: 404, message: `No message found with the ID: ${messageId}` } }; } // The receiver of the message is the only one allowed to report it. if (message.receiverId.toString() !== reportingUserId.toString()) { - return { - err: { - status: 403, - message: - "You are not the receiver of this message and hence not allowed to report it", - }, - }; + return { err: { status: 403, message: 'You are not the receiver of this message and hence not allowed to report it' } }; } // Update the report flag and reason @@ -378,28 +271,27 @@ const reportMessage = async (messageId, reason, reportingUserId) => { try { await message.save(); } catch (error) { - return { - err: { status: 500, message: "Error occurred while saving the message" }, - }; + return { err: { status: 500, message: 'Error occurred while saving the message' } }; } - return { successMessage: "Message reported successfully" }; + return { successMessage: 'Message reported successfully' }; }; + /** - * Removes a message by a user. - * - * @param {string} messageId - The ID of the message to be removed. - * @param {string} removingUserId - The ID of the user removing the message. - * - * @returns {Promise} - A promise that resolves to an object. If the function is successful, the object contains a 'successMessage' property with the success message. If an error occurs, the object contains an 'err' property with the status code and error message. - * - * @throws {Object} - If an error occurs, an object is thrown with an 'err' property containing the status code and error message. - */ + * Removes a message by a user. + * + * @param {string} messageId - The ID of the message to be removed. + * @param {string} removingUserId - The ID of the user removing the message. + * + * @returns {Promise} - A promise that resolves to an object. If the function is successful, the object contains a 'successMessage' property with the success message. If an error occurs, the object contains an 'err' property with the status code and error message. + * + * @throws {Object} - If an error occurs, an object is thrown with an 'err' property containing the status code and error message. + */ const removeMessage = async (messageId, removingUserId) => { if (!messageId) { - return { err: { status: 400, message: "Message ID is missing" } }; + return { err: { status: 400, message: 'Message ID is missing' } }; } // Find the message @@ -407,32 +299,16 @@ const removeMessage = async (messageId, removingUserId) => { try { message = await MessageModel.findOne({ _id: messageId }); } catch (error) { - return { - err: { - status: 500, - message: `Error occurred while trying to find the message with ID: ${messageId}`, - }, - }; + return { err: { status: 500, message: `Error occurred while trying to find the message with ID: ${messageId}` } }; } if (!message) { - return { - err: { - status: 404, - message: `No message found with the ID: ${messageId}`, - }, - }; + return { err: { status: 404, message: `No message found with the ID: ${messageId}` } }; } // The sender of the message is the only one allowed to remove it if (message.senderId.toString() !== removingUserId.toString()) { - return { - err: { - status: 403, - message: - "You are not the sender of this message and hence not allowed to remove it", - }, - }; + return { err: { status: 403, message: 'You are not the sender of this message and hence not allowed to remove it' } }; } // Find the chat that contains the message @@ -440,19 +316,12 @@ const removeMessage = async (messageId, removingUserId) => { try { chat = await ChatModel.findOne({ messages: messageId }); } catch (error) { - return { - err: { - status: 500, - message: `Error occurred while trying to find the chat containing the message with ID: ${messageId}`, - }, - }; + return { err: { status: 500, message: `Error occurred while trying to find the chat containing the message with ID: ${messageId}` } }; } // If the removed message was the last message in the chat, update the last message attribute if (chat && chat.lastMessage.toString() === messageId) { - const lastMessageIndex = chat.messages.findIndex( - (msgId) => msgId.toString() === messageId - ); + const lastMessageIndex = chat.messages.findIndex(msgId => msgId.toString() === messageId); if (lastMessageIndex > 0) { chat.lastMessage = chat.messages[lastMessageIndex - 1]; } else { @@ -461,9 +330,7 @@ const removeMessage = async (messageId, removingUserId) => { try { await chat.save(); } catch (error) { - return { - err: { status: 500, message: "Error occurred while saving the chat" }, - }; + return { err: { status: 500, message: 'Error occurred while saving the chat' } }; } } @@ -473,12 +340,10 @@ const removeMessage = async (messageId, removingUserId) => { try { await message.save(); } catch (error) { - return { - err: { status: 500, message: "Error occurred while saving the message" }, - }; + return { err: { status: 500, message: 'Error occurred while saving the message' } }; } - return { successMessage: "Message removed successfully" }; + return { successMessage: 'Message removed successfully' }; }; export { @@ -486,5 +351,5 @@ export { getMessages, getSideBarChats, reportMessage, - removeMessage, -}; + removeMessage +} \ No newline at end of file