Page MenuHomePhabricator

D8391.id28353.diff
No OneTemporary

D8391.id28353.diff

diff --git a/lib/types/thread-permission-types.js b/lib/types/thread-permission-types.js
--- a/lib/types/thread-permission-types.js
+++ b/lib/types/thread-permission-types.js
@@ -84,6 +84,150 @@
export type ThreadPermissionFilterPrefix = $Values<
typeof threadPermissionFilterPrefixes,
>;
+
+type ConfigurableCommunityPermission = {
+ // Type the permissions as `string`, as opposed to `ThreadPermission`,
+ // because we open up the permissions to include an optional prefix
+ // (i.e. `descendant_`) to propagate certain permissions down the community.
+ +permissions: $ReadOnlyArray<string>,
+ +title: string,
+ +description: string,
+};
+export const configurableCommunityPermissions: $ReadOnlyArray<ConfigurableCommunityPermission> =
+ [
+ {
+ permissions: [
+ threadPermissions.EDIT_ENTRIES,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.EDIT_ENTRIES,
+ ],
+ title: 'Edit calendar',
+ description: 'Allows members to edit the community calendar',
+ },
+ {
+ permissions: [
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.KNOW_OF,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.VISIBLE,
+ ],
+ title: 'See secret channels',
+ description: 'Allows members to see all secret channels',
+ },
+ {
+ permissions: [threadPermissions.VOICED],
+ title: 'Speak in announcement channels',
+ description: 'Allows members to speak in announcement channels',
+ },
+ {
+ permissions: [
+ threadPermissions.EDIT_THREAD_NAME,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.EDIT_THREAD_NAME,
+
+ threadPermissions.EDIT_THREAD_DESCRIPTION,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.EDIT_THREAD_DESCRIPTION,
+
+ threadPermissions.EDIT_THREAD_COLOR,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.EDIT_THREAD_COLOR,
+
+ threadPermissions.CREATE_SUBCHANNELS,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissionFilterPrefixes.TOP_LEVEL +
+ threadPermissions.CREATE_SUBCHANNELS,
+
+ threadPermissions.EDIT_THREAD_AVATAR,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.EDIT_THREAD_AVATAR,
+ ],
+ title: 'Create and edit channels',
+ description: 'Allows members to create new and edit existing channels',
+ },
+ {
+ permissions: [
+ threadPermissions.DELETE_THREAD,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.DELETE_THREAD,
+ ],
+ title: 'Delete channels',
+ description: 'Allows members to delete channels',
+ },
+ {
+ permissions: [
+ threadPermissions.ADD_MEMBERS,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.ADD_MEMBERS,
+ ],
+ title: 'Add members',
+ description: 'Allows members to add other members to channels',
+ },
+ {
+ permissions: [
+ threadPermissions.REMOVE_MEMBERS,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.REMOVE_MEMBERS,
+ ],
+ title: 'Remove members',
+ description: 'Allows members to remove other members from channels',
+ },
+ {
+ permissions: [
+ threadPermissions.CHANGE_ROLE,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.CHANGE_ROLE,
+ ],
+ title: 'Change roles',
+ description: 'Allows members to change the roles of other members',
+ },
+ {
+ permissions: [
+ threadPermissions.EDIT_PERMISSIONS,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.EDIT_PERMISSIONS,
+ ],
+ title: 'Edit permissions',
+ description: 'Allows members to edit visibility permissions of channels',
+ },
+ {
+ permissions: [
+ threadPermissions.MANAGE_PINS,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.MANAGE_PINS,
+ ],
+ title: 'Manage pins',
+ description: 'Allows members to pin or unpin messages in channels',
+ },
+ {
+ permissions: [
+ threadPermissions.REACT_TO_MESSAGE,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.MANAGE_PINS,
+ ],
+ title: 'React to messages',
+ description: 'Allows members to add reactions to messages',
+ },
+ {
+ permissions: [
+ threadPermissions.EDIT_MESSAGE,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.EDIT_ENTRIES,
+ ],
+ title: 'Edit messages',
+ description: 'Allows members to edit their sent messages',
+ },
+ {
+ permissions: [
+ threadPermissions.MANAGE_INVITE_LINKS,
+ threadPermissionPropagationPrefixes.DESCENDANT +
+ threadPermissions.MANAGE_INVITE_LINKS,
+ ],
+ title: 'Manage invite links',
+ description: 'Allows members to handle invite links for the community',
+ },
+ ];
+
export type ThreadPermissionInfo =
| { +value: true, +source: string }
| { +value: false, +source: null };
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
@@ -1,11 +1,17 @@
// @flow
import * as React from 'react';
+import { View, Text, TouchableOpacity, ScrollView } from 'react-native';
+import { configurableCommunityPermissions } 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 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 { useStyles } from '../themes/colors.js';
export type CreateRolesScreenParams = {
+threadInfo: ThreadInfo,
@@ -16,9 +22,162 @@
+route: NavigationRoute<'CreateRolesScreen'>,
};
-// eslint-disable-next-line no-unused-vars
function CreateRolesScreen(props: CreateRolesScreenProps): React.Node {
- return <></>;
+ // eslint-disable-next-line no-unused-vars
+ const { threadInfo } = props.route.params;
+
+ const [customRoleName, setCustomRoleName] =
+ React.useState<string>('New Role');
+ const [selectedPermissions, setSelectedPermissions] = React.useState([]);
+
+ const styles = useStyles(unboundStyles);
+
+ const onClearPermissions = React.useCallback(() => {
+ setSelectedPermissions([]);
+ }, []);
+
+ const isSelectedPermissionsEmpty = selectedPermissions.length === 0;
+ const clearPermissionsText = React.useMemo(() => {
+ if (isSelectedPermissionsEmpty) {
+ return (
+ <Text style={styles.clearPermissionsTextDisabled}>
+ Clear permissions
+ </Text>
+ );
+ }
+
+ return (
+ <TouchableOpacity onPress={onClearPermissions}>
+ <Text style={styles.clearPermissionsText}>Clear permissions</Text>
+ </TouchableOpacity>
+ );
+ }, [
+ isSelectedPermissionsEmpty,
+ onClearPermissions,
+ styles.clearPermissionsText,
+ styles.clearPermissionsTextDisabled,
+ ]);
+
+ const isPermissionSelected = React.useCallback(
+ (permissions: $ReadOnlyArray<string>) =>
+ permissions.some(permission => selectedPermissions.includes(permission)),
+ [selectedPermissions],
+ );
+
+ const onEnumValuePress = React.useCallback(
+ (permissions: $ReadOnlyArray<string>) => {
+ if (isPermissionSelected(permissions)) {
+ setSelectedPermissions(currentPermissions =>
+ currentPermissions.filter(
+ permission => !permissions.includes(permission),
+ ),
+ );
+ } else {
+ setSelectedPermissions(currentPermissions => [
+ ...currentPermissions,
+ ...permissions,
+ ]);
+ }
+ },
+ [isPermissionSelected],
+ );
+ console.log(selectedPermissions);
+
+ const permissionsList = React.useMemo(
+ () =>
+ configurableCommunityPermissions.map(permission => (
+ <EnumSettingsOption
+ key={permission.title}
+ name={permission.title}
+ description={permission.description}
+ enumValue={isPermissionSelected(permission.permissions)}
+ onEnumValuePress={() => onEnumValuePress(permission.permissions)}
+ />
+ )),
+ [isPermissionSelected, onEnumValuePress],
+ );
+
+ const onChangeRoleNameInput = React.useCallback((roleName: string) => {
+ setCustomRoleName(roleName);
+ }, []);
+
+ return (
+ <View>
+ <View style={styles.roleNameContainer}>
+ <Text style={styles.roleNameText}>ROLE NAME</Text>
+ <View style={styles.roleInput}>
+ <TextInput
+ style={styles.roleInputComponent}
+ value={customRoleName}
+ onChangeText={onChangeRoleNameInput}
+ editable={true}
+ />
+ <SWMansionIcon name="edit-1" size={20} style={styles.pencilIcon} />
+ </View>
+ </View>
+ <View style={styles.permissionsContainer}>
+ <View style={styles.permissionsHeader}>
+ <Text style={styles.permissionsText}>PERMISSIONS</Text>
+ {clearPermissionsText}
+ </View>
+ <ScrollView style={styles.permissionsListContainer}>
+ {permissionsList}
+ </ScrollView>
+ </View>
+ </View>
+ );
}
+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: 'whiteText',
+ 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,
+ },
+};
+
export default CreateRolesScreen;

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 30, 4:28 PM (21 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2601629
Default Alt Text
D8391.id28353.diff (10 KB)

Event Timeline