feat(topic-events): work in progress topic events logic and client-side implementation
parent
faf5960373
commit
ab2e1ecb40
@ -0,0 +1,90 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const db = require('../database');
|
||||||
|
const plugins = require('../plugins');
|
||||||
|
|
||||||
|
const Events = module.exports;
|
||||||
|
|
||||||
|
Events._types = {
|
||||||
|
pin: {
|
||||||
|
icon: 'fa-thumb-tack',
|
||||||
|
text: '[[topic:pinned]]',
|
||||||
|
},
|
||||||
|
pin_expiry: {
|
||||||
|
icon: 'fa-thumb-tack',
|
||||||
|
text: '[[topic:pinned-with-expiry]]',
|
||||||
|
},
|
||||||
|
unpin: {
|
||||||
|
icon: 'fa-thumb-tack',
|
||||||
|
text: '[[topic:unpinned]]',
|
||||||
|
},
|
||||||
|
lock: {
|
||||||
|
icon: 'fa-lock',
|
||||||
|
text: '[[topic:locked]]',
|
||||||
|
},
|
||||||
|
unlock: {
|
||||||
|
icon: 'fa-unlock',
|
||||||
|
text: '[[topic:unlocked]]',
|
||||||
|
},
|
||||||
|
delete: {
|
||||||
|
icon: 'fa-trash',
|
||||||
|
text: '[[topic:deleted]]',
|
||||||
|
},
|
||||||
|
restore: {
|
||||||
|
icon: 'fa-trash-o',
|
||||||
|
text: '[[topic:restored]]',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Events._ready = false;
|
||||||
|
|
||||||
|
Events.init = async () => {
|
||||||
|
if (!Events._ready) {
|
||||||
|
// Allow plugins to define additional topic event types
|
||||||
|
const { types } = await plugins.hooks.fire('filter:topicEvents.init', { types: Events._types });
|
||||||
|
Events._types = types;
|
||||||
|
Events._ready = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Events.get = async (tid) => {
|
||||||
|
await Events.init();
|
||||||
|
const topics = require('.');
|
||||||
|
|
||||||
|
if (!await topics.exists(tid)) {
|
||||||
|
throw new Error('[[error:no-topic]]');
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventIds = await db.getSortedSetRangeWithScores(`topic:${tid}:events`, 0, -1);
|
||||||
|
const keys = eventIds.map(obj => `topicEvent:${obj.value}`);
|
||||||
|
const timestamps = eventIds.map(obj => obj.score);
|
||||||
|
const events = await db.getObjects(keys);
|
||||||
|
events.forEach((event, idx) => {
|
||||||
|
event.id = parseInt(eventIds[idx].value, 10);
|
||||||
|
event.timestamp = timestamps[idx];
|
||||||
|
event.timestampISO = new Date(timestamps[idx]).toISOString();
|
||||||
|
|
||||||
|
Object.assign(event, Events._types[event.type]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return events;
|
||||||
|
};
|
||||||
|
|
||||||
|
Events.log = async (tid, payload) => {
|
||||||
|
await Events.init();
|
||||||
|
const topics = require('.');
|
||||||
|
const { type } = payload;
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
if (!Events._types.hasOwnProperty(type)) {
|
||||||
|
throw new Error(`[[error:topic-event-unrecognized, ${type}]]`);
|
||||||
|
} else if (!await topics.exists(tid)) {
|
||||||
|
throw new Error('[[error:no-topic]]');
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventId = await db.incrObjectField('global', 'nextTopicEventId');
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
db.setObject(`topicEvent:${eventId}`, payload),
|
||||||
|
db.sortedSetAdd(`topic:${tid}:events`, now, eventId),
|
||||||
|
]);
|
||||||
|
};
|
Loading…
Reference in New Issue