diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js --- a/lib/shared/thread-utils.js +++ b/lib/shared/thread-utils.js @@ -54,8 +54,10 @@ import { threadPermissionPropagationPrefixes, threadPermissions, + configurableCommunityPermissions, type ThreadPermission, type ThreadPermissionsInfo, + type UserSurfacedPermission, } from '../types/thread-permission-types.js'; import { type ThreadType, @@ -1566,6 +1568,34 @@ return roleNamesToMemberCount; } +type RoleUserSurfacedPermissions = { + +[roleName: string]: $ReadOnlyArray, +}; +function getRoleUserSurfacedPermissions( + threadInfo: ThreadInfo, +): RoleUserSurfacedPermissions { + const roleNamesToPermissions = {}; + + Object.keys(threadInfo.roles).forEach(roleID => { + const roleName = threadInfo.roles[roleID].name; + const rolePermissions = Object.keys(threadInfo.roles[roleID].permissions); + const setOfUserSurfacedPermissions = new Set(); + + rolePermissions.forEach(rolePermission => { + const userSurfacedPermission = Object.keys( + configurableCommunityPermissions, + ).find(key => configurableCommunityPermissions[key].has(rolePermission)); + + if (userSurfacedPermission) { + setOfUserSurfacedPermissions.add(userSurfacedPermission); + } + }); + roleNamesToPermissions[roleName] = [...setOfUserSurfacedPermissions]; + }); + + return roleNamesToPermissions; +} + export { threadHasPermission, viewerIsMember, @@ -1632,4 +1662,5 @@ patchThreadInfoToIncludeMentionedMembersOfParent, threadInfoInsideCommunity, getRoleMemberCountsForCommunity, + getRoleUserSurfacedPermissions, }; diff --git a/native/roles/community-roles-screen.react.js b/native/roles/community-roles-screen.react.js --- a/native/roles/community-roles-screen.react.js +++ b/native/roles/community-roles-screen.react.js @@ -5,7 +5,10 @@ import { ScrollView } from 'react-native-gesture-handler'; import { threadInfoSelector } from 'lib/selectors/thread-selectors.js'; -import { getRoleMemberCountsForCommunity } from 'lib/shared/thread-utils.js'; +import { + getRoleMemberCountsForCommunity, + getRoleUserSurfacedPermissions, +} from 'lib/shared/thread-utils.js'; import type { ThreadInfo } from 'lib/types/thread-types.js'; import RolePanelEntry from './role-panel-entry.react.js'; @@ -52,6 +55,11 @@ [threadInfo], ); + const roleNamesToUserSurfacedPermissions = React.useMemo( + () => getRoleUserSurfacedPermissions(threadInfo), + [threadInfo], + ); + const rolePanelList = React.useMemo(() => { const rolePanelEntries = []; @@ -59,14 +67,22 @@ rolePanelEntries.push( , ); }); return rolePanelEntries; - }, [roleNamesToMembers]); + }, [ + roleNamesToMembers, + props.navigation, + threadInfo, + roleNamesToUserSurfacedPermissions, + ]); const navigateToCreateRole = React.useCallback( () => diff --git a/native/roles/role-panel-entry.react.js b/native/roles/role-panel-entry.react.js --- a/native/roles/role-panel-entry.react.js +++ b/native/roles/role-panel-entry.react.js @@ -5,18 +5,27 @@ import { View, Text, TouchableOpacity, Platform } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import type { UserSurfacedPermission } from 'lib/types/thread-permission-types.js'; +import type { ThreadInfo } from 'lib/types/thread-types.js'; + +import type { RolesNavigationProp } from './roles-navigator.react.js'; import CommIcon from '../components/comm-icon.react.js'; import SWMansionIcon from '../components/swmansion-icon.react.js'; +import { CreateRolesScreenRouteName } from '../navigation/route-names.js'; import { useSelector } from '../redux/redux-utils.js'; import { useStyles } from '../themes/colors.js'; type RolePanelEntryProps = { + +navigation: RolesNavigationProp<'CommunityRolesScreen'>, + +threadInfo: ThreadInfo, +roleName: string, + +rolePermissions: $ReadOnlyArray, +memberCount: number, }; function RolePanelEntry(props: RolePanelEntryProps): React.Node { - const { roleName, memberCount } = props; + const { navigation, threadInfo, roleName, rolePermissions, memberCount } = + props; const styles = useStyles(unboundStyles); const menuButton = React.useMemo(() => { @@ -47,8 +56,19 @@ if (index === undefined || index === null || index === options.length) { return; } + + const selectedOption = options[index]; + + if (selectedOption === 'Edit role') { + navigation.navigate(CreateRolesScreenRouteName, { + threadInfo, + action: 'edit_role', + roleName, + rolePermissions, + }); + } }, - [options.length], + [navigation, options, roleName, rolePermissions, threadInfo], ); const activeTheme = useSelector(state => state.globalThemeInfo.activeTheme);