mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-29 18:16:17 +01:00
fix: #12357, properly update lists and counters
This commit is contained in:
@@ -6,24 +6,24 @@ define('forum/groups/details', [
|
||||
'components',
|
||||
'coverPhoto',
|
||||
'pictureCropper',
|
||||
'translator',
|
||||
'api',
|
||||
'slugify',
|
||||
'categorySelector',
|
||||
'bootbox',
|
||||
'alerts',
|
||||
'helpers',
|
||||
], function (
|
||||
memberList,
|
||||
iconSelect,
|
||||
components,
|
||||
coverPhoto,
|
||||
pictureCropper,
|
||||
translator,
|
||||
api,
|
||||
slugify,
|
||||
categorySelector,
|
||||
bootbox,
|
||||
alerts
|
||||
alerts,
|
||||
helpers
|
||||
) {
|
||||
const Details = {};
|
||||
let groupName;
|
||||
@@ -85,14 +85,19 @@ define('forum/groups/details', [
|
||||
break;
|
||||
|
||||
case 'kick':
|
||||
translator.translate('[[groups:details.kick-confirm]]', function (translated) {
|
||||
bootbox.confirm(translated, function (confirm) {
|
||||
if (!confirm) {
|
||||
return;
|
||||
}
|
||||
bootbox.confirm('[[groups:details.kick-confirm]]', function (confirm) {
|
||||
if (!confirm) {
|
||||
return;
|
||||
}
|
||||
|
||||
api.del(`/groups/${ajaxify.data.group.slug}/membership/${uid}`, undefined).then(() => userRow.slideUp().remove()).catch(alerts.error);
|
||||
});
|
||||
api.del(`/groups/${ajaxify.data.group.slug}/membership/${uid}`, undefined).then(
|
||||
() => {
|
||||
userRow.remove();
|
||||
$('[component="group/member/count"]').text(
|
||||
helpers.humanReadableNumber(ajaxify.data.group.memberCount - 1)
|
||||
);
|
||||
}
|
||||
).catch(alerts.error);
|
||||
});
|
||||
break;
|
||||
|
||||
@@ -105,29 +110,42 @@ define('forum/groups/details', [
|
||||
break;
|
||||
|
||||
case 'join':
|
||||
api.put('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined).then(() => ajaxify.refresh()).catch(alerts.error);
|
||||
api.put('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined).then(
|
||||
() => ajaxify.refresh()
|
||||
).catch(alerts.error);
|
||||
break;
|
||||
|
||||
case 'leave':
|
||||
api.del('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined).then(() => ajaxify.refresh()).catch(alerts.error);
|
||||
api.del('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined).then(
|
||||
() => ajaxify.refresh()
|
||||
).catch(alerts.error);
|
||||
break;
|
||||
|
||||
case 'accept':
|
||||
api.put(`/groups/${ajaxify.data.group.slug}/pending/${uid}`).then(() => ajaxify.refresh()).catch(alerts.error);
|
||||
api.put(`/groups/${ajaxify.data.group.slug}/pending/${uid}`).then(
|
||||
() => {
|
||||
userRow.remove();
|
||||
memberList.refresh();
|
||||
updatePendingAlertVisibility();
|
||||
}
|
||||
).catch(alerts.error);
|
||||
break;
|
||||
|
||||
case 'reject':
|
||||
api.del(`/groups/${ajaxify.data.group.slug}/pending/${uid}`).then(() => ajaxify.refresh()).catch(alerts.error);
|
||||
break;
|
||||
|
||||
case 'issueInvite':
|
||||
api.post(`/groups/${ajaxify.data.group.slug}/invites/${uid}`).then(() => ajaxify.refresh()).catch(alerts.error);
|
||||
api.del(`/groups/${ajaxify.data.group.slug}/pending/${uid}`).then(
|
||||
() => {
|
||||
userRow.remove();
|
||||
memberList.refresh();
|
||||
updatePendingAlertVisibility();
|
||||
}
|
||||
).catch(alerts.error);
|
||||
break;
|
||||
|
||||
case 'acceptInvite':
|
||||
api.put(`/groups/${ajaxify.data.group.slug}/invites/${app.user.uid}`).then(() => {
|
||||
if (uid) {
|
||||
userRow.remove();
|
||||
memberList.refresh();
|
||||
} else {
|
||||
ajaxify.refresh();
|
||||
}
|
||||
@@ -139,6 +157,8 @@ define('forum/groups/details', [
|
||||
api.del(`/groups/${ajaxify.data.group.slug}/invites/${uid || app.user.uid}`).then(() => {
|
||||
if (uid) {
|
||||
userRow.remove();
|
||||
updateInviteAlertVisibility();
|
||||
memberList.refresh();
|
||||
} else {
|
||||
ajaxify.refresh();
|
||||
}
|
||||
@@ -268,6 +288,20 @@ define('forum/groups/details', [
|
||||
});
|
||||
};
|
||||
|
||||
function updatePendingAlertVisibility() {
|
||||
$('[component="groups/pending/alert"]').toggleClass(
|
||||
'hidden',
|
||||
$('[component="groups/pending"] tbody tr').length > 0
|
||||
);
|
||||
}
|
||||
|
||||
function updateInviteAlertVisibility() {
|
||||
$('[component="groups/invited/alert"]').toggleClass(
|
||||
'hidden',
|
||||
$('[component="groups/invited"] tbody tr').length > 0
|
||||
);
|
||||
}
|
||||
|
||||
function handleMemberInvitations() {
|
||||
if (!ajaxify.data.group.isOwner) {
|
||||
return;
|
||||
@@ -275,8 +309,9 @@ define('forum/groups/details', [
|
||||
async function updateList() {
|
||||
const data = await api.get(`/api/groups/${ajaxify.data.group.slug}`);
|
||||
const html = await app.parseAndTranslate('groups/details', 'group.invited', { group: data.group });
|
||||
$('[component="groups/invited"] tbody tr').remove();
|
||||
$('[component="groups/invited"] tbody').html(html);
|
||||
updateInviteAlertVisibility();
|
||||
memberList.refresh();
|
||||
}
|
||||
const searchInput = $('[component="groups/members/invite"]');
|
||||
require(['autocomplete'], function (autocomplete) {
|
||||
@@ -305,21 +340,19 @@ define('forum/groups/details', [
|
||||
}
|
||||
|
||||
function removeCover() {
|
||||
translator.translate('[[groups:remove-group-cover-confirm]]', function (translated) {
|
||||
bootbox.confirm(translated, function (confirm) {
|
||||
if (!confirm) {
|
||||
return;
|
||||
}
|
||||
bootbox.confirm('[[groups:remove-group-cover-confirm]]', function (confirm) {
|
||||
if (!confirm) {
|
||||
return;
|
||||
}
|
||||
|
||||
socket.emit('groups.cover.remove', {
|
||||
groupName: ajaxify.data.group.name,
|
||||
}, function (err) {
|
||||
if (!err) {
|
||||
ajaxify.refresh();
|
||||
} else {
|
||||
alerts.error(err);
|
||||
}
|
||||
});
|
||||
socket.emit('groups.cover.remove', {
|
||||
groupName: ajaxify.data.group.name,
|
||||
}, function (err) {
|
||||
if (!err) {
|
||||
ajaxify.refresh();
|
||||
} else {
|
||||
alerts.error(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,19 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
define('forum/groups/memberlist', ['api', 'bootbox', 'alerts'], function (api, bootbox, alerts) {
|
||||
define('forum/groups/memberlist', ['api', 'bootbox', 'alerts', 'helpers'], function (api, bootbox, alerts, helpers) {
|
||||
const MemberList = {};
|
||||
let groupName;
|
||||
let templateName;
|
||||
|
||||
MemberList.init = function (_templateName) {
|
||||
templateName = _templateName || 'groups/details';
|
||||
groupName = ajaxify.data.group.name;
|
||||
|
||||
handleMemberAdd();
|
||||
handleMemberSearch();
|
||||
handleMemberInfiniteScroll();
|
||||
};
|
||||
|
||||
MemberList.refresh = async function () {
|
||||
const { group } = await api.get(`/api/groups/${ajaxify.data.group.slug}`);
|
||||
const html = await parseAndTranslate(group.members);
|
||||
$('[component="groups/members"] tbody').html(html);
|
||||
$('[component="group/member/count"]').text(
|
||||
helpers.humanReadableNumber(group.memberCount)
|
||||
);
|
||||
$('[component="group/pending/count"]').text(
|
||||
helpers.humanReadableNumber(group.pending.length)
|
||||
);
|
||||
$('[component="group/invited/count"]').text(
|
||||
helpers.humanReadableNumber(group.invited.length)
|
||||
);
|
||||
ajaxify.data.group.members = group.members;
|
||||
ajaxify.data.group.memberCount = group.memberCount;
|
||||
ajaxify.data.group.invited = group.invited;
|
||||
ajaxify.data.group.pending = group.pending;
|
||||
};
|
||||
|
||||
function handleMemberAdd() {
|
||||
$('[component="groups/members/add"]').on('click', function () {
|
||||
app.parseAndTranslate('admin/partials/groups/add-members', {}, function (html) {
|
||||
@@ -29,7 +46,7 @@ define('forum/groups/memberlist', ['api', 'bootbox', 'alerts'], function (api, b
|
||||
modal.find('[data-uid][data-selected]').each(function (index, el) {
|
||||
users.push(foundUsers[$(el).attr('data-uid')]);
|
||||
});
|
||||
addUserToGroup(users, function () {
|
||||
addUsersToGroup(users).then(() => {
|
||||
modal.modal('hide');
|
||||
});
|
||||
},
|
||||
@@ -65,99 +82,77 @@ define('forum/groups/memberlist', ['api', 'bootbox', 'alerts'], function (api, b
|
||||
});
|
||||
}
|
||||
|
||||
function addUserToGroup(users, callback) {
|
||||
function done() {
|
||||
users = users.filter(function (user) {
|
||||
return !$('[component="groups/members"] [data-uid="' + user.uid + '"]').length;
|
||||
});
|
||||
parseAndTranslate(users, function (html) {
|
||||
$('[component="groups/members"] tbody').prepend(html);
|
||||
});
|
||||
callback();
|
||||
}
|
||||
const uids = users.map(function (user) { return user.uid; });
|
||||
if (groupName === 'administrators') {
|
||||
socket.emit('admin.user.makeAdmins', uids, function (err) {
|
||||
if (err) {
|
||||
return alerts.error(err);
|
||||
}
|
||||
done();
|
||||
});
|
||||
async function addUsersToGroup(users) {
|
||||
const uids = users.map(u => u.uid);
|
||||
if (ajaxify.data.group.name === 'administrators') {
|
||||
await socket.emit('admin.user.makeAdmins', uids).catch(alerts.error);
|
||||
} else {
|
||||
Promise.all(uids.map(uid => api.put('/groups/' + ajaxify.data.group.slug + '/membership/' + uid))).then(done).catch(alerts.error);
|
||||
await Promise.all(uids.map(uid => api.put('/groups/' + ajaxify.data.group.slug + '/membership/' + uid))).catch(alerts.error);
|
||||
}
|
||||
|
||||
users = users.filter(user => !$('[component="groups/members"] [data-uid="' + user.uid + '"]').length);
|
||||
const html = await parseAndTranslate(users);
|
||||
$('[component="groups/members"] tbody').prepend(html);
|
||||
}
|
||||
|
||||
function handleMemberSearch() {
|
||||
const searchEl = $('[component="groups/members/search"]');
|
||||
searchEl.on('keyup', utils.debounce(function () {
|
||||
searchEl.on('keyup', utils.debounce(async function () {
|
||||
const query = searchEl.val();
|
||||
api.get(`/groups/${ajaxify.data.group.slug}/members`, { query }, function (err, results) {
|
||||
if (err) {
|
||||
return alerts.error(err);
|
||||
}
|
||||
parseAndTranslate(results.users, function (html) {
|
||||
$('[component="groups/members"] tbody').html(html);
|
||||
$('[component="groups/members"]').attr('data-nextstart', 20);
|
||||
});
|
||||
});
|
||||
const results = await api.get(`/groups/${ajaxify.data.group.slug}/members`, { query });
|
||||
const html = await parseAndTranslate(results.users);
|
||||
$('[component="groups/members"] tbody').html(html);
|
||||
$('[component="groups/members"]').attr('data-nextstart', 20);
|
||||
}, 250));
|
||||
}
|
||||
|
||||
function handleMemberInfiniteScroll() {
|
||||
$('[component="groups/members"]').on('scroll', function () {
|
||||
$('[component="groups/members"]').on('scroll', utils.debounce(function () {
|
||||
const $this = $(this);
|
||||
const bottom = ($this[0].scrollHeight - $this.innerHeight()) * 0.9;
|
||||
|
||||
if ($this.scrollTop() > bottom && !$('[component="groups/members/search"]').val()) {
|
||||
loadMoreMembers();
|
||||
}
|
||||
});
|
||||
}, 250));
|
||||
}
|
||||
|
||||
function loadMoreMembers() {
|
||||
async function loadMoreMembers() {
|
||||
const members = $('[component="groups/members"]');
|
||||
if (members.attr('loading')) {
|
||||
return;
|
||||
}
|
||||
|
||||
members.attr('loading', 1);
|
||||
api.get(`/groups/${ajaxify.data.group.slug}/members`, {
|
||||
const data = await api.get(`/groups/${ajaxify.data.group.slug}/members`, {
|
||||
after: members.attr('data-nextstart'),
|
||||
}, function (err, data) {
|
||||
if (err) {
|
||||
return alerts.error(err);
|
||||
}
|
||||
}).catch(alerts.error);
|
||||
|
||||
if (data && data.users.length) {
|
||||
onMembersLoaded(data.users, function () {
|
||||
members.removeAttr('loading');
|
||||
members.attr('data-nextstart', data.nextStart);
|
||||
});
|
||||
} else {
|
||||
members.removeAttr('loading');
|
||||
}
|
||||
});
|
||||
if (data && data.users.length) {
|
||||
await onMembersLoaded(data.users);
|
||||
members.removeAttr('loading');
|
||||
members.attr('data-nextstart', data.nextStart);
|
||||
} else {
|
||||
members.removeAttr('loading');
|
||||
}
|
||||
}
|
||||
|
||||
function onMembersLoaded(users, callback) {
|
||||
async function onMembersLoaded(users) {
|
||||
users = users.filter(function (user) {
|
||||
return !$('[component="groups/members"] [data-uid="' + user.uid + '"]').length;
|
||||
});
|
||||
|
||||
parseAndTranslate(users, function (html) {
|
||||
$('[component="groups/members"] tbody').append(html);
|
||||
callback();
|
||||
});
|
||||
const html = await parseAndTranslate(users);
|
||||
$('[component="groups/members"] tbody').append(html);
|
||||
}
|
||||
|
||||
function parseAndTranslate(users, callback) {
|
||||
app.parseAndTranslate(templateName, 'group.members', {
|
||||
async function parseAndTranslate(users) {
|
||||
return await app.parseAndTranslate(templateName, 'group.members', {
|
||||
group: {
|
||||
members: users,
|
||||
isOwner: ajaxify.data.group.isOwner,
|
||||
},
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
return MemberList;
|
||||
|
||||
@@ -167,7 +167,7 @@ module.exports = function (utils, Benchpress, relative_path) {
|
||||
if (groupObj.isPending && groupObj.name !== 'administrators') {
|
||||
return `<button class="btn btn-warning disabled ${btnClass}"><i class="fa fa-clock-o"></i> [[groups:membership.invitation-pending]]</button>`;
|
||||
} else if (groupObj.isInvited) {
|
||||
return `<button class="btn btn-link" data-action="rejectInvite" data-group="${groupObj.displayName}">[[groups:membership.reject]]</button><button class="btn btn-success" data-action="acceptInvite" data-group="${groupObj.name}"><i class="fa fa-plus"></i> [[groups:membership.accept-invitation]]</button>`;
|
||||
return `<button class="btn btn-warning" data-action="rejectInvite" data-group="${groupObj.displayName}">[[groups:membership.reject]]</button><button class="btn btn-success" data-action="acceptInvite" data-group="${groupObj.name}"><i class="fa fa-plus"></i> [[groups:membership.accept-invitation]]</button>`;
|
||||
} else if (!groupObj.disableJoinRequests && groupObj.name !== 'administrators') {
|
||||
return `<button class="btn btn-success" data-action="join" data-group="${groupObj.displayName}"><i class="fa fa-plus"></i> [[groups:membership.join-group]]</button>`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user