Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Group Members fixes #1445

Merged
merged 1 commit into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions components/StateHandlers/ActionSheetStateHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export default function ActionSheetStateHandler() {
options: ActionSheetOptions,
callback: (i?: number | undefined) => void | Promise<void>
) => {
if (options.options.length === 1) {
callback(0);
return;
}
useAppStore.getState().setActionSheetShown(true);
_showActionSheetWithOptions(options, (i?: number | undefined) => {
useAppStore.getState().setActionSheetShown(false);
Expand Down
16 changes: 12 additions & 4 deletions containers/GroupScreenMembersTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { actionSheetColors, textSecondaryColor } from "@styles/colors";
import {
getAccountIsAdmin,
getAccountIsSuperAdmin,
getAddressIsAdmin,
getAddressIsSuperAdmin,
} from "@utils/groupUtils/adminUtils";
import { getGroupMemberActions } from "@utils/groupUtils/getGroupMemberActions";
Expand Down Expand Up @@ -77,6 +78,11 @@ export const GroupScreenMembersTable: FC<GroupScreenMembersTableProps> = memo(
[currentAccount, members]
);

const currentAccountIsAdmin = useMemo(
() => getAddressIsAdmin(members, currentAccount),
[currentAccount, members]
);

const tableViewItems = useMemo(() => {
const items: TableViewItemType[] = [];

Expand All @@ -103,13 +109,14 @@ export const GroupScreenMembersTable: FC<GroupScreenMembersTableProps> = memo(
revokeSuperAdminIndex,
removeIndex,
destructiveButtonIndex,
} = getGroupMemberActions(
groupPermissionPolicy,
} = getGroupMemberActions({
groupPermissionLevel: groupPermissionPolicy,
isCurrentUser,
isSuperAdmin,
isAdmin,
currentAccountIsSuperAdmin
);
currentAccountIsSuperAdmin,
currentAccountIsAdmin,
});
showActionSheetWithOptions(
{
options,
Expand Down Expand Up @@ -201,6 +208,7 @@ export const GroupScreenMembersTable: FC<GroupScreenMembersTableProps> = memo(
colorScheme,
currentAccount,
currentAccountIsSuperAdmin,
currentAccountIsAdmin,
groupPermissionPolicy,
mappedData,
members,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export function ChatGroupMemberLeft({ inboxId }: IChatGroupMemberLeftProps) {
<ChatGroupUpdateText weight="bold">{readableName} </ChatGroupUpdateText>
</Pressable>
<ChatGroupUpdateText>
{translate("group_member_joined")}
{translate("group_member_left")}
</ChatGroupUpdateText>
</HStack>
);
Expand Down
92 changes: 49 additions & 43 deletions utils/groupUtils/getGroupMemberActions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,85 +3,91 @@ import { getGroupMemberActions } from "./getGroupMemberActions";

describe("getGroupMemberActions", () => {
test("should return correct actions when user can promote to admin", () => {
const result = getGroupMemberActions(
{
const result = getGroupMemberActions({
groupPermissionLevel: {
addAdminPolicy: "allow",
} as PermissionPolicySet,
false, // isCurrentUser
false, // isSuperAdmin
false, // isAdmin
true // currentAccountIsSuperAdmin
);
isCurrentUser: false,
isSuperAdmin: false,
isAdmin: false,
currentAccountIsSuperAdmin: true,
currentAccountIsAdmin: true,
});

expect(result.options).toContain("Promote to admin");
});

test("should return correct actions when user can promote to super admin", () => {
const result = getGroupMemberActions(
{
const result = getGroupMemberActions({
groupPermissionLevel: {
addAdminPolicy: "allow",
} as PermissionPolicySet,
false, // isCurrentUser
false, // isSuperAdmin
false, // isAdmin
true // currentAccountIsSuperAdmin
);
isCurrentUser: false,
isSuperAdmin: false,
isAdmin: false,
currentAccountIsSuperAdmin: true,
currentAccountIsAdmin: true,
});

expect(result.options).toContain("Promote to super admin");
});

test("should return correct actions when user can revoke admin", () => {
const result = getGroupMemberActions(
{
addAdminPolicy: "allow",
const result = getGroupMemberActions({
groupPermissionLevel: {
removeAdminPolicy: "allow",
} as PermissionPolicySet,
false, // isCurrentUser
false, // isSuperAdmin
true, // isAdmin
true // currentAccountIsSuperAdmin
);
isCurrentUser: false,
isSuperAdmin: false,
isAdmin: true,
currentAccountIsSuperAdmin: true,
currentAccountIsAdmin: true,
});

expect(result.options).toContain("Revoke admin");
});

test("should return correct actions when user can revoke super admin", () => {
const result = getGroupMemberActions(
{
const result = getGroupMemberActions({
groupPermissionLevel: {
addAdminPolicy: "allow",
} as PermissionPolicySet,
false, // isCurrentUser
true, // isSuperAdmin
false, // isAdmin
true // currentAccountIsSuperAdmin
);
isCurrentUser: false,
isSuperAdmin: true,
isAdmin: false,
currentAccountIsSuperAdmin: true,
currentAccountIsAdmin: true,
});

expect(result.options).toContain("Revoke super admin");
});

test("should return correct actions when user can remove from group", () => {
const result = getGroupMemberActions(
{
const result = getGroupMemberActions({
groupPermissionLevel: {
removeMemberPolicy: "allow",
} as PermissionPolicySet,
false, // isCurrentUser
false, // isSuperAdmin
false, // isAdmin
true // currentAccountIsSuperAdmin
);
isCurrentUser: false,
isSuperAdmin: false,
isAdmin: false,
currentAccountIsSuperAdmin: true,
currentAccountIsAdmin: true,
});

expect(result.options).toContain("Remove from group");
});

test("should not include admin actions for the current user", () => {
const result = getGroupMemberActions(
{
const result = getGroupMemberActions({
groupPermissionLevel: {
addAdminPolicy: "allow",
} as PermissionPolicySet,
true, // isCurrentUser
false, // isSuperAdmin
false, // isAdmin
true // currentAccountIsSuperAdmin
);
isCurrentUser: true,
isSuperAdmin: false,
isAdmin: false,
currentAccountIsSuperAdmin: true,
currentAccountIsAdmin: true,
});

expect(result.options).not.toContain("Promote to admin");
expect(result.options).not.toContain("Promote to super admin");
Expand Down
54 changes: 41 additions & 13 deletions utils/groupUtils/getGroupMemberActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,57 @@ import { translate } from "@i18n";
import { PermissionPolicySet } from "@xmtp/react-native-sdk/build/lib/types/PermissionPolicySet";
import { userCanDoGroupActions } from "./userCanDoGroupActions";

export const getGroupMemberActions = (
groupPermissionLevel: PermissionPolicySet | undefined,
isCurrentUser: boolean,
isSuperAdmin: boolean,
isAdmin: boolean,
currentAccountIsSuperAdmin: boolean
) => {
type GetGroupMemberActionsProps = {
groupPermissionLevel: PermissionPolicySet | undefined;
isCurrentUser: boolean;
isSuperAdmin: boolean;
isAdmin: boolean;
currentAccountIsSuperAdmin: boolean;
currentAccountIsAdmin: boolean;
};

export const getGroupMemberActions = ({
groupPermissionLevel,
isCurrentUser,
isSuperAdmin,
isAdmin,
currentAccountIsSuperAdmin,
currentAccountIsAdmin,
}: GetGroupMemberActionsProps) => {
const canRemove =
!isCurrentUser &&
userCanDoGroupActions(
groupPermissionLevel,
"removeMemberPolicy",
isSuperAdmin,
isAdmin
currentAccountIsSuperAdmin,
currentAccountIsAdmin
);
const canPromoteToSuperAdmin =
currentAccountIsSuperAdmin && !isSuperAdmin && !isCurrentUser;
!isSuperAdmin && !isCurrentUser && currentAccountIsSuperAdmin;
const canPromoteToAdmin =
!isCurrentUser && currentAccountIsSuperAdmin && !isAdmin && !isSuperAdmin;
!isCurrentUser &&
!isAdmin &&
!isSuperAdmin &&
userCanDoGroupActions(
groupPermissionLevel,
"addAdminPolicy",
currentAccountIsSuperAdmin,
currentAccountIsAdmin
);

const canRevokeAdmin =
!isCurrentUser && currentAccountIsSuperAdmin && isAdmin && !isSuperAdmin;
!isCurrentUser &&
isAdmin &&
!isSuperAdmin &&
userCanDoGroupActions(
groupPermissionLevel,
"removeAdminPolicy",
currentAccountIsSuperAdmin,
currentAccountIsAdmin
);
const canRevokeSuperAdmin =
!isCurrentUser && currentAccountIsSuperAdmin && isSuperAdmin;
const options = ["Profile page"];
const options = [translate("group_screen_member_actions.profile_page")];
let cancelButtonIndex = 1;
let promoteAdminIndex: number | undefined = undefined;
if (canPromoteToAdmin) {
Expand Down Expand Up @@ -54,6 +81,7 @@ export const getGroupMemberActions = (
cancelButtonIndex++;
}
let removeIndex: number | undefined = undefined;

if (canRemove) {
removeIndex = options.length;
options.push(translate("group_screen_member_actions.remove_member"));
Expand Down
6 changes: 3 additions & 3 deletions utils/groupUtils/userCanDoGroupActions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { PermissionPolicySet } from "@xmtp/react-native-sdk/build/lib/types/PermissionPolicySet";

type MemberRole = "admin" | "super_admin" | "member";
type MemberRole = "admin" | "superAdmin" | "member";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Update required: Multiple references to "super_admin" need to be changed

The codebase still contains multiple references to "super_admin" that need to be updated to maintain consistency with the new "superAdmin" naming convention. Here are the locations that require updates:

  • utils/groupUtils/getGroupMemberActions.ts: Translation key references
  • utils/groupUtils/adminUtils.ts: Permission level checks
  • utils/groupUtils/adminUtils.test.ts: Test case
  • queries/usePromoteToSuperAdminMutation.ts: Permission level assignment
  • screens/Profile.tsx: Translation key references
  • containers/GroupScreenMembersTable.tsx: Translation key reference
  • i18n/translations/en.ts and i18n/translations/fr.ts: Translation keys and values
🔗 Analysis chain

Renaming "super_admin" to "superAdmin" aligns with camelCase conventions.
This update maintains consistency. Ensure all references are updated.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify no lingering references to "super_admin" remain in the codebase.
rg "super_admin"

Length of output: 2014


type GetMemberRoleParams = {
isSuperAdmin: boolean;
Expand All @@ -11,7 +11,7 @@ const getMemberRole = ({
isSuperAdmin,
isAdmin,
}: GetMemberRoleParams): MemberRole => {
if (isSuperAdmin) return "super_admin";
if (isSuperAdmin) return "superAdmin";
if (isAdmin) return "admin";
return "member";
};
Expand All @@ -29,7 +29,7 @@ export const userCanDoGroupActions = (
if (policy === "deny") return false;
if (
policy === "admin" &&
(memberRole === "admin" || memberRole === "super_admin")
(memberRole === "admin" || memberRole === "superAdmin")
)
return true;
if (policy === memberRole) return true;
Expand Down
Loading