feat(topic-events): support for uids in topic event payloads

v1.18.x
Julian Lam 4 years ago
parent 425eca145b
commit 611d1f872d

@ -115,6 +115,8 @@
"guest": "Guest", "guest": "Guest",
"guests": "Guests", "guests": "Guests",
"former_user": "A Former User", "former_user": "A Former User",
"system-user": "System",
"unknown-user": "Unknown user",
"updated.title": "Forum Updated", "updated.title": "Forum Updated",
"updated.message": "This forum has just been updated to the latest version. Click here to refresh the page.", "updated.message": "This forum has just been updated to the latest version. Click here to refresh the page.",

@ -22,10 +22,8 @@
"login-to-view": "🔒 Log in to view", "login-to-view": "🔒 Log in to view",
"edit": "Edit", "edit": "Edit",
"delete": "Delete", "delete": "Delete",
"deleted": "Deleted",
"purge": "Purge", "purge": "Purge",
"restore": "Restore", "restore": "Restore",
"restored": "Restored",
"move": "Move", "move": "Move",
"change-owner": "Change Owner", "change-owner": "Change Owner",
"fork": "Fork", "fork": "Fork",
@ -33,16 +31,21 @@
"share": "Share", "share": "Share",
"tools": "Tools", "tools": "Tools",
"locked": "Locked", "locked": "Locked",
"unlocked": "Unlocked",
"pinned": "Pinned", "pinned": "Pinned",
"pinned-with-expiry": "Pinned until %1", "pinned-with-expiry": "Pinned until %1",
"unpinned": "Unpinned",
"moved": "Moved", "moved": "Moved",
"moved-from": "Moved from %1", "moved-from": "Moved from %1",
"copy-ip": "Copy IP", "copy-ip": "Copy IP",
"ban-ip": "Ban IP", "ban-ip": "Ban IP",
"view-history": "Edit History", "view-history": "Edit History",
"locked-by": "Locked by",
"unlocked-by": "Unlocked by",
"pinned-by": "Pinned by",
"unpinned-by": "Unpinned by",
"deleted-by": "Deleted by",
"restored-by": "Restored by",
"bookmark_instructions" : "Click here to return to the last read post in this thread.", "bookmark_instructions" : "Click here to return to the last read post in this thread.",
"flag-post": "Flag this post", "flag-post": "Flag this post",

@ -1,38 +1,44 @@
'use strict'; 'use strict';
const db = require('../database'); const db = require('../database');
const user = require('../user');
const plugins = require('../plugins'); const plugins = require('../plugins');
const Events = module.exports; const Events = module.exports;
/**
* Note: Plugins!
*
* You are able to define additional topic event types here.
* Register to hook `filter:topicEvents.init` and append your custom type to the `types` object.
* You can then log a custom topic event by calling `topics.events.log(tid, { type, uid });`
* `uid` is optional; if you pass in a valid uid in the payload, the user avatar/username will be rendered as part of the event text
*
*/
Events._types = { Events._types = {
pin: { pin: {
icon: 'fa-thumb-tack', icon: 'fa-thumb-tack',
text: '[[topic:pinned]]', text: '[[topic:pinned-by]]',
},
pin_expiry: {
icon: 'fa-thumb-tack',
text: '[[topic:pinned-with-expiry]]',
}, },
unpin: { unpin: {
icon: 'fa-thumb-tack', icon: 'fa-thumb-tack',
text: '[[topic:unpinned]]', text: '[[topic:unpinned-by]]',
}, },
lock: { lock: {
icon: 'fa-lock', icon: 'fa-lock',
text: '[[topic:locked]]', text: '[[topic:locked-by]]',
}, },
unlock: { unlock: {
icon: 'fa-unlock', icon: 'fa-unlock',
text: '[[topic:unlocked]]', text: '[[topic:unlocked-by]]',
}, },
delete: { delete: {
icon: 'fa-trash', icon: 'fa-trash',
text: '[[topic:deleted]]', text: '[[topic:deleted-by]]',
}, },
restore: { restore: {
icon: 'fa-trash-o', icon: 'fa-trash-o',
text: '[[topic:restored]]', text: '[[topic:restored-by]]',
}, },
}; };
Events._ready = false; Events._ready = false;
@ -57,11 +63,20 @@ Events.get = async (tid) => {
const eventIds = await db.getSortedSetRangeWithScores(`topic:${tid}:events`, 0, -1); const eventIds = await db.getSortedSetRangeWithScores(`topic:${tid}:events`, 0, -1);
const keys = eventIds.map(obj => `topicEvent:${obj.value}`); const keys = eventIds.map(obj => `topicEvent:${obj.value}`);
const timestamps = eventIds.map(obj => obj.score); const timestamps = eventIds.map(obj => obj.score);
const events = await db.getObjects(keys); let events = await db.getObjects(keys);
const users = await getUserInfo(events.map(event => event.uid).filter(Boolean));
// Remove events whose types no longer exist (e.g. plugin uninstalled)
events = events.filter(event => Events._types.hasOwnProperty(event.type));
// Add user & metadata
events.forEach((event, idx) => { events.forEach((event, idx) => {
event.id = parseInt(eventIds[idx].value, 10); event.id = parseInt(eventIds[idx].value, 10);
event.timestamp = timestamps[idx]; event.timestamp = timestamps[idx];
event.timestampISO = new Date(timestamps[idx]).toISOString(); event.timestampISO = new Date(timestamps[idx]).toISOString();
if (event.hasOwnProperty('uid')) {
event.user = users.get(event.uid === 'system' ? 'system' : parseInt(event.uid, 10));
}
Object.assign(event, Events._types[event.type]); Object.assign(event, Events._types[event.type]);
}); });
@ -69,6 +84,17 @@ Events.get = async (tid) => {
return events; return events;
}; };
async function getUserInfo(uids) {
uids = uids.filter((uid, idx) => !isNaN(parseInt(uid, 10)) && uids.indexOf(uid) === idx);
const userData = await user.getUsersFields(uids, ['picture', 'username', 'userslug']);
const userMap = userData.reduce((memo, cur) => memo.set(cur.uid, cur), new Map());
userMap.set('system', {
system: true,
});
return userMap;
}
Events.log = async (tid, payload) => { Events.log = async (tid, payload) => {
await Events.init(); await Events.init();
const topics = require('.'); const topics = require('.');

Loading…
Cancel
Save