diff --git a/native/roles/create-roles-screen.react.js b/native/roles/create-roles-screen.react.js index a70c9ed54..b37eae567 100644 --- a/native/roles/create-roles-screen.react.js +++ b/native/roles/create-roles-screen.react.js @@ -1,222 +1,254 @@ // @flow import * as React from 'react'; -import { View, Text, TouchableOpacity } from 'react-native'; +import { View, Text, TouchableOpacity, ActivityIndicator } from 'react-native'; import { ScrollView } from 'react-native-gesture-handler'; +import { modifyCommunityRoleActionTypes } from 'lib/actions/thread-actions.js'; +import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; +import type { LoadingStatus } from 'lib/types/loading-types.js'; import { type UserSurfacedPermissionOption, type UserSurfacedPermission, } from 'lib/types/thread-permission-types.js'; import type { ThreadInfo } from 'lib/types/thread-types.js'; import { useFilterPermissionOptionsByThreadType } from 'lib/utils/role-utils.js'; import CreateRolesHeaderRightButton from './create-roles-header-right-button.react.js'; import type { RolesNavigationProp } from './roles-navigator.react.js'; import EnumSettingsOption from '../components/enum-settings-option.react.js'; import SWMansionIcon from '../components/swmansion-icon.react.js'; import TextInput from '../components/text-input.react.js'; import type { NavigationRoute } from '../navigation/route-names.js'; +import { useSelector } from '../redux/redux-utils.js'; import { useStyles } from '../themes/colors.js'; export type CreateRolesScreenParams = { +threadInfo: ThreadInfo, +action: 'create_role' | 'edit_role', +roleName: string, +rolePermissions: $ReadOnlySet, }; type CreateRolesScreenProps = { +navigation: RolesNavigationProp<'CreateRolesScreen'>, +route: NavigationRoute<'CreateRolesScreen'>, }; +const createRolesLoadingStatusSelector = createLoadingStatusSelector( + modifyCommunityRoleActionTypes, +); + function CreateRolesScreen(props: CreateRolesScreenProps): React.Node { const { threadInfo, action, roleName: defaultRoleName, rolePermissions: defaultRolePermissions, } = props.route.params; + const createRolesLoadingStatus: LoadingStatus = useSelector( + createRolesLoadingStatusSelector, + ); + const [customRoleName, setCustomRoleName] = React.useState(defaultRoleName); const [selectedPermissions, setSelectedPermissions] = React.useState< $ReadOnlySet, >(defaultRolePermissions); const styles = useStyles(unboundStyles); const onClearPermissions = React.useCallback(() => { setSelectedPermissions(new Set()); }, []); const isSelectedPermissionsEmpty = selectedPermissions.size === 0; const clearPermissionsText = React.useMemo(() => { const textStyle = isSelectedPermissionsEmpty ? styles.clearPermissionsTextDisabled : styles.clearPermissionsText; return ( Clear permissions ); }, [ isSelectedPermissionsEmpty, onClearPermissions, styles.clearPermissionsText, styles.clearPermissionsTextDisabled, ]); const isUserSurfacedPermissionSelected = React.useCallback( (option: UserSurfacedPermissionOption) => selectedPermissions.has(option.userSurfacedPermission), [selectedPermissions], ); const onEnumValuePress = React.useCallback( (option: UserSurfacedPermissionOption) => setSelectedPermissions(currentPermissions => { if (currentPermissions.has(option.userSurfacedPermission)) { const newPermissions = new Set(currentPermissions); newPermissions.delete(option.userSurfacedPermission); return newPermissions; } else { return new Set([ ...currentPermissions, option.userSurfacedPermission, ]); } }), [], ); React.useEffect( () => props.navigation.setParams({ threadInfo, action, roleName: customRoleName, rolePermissions: selectedPermissions, }), [props.navigation, threadInfo, action, customRoleName, selectedPermissions], ); const filteredUserSurfacedPermissionOptions = useFilterPermissionOptionsByThreadType(threadInfo.type); const permissionsList = React.useMemo( () => [...filteredUserSurfacedPermissionOptions].map(permission => ( onEnumValuePress(permission)} /> )), [ isUserSurfacedPermissionSelected, filteredUserSurfacedPermissionOptions, onEnumValuePress, ], ); const onChangeRoleNameInput = React.useCallback((roleName: string) => { setCustomRoleName(roleName); }, []); React.useEffect( () => props.navigation.setOptions({ // eslint-disable-next-line react/display-name - headerRight: () => , + headerRight: () => { + if (createRolesLoadingStatus === 'loading') { + return ( + + ); + } + + return ; + }, }), - [props.navigation, props.route], + [ + createRolesLoadingStatus, + props.navigation, + styles.activityIndicator, + props.route, + ], ); return ( ROLE NAME PERMISSIONS {clearPermissionsText} {permissionsList} ); } const unboundStyles = { roleNameContainer: { marginTop: 30, }, roleNameText: { color: 'panelBackgroundLabel', fontSize: 12, marginBottom: 5, marginLeft: 10, }, roleInput: { backgroundColor: 'panelForeground', padding: 12, flexDirection: 'row', justifyContent: 'space-between', }, roleInputComponent: { color: 'panelForegroundLabel', fontSize: 16, }, pencilIcon: { color: 'panelInputSecondaryForeground', }, permissionsContainer: { marginTop: 20, paddingBottom: 220, }, permissionsHeader: { flexDirection: 'row', justifyContent: 'space-between', }, permissionsText: { color: 'panelBackgroundLabel', fontSize: 12, marginLeft: 10, }, clearPermissionsText: { color: 'purpleLink', fontSize: 12, marginRight: 15, }, clearPermissionsTextDisabled: { color: 'disabledButton', fontSize: 12, marginRight: 15, }, permissionsListContainer: { backgroundColor: 'panelForeground', marginTop: 10, }, + activityIndicator: { + paddingRight: 15, + }, }; export default CreateRolesScreen;