From c23689d305210a7d6e9453875991141a1b7440ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?=
 <barisusakli@gmail.com>
Date: Fri, 28 Apr 2023 16:08:02 -0400
Subject: [PATCH] fix: #11531, fix teasers

1. with scheduled topics, pid is no longer reliable, lower pid can have higher timestamp(scheduled in the future) so use timestamp for sorting teasers
2. when restoring/deleting topics, update the teaser tid as the last step because it checks topicData.deleted
---
 src/categories/recentreplies.js |  4 ++--
 src/topics/delete.js            | 24 ++++++++++--------------
 2 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/src/categories/recentreplies.js b/src/categories/recentreplies.js
index 58f46313b3..7b04974659 100644
--- a/src/categories/recentreplies.js
+++ b/src/categories/recentreplies.js
@@ -131,7 +131,7 @@ module.exports = function (Categories) {
 		categories.forEach((category) => {
 			if (category) {
 				category.posts = topics.filter(t => t.cid && (t.cid === category.cid || t.parentCids.includes(category.cid)))
-					.sort((a, b) => b.pid - a.pid)
+					.sort((a, b) => b.timestamp - a.timestamp)
 					.slice(0, parseInt(category.numRecentReplies, 10));
 			}
 		});
@@ -147,7 +147,7 @@ module.exports = function (Categories) {
 				const posts = [];
 				getPostsRecursive(category, posts);
 
-				posts.sort((a, b) => b.pid - a.pid);
+				posts.sort((a, b) => b.timestamp - a.timestamp);
 				if (posts.length) {
 					category.posts = [posts[0]];
 				}
diff --git a/src/topics/delete.js b/src/topics/delete.js
index 2e088f35c5..75472ffc69 100644
--- a/src/topics/delete.js
+++ b/src/topics/delete.js
@@ -11,44 +11,40 @@ const batch = require('../batch');
 
 module.exports = function (Topics) {
 	Topics.delete = async function (tid, uid) {
-		await removeTopicPidsFromCid(tid);
+		const cid = await Topics.getTopicField(tid, 'cid');
+		await removeTopicPidsFromCid(tid, cid);
 		await Topics.setTopicFields(tid, {
 			deleted: 1,
 			deleterUid: uid,
 			deletedTimestamp: Date.now(),
 		});
+		await categories.updateRecentTidForCid(cid);
 	};
 
-	async function removeTopicPidsFromCid(tid) {
-		const [cid, pids] = await Promise.all([
-			Topics.getTopicField(tid, 'cid'),
-			Topics.getPids(tid),
-		]);
+	async function removeTopicPidsFromCid(tid, cid) {
+		const pids = await Topics.getPids(tid);
 		await db.sortedSetRemove(`cid:${cid}:pids`, pids);
-		await categories.updateRecentTidForCid(cid);
 	}
 
-	async function addTopicPidsToCid(tid) {
-		const [cid, pids] = await Promise.all([
-			Topics.getTopicField(tid, 'cid'),
-			Topics.getPids(tid),
-		]);
+	async function addTopicPidsToCid(tid, cid) {
+		const pids = await Topics.getPids(tid);
 		let postData = await posts.getPostsFields(pids, ['pid', 'timestamp', 'deleted']);
 		postData = postData.filter(post => post && !post.deleted);
 		const pidsToAdd = postData.map(post => post.pid);
 		const scores = postData.map(post => post.timestamp);
 		await db.sortedSetAdd(`cid:${cid}:pids`, scores, pidsToAdd);
-		await categories.updateRecentTidForCid(cid);
 	}
 
 	Topics.restore = async function (tid) {
+		const cid = await Topics.getTopicField(tid, 'cid');
 		await Promise.all([
 			Topics.deleteTopicFields(tid, [
 				'deleterUid', 'deletedTimestamp',
 			]),
-			addTopicPidsToCid(tid),
+			addTopicPidsToCid(tid, cid),
 		]);
 		await Topics.setTopicField(tid, 'deleted', 0);
+		await categories.updateRecentTidForCid(cid);
 	};
 
 	Topics.purgePostsAndTopic = async function (tid, uid) {