mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 15:17:25 +01:00
Move Chat to Model (#9703)
* Began moving group chat to separate model * Fixed lint issue * Updated delete chat with new model * Updated flag chat to support model * Updated like chat to use model * Fixed duplicate code and chat messages * Added note about concat chat * Updated clear flags to user new model * Updated more chat checks when loading get group * Fixed spell test and back save * Moved get chat to json method * Updated flagging with new chat model * Added missing await * Fixed chat user styles. Fixed spell group test * Added new model to quest chat and group plan chat * Removed extra timestamps. Added limit check for group plans * Updated tests * Synced id fields * Fixed id creation * Add meta and fixed tests * Fixed group quest accept test * Updated puppeteer * Added migration * Export vars * Updated comments
This commit is contained in:
committed by
Sabe Jones
parent
0ec1a91774
commit
7d7fe6047c
@@ -1,12 +1,12 @@
|
||||
import { authWithHeaders } from '../../middlewares/auth';
|
||||
import { model as Group } from '../../models/group';
|
||||
import { model as User } from '../../models/user';
|
||||
import { model as Chat } from '../../models/chat';
|
||||
import {
|
||||
BadRequest,
|
||||
NotFound,
|
||||
NotAuthorized,
|
||||
} from '../../libs/errors';
|
||||
import _ from 'lodash';
|
||||
import { removeFromArray } from '../../libs/collectionManipulators';
|
||||
import { getUserInfo, getGroupUrl, sendTxn } from '../../libs/email';
|
||||
import slack from '../../libs/slack';
|
||||
@@ -70,10 +70,12 @@ api.getChat = {
|
||||
let validationErrors = req.validationErrors();
|
||||
if (validationErrors) throw validationErrors;
|
||||
|
||||
let group = await Group.getGroup({user, groupId: req.params.groupId, fields: 'chat'});
|
||||
const groupId = req.params.groupId;
|
||||
let group = await Group.getGroup({user, groupId, fields: 'chat'});
|
||||
if (!group) throw new NotFound(res.t('groupNotFound'));
|
||||
|
||||
res.respond(200, Group.toJSONCleanChat(group, user).chat);
|
||||
const groupChat = await Group.toJSONCleanChat(group, user);
|
||||
res.respond(200, groupChat.chat);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -164,35 +166,35 @@ api.postChat = {
|
||||
}
|
||||
}
|
||||
|
||||
let lastClientMsg = req.query.previousMsg;
|
||||
const chatRes = await Group.toJSONCleanChat(group, user);
|
||||
const lastClientMsg = req.query.previousMsg;
|
||||
chatUpdated = lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg ? true : false;
|
||||
|
||||
if (group.checkChatSpam(user)) {
|
||||
throw new NotAuthorized(res.t('messageGroupChatSpam'));
|
||||
}
|
||||
|
||||
let newChatMessage = group.sendChat(req.body.message, user);
|
||||
|
||||
let toSave = [group.save()];
|
||||
const newChatMessage = group.sendChat(req.body.message, user);
|
||||
let toSave = [newChatMessage.save()];
|
||||
|
||||
if (group.type === 'party') {
|
||||
user.party.lastMessageSeen = group.chat[0].id;
|
||||
user.party.lastMessageSeen = newChatMessage.id;
|
||||
toSave.push(user.save());
|
||||
}
|
||||
|
||||
let [savedGroup] = await Promise.all(toSave);
|
||||
await Promise.all(toSave);
|
||||
|
||||
// realtime chat is only enabled for private groups (for now only for parties)
|
||||
if (savedGroup.privacy === 'private' && savedGroup.type === 'party') {
|
||||
// @TODO: rethink if we want real-time
|
||||
if (group.privacy === 'private' && group.type === 'party') {
|
||||
// req.body.pusherSocketId is sent from official clients to identify the sender user's real time socket
|
||||
// see https://pusher.com/docs/server_api_guide/server_excluding_recipients
|
||||
pusher.trigger(`presencegroup${savedGroup._id}`, 'newchat', newChatMessage, req.body.pusherSocketId);
|
||||
pusher.trigger(`presence-group-${group._id}`, 'new-chat', newChatMessage, req.body.pusherSocketId);
|
||||
}
|
||||
|
||||
if (chatUpdated) {
|
||||
res.respond(200, {chat: Group.toJSONCleanChat(savedGroup, user).chat});
|
||||
res.respond(200, {chat: chatRes.chat});
|
||||
} else {
|
||||
res.respond(200, {message: savedGroup.chat[0]});
|
||||
res.respond(200, {message: newChatMessage});
|
||||
}
|
||||
|
||||
group.sendGroupChatReceivedWebhooks(newChatMessage);
|
||||
@@ -233,22 +235,16 @@ api.likeChat = {
|
||||
let group = await Group.getGroup({user, groupId});
|
||||
if (!group) throw new NotFound(res.t('groupNotFound'));
|
||||
|
||||
let message = _.find(group.chat, {id: req.params.chatId});
|
||||
let message = await Chat.findOne({id: req.params.chatId}).exec();
|
||||
if (!message) throw new NotFound(res.t('messageGroupChatNotFound'));
|
||||
// TODO correct this error type
|
||||
// @TODO correct this error type
|
||||
if (message.uuid === user._id) throw new NotFound(res.t('messageGroupChatLikeOwnMessage'));
|
||||
|
||||
let update = {$set: {}};
|
||||
|
||||
if (!message.likes) message.likes = {};
|
||||
|
||||
message.likes[user._id] = !message.likes[user._id];
|
||||
update.$set[`chat.$.likes.${user._id}`] = message.likes[user._id];
|
||||
message.markModified('likes');
|
||||
await message.save();
|
||||
|
||||
await Group.update(
|
||||
{_id: group._id, 'chat.id': message.id},
|
||||
update
|
||||
).exec();
|
||||
res.respond(200, message); // TODO what if the message is flagged and shouldn't be returned?
|
||||
},
|
||||
};
|
||||
@@ -334,15 +330,11 @@ api.clearChatFlags = {
|
||||
});
|
||||
if (!group) throw new NotFound(res.t('groupNotFound'));
|
||||
|
||||
let message = _.find(group.chat, {id: chatId});
|
||||
let message = await Chat.findOne({id: chatId}).exec();
|
||||
if (!message) throw new NotFound(res.t('messageGroupChatNotFound'));
|
||||
|
||||
message.flagCount = 0;
|
||||
|
||||
await Group.update(
|
||||
{_id: group._id, 'chat.id': message.id},
|
||||
{$set: {'chat.$.flagCount': message.flagCount}}
|
||||
).exec();
|
||||
await message.save();
|
||||
|
||||
let adminEmailContent = getUserInfo(user, ['email']).email;
|
||||
let authorEmail = getAuthorEmailFromMessage(message);
|
||||
@@ -466,25 +458,22 @@ api.deleteChat = {
|
||||
let group = await Group.getGroup({user, groupId, fields: 'chat'});
|
||||
if (!group) throw new NotFound(res.t('groupNotFound'));
|
||||
|
||||
let message = _.find(group.chat, {id: chatId});
|
||||
let message = await Chat.findOne({id: chatId}).exec();
|
||||
if (!message) throw new NotFound(res.t('messageGroupChatNotFound'));
|
||||
|
||||
if (user._id !== message.uuid && !user.contributor.admin) {
|
||||
throw new NotAuthorized(res.t('onlyCreatorOrAdminCanDeleteChat'));
|
||||
}
|
||||
|
||||
let lastClientMsg = req.query.previousMsg;
|
||||
let chatUpdated = lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg ? true : false;
|
||||
const chatRes = await Group.toJSONCleanChat(group, user);
|
||||
const lastClientMsg = req.query.previousMsg;
|
||||
const chatUpdated = lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg ? true : false;
|
||||
|
||||
await Group.update(
|
||||
{_id: group._id},
|
||||
{$pull: {chat: {id: chatId}}}
|
||||
).exec();
|
||||
await Chat.remove({_id: message._id}).exec();
|
||||
|
||||
if (chatUpdated) {
|
||||
let chatRes = Group.toJSONCleanChat(group, user).chat;
|
||||
removeFromArray(chatRes, {id: chatId});
|
||||
res.respond(200, chatRes);
|
||||
removeFromArray(chatRes.chat, {id: chatId});
|
||||
res.respond(200, chatRes.chat);
|
||||
} else {
|
||||
res.respond(200, {});
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ api.getGroup = {
|
||||
throw new NotFound(res.t('groupNotFound'));
|
||||
}
|
||||
|
||||
let groupJson = Group.toJSONCleanChat(group, user);
|
||||
let groupJson = await Group.toJSONCleanChat(group, user);
|
||||
|
||||
if (groupJson.leader === user._id) {
|
||||
groupJson.purchased.plan = group.purchased.plan.toObject();
|
||||
@@ -456,7 +456,7 @@ api.updateGroup = {
|
||||
_.assign(group, _.merge(group.toObject(), Group.sanitizeUpdate(req.body)));
|
||||
|
||||
let savedGroup = await group.save();
|
||||
let response = Group.toJSONCleanChat(savedGroup, user);
|
||||
let response = await Group.toJSONCleanChat(savedGroup, user);
|
||||
|
||||
// If the leader changed fetch new data, otherwise use authenticated user
|
||||
if (response.leader !== user._id) {
|
||||
@@ -625,7 +625,7 @@ api.joinGroup = {
|
||||
|
||||
promises = await Promise.all(promises);
|
||||
|
||||
let response = Group.toJSONCleanChat(promises[0], user);
|
||||
let response = await Group.toJSONCleanChat(promises[0], user);
|
||||
let leader = await User.findById(response.leader).select(nameFields).exec();
|
||||
if (leader) {
|
||||
response.leader = leader.toJSON({minimize: true});
|
||||
|
||||
@@ -421,7 +421,8 @@ api.abortQuest = {
|
||||
if (user._id !== group.leader && user._id !== group.quest.leader) throw new NotAuthorized(res.t('onlyLeaderAbortQuest'));
|
||||
|
||||
let questName = questScrolls[group.quest.key].text('en');
|
||||
group.sendChat(`\`${user.profile.name} aborted the party quest ${questName}.\``);
|
||||
const newChatMessage = group.sendChat(`\`${user.profile.name} aborted the party quest ${questName}.\``);
|
||||
await newChatMessage.save();
|
||||
|
||||
let memberUpdates = User.update({
|
||||
'party._id': groupId,
|
||||
|
||||
@@ -195,13 +195,15 @@ api.assignTask = {
|
||||
|
||||
if (canNotEditTasks(group, user, assignedUserId)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
|
||||
|
||||
let promises = [];
|
||||
|
||||
// User is claiming the task
|
||||
if (user._id === assignedUserId) {
|
||||
let message = res.t('userIsClamingTask', {username: user.profile.name, task: task.text});
|
||||
group.sendChat(message);
|
||||
const newMessage = group.sendChat(message);
|
||||
promises.push(newMessage.save());
|
||||
}
|
||||
|
||||
let promises = [];
|
||||
promises.push(group.syncTask(task, assignedUser));
|
||||
promises.push(group.save());
|
||||
await Promise.all(promises);
|
||||
|
||||
@@ -130,8 +130,8 @@ api.castSpell = {
|
||||
|
||||
if (party && !spell.silent) {
|
||||
let message = `\`${user.profile.name} casts ${spell.text()}${targetType === 'user' ? ` on ${partyMembers.profile.name}` : ' for the party'}.\``;
|
||||
party.sendChat(message);
|
||||
await party.save();
|
||||
const newChatMessage = party.sendChat(message);
|
||||
await newChatMessage.save();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user