diff --git a/native/roles/create-roles-header-right-button.react.js b/native/roles/create-roles-header-right-button.react.js --- a/native/roles/create-roles-header-right-button.react.js +++ b/native/roles/create-roles-header-right-button.react.js @@ -12,23 +12,36 @@ useServerCall, useDispatchActionPromise, } from 'lib/utils/action-utils.js'; +import { values } from 'lib/utils/objects.js'; import type { NavigationRoute } from '../navigation/route-names'; import { useStyles } from '../themes/colors.js'; type Props = { +route: NavigationRoute<'CreateRolesScreen'>, + +setRoleCreationFailed: boolean => mixed, }; function CreateRolesHeaderRightButton(props: Props): React.Node { const { threadInfo, action, roleName, rolePermissions } = props.route.params; + const { setRoleCreationFailed } = props; const navigation = useNavigation(); const styles = useStyles(unboundStyles); const callModifyCommunityRole = useServerCall(modifyCommunityRole); const dispatchActionPromise = useDispatchActionPromise(); + const threadRoleNames = React.useMemo( + () => values(threadInfo.roles).map(role => role.name), + [threadInfo.roles], + ); + const onPressCreate = React.useCallback(() => { + if (threadRoleNames.includes(roleName)) { + setRoleCreationFailed(true); + return; + } + dispatchActionPromise( modifyCommunityRoleActionTypes, callModifyCommunityRole({ @@ -48,6 +61,8 @@ roleName, rolePermissions, navigation, + setRoleCreationFailed, + threadRoleNames, ]); const shouldHeaderRightBeDisabled = roleName.length === 0; diff --git a/native/roles/create-roles-screen.react.js b/native/roles/create-roles-screen.react.js --- a/native/roles/create-roles-screen.react.js +++ b/native/roles/create-roles-screen.react.js @@ -57,8 +57,19 @@ $ReadOnlySet, >(defaultRolePermissions); + const [roleCreationFailed, setRoleCreationFailed] = + React.useState(false); + const styles = useStyles(unboundStyles); + const errorStyles = React.useMemo( + () => + roleCreationFailed + ? [styles.errorContainer, styles.errorContainerVisible] + : styles.errorContainer, + [roleCreationFailed, styles.errorContainer, styles.errorContainerVisible], + ); + const onClearPermissions = React.useCallback(() => { setSelectedPermissions(new Set()); }, []); @@ -140,6 +151,7 @@ ); const onChangeRoleNameInput = React.useCallback((roleName: string) => { + setRoleCreationFailed(false); setCustomRoleName(roleName); }, []); @@ -158,7 +170,12 @@ ); } - return ; + return ( + + ); }, }), [ @@ -182,6 +199,11 @@ /> + + + There is already a role with this name in the community + + @@ -219,6 +241,18 @@ pencilIcon: { color: 'panelInputSecondaryForeground', }, + errorContainer: { + marginTop: 10, + alignItems: 'center', + opacity: 0, + }, + errorContainerVisible: { + opacity: 1, + }, + errorText: { + color: 'redText', + fontSize: 14, + }, permissionsContainer: { marginTop: 20, paddingBottom: 220,