From 0c79eaa529e7f0265f0cd5339a305593f1292f61 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 19 Jan 2026 19:06:23 -0500 Subject: [PATCH] feat: topic crossposts generate topic events, #13908 --- public/language/en-GB/topic.json | 2 ++ src/topics/crossposts.js | 7 ++++++- src/topics/events.js | 14 +++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/public/language/en-GB/topic.json b/public/language/en-GB/topic.json index f736000fb9..7b0979f70b 100644 --- a/public/language/en-GB/topic.json +++ b/public/language/en-GB/topic.json @@ -74,6 +74,8 @@ "user-referenced-topic-on": "%1 referenced this topic on %3", "user-forked-topic-ago": "%1 forked this topic %3", "user-forked-topic-on": "%1 forked 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.", diff --git a/src/topics/crossposts.js b/src/topics/crossposts.js index e677e11481..0bd2f918af 100644 --- a/src/topics/crossposts.js +++ b/src/topics/crossposts.js @@ -98,8 +98,9 @@ Crossposts.add = async function (tid, cid, uid) { db.setObject(`crosspost:${crosspostId}`, { uid, tid, cid, timestamp: now }), db.sortedSetAdd(`tid:${tid}:crossposts`, now, crosspostId), 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 { throw new Error('[[error:topic-already-crossposted]]'); } @@ -146,6 +147,10 @@ Crossposts.remove = async function (tid, cid, uid) { ]); 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); return crossposts; }; diff --git a/src/topics/events.js b/src/topics/events.js index 0748318c37..87d81b3100 100644 --- a/src/topics/events.js +++ b/src/topics/events.js @@ -73,6 +73,10 @@ Events._types = { icon: 'fa-code-fork', 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 () => { @@ -117,6 +121,10 @@ function renderUser(event) { return `${helpers.buildAvatar(user, '16px', true)} ${user.displayname}`; } +function renderCategory(category) { + return `${helpers.buildCategoryLabel(category, 'a')}`; +} + function renderTimeago(event) { return ``; } @@ -183,9 +191,10 @@ async function addEventsFromPostQueue(tid, 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)), getCategoryInfo(events.map(event => event.fromCid).filter(Boolean)), + getCategoryInfo(events.map(event => event.toCid).filter(Boolean)), user.getSettings(uid), ]); @@ -215,6 +224,9 @@ async function modifyEvent({ uid, events }) { if (event.hasOwnProperty('fromCid')) { event.fromCategory = fromCategories[event.fromCid]; } + if (event.hasOwnProperty('toCid')) { + event.toCategory = toCategories[event.toCid]; + } Object.assign(event, Events._types[event.type]); });