diff --git a/lib/utils/role-utils.js b/lib/utils/role-utils.js --- a/lib/utils/role-utils.js +++ b/lib/utils/role-utils.js @@ -4,42 +4,12 @@ import { useSelector } from './redux-utils.js'; import { threadInfoSelector } from '../selectors/thread-selectors.js'; -import { - type UserSurfacedPermissionOption, - userSurfacedPermissions, - userSurfacedPermissionOptions, -} from '../types/thread-permission-types.js'; -import { type ThreadType, threadTypes } from '../types/thread-types-enum.js'; import type { ThreadInfo, RelativeMemberInfo, RoleInfo, -} from '../types/thread-types.js'; - -function useFilterPermissionOptionsByThreadType( - threadType: ThreadType, -): $ReadOnlySet { - // If the thread is a community announcement root, we want to allow - // the option to be voiced in the announcement channels. Otherwise, - // we want to remove that option from being configured since this will - // be guaranteed on the keyserver. - const shouldFilterVoicedInAnnouncementChannel = - threadType === threadTypes.COMMUNITY_ROOT; - - return React.useMemo(() => { - if (!shouldFilterVoicedInAnnouncementChannel) { - return userSurfacedPermissionOptions; - } - - return new Set( - [...userSurfacedPermissionOptions].filter( - option => - option.userSurfacedPermission !== - userSurfacedPermissions.VOICED_IN_ANNOUNCEMENT_CHANNELS, - ), - ); - }, [shouldFilterVoicedInAnnouncementChannel]); -} +} from '../types/thread-types'; +import { threadTypes } from '../types/thread-types-enum.js'; function constructRoleDeletionMessagePrompt( defaultRoleName: string, @@ -119,7 +89,6 @@ } export { - useFilterPermissionOptionsByThreadType, constructRoleDeletionMessagePrompt, useRoleDeletableAndEditableStatus, useRolesFromCommunityThreadInfo, diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -87,7 +87,7 @@ import { defaultState } from './default-state.js'; import { migrateThreadStoreForEditThreadPermissions } from './edit-thread-permission-migration.js'; import { persistMigrationForManagePinsThreadPermission } from './manage-pins-permission-migration.js'; -import { persistMigrationToRemoveDescendantOpenVoiced } from './remove-select-role-permissions.js'; +import { persistMigrationToRemoveSelectRolePermissions } from './remove-select-role-permissions.js'; import type { AppState } from './state-types.js'; import { unshimClientDB } from './unshim-utils.js'; import { updateRolesAndPermissions } from './update-roles-and-permissions.js'; @@ -865,7 +865,7 @@ }, {}); const migratedRawThreadInfos = - persistMigrationToRemoveDescendantOpenVoiced(rawThreadInfosObject); + persistMigrationToRemoveSelectRolePermissions(rawThreadInfosObject); const migratedThreadInfosArray = Object.keys(migratedRawThreadInfos).map( id => migratedRawThreadInfos[id], diff --git a/native/redux/remove-select-role-permissions.js b/native/redux/remove-select-role-permissions.js --- a/native/redux/remove-select-role-permissions.js +++ b/native/redux/remove-select-role-permissions.js @@ -1,8 +1,9 @@ // @flow import type { RawThreadInfos } from 'lib/types/thread-types.js'; +import { permissionsToRemoveInMigration } from 'lib/utils/migration-utils.js'; -function persistMigrationToRemoveDescendantOpenVoiced( +function persistMigrationToRemoveSelectRolePermissions( rawThreadInfos: RawThreadInfos, ): RawThreadInfos { // This is to handle the client being logged out and not having any threads @@ -23,7 +24,7 @@ const { permissions: rolePermissions } = role; const updatedPermissions = {}; for (const permission in rolePermissions) { - if (permission !== 'descendant_open_voiced') { + if (!permissionsToRemoveInMigration.includes(permission)) { updatedPermissions[permission] = rolePermissions[permission]; } } @@ -41,4 +42,4 @@ return updatedThreadInfos; } -export { persistMigrationToRemoveDescendantOpenVoiced }; +export { persistMigrationToRemoveSelectRolePermissions }; diff --git a/native/redux/remove-select-role-permissions.test.js b/native/redux/remove-select-role-permissions.test.js --- a/native/redux/remove-select-role-permissions.test.js +++ b/native/redux/remove-select-role-permissions.test.js @@ -3,28 +3,72 @@ import type { RawThreadInfos } from 'lib/types/thread-types.js'; import { deepDiff } from 'lib/utils/objects.js'; -import { persistMigrationToRemoveDescendantOpenVoiced } from './remove-select-role-permissions.js'; -import { threadStoreThreadsWithDescendantOpenVoiced } from './update-roles-and-permissions-test-data.js'; +import { persistMigrationToRemoveSelectRolePermissions } from './remove-select-role-permissions.js'; +import { threadStoreThreadsWithIncorrectPermissions } from './update-roles-and-permissions-test-data.js'; describe('persistMigrationToRemoveDescendantOpenVoiced', () => { it("should correctly remove 'descendant_open_voiced' from permissions", () => { const migratedRawThreadInfos: RawThreadInfos = - persistMigrationToRemoveDescendantOpenVoiced( - threadStoreThreadsWithDescendantOpenVoiced, + persistMigrationToRemoveSelectRolePermissions( + threadStoreThreadsWithIncorrectPermissions, ); - // Only role 256|85027 in thread 256|85022 has - // 'descendant_open_voiced' permissions included const threadDiff = deepDiff( - threadStoreThreadsWithDescendantOpenVoiced, + threadStoreThreadsWithIncorrectPermissions, migratedRawThreadInfos, ); + expect(threadDiff).toStrictEqual({ + '256|84852': { + roles: { + '256|84853': { + permissions: { + descendant_add_members: true, + descendant_edit_message: true, + descendant_react_to_message: true, + join_thread: true, + }, + }, + '256|84854': { + permissions: { + descendant_add_members: true, + descendant_change_role: true, + descendant_edit_entries: true, + descendant_edit_permissions: true, + descendant_edit_thread: true, + descendant_edit_thread_avatar: true, + descendant_edit_thread_color: true, + descendant_edit_thread_description: true, + descendant_manage_pins: true, + descendant_remove_members: true, + descendant_toplevel_create_sidebars: true, + descendant_toplevel_create_subthreads: true, + }, + }, + }, + }, '256|85022': { roles: { + '256|85024': { + permissions: { + descendant_add_members: true, + descendant_change_role: true, + descendant_edit_entries: true, + descendant_edit_permissions: true, + descendant_edit_thread: true, + descendant_edit_thread_avatar: true, + descendant_edit_thread_color: true, + descendant_edit_thread_description: true, + descendant_manage_pins: true, + descendant_remove_members: true, + descendant_toplevel_create_sidebars: true, + descendant_toplevel_create_subthreads: true, + }, + }, '256|85027': { permissions: { descendant_open_voiced: true, + join_thread: true, }, }, }, diff --git a/native/redux/update-roles-and-permissions-test-data.js b/native/redux/update-roles-and-permissions-test-data.js --- a/native/redux/update-roles-and-permissions-test-data.js +++ b/native/redux/update-roles-and-permissions-test-data.js @@ -8593,7 +8593,7 @@ }, }; -const threadStoreThreadsWithDescendantOpenVoiced: ThreadStoreThreadInfos = { +const threadStoreThreadsWithIncorrectPermissions: ThreadStoreThreadInfos = { '256|84852': { id: '256|84852', type: 9, @@ -10027,5 +10027,5 @@ threadStoreThreadsWithEmptyRolePermissions, threadStoreThreadsWithEmptyRolePermissionsAndMemberPermissions, threadStoreThreadsWithEmptyRoleAndMemberAndCurrentUserPermissions, - threadStoreThreadsWithDescendantOpenVoiced, + threadStoreThreadsWithIncorrectPermissions, }; 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 @@ -10,9 +10,9 @@ import { type UserSurfacedPermissionOption, type UserSurfacedPermission, + userSurfacedPermissionOptions, } 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'; @@ -139,12 +139,9 @@ ], ); - const filteredUserSurfacedPermissionOptions = - useFilterPermissionOptionsByThreadType(threadInfo.type); - const permissionsList = React.useMemo( () => - [...filteredUserSurfacedPermissionOptions].map(permission => ( + [...userSurfacedPermissionOptions].map(permission => ( onEnumValuePress(permission)} /> )), - [ - isUserSurfacedPermissionSelected, - filteredUserSurfacedPermissionOptions, - onEnumValuePress, - ], + [isUserSurfacedPermissionSelected, onEnumValuePress], ); const onChangeRoleNameInput = React.useCallback((roleName: string) => { diff --git a/web/roles/create-roles-modal.react.js b/web/roles/create-roles-modal.react.js --- a/web/roles/create-roles-modal.react.js +++ b/web/roles/create-roles-modal.react.js @@ -11,9 +11,10 @@ import { useModalContext } from 'lib/components/modal-provider.react.js'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; import type { LoadingStatus } from 'lib/types/loading-types.js'; -import type { - UserSurfacedPermission, - UserSurfacedPermissionOption, +import { + type UserSurfacedPermission, + type UserSurfacedPermissionOption, + userSurfacedPermissionOptions, } from 'lib/types/thread-permission-types.js'; import type { ThreadInfo, @@ -21,7 +22,6 @@ } from 'lib/types/thread-types.js'; import { useDispatchActionPromise } from 'lib/utils/action-utils.js'; import { values } from 'lib/utils/objects.js'; -import { useFilterPermissionOptionsByThreadType } from 'lib/utils/role-utils.js'; import css from './create-roles-modal.css'; import Button, { buttonThemes } from '../components/button.react.js'; @@ -141,12 +141,9 @@ [], ); - const filteredUserSurfacedPermissionOptions = - useFilterPermissionOptionsByThreadType(threadInfo.type); - const permissionsList = React.useMemo( () => - [...filteredUserSurfacedPermissionOptions].map(permission => ( + [...userSurfacedPermissionOptions].map(permission => ( )), - [ - filteredUserSurfacedPermissionOptions, - isUserSurfacedPermissionSelected, - onEnumValuePress, - ], + [isUserSurfacedPermissionSelected, onEnumValuePress], ); const errorMessageClassNames = classNames({