Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matched The Modified File(sorted.js) from Project NodeBB #29

Merged
merged 1 commit into from
Sep 22, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 87 additions & 76 deletions src/topics/sorted.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,23 @@ const meta = require('../meta');
const plugins = require('../plugins');

module.exports = function (Topics) {
console.log('ndevidze');
Topics.getSortedTopics = async function (params) {
const data = {
nextStart: 0,
topicCount: 0,
topics: [],
};

params = initializeParams(params);
data.tids = await getTids(params);
data.tids = await sortTids(data.tids, params);
data.tids = await filterTids(data.tids.slice(0, meta.config.recentMaxTopics), params);
data.topicCount = data.tids.length;
data.topics = await getTopics(data.tids, params);
data.nextStart = params.stop + 1;
return data;
};
function initializeParams(params) {
params.term = params.term || 'alltime';
params.sort = params.sort || 'recent';
params.query = params.query || {};
Expand All @@ -28,15 +38,8 @@ module.exports = function (Topics) {
if (params.tags && !Array.isArray(params.tags)) {
params.tags = [params.tags];
}
data.tids = await getTids(params);
data.tids = await sortTids(data.tids, params);
data.tids = await filterTids(data.tids.slice(0, meta.config.recentMaxTopics), params);
data.topicCount = data.tids.length;
data.topics = await getTopics(data.tids, params);
data.nextStart = params.stop + 1;
return data;
};

return params;
}
async function getTids(params) {
if (plugins.hooks.hasListeners('filter:topics.getSortedTids')) {
const result = await plugins.hooks.fire('filter:topics.getSortedTids', { params: params, tids: [] });
Expand Down Expand Up @@ -137,69 +140,80 @@ module.exports = function (Topics) {
}

async function getCidTids(params) {
console.log('getting Tids');
if (params.tags.length) {
return _.intersection(...await Promise.all(params.tags.map(async (tag) => {
const sets = params.cids.map(cid => `cid:${cid}:tag:${tag}:topics`);
return await db.getSortedSetRevRange(sets, 0, -1);
})));
return await getTidsForTagsAndCids(params);
}

const sets = getCidSets(params.cids, params.sort);
let pinnedTids = await db.getSortedSetRevRange(sets.pinnedSets, 0, -1);
pinnedTids = await Topics.tools.checkPinExpiry(pinnedTids);
const tids = await db[sets.method](sets.normalSets, 0, meta.config.recentMaxTopics - 1);
return pinnedTids.concat(tids);
}
function getCidSets(cids, sort) {
const sets = [];
const pinnedSets = [];
params.cids.forEach((cid) => {
if (params.sort === 'recent' || params.sort === 'old') {
cids.forEach((cid) => {
if (sort === 'recent' || sort === 'old') {
sets.push(`cid:${cid}:tids`);
} else {
sets.push(`cid:${cid}:tids${params.sort ? `:${params.sort}` : ''}`);
sets.push(`cid:${cid}:tids${sort ? `:${sort}` : ''}`);
}
pinnedSets.push(`cid:${cid}:tids:pinned`);
});
let pinnedTids = await db.getSortedSetRevRange(pinnedSets, 0, -1);
pinnedTids = await Topics.tools.checkPinExpiry(pinnedTids);
const method = params.sort === 'old' ?
'getSortedSetRange' :
'getSortedSetRevRange';
const tids = await db[method](sets, 0, meta.config.recentMaxTopics - 1);
return pinnedTids.concat(tids);
const method = (sort === 'old') ? 'getSortedSetRange' : 'getSortedSetRevRange';
return { normalSets: sets, pinnedSets: pinnedSets, method: method };
}
async function getTidsForTagsAndCids(params) {
return _.intersection(
...await Promise.all(params.tags.map(async (tag) => {
const sets = params.cids.map(cid => `cid:${cid}:tag:${tag}:topics`);
return await db.getSortedSetRevRange(sets, 0, -1);
}))
);
}

async function sortTids(tids, params) {
if (params.term === 'alltime' && !params.cids && !params.tags.length && params.filter !== 'watched' && !params.floatPinned) {
console.log('sorting Tids');
if (canSkipSorting(params)) {
return tids;
}

if (params.sort === 'posts' && params.term !== 'alltime') {
return tids;
}

const { sortMap, fields } = await plugins.hooks.fire('filter:topics.sortOptions', {
params,
fields: [
'tid', 'timestamp', 'lastposttime', 'upvotes', 'downvotes', 'postcount', 'pinned',
],
sortMap: {
recent: sortRecent,
old: sortOld,
create: sortCreate,
posts: sortPopular,
votes: sortVotes,
views: sortViews,
},
fields: getFields(),
sortMap: getSortMap(),
});

const topicData = await Topics.getTopicsFields(tids, fields);
const sortFn = sortMap.hasOwnProperty(params.sort) && sortMap[params.sort] ?
sortMap[params.sort] : sortRecent;

const sortFn = getSortFunction(params.sort, sortMap);
if (params.floatPinned) {
floatPinned(topicData, sortFn);
} else {
topicData.sort(sortFn);
}

return topicData.map(topic => topic && topic.tid);
}

function canSkipSorting(params) {
return params.term === 'alltime' && !params.cids && !params.tags.length && params.filter !== 'watched' && !params.floatPinned;
}
function getFields() {
return ['tid', 'timestamp', 'lastposttime', 'upvotes', 'downvotes', 'postcount', 'pinned'];
}
function getSortMap() {
return {
recent: sortRecent,
old: sortOld,
create: sortCreate,
posts: sortPopular,
votes: sortVotes,
views: sortViews,
};
}
function getSortFunction(sort, sortMap) {
return sortMap.hasOwnProperty(sort) && sortMap[sort] ? sortMap[sort] : sortRecent;
}
function floatPinned(topicData, sortFn) {
topicData.sort((a, b) => (a.pinned !== b.pinned ? b.pinned - a.pinned : sortFn(a, b)));
}
Expand Down Expand Up @@ -235,49 +249,46 @@ module.exports = function (Topics) {
}

async function filterTids(tids, params) {
const { filter } = params;
const { uid } = params;

if (filter === 'new') {
tids = await Topics.filterNewTids(tids, uid);
} else if (filter === 'unreplied') {
tids = await Topics.filterUnrepliedTids(tids);
} else {
tids = await Topics.filterNotIgnoredTids(tids, uid);
}

tids = await privileges.topics.filterTids('topics:read', tids, uid);
let topicData = await Topics.getTopicsFields(tids, ['uid', 'tid', 'cid', 'tags']);
console.log('filtering Tids');
tids = await applyFilterByType(tids, params);
tids = await privileges.topics.filterTids('topics:read', tids, params.uid);
const topicData = await Topics.getTopicsFields(tids, ['uid', 'tid', 'cid', 'tags']);
const topicCids = _.uniq(topicData.map(topic => topic.cid)).filter(Boolean);

async function getIgnoredCids() {
if (params.cids || filter === 'watched' || meta.config.disableRecentCategoryFilter) {
return [];
}
return await categories.isIgnored(topicCids, uid);
}
const [ignoredCids, filtered] = await Promise.all([
getIgnoredCids(),
user.blocks.filter(uid, topicData),
getIgnoredCids(params, topicCids),
user.blocks.filter(params.uid, topicData),
]);

const isCidIgnored = _.zipObject(topicCids, ignoredCids);
topicData = filtered;

return filterTopicsByCidsAndTags(filtered, ignoredCids, params);
}
async function applyFilterByType(tids, params) {
switch (params.filter) {
case 'new':
return await Topics.filterNewTids(tids, params.uid);
case 'unreplied':
return await Topics.filterUnrepliedTids(tids);
default:
return await Topics.filterNotIgnoredTids(tids, params.uid);
}
}
async function getIgnoredCids(params, topicCids) {
if (params.cids || params.filter === 'watched' || meta.config.disableRecentCategoryFilter) {
return [];
}
return await categories.isIgnored(topicCids, params.uid);
}
function filterTopicsByCidsAndTags(topicData, ignoredCids, params) {
const isCidIgnored = _.zipObject(topicData.map(t => t.cid), ignoredCids);
const cids = params.cids && params.cids.map(String);
const { tags } = params;
tids = topicData.filter(t => (
const tids = topicData.filter(t => (
t &&
t.cid &&
!isCidIgnored[t.cid] &&
(!cids || cids.includes(String(t.cid))) &&
(!tags.length || tags.every(tag => t.tags.find(topicTag => topicTag.value === tag)))
)).map(t => t.tid);

const result = await plugins.hooks.fire('filter:topics.filterSortedTids', { tids: tids, params: params });
return result.tids;
return plugins.hooks.fire('filter:topics.filterSortedTids', { tids, params }).then(result => result.tids);
}

async function getTopics(tids, params) {
tids = tids.slice(params.start, params.stop !== -1 ? params.stop + 1 : undefined);
const topicData = await Topics.getTopicsByTids(tids, params);
Expand Down