You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nodebb/src/posts/bookmarks.js

69 lines
1.8 KiB
JavaScript

'use strict';
const db = require('../database');
const plugins = require('../plugins');
module.exports = function (Posts) {
Posts.bookmark = async function (pid, uid) {
return await toggleBookmark('bookmark', pid, uid);
};
Posts.unbookmark = async function (pid, uid) {
return await toggleBookmark('unbookmark', pid, uid);
};
async function toggleBookmark(type, pid, uid) {
if (parseInt(uid, 10) <= 0) {
throw new Error('[[error:not-logged-in]]');
}
const isBookmarking = type === 'bookmark';
const [postData, hasBookmarked] = await Promise.all([
Posts.getPostFields(pid, ['pid', 'uid']),
Posts.hasBookmarked(pid, uid),
]);
if (isBookmarking && hasBookmarked) {
throw new Error('[[error:already-bookmarked]]');
}
if (!isBookmarking && !hasBookmarked) {
throw new Error('[[error:already-unbookmarked]]');
}
if (isBookmarking) {
await db.sortedSetAdd(`uid:${uid}:bookmarks`, Date.now(), pid);
} else {
await db.sortedSetRemove(`uid:${uid}:bookmarks`, pid);
}
await db[isBookmarking ? 'setAdd' : 'setRemove'](`pid:${pid}:users_bookmarked`, uid);
postData.bookmarks = await db.setCount(`pid:${pid}:users_bookmarked`);
await Posts.setPostField(pid, 'bookmarks', postData.bookmarks);
plugins.hooks.fire(`action:post.${type}`, {
pid: pid,
uid: uid,
owner: postData.uid,
current: hasBookmarked ? 'bookmarked' : 'unbookmarked',
});
return {
post: postData,
isBookmarked: isBookmarking,
};
}
Posts.hasBookmarked = async function (pid, uid) {
if (parseInt(uid, 10) <= 0) {
return Array.isArray(pid) ? pid.map(() => false) : false;
}
if (Array.isArray(pid)) {
const sets = pid.map(pid => `pid:${pid}:users_bookmarked`);
return await db.isMemberOfSets(sets, uid);
}
return await db.isSetMember(`pid:${pid}:users_bookmarked`, uid);
};
};