'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); }; };