From 523a2dc54c9c00eec1e8919b358b47addfbf71ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Zanghelini?= Date: Fri, 5 Oct 2018 14:00:18 -0300 Subject: [PATCH] Add settings page to control watched categories (#6648) * Add settings page to control watched categories * Fix passing undefined to pushUnreadCount --- public/src/client/account/categories.js | 41 +++++++++++++++ src/controllers/accounts.js | 1 + src/controllers/accounts/categories.js | 70 +++++++++++++++++++++++++ src/routes/accounts.js | 1 + src/socket.io/categories.js | 8 +-- 5 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 public/src/client/account/categories.js create mode 100644 src/controllers/accounts/categories.js diff --git a/public/src/client/account/categories.js b/public/src/client/account/categories.js new file mode 100644 index 0000000000..84202b6696 --- /dev/null +++ b/public/src/client/account/categories.js @@ -0,0 +1,41 @@ +'use strict'; + + +define('forum/account/categories', ['forum/account/header'], function (header) { + var Categories = {}; + + Categories.init = function () { + header.init(); + + ajaxify.data.categories.forEach(function (category) { + handleIgnoreWatch(category.cid); + }); + }; + + function handleIgnoreWatch(cid) { + var category = $('[data-cid="' + cid + '"]'); + category.find('[component="category/watching"], [component="category/ignoring"]').on('click', function () { + var $this = $(this); + var command = $this.attr('component') === 'category/watching' ? 'watch' : 'ignore'; + + socket.emit('categories.' + command, cid, function (err, modified_cids) { + if (err) { + return app.alertError(err.message); + } + + modified_cids.forEach(function (cid) { + var category = $('[data-cid="' + cid + '"]'); + category.find('[component="category/watching/menu"]').toggleClass('hidden', command !== 'watch'); + category.find('[component="category/watching/check"]').toggleClass('fa-check', command === 'watch'); + + category.find('[component="category/ignoring/menu"]').toggleClass('hidden', command !== 'ignore'); + category.find('[component="category/ignoring/check"]').toggleClass('fa-check', command === 'ignore'); + }); + + app.alertSuccess('[[category:' + command + '.message]]'); + }); + }); + } + + return Categories; +}); diff --git a/src/controllers/accounts.js b/src/controllers/accounts.js index 8a8994e720..8a7f1f1db6 100644 --- a/src/controllers/accounts.js +++ b/src/controllers/accounts.js @@ -4,6 +4,7 @@ var accountsController = { profile: require('./accounts/profile'), edit: require('./accounts/edit'), info: require('./accounts/info'), + categories: require('./accounts/categories'), settings: require('./accounts/settings'), groups: require('./accounts/groups'), follow: require('./accounts/follow'), diff --git a/src/controllers/accounts/categories.js b/src/controllers/accounts/categories.js new file mode 100644 index 0000000000..ee153a00b7 --- /dev/null +++ b/src/controllers/accounts/categories.js @@ -0,0 +1,70 @@ +'use strict'; + +var async = require('async'); + +var user = require('../../user'); +var categories = require('../../categories'); +var accountHelpers = require('./helpers'); + +var categoriesController = {}; + + +categoriesController.get = function (req, res, callback) { + var userData; + async.waterfall([ + function (next) { + accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, next); + }, + function (_userData, next) { + userData = _userData; + if (!userData) { + return callback(); + } + + async.parallel({ + ignored: function (next) { + user.getIgnoredCategories(userData.uid, next); + }, + all: function (next) { + categories.getCategoriesByPrivilege('cid:0:children', userData.uid, 'find', next); + }, + }, next); + }, + function (results, next) { + flattenArray(results); + userData.categories = results.all; + next(); + }, + ], function (err) { + if (err) { + return callback(err); + } + + userData.title = '[[pages:account/watched_categories]]'; + res.render('account/categories', userData); + }); +}; + +function moveChildrenToRoot(child) { + this.results.all.splice(this.i + this.results.j, 0, child); + this.results.j = this.results.j + 1; +} + +function flattenArray(results) { + for (var i = 0; i < results.all.length; i++) { + var category = results.all[i]; + + category.isIgnored = false; + if (results.ignored.includes(category.cid)) { + category.isIgnored = true; + } + + if (!!category.children && !!category.children.length) { + results.j = 1; + category.children.forEach(moveChildrenToRoot, { i: i, results: results }); + category.children = []; + } + } +} + +module.exports = categoriesController; diff --git a/src/routes/accounts.js b/src/routes/accounts.js index 61b5e6dd66..e5b6198ed1 100644 --- a/src/routes/accounts.js +++ b/src/routes/accounts.js @@ -14,6 +14,7 @@ module.exports = function (app, middleware, controllers) { setupPageRoute(app, '/user/:userslug/following', middleware, middlewares, controllers.accounts.follow.getFollowing); setupPageRoute(app, '/user/:userslug/followers', middleware, middlewares, controllers.accounts.follow.getFollowers); + setupPageRoute(app, '/user/:userslug/categories', middleware, middlewares, controllers.accounts.categories.get); setupPageRoute(app, '/user/:userslug/posts', middleware, middlewares, controllers.accounts.posts.getPosts); setupPageRoute(app, '/user/:userslug/topics', middleware, middlewares, controllers.accounts.posts.getTopics); setupPageRoute(app, '/user/:userslug/best', middleware, middlewares, controllers.accounts.posts.getBestPosts); diff --git a/src/socket.io/categories.js b/src/socket.io/categories.js index 9dfb285d82..8c7ac5d394 100644 --- a/src/socket.io/categories.js +++ b/src/socket.io/categories.js @@ -174,6 +174,8 @@ SocketCategories.ignore = function (socket, cid, callback) { }; function ignoreOrWatch(fn, socket, cid, callback) { + var cids = [parseInt(cid, 10)]; + async.waterfall([ function (next) { db.getSortedSetRange('categories:cid', 0, -1, next); @@ -187,10 +189,7 @@ function ignoreOrWatch(fn, socket, cid, callback) { c.parentCid = parseInt(c.parentCid, 10); }); - var cids = [parseInt(cid, 10)]; - // filter to subcategories of cid - var cat; do { cat = categoryData.find(function (c) { @@ -208,6 +207,9 @@ function ignoreOrWatch(fn, socket, cid, callback) { function (next) { topics.pushUnreadCount(socket.uid, next); }, + function (next) { + next(null, cids); + }, ], callback); }