-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcontroller.js
More file actions
64 lines (55 loc) · 3.05 KB
/
Copy pathcontroller.js
File metadata and controls
64 lines (55 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
const { SCHEMA_TYPE } = require("../../Config/schemaType");
const { MongoDbCrudOpration } = require("../../utils/mongo-handler/mongoQueries");
const mongoose = require("mongoose");
const logger = require("../../Config/loggerConfig");
const socketEmitter = require('../../event/socketEventEmitter');
const { validateReactionInput } = require('./helpers/reactionRules');
// Emoji reactions on tasks and comments. Reactions live as an embedded
// array on the target document — `reactions: [{ emoji, userId, createdAt }]`,
// one entry per user+emoji — so reads need no extra query and socket
// updates carry them automatically. Toggle semantics: present → pull,
// absent → push.
/**
* POST /api/v2/reactions
* body: { targetType: 'task'|'comment', targetId, emoji, userData, isProjectComment? }
* companyId comes from the verified header (same convention as /api/v2/tasks/bulk).
*/
exports.toggleReaction = async (req, res) => {
try {
const companyId = req.headers['companyid'] || '';
const { targetType, targetId, emoji, userData, isProjectComment = false } = req.body || {};
const userId = userData && (userData.id || userData._id) ? String(userData.id || userData._id) : '';
const check = validateReactionInput({ companyId, targetType, targetId, emoji, userId });
if (!check.valid) {
return res.send({ status: false, statusText: check.reason });
}
const schemaType = targetType === 'task' ? SCHEMA_TYPE.TASKS : SCHEMA_TYPE.COMMENTS;
const targetObjId = new mongoose.Types.ObjectId(targetId);
const doc = await MongoDbCrudOpration(companyId, { type: schemaType, data: [{ _id: targetObjId }] }, 'findOne');
if (!doc) {
return res.send({ status: false, statusText: 'Target not found.' });
}
const alreadyReacted = (doc.reactions || []).some((reaction) => reaction.emoji === emoji && String(reaction.userId) === userId);
const updateObj = alreadyReacted
? { $pull: { reactions: { emoji, userId } } }
: { $push: { reactions: { emoji, userId, createdAt: new Date() } } };
const updated = await MongoDbCrudOpration(companyId, {
type: schemaType,
data: [{ _id: targetObjId }, updateObj, { returnDocument: 'after' }],
}, 'findOneAndUpdate');
const updatedFields = { reactions: updated?.reactions || [] };
if (targetType === 'task') {
socketEmitter.emit('update', { type: "update", data: updated, updatedFields, module: 'task' });
} else {
socketEmitter.emit('update', { type: "update", data: updated, updatedFields, module: isProjectComment ? 'comments_project' : 'comments' });
}
return res.send({
status: true,
statusText: alreadyReacted ? 'Reaction removed.' : 'Reaction added.',
data: { reactions: updated?.reactions || [] },
});
} catch (error) {
logger.error(`ERROR in toggle reaction: ${error.message}`);
return res.send({ status: false, statusText: error.message });
}
};