feat: topic crossposts generate topic events, #13908

This commit is contained in:
Julian Lam
2026-01-19 19:06:23 -05:00
parent e2e1744824
commit 0c79eaa529
3 changed files with 21 additions and 2 deletions

View File

@@ -74,6 +74,8 @@
"user-referenced-topic-on": "%1 <a href=\"%2\">referenced</a> this topic on %3", "user-referenced-topic-on": "%1 <a href=\"%2\">referenced</a> this topic on %3",
"user-forked-topic-ago": "%1 <a href=\"%2\">forked</a> this topic %3", "user-forked-topic-ago": "%1 <a href=\"%2\">forked</a> this topic %3",
"user-forked-topic-on": "%1 <a href=\"%2\">forked</a> this topic on %3", "user-forked-topic-on": "%1 <a href=\"%2\">forked</a> this topic on %3",
"user-crossposted-topic-ago": "%1 crossposted this topic to %2 %3",
"user-crossposted-topic-on": "%1 crossposted this topicto %2 on %3",
"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.",

View File

@@ -98,8 +98,9 @@ Crossposts.add = async function (tid, cid, uid) {
db.setObject(`crosspost:${crosspostId}`, { uid, tid, cid, timestamp: now }), db.setObject(`crosspost:${crosspostId}`, { uid, tid, cid, timestamp: now }),
db.sortedSetAdd(`tid:${tid}:crossposts`, now, crosspostId), db.sortedSetAdd(`tid:${tid}:crossposts`, now, crosspostId),
uid > 0 ? db.sortedSetAdd(`uid:${uid}:crossposts`, now, crosspostId) : false, uid > 0 ? db.sortedSetAdd(`uid:${uid}:crossposts`, now, crosspostId) : false,
topics.events.log(tid, { uid, type: 'crosspost', toCid: cid }),
]); ]);
await categories.onTopicsMoved([cid]); await categories.onTopicsMoved([cid]); // must be done after
} else { } else {
throw new Error('[[error:topic-already-crossposted]]'); throw new Error('[[error:topic-already-crossposted]]');
} }
@@ -146,6 +147,10 @@ Crossposts.remove = async function (tid, cid, uid) {
]); ]);
await categories.onTopicsMoved([cid]); await categories.onTopicsMoved([cid]);
topics.events.find(tid, { uid, toCid: cid, type: 'crosspost' }).then((eventIds) => {
topics.events.purge(tid, eventIds);
});
crossposts = await Crossposts.get(tid); crossposts = await Crossposts.get(tid);
return crossposts; return crossposts;
}; };

View File

@@ -73,6 +73,10 @@ Events._types = {
icon: 'fa-code-fork', icon: 'fa-code-fork',
translation: async (event, language) => translateEventArgs(event, language, 'topic:user-forked-topic', renderUser(event), `${relative_path}${event.href}`, renderTimeago(event)), translation: async (event, language) => translateEventArgs(event, language, 'topic:user-forked-topic', renderUser(event), `${relative_path}${event.href}`, renderTimeago(event)),
}, },
crosspost: {
icon: 'fa-square-arrow-up-right',
translation: async (event, language) => translateEventArgs(event, language, 'topic:user-crossposted-topic', renderUser(event), renderCategory(event.toCategory), renderTimeago(event)),
},
}; };
Events.init = async () => { Events.init = async () => {
@@ -117,6 +121,10 @@ function renderUser(event) {
return `${helpers.buildAvatar(user, '16px', true)} <a href="${relative_path}/user/${user.userslug}">${user.displayname}</a>`; return `${helpers.buildAvatar(user, '16px', true)} <a href="${relative_path}/user/${user.userslug}">${user.displayname}</a>`;
} }
function renderCategory(category) {
return `${helpers.buildCategoryLabel(category, 'a')}`;
}
function renderTimeago(event) { function renderTimeago(event) {
return `<span class="timeago timeline-text" title="${event.timestampISO}"></span>`; return `<span class="timeago timeline-text" title="${event.timestampISO}"></span>`;
} }
@@ -183,9 +191,10 @@ async function addEventsFromPostQueue(tid, uid, events) {
} }
async function modifyEvent({ uid, events }) { async function modifyEvent({ uid, events }) {
const [users, fromCategories, userSettings] = await Promise.all([ const [users, fromCategories, toCategories, userSettings] = await Promise.all([
getUserInfo(events.map(event => event.uid).filter(Boolean)), getUserInfo(events.map(event => event.uid).filter(Boolean)),
getCategoryInfo(events.map(event => event.fromCid).filter(Boolean)), getCategoryInfo(events.map(event => event.fromCid).filter(Boolean)),
getCategoryInfo(events.map(event => event.toCid).filter(Boolean)),
user.getSettings(uid), user.getSettings(uid),
]); ]);
@@ -215,6 +224,9 @@ async function modifyEvent({ uid, events }) {
if (event.hasOwnProperty('fromCid')) { if (event.hasOwnProperty('fromCid')) {
event.fromCategory = fromCategories[event.fromCid]; event.fromCategory = fromCategories[event.fromCid];
} }
if (event.hasOwnProperty('toCid')) {
event.toCategory = toCategories[event.toCid];
}
Object.assign(event, Events._types[event.type]); Object.assign(event, Events._types[event.type]);
}); });