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 @@ -1320,6 +1320,43 @@ ); } +function getAvailableThreadMemberActions( + memberInfo: RelativeMemberInfo, + threadInfo: ThreadInfo, + canEdit: ?boolean = true, +): $ReadOnlyArray<'remove_user' | 'remove_admin' | 'make_admin'> { + const role = memberInfo.role; + if (!canEdit || !role) { + return []; + } + + const canRemoveMembers = threadHasPermission( + threadInfo, + threadPermissions.REMOVE_MEMBERS, + ); + const canChangeRoles = threadHasPermission( + threadInfo, + threadPermissions.CHANGE_ROLE, + ); + + const result = []; + if ( + canRemoveMembers && + !memberInfo.isViewer && + (canChangeRoles || threadInfo.roles[role]?.isDefault) + ) { + result.push('remove_user'); + } + + if (canChangeRoles && memberInfo.username && threadHasAdminRole(threadInfo)) { + result.push( + memberIsAdmin(memberInfo, threadInfo) ? 'remove_admin' : 'make_admin', + ); + } + + return result; +} + export { colorIsDark, generateRandomColor, @@ -1379,4 +1416,5 @@ useThreadListSearch, removeMemberFromThread, switchMemberAdminRoleInThread, + getAvailableThreadMemberActions, }; 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 @@ -16,17 +16,15 @@ } from 'lib/actions/thread-actions'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors'; import { - threadHasPermission, memberIsAdmin, memberHasAdminPowers, - threadHasAdminRole, + getAvailableThreadMemberActions, } from 'lib/shared/thread-utils'; import { stringForUser } from 'lib/shared/user-utils'; import type { LoadingStatus } from 'lib/types/loading-types'; import { type ThreadInfo, type RelativeMemberInfo, - threadPermissions, } from 'lib/types/thread-types'; import PencilIcon from '../../components/pencil-icon.react'; @@ -70,47 +68,6 @@ class ThreadSettingsMember extends React.PureComponent { editButton: ?React.ElementRef; - visibleEntryIDs() { - const role = this.props.memberInfo.role; - if (!this.props.canEdit || !role) { - return []; - } - - const canRemoveMembers = threadHasPermission( - this.props.threadInfo, - threadPermissions.REMOVE_MEMBERS, - ); - const canChangeRoles = threadHasPermission( - this.props.threadInfo, - threadPermissions.CHANGE_ROLE, - ); - - const result = []; - if ( - canRemoveMembers && - !this.props.memberInfo.isViewer && - (canChangeRoles || - (this.props.threadInfo.roles[role] && - this.props.threadInfo.roles[role].isDefault)) - ) { - result.push('remove_user'); - } - - if ( - canChangeRoles && - this.props.memberInfo.username && - threadHasAdminRole(this.props.threadInfo) - ) { - result.push( - memberIsAdmin(this.props.memberInfo, this.props.threadInfo) - ? 'remove_admin' - : 'make_admin', - ); - } - - return result; - } - render() { const userText = stringForUser(this.props.memberInfo); let userInfo = null; @@ -139,7 +96,13 @@ color={this.props.colors.panelForegroundSecondaryLabel} /> ); - } else if (this.visibleEntryIDs().length !== 0) { + } else if ( + getAvailableThreadMemberActions( + this.props.memberInfo, + this.props.threadInfo, + this.props.canEdit, + ).length !== 0 + ) { editButton = ( { - const { role } = memberInfo; - if (!role) { - return []; - } - - const canRemoveMembers = threadHasPermission( - threadInfo, - threadPermissions.REMOVE_MEMBERS, - ); - const canChangeRoles = threadHasPermission( - threadInfo, - threadPermissions.CHANGE_ROLE, - ); - - const actions = []; - - const isAdmin = memberIsAdmin(memberInfo, threadInfo); - if (canChangeRoles && memberInfo.username && isAdmin) { - actions.push( - , - ); - } else if (canChangeRoles && memberInfo.username) { - actions.push( - , - ); - } - - if ( - canRemoveMembers && - !memberInfo.isViewer && - (canChangeRoles || threadInfo.roles[role]?.isDefault) - ) { - actions.push( - , - ); - } - - return actions; - }, [memberInfo, onClickRemoveUser, onMemberAdminRoleToggled, threadInfo]); + const menuItems = React.useMemo( + () => + getAvailableThreadMemberActions(memberInfo, threadInfo).map(action => { + if (action === 'remove_admin') { + return ( + + ); + } + if (action === 'make_admin') { + return ( + + ); + } + if (action === 'remove_user') { + return ( + + ); + } + return null; + }), + [memberInfo, onClickRemoveUser, onMemberAdminRoleToggled, threadInfo], + ); const userSettingsIcon = React.useMemo( () => ,