diff --git a/lib/utils/role-utils.js b/lib/utils/role-utils.js
--- a/lib/utils/role-utils.js
+++ b/lib/utils/role-utils.js
@@ -2,6 +2,8 @@
import * as React from 'react';
+import { useSelector } from './redux-utils.js';
+import { threadInfoSelector } from '../selectors/thread-selectors.js';
import {
type UserSurfacedPermissionOption,
userSurfacedPermissions,
@@ -9,6 +11,7 @@
} from '../types/thread-permission-types.js';
import type { ThreadType } from '../types/thread-types-enum.js';
import { threadTypes } from '../types/thread-types-enum.js';
+import type { ThreadInfo, RelativeMemberInfo } from '../types/thread-types.js';
function useFilterPermissionOptionsByThreadType(
threadType: ThreadType,
@@ -74,8 +77,58 @@
}, [roleName, defaultRoleID, existingRoleID]);
}
+function useRoleNameFromCommunityThreadInfo(
+ threadInfo: ThreadInfo,
+ memberInfo: RelativeMemberInfo,
+): ?string {
+ // With the nature of how roles are set up, when introspecting into a
+ // non-community root thread, the roles in the threadInfo will just be
+ // "Members". This means that if we simply introspect into the threadInfo
+ // here, and try to pull the role, we'll potentially only get Members.
+ // The solution here is to pull the roles information from the top-most
+ // (i.e. community) threadInfo, and then use the roles from there.
+ // In the event that the threadInfo is a community thread, then we can just
+ // use the roles from the threadInfo directly. I'm choosing to fallback
+ // if (for some reason) the memberInfo from the 'topMostThreadInfo' is
+ // undefined to prevent the app from crashing, but this ideally shouldn't
+ // happen in the first place in non-GENESIS threads since a member part of a
+ // subchannel should be a member of the community.
+ const { community } = threadInfo;
+ const communityThreadInfo = useSelector(state =>
+ community ? threadInfoSelector(state)[community] : null,
+ );
+ const topMostThreadInfo = communityThreadInfo || threadInfo;
+
+ // The special case is GENESIS threads, since per prior discussion
+ // (see context: https://linear.app/comm/issue/ENG-4077/), we don't really
+ // support roles for it. Also with GENESIS, the list of
+ // members are not populated in the community root. So in this case
+ // to prevent crashing, we should just return the role name from the
+ // current thread info.
+ if (topMostThreadInfo.type === threadTypes.GENESIS) {
+ return memberInfo.role && threadInfo.roles[memberInfo.role].name;
+ }
+
+ const { roles } = topMostThreadInfo;
+ const memberInfoFromTopMostThreadInfo = topMostThreadInfo.members.find(
+ member => member.id === memberInfo.id,
+ );
+ if (!memberInfoFromTopMostThreadInfo) {
+ console.warn(
+ `Could not find memberInfo for member ${memberInfo.id} in ` +
+ `thread ${topMostThreadInfo.id}. This is unexpected, ` +
+ `please investigate.`,
+ );
+ }
+
+ const { role } = memberInfoFromTopMostThreadInfo || memberInfo;
+ const roleName = role && roles[role].name;
+ return roleName;
+}
+
export {
useFilterPermissionOptionsByThreadType,
constructRoleDeletionMessagePrompt,
useRoleDeletableAndEditableStatus,
+ useRoleNameFromCommunityThreadInfo,
};
diff --git a/native/chat/settings/thread-settings-member.react.js b/native/chat/settings/thread-settings-member.react.js
--- a/native/chat/settings/thread-settings-member.react.js
+++ b/native/chat/settings/thread-settings-member.react.js
@@ -23,6 +23,7 @@
type ThreadInfo,
type RelativeMemberInfo,
} from 'lib/types/thread-types.js';
+import { useRoleNameFromCommunityThreadInfo } from 'lib/utils/role-utils.js';
import type { ThreadSettingsNavigate } from './thread-settings.react.js';
import UserAvatar from '../../avatars/user-avatar.react.js';
@@ -54,6 +55,7 @@
type Props = {
...BaseProps,
// Redux state
+ +roleName: ?string,
+removeUserLoadingStatus: LoadingStatus,
+changeRoleLoadingStatus: LoadingStatus,
+colors: Colors,
@@ -114,14 +116,10 @@
);
}
- const roleName =
- this.props.memberInfo.role &&
- this.props.threadInfo.roles[this.props.memberInfo.role].name;
-
const roleInfo = (
- {roleName}
+ {this.props.roleName}
);
@@ -274,10 +272,16 @@
const keyboardState = React.useContext(KeyboardContext);
const overlayContext = React.useContext(OverlayContext);
+ const roleName = useRoleNameFromCommunityThreadInfo(
+ props.threadInfo,
+ props.memberInfo,
+ );
+
return (
{
@@ -110,8 +111,6 @@
[],
);
- const roleName = role && roles[role].name;
-
const label = React.useMemo(
() => ,
[roleName],