|
|
|
'use strict';
|
|
|
|
|
|
|
|
const categories = require('../categories');
|
|
|
|
const privileges = require('../privileges');
|
|
|
|
const user = require('../user');
|
|
|
|
const topics = require('../topics');
|
|
|
|
const apiController = require('../controllers/api');
|
|
|
|
|
|
|
|
const SocketCategories = module.exports;
|
|
|
|
|
|
|
|
SocketCategories.getRecentReplies = async function (socket, cid) {
|
|
|
|
return await categories.getRecentReplies(cid, socket.uid, 4);
|
|
|
|
};
|
|
|
|
|
|
|
|
SocketCategories.get = async function (socket) {
|
|
|
|
async function getCategories() {
|
|
|
|
const cids = await categories.getCidsByPrivilege('categories:cid', socket.uid, 'find');
|
|
|
|
return await categories.getCategoriesData(cids);
|
|
|
|
}
|
|
|
|
const [isAdmin, categoriesData] = await Promise.all([
|
|
|
|
user.isAdministrator(socket.uid),
|
|
|
|
getCategories(),
|
|
|
|
]);
|
|
|
|
return categoriesData.filter(category => category && (!category.disabled || isAdmin));
|
|
|
|
};
|
|
|
|
|
|
|
|
SocketCategories.getWatchedCategories = async function (socket) {
|
|
|
|
const [categoriesData, ignoredCids] = await Promise.all([
|
|
|
|
categories.getCategoriesByPrivilege('cid:0:children', socket.uid, 'find'),
|
|
|
|
user.getIgnoredCategories(socket.uid),
|
|
|
|
]);
|
|
|
|
return categoriesData.filter(category => category && !ignoredCids.includes(String(category.cid)));
|
|
|
|
};
|
|
|
|
|
|
|
|
SocketCategories.loadMore = async function (socket, data) {
|
|
|
|
if (!data) {
|
|
|
|
throw new Error('[[error:invalid-data]]');
|
|
|
|
}
|
|
|
|
data.query = data.query || {};
|
|
|
|
const [userPrivileges, settings, targetUid] = await Promise.all([
|
|
|
|
privileges.categories.get(data.cid, socket.uid),
|
|
|
|
user.getSettings(socket.uid),
|
|
|
|
user.getUidByUserslug(data.query.author),
|
|
|
|
]);
|
|
|
|
|
|
|
|
if (!userPrivileges.read) {
|
|
|
|
throw new Error('[[error:no-privileges]]');
|
|
|
|
}
|
|
|
|
|
|
|
|
const infScrollTopicsPerPage = 20;
|
|
|
|
const sort = data.sort || data.categoryTopicSort;
|
|
|
|
|
|
|
|
let start = Math.max(0, parseInt(data.after, 10));
|
|
|
|
|
|
|
|
if (data.direction === -1) {
|
|
|
|
start -= infScrollTopicsPerPage;
|
|
|
|
}
|
|
|
|
|
|
|
|
let stop = start + infScrollTopicsPerPage - 1;
|
|
|
|
|
|
|
|
start = Math.max(0, start);
|
|
|
|
stop = Math.max(0, stop);
|
|
|
|
const result = await categories.getCategoryTopics({
|
|
|
|
uid: socket.uid,
|
|
|
|
cid: data.cid,
|
|
|
|
start: start,
|
|
|
|
stop: stop,
|
|
|
|
sort: sort,
|
|
|
|
settings: settings,
|
|
|
|
query: data.query,
|
|
|
|
tag: data.query.tag,
|
|
|
|
targetUid: targetUid,
|
|
|
|
});
|
|
|
|
categories.modifyTopicsByPrivilege(data.topics, userPrivileges);
|
|
|
|
|
|
|
|
result.privileges = userPrivileges;
|
|
|
|
result.template = {
|
|
|
|
category: true,
|
|
|
|
name: 'category',
|
|
|
|
};
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
|
|
|
|
SocketCategories.getTopicCount = async function (socket, cid) {
|
|
|
|
return await categories.getCategoryField(cid, 'topic_count');
|
|
|
|
};
|
|
|
|
|
|
|
|
SocketCategories.getCategoriesByPrivilege = async function (socket, privilege) {
|
|
|
|
return await categories.getCategoriesByPrivilege('categories:cid', socket.uid, privilege);
|
|
|
|
};
|
|
|
|
|
|
|
|
SocketCategories.getMoveCategories = async function (socket, data) {
|
|
|
|
return await SocketCategories.getSelectCategories(socket, data);
|
|
|
|
};
|
|
|
|
|
|
|
|
SocketCategories.getSelectCategories = async function (socket) {
|
|
|
|
const [isAdmin, categoriesData] = await Promise.all([
|
|
|
|
user.isAdministrator(socket.uid),
|
|
|
|
categories.buildForSelect(socket.uid, 'find'),
|
|
|
|
]);
|
|
|
|
return categoriesData.filter(category => category && (!category.disabled || isAdmin) && !category.link);
|
|
|
|
};
|
|
|
|
|
|
|
|
SocketCategories.setWatchState = async function (socket, data) {
|
|
|
|
if (!data || !data.cid || !data.state) {
|
|
|
|
throw new Error('[[error:invalid-data]]');
|
|
|
|
}
|
|
|
|
await ignoreOrWatch(async function (uid, cid) {
|
|
|
|
await user.setCategoryWatchState(uid, cid, categories.watchStates[data.state]);
|
|
|
|
}, socket, data);
|
|
|
|
};
|
|
|
|
|
|
|
|
SocketCategories.watch = async function (socket, data) {
|
|
|
|
await ignoreOrWatch(user.watchCategory, socket, data);
|
|
|
|
};
|
|
|
|
|
|
|
|
SocketCategories.ignore = async function (socket, data) {
|
|
|
|
await ignoreOrWatch(user.ignoreCategory, socket, data);
|
|
|
|
};
|
|
|
|
|
|
|
|
async function ignoreOrWatch(fn, socket, data) {
|
|
|
|
let targetUid = socket.uid;
|
|
|
|
const cids = [parseInt(data.cid, 10)];
|
|
|
|
if (data.hasOwnProperty('uid')) {
|
|
|
|
targetUid = data.uid;
|
|
|
|
}
|
|
|
|
await user.isAdminOrGlobalModOrSelf(socket.uid, targetUid);
|
|
|
|
const allCids = await categories.getAllCidsFromSet('categories:cid');
|
|
|
|
const categoryData = await categories.getCategoriesFields(allCids, ['cid', 'parentCid']);
|
|
|
|
|
|
|
|
// filter to subcategories of cid
|
|
|
|
let cat;
|
|
|
|
do {
|
|
|
|
cat = categoryData.find(c => !cids.includes(c.cid) && cids.includes(c.parentCid));
|
|
|
|
if (cat) {
|
|
|
|
cids.push(cat.cid);
|
|
|
|
}
|
|
|
|
} while (cat);
|
|
|
|
|
|
|
|
await Promise.all(cids.map(cid => fn(targetUid, cid)));
|
|
|
|
await topics.pushUnreadCount(targetUid);
|
|
|
|
return cids;
|
|
|
|
}
|
|
|
|
|
|
|
|
SocketCategories.isModerator = async function (socket, cid) {
|
|
|
|
return await user.isModerator(socket.uid, cid);
|
|
|
|
};
|
|
|
|
|
|
|
|
SocketCategories.getCategory = async function (socket, cid) {
|
|
|
|
return await apiController.getCategoryData(cid, socket.uid);
|
|
|
|
};
|
|
|
|
|
|
|
|
require('../promisify')(SocketCategories);
|