Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: pagination group apis (#813)
Browse files Browse the repository at this point in the history
* fix: SDK delta API changes

* fix: updategroupMembers

* fix: test cases and minor fixes

* fix: getAllGroupMembers

---------

Co-authored-by: aman035 <guptaaman200115@gmail.com>
mohammeds1992 and Aman035 authored Nov 7, 2023
1 parent bc4cd16 commit 76bd15c
Showing 17 changed files with 616 additions and 293 deletions.
Original file line number Diff line number Diff line change
@@ -30,8 +30,8 @@ const GetGroupMembersTest = () => {
try {
const result = await PushAPI.chat.getGroupMembers({
chatId,
pageNumber,
pageSize,
page: pageNumber,
limit: pageSize,
env,
});
setSendResponse(result);
93 changes: 23 additions & 70 deletions packages/restapi/src/lib/chat/addAdmins.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
import { isValidETHAddress, walletToPCAIP10 } from '../helpers';
import Constants from '../constants';
import { EnvOptionsType, SignerType, GroupDTO } from '../types';
import { EnvOptionsType, SignerType, GroupInfoDTO } from '../types';
import {
getMembersList,
getAdminsList,
} from './helpers';
import {
getGroup
} from './getGroup';
import {
updateGroup
} from './updateGroup';
GroupMemberUpdateOptions,
updateGroupMembers,
} from './updateGroupMembers';
export interface AddAdminsToGroupType extends EnvOptionsType {
chatId: string;
admins: Array<string>;
account?: string | null;
signer?: SignerType | null;
pgpPrivateKey?: string | null;
pgpPrivateKey?: string | null;
}

export const addAdmins = async (
options: AddAdminsToGroupType
): Promise<GroupDTO> => {
): Promise<GroupInfoDTO> => {
const {
chatId,
admins,
@@ -34,70 +27,30 @@ export const addAdmins = async (
if (account == null && signer == null) {
throw new Error(`At least one from account or signer is necessary!`);
}

if (!admins || admins.length === 0) {
throw new Error("Admin address array cannot be empty!");
throw new Error('Admin address array cannot be empty!');
}

admins.forEach((admin) => {
if (!isValidETHAddress(admin)) {
throw new Error(`Invalid admin address: ${admin}`);
}
});

const group = await getGroup({
chatId: chatId,
env,
})

// TODO: look at user did in updateGroup
const convertedMembers = getMembersList(
group.members, group.pendingMembers
);

// TODO: look at user did in updateGroup
const adminsToBeAdded = admins.map((admin) => walletToPCAIP10(admin));

adminsToBeAdded.forEach((admin) => {
if (!convertedMembers.includes(admin)) {
convertedMembers.push(admin);
}
});

const convertedAdmins = getAdminsList(
group.members, group.pendingMembers
);

adminsToBeAdded.forEach((admin) => {
if (convertedAdmins.includes(admin)) {
throw new Error(`Admin ${admin} already exists in the list`);
}
});

convertedAdmins.push(...adminsToBeAdded);

return await updateGroup({
chatId: chatId,
groupName: group.groupName,
groupImage: group.groupImage,
groupDescription: group.groupDescription,
members: convertedMembers,
admins: convertedAdmins,
scheduleAt: group.scheduleAt,
scheduleEnd: group.scheduleEnd,
status: group.status,
account: account,
signer: signer,
env: env,
pgpPrivateKey: pgpPrivateKey
});
const upsertPayload = {
admins: admins,
};

const groupMemberUpdateOptions: GroupMemberUpdateOptions = {
chatId: chatId,
upsert: upsertPayload,
remove: [], // No members to remove in this case
account: account,
signer: signer,
pgpPrivateKey: pgpPrivateKey,
env: env,
};
return await updateGroupMembers(groupMemberUpdateOptions);
} catch (err) {
console.error(
`[Push SDK] - API - Error - API ${addAdmins.name} -: `,
err
);
throw Error(
`[Push SDK] - API - Error - API ${addAdmins.name} -: ${err}`
);
throw Error(`[Push SDK] - API - Error - API ${addAdmins.name} -: ${err}`);
}
};
75 changes: 16 additions & 59 deletions packages/restapi/src/lib/chat/addMembers.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
import { isValidETHAddress, walletToPCAIP10 } from '../helpers';
import Constants from '../constants';
import { EnvOptionsType, SignerType, GroupDTO } from '../types';
import {
getMembersList,
getAdminsList
} from './helpers';
import {
getGroup
} from './getGroup';
import {
updateGroup
} from './updateGroup';
import { EnvOptionsType, SignerType, GroupInfoDTO } from '../types';
import { updateGroupMembers } from './updateGroupMembers';
import { GroupMemberUpdateOptions } from './updateGroupMembers';
export interface AddMembersToGroupType extends EnvOptionsType {
chatId: string;
members: Array<string>;
@@ -24,7 +15,7 @@ export interface AddMembersToGroupType extends EnvOptionsType {
*/
export const addMembers = async (
options: AddMembersToGroupType
): Promise<GroupDTO> => {
): Promise<GroupInfoDTO> => {
const {
chatId,
members,
@@ -37,64 +28,30 @@ export const addMembers = async (
if (account == null && signer == null) {
throw new Error(`At least one from account or signer is necessary!`);
}

if (!members || members.length === 0) {
throw new Error("Member address array cannot be empty!");
throw new Error('Member address array cannot be empty!');
}

members.forEach((member) => {
if (!isValidETHAddress(member)) {
throw new Error(`Invalid member address: ${member}`);
}
});

const group = await getGroup({
chatId: chatId,
env,
})

const convertedMembers = getMembersList(
group.members, group.pendingMembers
);

const membersToBeAdded = members.map((member) => walletToPCAIP10(member));

membersToBeAdded.forEach((member) => {
if (convertedMembers.includes(member)) {
throw new Error(`Member ${member} already exists in the list`);
}
});

convertedMembers.push(...membersToBeAdded);
const upsertPayload = {
members: members,
};

const convertedAdmins = getAdminsList(
group.members, group.pendingMembers
);

return await updateGroup({
const groupMemberUpdateOptions: GroupMemberUpdateOptions = {
chatId: chatId,
groupName: group.groupName,
groupImage: group.groupImage,
groupDescription: group.groupDescription,
members: convertedMembers,
admins: convertedAdmins,
scheduleAt: group.scheduleAt,
scheduleEnd: group.scheduleEnd,
status: group.status,
upsert: upsertPayload,
remove: [], // No members to remove in this case
account: account,
signer: signer,
env: env,
rules: group.rules,
meta: group.meta,
pgpPrivateKey: pgpPrivateKey,
});
env: env,
};
return await updateGroupMembers(groupMemberUpdateOptions);
} catch (err) {
console.error(
`[Push SDK] - API - Error - API ${addMembers.name} -: `,
err
);
throw Error(
`[Push SDK] - API - Error - API ${addMembers.name} -: ${err}`
);
throw Error(`[Push SDK] - API - Error - API ${addMembers.name} -: ${err}`);
}
};
29 changes: 29 additions & 0 deletions packages/restapi/src/lib/chat/getAllGroupMembers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { getGroupMembers } from './getGroupMembers';
import { getChatMemberCount } from './getChatMemberCount';
import { ChatMemberProfile, EnvOptionsType } from '../types';

export const getAllGroupMembers = async (options: {
chatId: string;
env: EnvOptionsType['env'];
}): Promise<ChatMemberProfile[]> => {
const { chatId, env } = options;
const count = await getChatMemberCount({ chatId, env });
const overallCount = count.overallCount;
const limit = 5000;
const totalPages = Math.ceil(overallCount / limit);
const pageNumbers = Array.from({ length: totalPages }, (_, i) => i + 1);
const groupMembers: ChatMemberProfile[] = [];

const memberFetchPromises = pageNumbers.map((page) =>
getGroupMembers({ chatId, env, page, limit })
);

const membersResults = await Promise.all(memberFetchPromises);
membersResults.forEach((result) => {
if (result.members.length > 0) {
groupMembers.push(...result.members);
}
});

return groupMembers;
};
13 changes: 4 additions & 9 deletions packages/restapi/src/lib/chat/getGroupMembers.ts
Original file line number Diff line number Diff line change
@@ -9,8 +9,8 @@ import { ChatMemberCounts, ChatMemberProfile } from '../types';

export interface FetchChatGroupInfoType {
chatId: string;
pageNumber?: number;
pageSize?: number;
page?: number;
limit?: number;
env?: ENV;
}

@@ -20,20 +20,15 @@ export const getGroupMembers = async (
totalMembersCount: ChatMemberCounts;
members: ChatMemberProfile[];
}> => {
const {
chatId,
pageNumber = 1,
pageSize = 20,
env = Constants.ENV.PROD,
} = options;
const { chatId, page = 1, limit = 20, env = Constants.ENV.PROD } = options;

try {
if (!chatId) {
throw new Error('Chat ID is required.');
}

const API_BASE_URL = getAPIBaseUrls(env);
const requestUrl = `${API_BASE_URL}/v1/chat/${chatId}/members?pageNumber=${pageNumber}&pageSize=${pageSize}`;
const requestUrl = `${API_BASE_URL}/v1/chat/${chatId}/members?pageNumber=${page}&pageSize=${limit}`;

const response = await axios.get(requestUrl);
return response.data;
56 changes: 54 additions & 2 deletions packages/restapi/src/lib/chat/helpers/payloadHelper.ts
Original file line number Diff line number Diff line change
@@ -10,15 +10,15 @@ import {
GroupAccess,
SpaceAccess,
GroupInfoDTO,
ChatMemberProfile,
} from '../../types';
import { getEncryptedRequest } from './crypto';
import { ENV } from '../../constants';
import { IPGPHelper, PGPHelper, pgpDecrypt } from './pgp';
import * as AES from './aes';
import { sign } from './pgp';
import { MessageObj } from '../../types/messageTypes';

import * as CryptoJS from 'crypto-js';
import { getAllGroupMembers } from '../getAllGroupMembers';
export interface ISendMessagePayload {
fromDID: string;
toDID: string;
@@ -281,6 +281,58 @@ export const groupDtoToSpaceDto = (groupDto: GroupDTO): SpaceDTO => {
return spaceDto;
};

export const groupDtoToSpaceDtoV2 = async (
groupDto: GroupInfoDTO,
env: ENV = ENV.PROD
): Promise<SpaceDTO> => {
const members = await getAllGroupMembers({
chatId: groupDto.chatId,
env: env,
});

const spaceDto: SpaceDTO = {
members: members
.filter((member) => member.intent)
.map((member) => ({
wallet: member.address,
publicKey: member.userInfo.publicKey ?? '',
isSpeaker: member.role === 'admin',
image: member.userInfo.profile.picture ?? '',
})),
pendingMembers: members
.filter((member) => !member.intent)
.map((pendingMember) => ({
wallet: pendingMember.address,
publicKey: pendingMember.userInfo.publicKey ?? '',
isSpeaker: pendingMember.role === 'admin',
image: pendingMember.userInfo.profile.picture ?? '',
})),
contractAddressERC20: null,
numberOfERC20: 0,
contractAddressNFT: null,
numberOfNFTTokens: 0,
verificationProof: 'a',
spaceImage: groupDto.groupImage,
spaceName: groupDto.groupName,
isPublic: groupDto.isPublic,
spaceDescription: groupDto.groupDescription,
spaceCreator: groupDto.groupCreator,
spaceId: groupDto.chatId,
scheduleAt: groupDto.scheduleAt,
scheduleEnd: groupDto.scheduleEnd,
status: groupDto.status ?? null,
meta: groupDto.meta,
};

if (groupDto.rules) {
spaceDto.rules = {
entry: groupDto.rules.entry,
};
}

return spaceDto;
};

export const convertSpaceRulesToRules = (spaceRules: SpaceRules): Rules => {
return {
entry: spaceRules.entry,
Loading

0 comments on commit 76bd15c

Please sign in to comment.