import { Server as SocketIOServer } from "socket.io"; import Message from "./model/MessagesModel.js"; import Channel from "./model/ChannelModel.js"; const setupSocket = (server) => { const io = new SocketIOServer(server, { cors: { origin: process.env.ORIGIN, methods: ["GET", "POST"], credentials: true, }, }); const userSocketMap = new Map(); const addChannelNotify = async (channel) => { if (channel && channel.members) { channel.members.forEach((member) => { const memberSocketId = userSocketMap.get(member.toString()); if (memberSocketId) { io.to(memberSocketId).emit("new-channel-added", channel); } }); } }; const sendMessage = async (message) => { const recipientSocketId = userSocketMap.get(message.recipient); const senderSocketId = userSocketMap.get(message.sender); // Create the message const createdMessage = await Message.create(message); // Find the created message by its ID and populate sender and recipient details const messageData = await Message.findById(createdMessage._id) .populate("sender", "id email firstName lastName image color") .populate("recipient", "id email firstName lastName image color") .exec(); if (recipientSocketId) { io.to(recipientSocketId).emit("receiveMessage", messageData); } // Optionally, send the message back to the sender (e.g., for message confirmation) if (senderSocketId) { io.to(senderSocketId).emit("receiveMessage", messageData); } }; const sendChannelMessage = async (message) => { const { channelId, sender, content, messageType, fileUrl } = message; // Create and save the message const createdMessage = await Message.create({ sender, recipient: null, // Channel messages don't have a single recipient content, messageType, timestamp: new Date(), fileUrl, }); const messageData = await Message.findById(createdMessage._id) .populate("sender", "id email firstName lastName image color") .exec(); // Add message to the channel await Channel.findByIdAndUpdate(channelId, { $push: { messages: createdMessage._id }, }); // Fetch all members of the channel const channel = await Channel.findById(channelId).populate("members"); const finalData = { ...messageData._doc, channelId: channel._id }; if (channel && channel.members) { channel.members.forEach((member) => { const memberSocketId = userSocketMap.get(member._id.toString()); if (memberSocketId) { io.to(memberSocketId).emit("recieve-channel-message", finalData); } }); const adminSocketId = userSocketMap.get(channel.admin._id.toString()); if (adminSocketId) { io.to(adminSocketId).emit("recieve-channel-message", finalData); } } }; const disconnect = (socket) => { console.log("Client disconnected", socket.id); for (const [userId, socketId] of userSocketMap.entries()) { if (socketId === socket.id) { userSocketMap.delete(userId); break; } } }; io.on("connection", (socket) => { const userId = socket.handshake.query.userId; if (userId) { userSocketMap.set(userId, socket.id); console.log(`User connected: ${userId} with socket ID: ${socket.id}`); } else { console.log("User ID not provided during connection."); } socket.on("add-channel-notify", addChannelNotify); socket.on("sendMessage", sendMessage); socket.on("send-channel-message", sendChannelMessage); socket.on("disconnect", () => disconnect(socket)); }); }; export default setupSocket;