diff --git a/app/soapbox/features/group/components/group-member-list-item.tsx b/app/soapbox/features/group/components/group-member-list-item.tsx index 6ee6c5c59..76ebc1863 100644 --- a/app/soapbox/features/group/components/group-member-list-item.tsx +++ b/app/soapbox/features/group/components/group-member-list-item.tsx @@ -10,11 +10,10 @@ import { HStack, IconButton, Menu, MenuButton, MenuDivider, MenuItem, MenuLink, import SvgIcon from 'soapbox/components/ui/icon/svg-icon'; import { useAccount, useAppDispatch } from 'soapbox/hooks'; import { BaseGroupRoles, useGroupRoles } from 'soapbox/hooks/useGroupRoles'; -import { GroupMember } from 'soapbox/normalizers/group-member'; import toast from 'soapbox/toast'; import type { Menu as IMenu } from 'soapbox/components/dropdown-menu'; -import type { Account as AccountEntity, Group } from 'soapbox/types/entities'; +import type { Account as AccountEntity, Group, GroupMember } from 'soapbox/types/entities'; const messages = defineMessages({ blockConfirm: { id: 'confirmations.block_from_group.confirm', defaultMessage: 'Block' }, diff --git a/app/soapbox/hooks/api/useGroupMembers.ts b/app/soapbox/hooks/api/useGroupMembers.ts index 24e112ffa..305a969d5 100644 --- a/app/soapbox/hooks/api/useGroupMembers.ts +++ b/app/soapbox/hooks/api/useGroupMembers.ts @@ -1,28 +1,17 @@ import { Entities } from 'soapbox/entity-store/entities'; import { useEntities } from 'soapbox/entity-store/hooks'; -import { normalizeAccount } from 'soapbox/normalizers'; -import { Account } from 'soapbox/types/entities'; +import { GroupMember, groupMemberSchema } from 'soapbox/schemas'; -import { BaseGroupRoles, TruthSocialGroupRoles } from '../useGroupRoles'; - -interface GroupMember { - id: string - role: BaseGroupRoles | TruthSocialGroupRoles - account: Account | any -} - -const normalizeGroupMember = (groupMember: GroupMember): GroupMember => { - return { - ...groupMember, - account: normalizeAccount(groupMember.account), - }; +const parseGroupMember = (entity: unknown) => { + const result = groupMemberSchema.safeParse(entity); + if (result.success) { + return result.data; + } }; -const parseGroupMember = (entity: unknown) => entity ? normalizeGroupMember(entity as GroupMember) : undefined; - function useGroupMembers(groupId: string, role: string) { const { entities, ...result } = useEntities( - [Entities.GROUP_MEMBERSHIPS, `${groupId}:${role}`], + [Entities.GROUP_MEMBERSHIPS, groupId, role], `/api/v1/groups/${groupId}/memberships?role=${role}&limit=1`, { parser: parseGroupMember }, ); diff --git a/app/soapbox/normalizers/group-member.ts b/app/soapbox/normalizers/group-member.ts deleted file mode 100644 index 0f2dc97f9..000000000 --- a/app/soapbox/normalizers/group-member.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Group Member normalizer: - * Converts API group members into our internal format. - */ -import { BaseGroupRoles, TruthSocialGroupRoles } from 'soapbox/hooks/useGroupRoles'; -import { Account } from 'soapbox/types/entities'; - -import { normalizeAccount } from './account'; - -export interface GroupMember { - id: string - role: BaseGroupRoles | TruthSocialGroupRoles - account: Account | any -} - -export const normalizeGroupMember = (groupMember: GroupMember): GroupMember => { - return { - ...groupMember, - account: normalizeAccount(groupMember.account), - }; -}; diff --git a/app/soapbox/normalizers/index.ts b/app/soapbox/normalizers/index.ts index c4f4883bc..004049988 100644 --- a/app/soapbox/normalizers/index.ts +++ b/app/soapbox/normalizers/index.ts @@ -13,7 +13,6 @@ export { FilterRecord, normalizeFilter } from './filter'; export { FilterKeywordRecord, normalizeFilterKeyword } from './filter-keyword'; export { FilterStatusRecord, normalizeFilterStatus } from './filter-status'; export { normalizeGroup } from './group'; -// export { GroupMember, normalizeGroupMember } from './group-member'; export { GroupRelationshipRecord, normalizeGroupRelationship } from './group-relationship'; export { HistoryRecord, normalizeHistory } from './history'; export { InstanceRecord, normalizeInstance } from './instance'; diff --git a/app/soapbox/schemas/group-member.ts b/app/soapbox/schemas/group-member.ts new file mode 100644 index 000000000..99340911f --- /dev/null +++ b/app/soapbox/schemas/group-member.ts @@ -0,0 +1,26 @@ +import z from 'zod'; + +enum TruthSocialGroupRoles { + ADMIN = 'owner', + MODERATOR = 'admin', + USER = 'user' +} + +enum BaseGroupRoles { + ADMIN = 'admin', + MODERATOR = 'moderator', + USER = 'user' +} + +const groupMemberSchema = z.object({ + id: z.string(), + account: z.any(), + role: z.union([ + z.nativeEnum(TruthSocialGroupRoles), + z.nativeEnum(BaseGroupRoles), + ]), +}); + +type GroupMember = z.infer; + +export { groupMemberSchema, GroupMember }; \ No newline at end of file diff --git a/app/soapbox/schemas/index.ts b/app/soapbox/schemas/index.ts index f89e714c1..bae2eb830 100644 --- a/app/soapbox/schemas/index.ts +++ b/app/soapbox/schemas/index.ts @@ -2,5 +2,7 @@ export { customEmojiSchema } from './custom-emoji'; export type { CustomEmoji } from './custom-emoji'; export { groupSchema } from './group'; export type { Group } from './group'; +export { groupMemberSchema } from './group-member'; +export type { GroupMember } from './group-member'; export { groupRelationshipSchema } from './group-relationship'; export type { GroupRelationship } from './group-relationship';