refactor(socket.io): deprecate categories.setWatchState in favour of api.categories.setWatchState

This commit is contained in:
Julian Lam
2023-10-23 12:11:34 -04:00
parent f1dbfaa283
commit d7c6b3d60e
7 changed files with 81 additions and 24 deletions

View File

@@ -1,7 +1,7 @@
'use strict';
define('forum/account/categories', ['forum/account/header', 'alerts'], function (header, alerts) {
define('forum/account/categories', ['forum/account/header', 'alerts', 'api'], function (header, alerts, api) {
const Categories = {};
Categories.init = function () {
@@ -11,37 +11,33 @@ define('forum/account/categories', ['forum/account/header', 'alerts'], function
handleIgnoreWatch(category.cid);
});
$('[component="category/watch/all"]').find('[component="category/watching"], [component="category/ignoring"], [component="category/notwatching"]').on('click', function () {
$('[component="category/watch/all"]').find('[component="category/watching"], [component="category/ignoring"], [component="category/notwatching"]').on('click', async (e) => {
const cids = [];
const state = $(this).attr('data-state');
const state = e.currentTarget.getAttribute('data-state');
const { uid } = ajaxify.data;
$('[data-parent-cid="0"]').each(function (index, el) {
cids.push($(el).attr('data-cid'));
});
socket.emit('categories.setWatchState', { cid: cids, state: state, uid: ajaxify.data.uid }, function (err, modified_cids) {
if (err) {
return alerts.error(err);
}
let modified_cids = await Promise.all(cids.map(async cid => api.put(`/categories/${cid}/watch`, { state, uid })));
modified_cids = modified_cids
.reduce((memo, cur) => memo.concat(cur.modified), [])
.filter((cid, idx, arr) => arr.indexOf(cid) === idx);
updateDropdowns(modified_cids, state);
});
});
};
function handleIgnoreWatch(cid) {
const category = $('[data-cid="' + cid + '"]');
category.find('[component="category/watching"], [component="category/ignoring"], [component="category/notwatching"]').on('click', function () {
const $this = $(this);
const state = $this.attr('data-state');
socket.emit('categories.setWatchState', { cid: cid, state: state, uid: ajaxify.data.uid }, function (err, modified_cids) {
if (err) {
return alerts.error(err);
}
updateDropdowns(modified_cids, state);
category.find('[component="category/watching"], [component="category/ignoring"], [component="category/notwatching"]').on('click', async (e) => {
const state = e.currentTarget.getAttribute('data-state');
const { uid } = ajaxify.data;
const { modified } = await api.put(`/categories/${cid}/watch`, { state, uid });
updateDropdowns(modified, state);
alerts.success('[[category:' + state + '.message]]');
});
});
}
function updateDropdowns(modified_cids, state) {

View File

@@ -69,7 +69,7 @@ define('forum/category', [
const $this = $(this);
const state = $this.attr('data-state');
socket.emit('categories.setWatchState', { cid: cid, state: state }, function (err) {
api.put(`/categories/${cid}/watch`, { state }, (err) => {
if (err) {
return alerts.error(err);
}

View File

@@ -1,6 +1,7 @@
'use strict';
const categories = require('../categories');
const topics = require('../topics');
const events = require('../events');
const user = require('../user');
const groups = require('../groups');
@@ -84,6 +85,31 @@ categoriesAPI.getTopicCount = async (caller, { cid }) => {
categoriesAPI.getPosts = async (caller, { cid }) => await categories.getRecentReplies(cid, caller.uid, 0, 4);
categoriesAPI.setWatchState = async (caller, { cid, state, uid }) => {
let targetUid = caller.uid;
const cids = Array.isArray(cid) ? cid.map(cid => parseInt(cid, 10)) : [parseInt(cid, 10)];
if (uid) {
targetUid = uid;
}
await user.isAdminOrGlobalModOrSelf(caller.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 user.setCategoryWatchState(targetUid, cids, state);
await topics.pushUnreadCount(targetUid);
return { cids };
};
categoriesAPI.getPrivileges = async (caller, { cid }) => {
await hasAdminPrivilege(caller.uid, 'privileges');

View File

@@ -1,6 +1,7 @@
'use strict';
const categories = require('../../categories');
const meta = require('../../meta');
const api = require('../../api');
const helpers = require('../helpers');
@@ -44,6 +45,24 @@ Categories.getPosts = async (req, res) => {
helpers.formatApiResponse(200, res, posts);
};
Categories.setWatchState = async (req, res) => {
const { cid } = req.params;
let { uid, state } = req.body;
if (req.method === 'DELETE') {
// DELETE is always setting state to system default in acp
state = categories.watchStates[meta.config.categoryWatchState];
} else if (Object.keys(categories.watchStates).includes(state)) {
state = categories.watchStates[state]; // convert to integer for backend processing
} else {
throw new Error('[[error:invalid-data]]');
}
const { cids: modified } = await api.categories.setWatchState(req, { cid, state, uid });
helpers.formatApiResponse(200, res, { modified });
};
Categories.getPrivileges = async (req, res) => {
const privilegeSet = await api.categories.getPrivileges(req, { cid: req.params.cid });
helpers.formatApiResponse(200, res, privilegeSet);

View File

@@ -11,6 +11,7 @@ const nconf = require('nconf');
const file = require('../file');
const user = require('../user');
const groups = require('../groups');
const categories = require('../categories');
const topics = require('../topics');
const posts = require('../posts');
const messaging = require('../messaging');
@@ -39,6 +40,14 @@ Assert.group = helpers.try(async (req, res, next) => {
next();
});
Assert.category = helpers.try(async (req, res, next) => {
if (!await categories.exists(req.params.cid)) {
return controllerHelpers.formatApiResponse(404, res, new Error('[[error:no-category]]'));
}
next();
});
Assert.topic = helpers.try(async (req, res, next) => {
if (!await topics.exists(req.params.tid)) {
return controllerHelpers.formatApiResponse(404, res, new Error('[[error:no-topic]]'));

View File

@@ -19,6 +19,9 @@ module.exports = function () {
setupApiRoute(router, 'get', '/:cid/count', [...middlewares], controllers.write.categories.getTopicCount);
setupApiRoute(router, 'get', '/:cid/posts', [...middlewares], controllers.write.categories.getPosts);
setupApiRoute(router, 'put', '/:cid/watch', [...middlewares, middleware.assert.category], controllers.write.categories.setWatchState);
setupApiRoute(router, 'delete', '/:cid/watch', [...middlewares, middleware.assert.category], controllers.write.categories.setWatchState);
setupApiRoute(router, 'get', '/:cid/privileges', [...middlewares], controllers.write.categories.getPrivileges);
setupApiRoute(router, 'put', '/:cid/privileges/:privilege', [...middlewares, middleware.checkRequired.bind(null, ['member'])], controllers.write.categories.setPrivilege);
setupApiRoute(router, 'delete', '/:cid/privileges/:privilege', [...middlewares, middleware.checkRequired.bind(null, ['member'])], controllers.write.categories.setPrivilege);

View File

@@ -112,12 +112,16 @@ SocketCategories.getSelectCategories = async function (socket) {
};
SocketCategories.setWatchState = async function (socket, data) {
sockets.warnDeprecated(socket, 'PUT/DELETE /api/v3/categories/:cid/watch');
if (!data || !data.cid || !data.state) {
throw new Error('[[error:invalid-data]]');
}
return await ignoreOrWatch(async (uid, cids) => {
await user.setCategoryWatchState(uid, cids, categories.watchStates[data.state]);
}, socket, data);
data.state = categories.watchStates[data.state];
await api.categories.setWatchState(socket, data);
return data.cid;
};
SocketCategories.watch = async function (socket, data) {