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