mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-03 20:45:58 +01:00
feat: closes #9845, sort by views
This commit is contained in:
@@ -180,6 +180,7 @@
|
|||||||
"newest_to_oldest": "Newest to Oldest",
|
"newest_to_oldest": "Newest to Oldest",
|
||||||
"most_votes": "Most Votes",
|
"most_votes": "Most Votes",
|
||||||
"most_posts": "Most Posts",
|
"most_posts": "Most Posts",
|
||||||
|
"most_views": "Most Views",
|
||||||
|
|
||||||
"stale.title": "Create new topic instead?",
|
"stale.title": "Create new topic instead?",
|
||||||
"stale.warning": "The topic you are replying to is quite old. Would you like to create a new topic instead, and reference this one in your reply?",
|
"stale.warning": "The topic you are replying to is quite old. Would you like to create a new topic instead, and reference this one in your reply?",
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ module.exports = function (Categories) {
|
|||||||
`cid:${cid}:tids:pinned`,
|
`cid:${cid}:tids:pinned`,
|
||||||
`cid:${cid}:tids:posts`,
|
`cid:${cid}:tids:posts`,
|
||||||
`cid:${cid}:tids:votes`,
|
`cid:${cid}:tids:votes`,
|
||||||
|
`cid:${cid}:tids:views`,
|
||||||
`cid:${cid}:tids:lastposttime`,
|
`cid:${cid}:tids:lastposttime`,
|
||||||
`cid:${cid}:recent_tids`,
|
`cid:${cid}:recent_tids`,
|
||||||
`cid:${cid}:pids`,
|
`cid:${cid}:pids`,
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ module.exports = function (Categories) {
|
|||||||
set = `cid:${cid}:tids:posts`;
|
set = `cid:${cid}:tids:posts`;
|
||||||
} else if (sort === 'most_votes') {
|
} else if (sort === 'most_votes') {
|
||||||
set = `cid:${cid}:tids:votes`;
|
set = `cid:${cid}:tids:votes`;
|
||||||
|
} else if (sort === 'most_views') {
|
||||||
|
set = `cid:${cid}:tids:views`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.tag) {
|
if (data.tag) {
|
||||||
@@ -123,7 +125,7 @@ module.exports = function (Categories) {
|
|||||||
|
|
||||||
Categories.getSortedSetRangeDirection = async function (sort) {
|
Categories.getSortedSetRangeDirection = async function (sort) {
|
||||||
sort = sort || 'newest_to_oldest';
|
sort = sort || 'newest_to_oldest';
|
||||||
const direction = sort === 'newest_to_oldest' || sort === 'most_posts' || sort === 'most_votes' ? 'highest-to-lowest' : 'lowest-to-highest';
|
const direction = ['newest_to_oldest', 'most_posts', 'most_votes', 'most_views'].includes(sort) ? 'highest-to-lowest' : 'lowest-to-highest';
|
||||||
const result = await plugins.hooks.fire('filter:categories.getSortedSetRangeDirection', {
|
const result = await plugins.hooks.fire('filter:categories.getSortedSetRangeDirection', {
|
||||||
sort: sort,
|
sort: sort,
|
||||||
direction: direction,
|
direction: direction,
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ module.exports = function (Topics) {
|
|||||||
'topics:views', 'topics:posts', 'topics:votes',
|
'topics:views', 'topics:posts', 'topics:votes',
|
||||||
`cid:${topicData.cid}:tids:votes`,
|
`cid:${topicData.cid}:tids:votes`,
|
||||||
`cid:${topicData.cid}:tids:posts`,
|
`cid:${topicData.cid}:tids:posts`,
|
||||||
|
`cid:${topicData.cid}:tids:views`,
|
||||||
], 0, topicData.tid),
|
], 0, topicData.tid),
|
||||||
user.addTopicIdToUser(topicData.uid, topicData.tid, timestamp),
|
user.addTopicIdToUser(topicData.uid, topicData.tid, timestamp),
|
||||||
db.incrObjectField(`category:${topicData.cid}`, 'topic_count'),
|
db.incrObjectField(`category:${topicData.cid}`, 'topic_count'),
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ module.exports = function (Topics) {
|
|||||||
`cid:${topicData.cid}:tids:posts`,
|
`cid:${topicData.cid}:tids:posts`,
|
||||||
`cid:${topicData.cid}:tids:lastposttime`,
|
`cid:${topicData.cid}:tids:lastposttime`,
|
||||||
`cid:${topicData.cid}:tids:votes`,
|
`cid:${topicData.cid}:tids:votes`,
|
||||||
|
`cid:${topicData.cid}:tids:views`,
|
||||||
`cid:${topicData.cid}:recent_tids`,
|
`cid:${topicData.cid}:recent_tids`,
|
||||||
`cid:${topicData.cid}:uid:${topicData.uid}:tids`,
|
`cid:${topicData.cid}:uid:${topicData.uid}:tids`,
|
||||||
`uid:${topicData.uid}:topics`,
|
`uid:${topicData.uid}:topics`,
|
||||||
|
|||||||
@@ -208,12 +208,13 @@ module.exports = function (Topics) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Topics.increaseViewCount = async function (tid) {
|
Topics.increaseViewCount = async function (tid) {
|
||||||
incrementFieldAndUpdateSortedSet(tid, 'viewcount', 1, 'topics:views');
|
const cid = await Topics.getTopicField(tid, 'cid');
|
||||||
|
incrementFieldAndUpdateSortedSet(tid, 'viewcount', 1, ['topics:views', `cid:${cid}:tids:views`]);
|
||||||
};
|
};
|
||||||
|
|
||||||
async function incrementFieldAndUpdateSortedSet(tid, field, by, set) {
|
async function incrementFieldAndUpdateSortedSet(tid, field, by, set) {
|
||||||
const value = await db.incrObjectFieldBy(`topic:${tid}`, field, by);
|
const value = await db.incrObjectFieldBy(`topic:${tid}`, field, by);
|
||||||
await db.sortedSetAdd(set, value, tid);
|
await db[Array.isArray(set) ? 'sortedSetsAdd' : 'sortedSetAdd'](set, value, tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
Topics.getTitleByPid = async function (pid) {
|
Topics.getTitleByPid = async function (pid) {
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ Scheduled.pin = async function (tid, topicData) {
|
|||||||
`cid:${topicData.cid}:tids`,
|
`cid:${topicData.cid}:tids`,
|
||||||
`cid:${topicData.cid}:tids:posts`,
|
`cid:${topicData.cid}:tids:posts`,
|
||||||
`cid:${topicData.cid}:tids:votes`,
|
`cid:${topicData.cid}:tids:votes`,
|
||||||
|
`cid:${topicData.cid}:tids:views`,
|
||||||
], tid),
|
], tid),
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
@@ -80,6 +81,7 @@ function unpin(tid, topicData) {
|
|||||||
[`cid:${topicData.cid}:tids`, topicData.lastposttime, tid],
|
[`cid:${topicData.cid}:tids`, topicData.lastposttime, tid],
|
||||||
[`cid:${topicData.cid}:tids:posts`, topicData.postcount, tid],
|
[`cid:${topicData.cid}:tids:posts`, topicData.postcount, tid],
|
||||||
[`cid:${topicData.cid}:tids:votes`, parseInt(topicData.votes, 10) || 0, tid],
|
[`cid:${topicData.cid}:tids:votes`, parseInt(topicData.votes, 10) || 0, tid],
|
||||||
|
[`cid:${topicData.cid}:tids:views`, topicData.viewcount, tid],
|
||||||
]),
|
]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ module.exports = function (Topics) {
|
|||||||
old: sortOld,
|
old: sortOld,
|
||||||
posts: sortPopular,
|
posts: sortPopular,
|
||||||
votes: sortVotes,
|
votes: sortVotes,
|
||||||
|
views: sortViews,
|
||||||
};
|
};
|
||||||
const sortFn = sortMap[params.sort] || sortRecent;
|
const sortFn = sortMap[params.sort] || sortRecent;
|
||||||
|
|
||||||
@@ -156,6 +157,10 @@ module.exports = function (Topics) {
|
|||||||
return b.viewcount - a.viewcount;
|
return b.viewcount - a.viewcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sortViews(a, b) {
|
||||||
|
return b.viewcount - a.viewcount;
|
||||||
|
}
|
||||||
|
|
||||||
async function filterTids(tids, params) {
|
async function filterTids(tids, params) {
|
||||||
const { filter } = params;
|
const { filter } = params;
|
||||||
const { uid } = params;
|
const { uid } = params;
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ module.exports = function (Topics) {
|
|||||||
`cid:${topicData.cid}:tids`,
|
`cid:${topicData.cid}:tids`,
|
||||||
`cid:${topicData.cid}:tids:posts`,
|
`cid:${topicData.cid}:tids:posts`,
|
||||||
`cid:${topicData.cid}:tids:votes`,
|
`cid:${topicData.cid}:tids:votes`,
|
||||||
|
`cid:${topicData.cid}:tids:views`,
|
||||||
], tid));
|
], tid));
|
||||||
} else {
|
} else {
|
||||||
promises.push(db.sortedSetRemove(`cid:${topicData.cid}:tids:pinned`, tid));
|
promises.push(db.sortedSetRemove(`cid:${topicData.cid}:tids:pinned`, tid));
|
||||||
@@ -181,6 +182,7 @@ module.exports = function (Topics) {
|
|||||||
[`cid:${topicData.cid}:tids`, topicData.lastposttime, tid],
|
[`cid:${topicData.cid}:tids`, topicData.lastposttime, tid],
|
||||||
[`cid:${topicData.cid}:tids:posts`, topicData.postcount, tid],
|
[`cid:${topicData.cid}:tids:posts`, topicData.postcount, tid],
|
||||||
[`cid:${topicData.cid}:tids:votes`, parseInt(topicData.votes, 10) || 0, tid],
|
[`cid:${topicData.cid}:tids:votes`, parseInt(topicData.votes, 10) || 0, tid],
|
||||||
|
[`cid:${topicData.cid}:tids:views`, topicData.viewcount, tid],
|
||||||
]));
|
]));
|
||||||
topicData.pinExpiry = undefined;
|
topicData.pinExpiry = undefined;
|
||||||
topicData.pinExpiryISO = undefined;
|
topicData.pinExpiryISO = undefined;
|
||||||
@@ -243,6 +245,7 @@ module.exports = function (Topics) {
|
|||||||
`cid:${topicData.cid}:tids:pinned`,
|
`cid:${topicData.cid}:tids:pinned`,
|
||||||
`cid:${topicData.cid}:tids:posts`,
|
`cid:${topicData.cid}:tids:posts`,
|
||||||
`cid:${topicData.cid}:tids:votes`,
|
`cid:${topicData.cid}:tids:votes`,
|
||||||
|
`cid:${topicData.cid}:tids:views`,
|
||||||
`cid:${topicData.cid}:tids:lastposttime`,
|
`cid:${topicData.cid}:tids:lastposttime`,
|
||||||
`cid:${topicData.cid}:recent_tids`,
|
`cid:${topicData.cid}:recent_tids`,
|
||||||
`cid:${topicData.cid}:uid:${topicData.uid}:tids`,
|
`cid:${topicData.cid}:uid:${topicData.uid}:tids`,
|
||||||
@@ -263,6 +266,7 @@ module.exports = function (Topics) {
|
|||||||
bulk.push([`cid:${cid}:tids`, topicData.lastposttime, tid]);
|
bulk.push([`cid:${cid}:tids`, topicData.lastposttime, tid]);
|
||||||
bulk.push([`cid:${cid}:tids:posts`, topicData.postcount, tid]);
|
bulk.push([`cid:${cid}:tids:posts`, topicData.postcount, tid]);
|
||||||
bulk.push([`cid:${cid}:tids:votes`, votes, tid]);
|
bulk.push([`cid:${cid}:tids:votes`, votes, tid]);
|
||||||
|
bulk.push([`cid:${cid}:tids:views`, topicData.viewcount, tid]);
|
||||||
}
|
}
|
||||||
await db.sortedSetAddBulk(bulk);
|
await db.sortedSetAddBulk(bulk);
|
||||||
|
|
||||||
|
|||||||
23
src/upgrades/1.18.4/category_topics_views.js
Normal file
23
src/upgrades/1.18.4/category_topics_views.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const db = require('../../database');
|
||||||
|
const batch = require('../../batch');
|
||||||
|
const topics = require('../../topics');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'Category topics sorted sets by views',
|
||||||
|
timestamp: Date.UTC(2021, 8, 28),
|
||||||
|
method: async function () {
|
||||||
|
const { progress } = this;
|
||||||
|
|
||||||
|
await batch.processSortedSet('topics:tid', async (tids) => {
|
||||||
|
let topicData = await topics.getTopicsData(tids);
|
||||||
|
topicData = topicData.filter(t => t && t.cid);
|
||||||
|
await db.sortedSetAddBulk(topicData.map(t => ([`cid:${t.cid}:tids:views`, t.viewcount || 0, t.tid])));
|
||||||
|
progress.incr(tids.length);
|
||||||
|
}, {
|
||||||
|
batch: 500,
|
||||||
|
progress: progress,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user