ChatManager = class ChatManager { /** * Constructor. * * @param {Collection} chats * A Chats collection instance. * * @returns {void} */ constructor(chats) { this.chats = chats; } /** * Order two comparable objects (usually strings) as min, max. * * @param {Object} s1 * The first object. * @param {Object} s2 * The second object. * @returns {*[]} * An array of the two objects, minimum first, maximum last. */ static ordered(s1, s2) { let id1; let id2; // Ensure ordering as id1 <= id2. Equality should not happen, but handle it correctly nonetheless. if (s1 <= s2) { id1 = s1; id2 = s2; } else { id1 = s2; id2 = s1; } return [id1, id2]; } /** * Find the id of a chat between two users. * * @param {String} myId * The current user id. * @param {String} otherUserId * The id of an other user. * @param {Session} session * The session global. * * @returns {void} */ assignChatId(myId, otherUserId, session) { let [user1Id, user2Id] = ChatManager.ordered(myId, otherUserId); // Since ids are ordered, we do not need a $or. const chat = this.chats.findOne({ user1Id, user2Id }); Meteor._debug("filter", { user1Id, user2Id }, chat); // No chat matching the filter - need to insert a new one. if (!chat) { Meteor.call("chats.insert", { user1Id, user2Id }, function (err, chatId) { if (err) { throw new Meteor.Error("access-denied", "Could not insert new chat."); } session.set("chatId", chatId); console.log("-- No chat found between " + user1Id + " and " + user2Id + ". Created " + chatId); }); } // There is a chat going already - use that. else { const chatId = chat._id; session.set("chatId", chatId); console.log("-- Chat " + chatId + " found between " + user1Id + " and " + user2Id + "."); } } /** * Meteor Method: insert a chat. * * @param {Object} chat * A chat object, with user1Id, user2Id, and messages keys. * * @returns {String} * The id of the inserted chat document. */ static insertMethod(chat) { check(chat, { user1Id: String, user2Id: String }); chat.messages = []; const chatId = Chats.insert(chat); // Meteor._debug("chats.insert", chat, chatId); return chatId; } /** * Meteor Method: push a message to a chat. * * @param {Object} chat * A chat object, with user1Id, user2Id, and messages keys. * @param {String} chatValue * The message to push. * * @returns {void} */ static pushMessageMethod(chat, chatValue) { check(chat, { _id: String, user1Id: String, user2Id: String, messages: Array }); // is a good idea to insert data straight from the form // (i.e. the user) into the database?? certainly not. // push adds the message to the end of the array const changes = { $push: { messages: { text: chatValue, sender: this.userId } } }; // update the chat object in the database. Chats.update(chat._id, changes); } };