From a373731570e0fc7cb782894c1db03767d4076abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 6 Apr 2021 12:43:32 -0400 Subject: [PATCH] feat: add reverse of recent to getSortedTopics --- src/topics/sorted.js | 50 +++++++++++++++++++++++++++++++++++--------- test/topics.js | 42 ++++++++++++++++++++++++++++++++----- 2 files changed, 77 insertions(+), 15 deletions(-) diff --git a/src/topics/sorted.js b/src/topics/sorted.js index a8d4ac53b7..85f709e984 100644 --- a/src/topics/sorted.js +++ b/src/topics/sorted.js @@ -48,6 +48,10 @@ module.exports = function (Topics) { tids = await db.getSortedSetRevRange('uid:' + params.uid + ':followed_tids', 0, -1); } else if (params.cids) { tids = await getCidTids(params); + } else if (params.tags.length) { + tids = await getTagTids(params); + } else if (params.sort === 'old') { + tids = await db.getSortedSetRange(`topics:recent`, 0, meta.config.recentMaxTopics - 1); } else { tids = await db.getSortedSetRevRange('topics:' + params.sort, 0, meta.config.recentMaxTopics - 1); } @@ -55,12 +59,30 @@ module.exports = function (Topics) { return tids; } + async function getTagTids(params) { + const sets = [ + params.sort === 'old' ? + 'topics:recent' : + `topics:${params.sort}`, + ...params.tags.map(tag => `tag:${tag}:topics`), + ]; + const method = params.sort === 'old' ? + 'getSortedSetIntersect' : + 'getSortedSetRevIntersect'; + return await db[method]({ + sets: sets, + start: 0, + stop: meta.config.recentMaxTopics - 1, + weights: sets.map((s, index) => (index ? 0 : 1)), + }); + } + async function getCidTids(params) { const sets = []; const pinnedSets = []; - params.cids.forEach(function (cid) { - if (params.sort === 'recent') { - sets.push('cid:' + cid + ':tids'); + params.cids.forEach((cid) => { + if (params.sort === 'recent' || params.sort === 'old') { + sets.push(`cid:${cid}:tids`); } else { sets.push('cid:' + cid + ':tids' + (params.sort ? ':' + params.sort : '')); } @@ -68,7 +90,10 @@ module.exports = function (Topics) { }); let pinnedTids = await db.getSortedSetRevRange(pinnedSets, 0, -1); pinnedTids = await Topics.tools.checkPinExpiry(pinnedTids); - const tids = await db.getSortedSetRevRange(sets, 0, meta.config.recentMaxTopics - 1); + const method = params.sort === 'old' ? + 'getSortedSetRange' : + 'getSortedSetRevRange'; + const tids = await db[method](sets, 0, meta.config.recentMaxTopics - 1); return pinnedTids.concat(tids); } @@ -77,12 +102,13 @@ module.exports = function (Topics) { return tids; } const topicData = await Topics.getTopicsFields(tids, ['tid', 'lastposttime', 'upvotes', 'downvotes', 'postcount', 'pinned']); - let sortFn = sortRecent; - if (params.sort === 'posts') { - sortFn = sortPopular; - } else if (params.sort === 'votes') { - sortFn = sortVotes; - } + const sortMap = { + recent: sortRecent, + old: sortOld, + posts: sortPopular, + votes: sortVotes, + }; + const sortFn = sortMap[params.sort] || sortRecent; if (params.floatPinned) { floatPinned(topicData, sortFn); @@ -106,6 +132,10 @@ module.exports = function (Topics) { return b.lastposttime - a.lastposttime; } + function sortOld(a, b) { + return a.lastposttime - b.lastposttime; + } + function sortVotes(a, b) { if (a.votes !== b.votes) { return b.votes - a.votes; diff --git a/test/topics.js b/test/topics.js index 855612b1e1..e37d1db496 100644 --- a/test/topics.js +++ b/test/topics.js @@ -2518,12 +2518,21 @@ describe('Topic\'s', function () { }); }); - describe('sorted topics', function () { - it('should get sorted topics in category', function (done) { - var filters = ['', 'watched', 'unreplied', 'new']; - async.map(filters, function (filter, next) { + describe('sorted topics', () => { + let category; + before(async () => { + category = await categories.create({ name: 'sorted' }); + const topic1Result = await topics.post({ uid: topic.userId, cid: category.cid, title: 'old replied', content: 'topic 1 OP' }); + const topic2Result = await topics.post({ uid: topic.userId, cid: category.cid, title: 'most recent replied', content: 'topic 2 OP' }); + await topics.reply({ uid: topic.userId, content: 'topic 1 reply', tid: topic1Result.topicData.tid }); + await topics.reply({ uid: topic.userId, content: 'topic 2 reply', tid: topic2Result.topicData.tid }); + }); + + it('should get sorted topics in category', (done) => { + const filters = ['', 'watched', 'unreplied', 'new']; + async.map(filters, (filter, next) => { topics.getSortedTopics({ - cids: [topic.categoryId], + cids: [category.cid], uid: topic.userId, start: 0, stop: -1, @@ -2539,5 +2548,28 @@ describe('Topic\'s', function () { done(); }); }); + it('should get topics recent replied first', async () => { + const data = await topics.getSortedTopics({ + cids: [category.cid], + uid: topic.userId, + start: 0, + stop: -1, + sort: 'recent', + }); + assert.strictEqual(data.topics[0].title, 'most recent replied'); + assert.strictEqual(data.topics[1].title, 'old replied'); + }); + + it('should get topics recent replied last', async () => { + const data = await topics.getSortedTopics({ + cids: [category.cid], + uid: topic.userId, + start: 0, + stop: -1, + sort: 'old', + }); + assert.strictEqual(data.topics[0].title, 'old replied'); + assert.strictEqual(data.topics[1].title, 'most recent replied'); + }); }); });