diff --git a/public/src/client/account/blocks.js b/public/src/client/account/blocks.js index 921065fd37..91b0745a19 100644 --- a/public/src/client/account/blocks.js +++ b/public/src/client/account/blocks.js @@ -11,12 +11,19 @@ define('forum/account/blocks', [ Blocks.init = function () { header.init(); const blockListEl = $('[component="blocks/search/list"]'); + const startTypingEl = blockListEl.find('[component="blocks/start-typing"]'); + const noUsersEl = blockListEl.find('[component="blocks/no-users"]'); - $('#user-search').on('keyup', function () { + $('#user-search').on('keyup', utils.debounce(function () { const username = this.value; + if (!username) { - return blockListEl.translateHtml('
  • [[admin/menu:search.start-typing]]
  • '); + blockListEl.find('[component="blocks/search/match"]').remove(); + startTypingEl.removeClass('hidden'); + noUsersEl.addClass('hidden'); + return; } + startTypingEl.addClass('hidden'); api.get('/api/users', { query: username, searchBy: 'username', @@ -26,8 +33,10 @@ define('forum/account/blocks', [ return alerts.error(err); } if (!data.users.length) { - return blockListEl.translateHtml('
  • [[users:no-users-found]]
  • '); + noUsersEl.removeClass('hidden'); + return; } + noUsersEl.addClass('hidden'); // Only show first 10 matches if (data.matchCount > 10) { data.users.length = 10; @@ -36,25 +45,36 @@ define('forum/account/blocks', [ app.parseAndTranslate('account/blocks', 'edit', { edit: data.users, }, function (html) { - $('.block-edit').html(html); + blockListEl.find('[component="blocks/search/match"]').remove(); + html.insertAfter(noUsersEl); }); }); + }, 200)); + + $('.block-edit').on('click', '[data-action="block"], [data-action="unblock"]', async function () { + const uid = parseInt(this.getAttribute('data-uid'), 10); + const action = $(this).attr('data-action'); + const currentBtn = $(this); + await performBlock(uid, action); + currentBtn.addClass('hidden').siblings('[data-action]').removeClass('hidden'); + Blocks.refreshList(); }); - $('.block-edit').on('click', '[data-action="toggle"]', function () { - const uid = parseInt(this.getAttribute('data-uid'), 10); - socket.emit('user.toggleBlock', { - blockeeUid: uid, - blockerUid: ajaxify.data.uid, - }, Blocks.refreshList); + $('#users-container').on('click', '[data-action="unblock"]', async function () { + await performBlock($(this).attr('data-uid'), $(this).attr('data-action')); + Blocks.refreshList(); }); }; - Blocks.refreshList = function (err) { - if (err) { - return alerts.error(err); - } + async function performBlock(uid, action) { + return socket.emit('user.toggleBlock', { + blockeeUid: uid, + blockerUid: ajaxify.data.uid, + action: action, + }).catch(alerts.error); + } + Blocks.refreshList = function () { $.get(config.relative_path + '/api/' + ajaxify.currentPage) .done(function (payload) { app.parseAndTranslate('account/blocks', 'users', payload, function (html) { diff --git a/src/api/users.js b/src/api/users.js index febcf290e6..7c8a725019 100644 --- a/src/api/users.js +++ b/src/api/users.js @@ -601,6 +601,7 @@ usersAPI.search = async function (caller, data) { throw new Error('[[error:no-privileges]]'); } return await user.search({ + uid: caller.uid, query: data.query, searchBy: data.searchBy || 'username', page: data.page || 1, diff --git a/src/controllers/users.js b/src/controllers/users.js index f55296bdb9..41194e6c82 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -25,7 +25,7 @@ usersController.index = async function (req, res, next) { if (req.query.query) { await usersController.search(req, res, next); - } else if (sectionToController[section]) { + } else if (sectionToController.hasOwnProperty(section) && sectionToController[section]) { await sectionToController[section](req, res, next); } else { await usersController.getUsersSortedByJoinDate(req, res, next); diff --git a/src/socket.io/user/profile.js b/src/socket.io/user/profile.js index 5d4c4624f3..277b75ccc4 100644 --- a/src/socket.io/user/profile.js +++ b/src/socket.io/user/profile.js @@ -41,8 +41,16 @@ module.exports = function (SocketUser) { SocketUser.toggleBlock = async function (socket, data) { const isBlocked = await user.blocks.is(data.blockeeUid, data.blockerUid); - await user.blocks.can(socket.uid, data.blockerUid, data.blockeeUid, isBlocked ? 'unblock' : 'block'); - await user.blocks[isBlocked ? 'remove' : 'add'](data.blockeeUid, data.blockerUid); + const { action, blockerUid, blockeeUid } = data; + if (action !== 'block' && action !== 'unblock') { + throw new Error('[[error:unknow-block-action]]'); + } + await user.blocks.can(socket.uid, blockerUid, blockeeUid, action); + if (data.action === 'block') { + await user.blocks.add(blockeeUid, blockerUid); + } else if (data.action === 'unblock') { + await user.blocks.remove(blockeeUid, blockerUid); + } return !isBlocked; }; }; diff --git a/src/user/search.js b/src/user/search.js index 2713b3a8dd..ec0b81d025 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -60,7 +60,19 @@ module.exports = function (User) { uids = uids.slice(start, stop); } - const userData = await User.getUsers(uids, uid); + const [userData, blocks] = await Promise.all([ + User.getUsers(uids, uid), + User.blocks.list(uid), + ]); + + if (blocks.length) { + userData.forEach((user) => { + if (user) { + user.isBlocked = blocks.includes(user.uid); + } + }); + } + searchResult.timing = (process.elapsedTimeSince(startTime) / 1000).toFixed(2); searchResult.users = userData.filter(user => user && user.uid > 0); return searchResult;