Skip to content
Open
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
120 changes: 70 additions & 50 deletions src/topics/bookmarks.js
Original file line number Diff line number Diff line change
@@ -1,69 +1,89 @@

'use strict';

const async = require('async');

const db = require('../database');
const user = require('../user');

module.exports = function (Topics) {
Topics.getUserBookmark = async function (tid, uid) {
if (parseInt(uid, 10) <= 0) {
return null;
}
return await db.sortedSetScore(`tid:${tid}:bookmarks`, uid);
};
// ---- implementations moved out of the exports wrapper ----

Topics.getUserBookmarks = async function (tids, uid) {
if (parseInt(uid, 10) <= 0) {
return tids.map(() => null);
}
return await db.sortedSetsScore(tids.map(tid => `tid:${tid}:bookmarks`), uid);
};
async function getUserBookmark(tid, uid) {
// TEMP: log for manual verification; remove before final commit
//console.log('NOOR_NIKNAM:getUserBookmark', { tid, uid });
// Or, if you prefer winston:
// require.main.require('winston').info('NOOR_NIKNAM:getUserBookmark', { tid, uid });

Topics.setUserBookmark = async function (tid, uid, index) {
if (parseInt(uid, 10) <= 0) {
return;
}
await db.sortedSetAdd(`tid:${tid}:bookmarks`, index, uid);
};
if (Number.parseInt(uid, 10) <= 0) {
return null;
}
return db.sortedSetScore(`tid:${tid}:bookmarks`, uid);
}

Topics.getTopicBookmarks = async function (tid) {
return await db.getSortedSetRangeWithScores(`tid:${tid}:bookmarks`, 0, -1);
};
async function getUserBookmarks(tids, uid) {
if (Number.parseInt(uid, 10) <= 0) {
return tids.map(() => null);
}
return db.sortedSetsScore(
tids.map(tid => `tid:${tid}:bookmarks`),
uid
);
}

Topics.updateTopicBookmarks = async function (tid, pids) {
const maxIndex = await Topics.getPostCount(tid);
const indices = await db.sortedSetRanks(`tid:${tid}:posts`, pids);
const postIndices = indices.map(i => (i === null ? 0 : i + 1));
const minIndex = Math.min(...postIndices);
async function setUserBookmark(tid, uid, index) {
// TEMP: log for manual verification; remove before final commit
//console.log('NOOR_NIKNAM:setUserBookmark', { tid, uid, index });

const bookmarks = await Topics.getTopicBookmarks(tid);
if (Number.parseInt(uid, 10) <= 0) {
return;
}
await db.sortedSetAdd(`tid:${tid}:bookmarks`, index, uid);
}

const uidData = bookmarks.map(b => ({ uid: b.value, bookmark: parseInt(b.score, 10) }))
.filter(data => data.bookmark >= minIndex);
async function getTopicBookmarks(tid) {
return db.getSortedSetRangeWithScores(`tid:${tid}:bookmarks`, 0, -1);
}

await async.eachLimit(uidData, 50, async (data) => {
let bookmark = Math.min(data.bookmark, maxIndex);
async function updateTopicBookmarks(Topics, tid, pids) {
const maxIndex = await Topics.getPostCount(tid);
const indices = await db.sortedSetRanks(`tid:${tid}:posts`, pids);
const postIndices = indices.map(i => (i === null ? 0 : i + 1));
const minIndex = Math.min(...postIndices);

postIndices.forEach((i) => {
if (i < data.bookmark) {
bookmark -= 1;
}
});
const bookmarks = await getTopicBookmarks(tid);

// make sure the bookmark is valid if we removed the last post
bookmark = Math.min(bookmark, maxIndex - pids.length);
if (bookmark === data.bookmark) {
return;
}
const uidData = bookmarks
.map(b => ({ uid: b.value, bookmark: Number.parseInt(b.score, 10) }))
.filter(data => data.bookmark >= minIndex);

const settings = await user.getSettings(data.uid);
if (settings.topicPostSort === 'most_votes') {
return;
}
await async.eachLimit(uidData, 50, async (data) => {
let bookmark = Math.min(data.bookmark, maxIndex);

await Topics.setUserBookmark(tid, data.uid, bookmark);
postIndices.forEach((i) => {
if (i < data.bookmark) {
bookmark -= 1;
}
});
};

// ensure valid bookmark if last post(s) were removed
bookmark = Math.min(bookmark, maxIndex - pids.length);
if (bookmark === data.bookmark) {
return;
}

const settings = await user.getSettings(data.uid);
if (settings.topicPostSort === 'most_votes') {
return;
}

await setUserBookmark(tid, data.uid, bookmark);
});
}

// ---- export wrapper with no returns ----
module.exports = function (Topics) {
Topics.getUserBookmark = getUserBookmark;
Topics.getUserBookmarks = getUserBookmarks;
Topics.setUserBookmark = setUserBookmark;
Topics.getTopicBookmarks = getTopicBookmarks;
Topics.updateTopicBookmarks = (tid, pids) =>
updateTopicBookmarks(Topics, tid, pids);
};