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 @@ -9,12 +9,13 @@ userSurfacedPermissions, userSurfacedPermissionOptions, } from '../types/thread-permission-types.js'; -import { type ThreadType, threadTypes } from '../types/thread-types-enum.js'; import type { + RawThreadInfos, ThreadInfo, RelativeMemberInfo, RoleInfo, -} from '../types/thread-types.js'; +} from '../types/thread-types'; +import { type ThreadType, threadTypes } from '../types/thread-types-enum.js'; function useFilterPermissionOptionsByThreadType( threadType: ThreadType, @@ -118,9 +119,46 @@ return roleMap; } +function persistMigrationToRemoveDescendantOpenVoiced( + rawThreadInfos: RawThreadInfos, +): RawThreadInfos { + if (!rawThreadInfos) { + return {}; + } + + const updatedThreadInfos = {}; + for (const threadID in rawThreadInfos) { + const threadInfo = rawThreadInfos[threadID]; + const { roles } = threadInfo; + + const updatedRoles = {}; + for (const roleID in roles) { + const role = roles[roleID]; + const { permissions: rolePermissions } = role; + const updatedPermissions = {}; + for (const permission in rolePermissions) { + if (permission !== 'descendant_open_voiced') { + updatedPermissions[permission] = rolePermissions[permission]; + } + } + updatedRoles[roleID] = { ...role, permissions: updatedPermissions }; + } + + const updatedThreadInfo = { + ...threadInfo, + roles: updatedRoles, + }; + + updatedThreadInfos[threadID] = updatedThreadInfo; + } + + return updatedThreadInfos; +} + export { useFilterPermissionOptionsByThreadType, constructRoleDeletionMessagePrompt, useRoleDeletableAndEditableStatus, useRolesFromCommunityThreadInfo, + persistMigrationToRemoveDescendantOpenVoiced, }; diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -71,6 +71,7 @@ convertThreadStoreThreadInfosToNewIDSchema, } from 'lib/utils/migration-utils.js'; import { defaultNotifPermissionAlertInfo } from 'lib/utils/push-alerts.js'; +import { persistMigrationToRemoveDescendantOpenVoiced } from 'lib/utils/role-utils.js'; import { convertClientDBThreadInfoToRawThreadInfo, convertRawThreadInfoToClientDBThreadInfo, @@ -836,6 +837,44 @@ }, }; }, + [55]: state => { + const clientDBThreadInfos = commCoreModule.getAllThreadsSync(); + const rawThreadInfos = clientDBThreadInfos.map( + convertClientDBThreadInfoToRawThreadInfo, + ); + const rawThreadInfosObject = rawThreadInfos.reduce((acc, threadInfo) => { + acc[threadInfo.id] = threadInfo; + return acc; + }, {}); + + const migratedRawThreadInfos = + persistMigrationToRemoveDescendantOpenVoiced(rawThreadInfosObject); + + const migratedThreadInfosArray = Object.keys(migratedRawThreadInfos).map( + id => migratedRawThreadInfos[id], + ); + const convertedClientDBThreadInfos = migratedThreadInfosArray.map( + convertRawThreadInfoToClientDBThreadInfo, + ); + const operations: $ReadOnlyArray = [ + { + type: 'remove_all', + }, + ...convertedClientDBThreadInfos.map((thread: ClientDBThreadInfo) => ({ + type: 'replace', + payload: thread, + })), + ]; + + try { + commCoreModule.processThreadStoreOperationsSync(operations); + } catch (exception) { + console.log(exception); + return { ...state, cookie: null }; + } + + return state; + }, }; // After migration 31, we'll no longer want to persist `messageStore.messages` @@ -965,7 +1004,7 @@ 'connection', ], debug: __DEV__, - version: 54, + version: 55, transforms: [ messageStoreMessagesBlocklistTransform, reportStoreTransform,