refactor: add new hooks for notifications/websockets

filter:sockets.sendNewNotificationToUid - fires before emitting "event:new_notification"

filter:sockets.sendNewPostToUid - fires before emitting "event:new_post"

filter:sockets.sendNewTopicToUid - fires before emitting "event:new_topic"

filter:user.toggleFollow- fires before follow/unfollow
This commit is contained in:
Barış Soner Uşaklı
2024-04-15 11:31:27 -04:00
parent 8f317c01bb
commit d2e042d15b
4 changed files with 51 additions and 25 deletions

View File

@@ -197,9 +197,13 @@ async function pushToUids(uids, notification) {
await db.sortedSetsRemoveRangeByScore(unreadKeys.concat(readKeys), '-inf', cutoff); await db.sortedSetsRemoveRangeByScore(unreadKeys.concat(readKeys), '-inf', cutoff);
const websockets = require('./socket.io'); const websockets = require('./socket.io');
if (websockets.server) { if (websockets.server) {
uids.forEach((uid) => { await Promise.all(uids.map(async (uid) => {
await plugins.hooks.fire('filter:sockets.sendNewNoticationToUid', {
uid,
notification,
});
websockets.in(`uid_${uid}`).emit('event:new_notification', notification); websockets.in(`uid_${uid}`).emit('event:new_notification', notification);
}); }));
} }
} }
@@ -223,7 +227,10 @@ async function pushToUids(uids, notification) {
// Remove uid from recipients list if they have blocked the user triggering the notification // Remove uid from recipients list if they have blocked the user triggering the notification
uids = await User.blocks.filterUids(notification.from, uids); uids = await User.blocks.filterUids(notification.from, uids);
const data = await plugins.hooks.fire('filter:notification.push', { notification: notification, uids: uids }); const data = await plugins.hooks.fire('filter:notification.push', {
notification,
uids,
});
if (!data || !data.notification || !data.uids || !data.uids.length) { if (!data || !data.notification || !data.uids || !data.uids.length) {
return; return;
} }

View File

@@ -28,8 +28,7 @@ SocketHelpers.notifyNew = async function (uid, type, result) {
async function notifyUids(uid, uids, type, result) { async function notifyUids(uid, uids, type, result) {
const post = result.posts[0]; const post = result.posts[0];
const { tid } = post.topic; const { tid, cid } = post.topic;
const { cid } = post.topic;
uids = await privileges.topics.filterUids('topics:read', tid, uids); uids = await privileges.topics.filterUids('topics:read', tid, uids);
const watchStateUids = uids; const watchStateUids = uids;
@@ -49,14 +48,28 @@ async function notifyUids(uid, uids, type, result) {
post.ip = undefined; post.ip = undefined;
data.uidsTo.forEach((toUid) => { await Promise.all(data.uidsTo.map(async (toUid) => {
post.categoryWatchState = categoryWatchStates[toUid]; const copyResult = _.cloneDeep(result);
post.topic.isFollowing = topicFollowState[toUid]; const postToUid = copyResult.posts[0];
websockets.in(`uid_${toUid}`).emit('event:new_post', result); postToUid.categoryWatchState = categoryWatchStates[toUid];
if (result.topic && type === 'newTopic') { postToUid.topic.isFollowing = topicFollowState[toUid];
websockets.in(`uid_${toUid}`).emit('event:new_topic', result.topic);
await plugins.hooks.fire('filter:sockets.sendNewPostToUid', {
uid: toUid,
uidFrom: uid,
post: postToUid,
});
websockets.in(`uid_${toUid}`).emit('event:new_post', copyResult);
if (copyResult.topic && type === 'newTopic') {
await plugins.hooks.fire('filter:sockets.sendNewTopicToUid', {
uid: toUid,
uidFrom: uid,
topic: copyResult.topic,
});
websockets.in(`uid_${toUid}`).emit('event:new_topic', copyResult.topic);
} }
}); }));
} }
async function getWatchStates(uids, tid, cid) { async function getWatchStates(uids, tid, cid) {

View File

@@ -21,31 +21,37 @@ module.exports = function (User) {
if (parseInt(uid, 10) === parseInt(theiruid, 10)) { if (parseInt(uid, 10) === parseInt(theiruid, 10)) {
throw new Error('[[error:you-cant-follow-yourself]]'); throw new Error('[[error:you-cant-follow-yourself]]');
} }
const exists = await User.exists(theiruid); const [exists, isFollowing] = await Promise.all([
User.exists(theiruid),
User.isFollowing(uid, theiruid),
]);
if (!exists) { if (!exists) {
throw new Error('[[error:no-user]]'); throw new Error('[[error:no-user]]');
} }
const isFollowing = await User.isFollowing(uid, theiruid);
await plugins.hooks.fire('filter:user.toggleFollow', {
type,
uid,
theiruid,
isFollowing,
});
if (type === 'follow') { if (type === 'follow') {
if (isFollowing) { if (isFollowing) {
throw new Error('[[error:already-following]]'); throw new Error('[[error:already-following]]');
} }
const now = Date.now(); const now = Date.now();
await Promise.all([ await db.sortedSetAddBulk([
db.sortedSetAddBulk([ [`following:${uid}`, now, theiruid],
[`following:${uid}`, now, theiruid], [`followers:${theiruid}`, now, uid],
[`followers:${theiruid}`, now, uid],
]),
]); ]);
} else { } else {
if (!isFollowing) { if (!isFollowing) {
throw new Error('[[error:not-following]]'); throw new Error('[[error:not-following]]');
} }
await Promise.all([ await db.sortedSetRemoveBulk([
db.sortedSetRemoveBulk([ [`following:${uid}`, theiruid],
[`following:${uid}`, theiruid], [`followers:${theiruid}`, uid],
[`followers:${theiruid}`, uid],
]),
]); ]);
} }

View File

@@ -214,7 +214,7 @@ UserNotifications.sendTopicNotificationToFollowers = async function (uid, topicD
const notifObj = await notifications.create({ const notifObj = await notifications.create({
type: 'new-topic', type: 'new-topic',
bodyShort: `[[notifications:user-posted-topic, ${postData.user.displayname}, ${title}]]`, bodyShort: translator.compile('notifications:user-posted-topic', postData.user.displayname, title),
bodyLong: postData.content, bodyLong: postData.content,
pid: postData.pid, pid: postData.pid,
path: `/post/${postData.pid}`, path: `/post/${postData.pid}`,