refactor(socket.io): deprecate socketGroups.loadMoreMembers in favour of api.groups.listMembers

This commit is contained in:
Julian Lam
2023-11-02 12:04:53 -04:00
parent d2f3333af0
commit 807d778c77
5 changed files with 52 additions and 37 deletions

View File

@@ -9,18 +9,31 @@ get:
schema: schema:
type: string type: string
required: true required: true
description: group slug (that also acts as its identifier) to check description: a group slug (that also acts as its identifier)
example: administrators example: administrators
- in: query - in: query
name: 'query' name: 'query'
schema: schema:
type: string type: string
required: false required: false
description: A keyword search query description: >
A keyword search query.
This parameter conflicts with `after`. If both are present, `after` is ignored.
example: 'a' example: 'a'
- in: query
name: 'after'
schema:
type: string
required: false
description: >
Offset returned results.
This parameter conflicts with `query`. If both are present, this parameter is ignored.
example: '0'
responses: responses:
'200': '200':
description: matching user group members successfully listed description: user group members successfully listed
content: content:
application/json: application/json:
schema: schema:
@@ -42,5 +55,10 @@ get:
type: boolean type: boolean
matchCount: matchCount:
type: number type: number
nullable: true
timing: timing:
type: string type: string
nullable: true
nextStart:
type: number
nullable: true

View File

@@ -36,7 +36,7 @@ define('forum/groups/list', [
return; return;
} }
infinitescroll.loadMore('groups.loadMore', { infinitescroll.loadMore('/groups', {
sort: $('#search-sort').val(), sort: $('#search-sort').val(),
after: $('[component="groups/container"]').attr('data-nextstart'), after: $('[component="groups/container"]').attr('data-nextstart'),
}, function (data, done) { }, function (data, done) {

View File

@@ -92,10 +92,7 @@ define('forum/groups/memberlist', ['api', 'bootbox', 'alerts'], function (api, b
const searchEl = $('[component="groups/members/search"]'); const searchEl = $('[component="groups/members/search"]');
searchEl.on('keyup', utils.debounce(function () { searchEl.on('keyup', utils.debounce(function () {
const query = searchEl.val(); const query = searchEl.val();
socket.emit('groups.searchMembers', { api.get(`/groups/${groupName}/members`, { query }, function (err, results) {
groupName: groupName,
query: query,
}, function (err, results) {
if (err) { if (err) {
return alerts.error(err); return alerts.error(err);
} }
@@ -125,8 +122,7 @@ define('forum/groups/memberlist', ['api', 'bootbox', 'alerts'], function (api, b
} }
members.attr('loading', 1); members.attr('loading', 1);
socket.emit('groups.loadMoreMembers', { api.get(`/groups/${groupName}/members`, {
groupName: groupName,
after: members.attr('data-nextstart'), after: members.attr('data-nextstart'),
}, function (err, data) { }, function (err, data) {
if (err) { if (err) {

View File

@@ -74,6 +74,7 @@ groupsAPI.delete = async function (caller, data) {
}; };
groupsAPI.listMembers = async (caller, data) => { groupsAPI.listMembers = async (caller, data) => {
// v4 wishlist — search should paginate (with lru caching I guess) to match index listing behaviour
const groupName = await groups.getGroupNameByGroupSlug(data.slug); const groupName = await groups.getGroupNameByGroupSlug(data.slug);
await canSearchMembers(caller.uid, groupName); await canSearchMembers(caller.uid, groupName);
@@ -81,11 +82,26 @@ groupsAPI.listMembers = async (caller, data) => {
throw new Error('[[error:no-privileges]]'); throw new Error('[[error:no-privileges]]');
} }
return await groups.searchMembers({ const { query } = data;
uid: caller.uid, const after = parseInt(data.after || 0, 10);
query: data.query, let response;
groupName, if (query) {
}); response = await groups.searchMembers({
uid: caller.uid,
query,
groupName,
});
response.nextStart = null;
} else {
response = {
users: await groups.getOwnersAndMembers(groupName, caller.uid, after, after + 19),
nextStart: after + 20,
matchCount: null,
timing: null,
};
}
return response;
}; };
async function canSearchMembers(uid, groupName) { async function canSearchMembers(uid, groupName) {

View File

@@ -53,16 +53,15 @@ SocketGroups.searchMembers = async (socket, data) => {
}; };
SocketGroups.loadMoreMembers = async (socket, data) => { SocketGroups.loadMoreMembers = async (socket, data) => {
sockets.warnDeprecated(socket, 'GET /api/v3/groups/:groupName/members');
if (!data.groupName || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) { if (!data.groupName || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) {
throw new Error('[[error:invalid-data]]'); throw new Error('[[error:invalid-data]]');
} }
await canSearchMembers(socket.uid, data.groupName); data.slug = slugify(data.groupName);
data.after = parseInt(data.after, 10); delete data.groupName;
const users = await groups.getOwnersAndMembers(data.groupName, socket.uid, data.after, data.after + 9);
return { return api.groups.listMembers(socket, data);
users: users,
nextStart: data.after + 10,
};
}; };
SocketGroups.getChatGroups = async (socket) => { SocketGroups.getChatGroups = async (socket) => {
@@ -76,20 +75,6 @@ SocketGroups.getChatGroups = async (socket) => {
return groupsList.map(g => ({ name: g.name, displayName: g.displayName })); return groupsList.map(g => ({ name: g.name, displayName: g.displayName }));
}; };
async function canSearchMembers(uid, groupName) {
const [isHidden, isMember, hasAdminPrivilege, isGlobalMod, viewGroups] = await Promise.all([
groups.isHidden(groupName),
groups.isMember(uid, groupName),
privileges.admin.can('admin:groups', uid),
user.isGlobalModerator(uid),
privileges.global.can('view:groups', uid),
]);
if (!viewGroups || (isHidden && !isMember && !hasAdminPrivilege && !isGlobalMod)) {
throw new Error('[[error:no-privileges]]');
}
}
SocketGroups.cover = {}; SocketGroups.cover = {};
SocketGroups.cover.update = async (socket, data) => { SocketGroups.cover.update = async (socket, data) => {