diff --git a/dump.rdb b/dump.rdb new file mode 100644 index 0000000000..c324d203be Binary files /dev/null and b/dump.rdb differ diff --git a/src/topics/bookmarks.ts b/src/topics/bookmarks.ts new file mode 100644 index 0000000000..58c4fb67f2 --- /dev/null +++ b/src/topics/bookmarks.ts @@ -0,0 +1,67 @@ +'use strict'; + +import async from 'async'; +import db from '../database'; +import user from '../user'; + +export function bookmarks(Topics: any) { + Topics.getUserBookmark = async function (tid: [number], uid: number) { + if (parseInt(uid.toString(), 10) <= 0) { + return null; + } + return await db.sortedSetScore(`tid:${tid}:bookmarks`, uid); + }; + + Topics.getUserBookmarks = async function (tids: [number], uid: number) { + if (parseInt(uid.toString(), 10) <= 0) { + return tids.map(() => null); + } + return await db.sortedSetsScore(tids.map(tid => `tid:${tid}:bookmarks`), uid); + }; + + Topics.setUserBookmark = async function (tid: [number], uid: number, index: any) { + if (parseInt(uid.toString(), 10) <= 0) { + return; + } + await db.sortedSetAdd(`tid:${tid}:bookmarks`, index, uid); + }; + + Topics.getTopicBookmarks = async function (tid: [number]) { + return await db.getSortedSetRangeWithScores(`tid:${tid}:bookmarks`, 0, -1); + }; + + Topics.updateTopicBookmarks = async function (tid: number , pids: string) { + 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); + + const bookmarks = await Topics.getTopicBookmarks(tid); + + const uidData = bookmarks.map(b => ({ uid: b.value, bookmark: parseInt(b.score, 10) })) + .filter(data => data.bookmark >= minIndex); + + await async.eachLimit(uidData, 50, async (data) => { + let bookmark = Math.min(data.bookmark, maxIndex); + + postIndices.forEach((i) => { + if (i < data.bookmark) { + bookmark -= 1; + } + }); + + // 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 settings = await user.getSettings(data.uid); + if (settings.topicPostSort === 'most_votes') { + return; + } + + await Topics.setUserBookmark(tid, data.uid, bookmark); + }); + }; +}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..03a6e64df4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "outDir": "./built", + "allowJs": true, + "target": "es2017" + }, + "include": ["./src/**/*"] + } \ No newline at end of file