diff --git a/lib/shared/search-utils.js b/lib/shared/search-utils.js --- a/lib/shared/search-utils.js +++ b/lib/shared/search-utils.js @@ -4,11 +4,7 @@ import { messageID } from './message-utils.js'; import SearchIndex from './search-index.js'; -import { - getContainingThreadID, - threadMemberHasPermission, - userIsMember, -} from './thread-utils.js'; +import { getContainingThreadID, userIsMember } from './thread-utils.js'; import { searchMessagesActionTypes, useSearchMessages as useSearchMessagesAction, @@ -21,6 +17,7 @@ import genesis from '../facts/genesis.js'; import { useIdentitySearch } from '../identity-search/identity-search-context.js'; import { useLegacyAshoatKeyserverCall } from '../keyserver-conn/legacy-keyserver-call.js'; +import { decodeThreadRolePermissionsBitmaskArray } from '../permissions/minimally-encoded-thread-permissions.js'; import type { ChatMessageInfoItem, MessageListData, @@ -28,9 +25,14 @@ import { useUserSearchIndex } from '../selectors/nav-selectors.js'; import { relationshipBlockedInEitherDirection } from '../shared/relationship-utils.js'; import type { MessageInfo, RawMessageInfo } from '../types/message-types.js'; -import type { ThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js'; +import type { + RoleInfo, + ThreadInfo, + RelativeMemberInfo, +} from '../types/minimally-encoded-thread-permissions-types.js'; import { userRelationshipStatus } from '../types/relationship-types.js'; import { threadPermissions } from '../types/thread-permission-types.js'; +import type { ThreadRolePermissionsBlob } from '../types/thread-permission-types.js'; import { type ThreadType, threadTypes } from '../types/thread-types-enum.js'; import type { AccountUserInfo, @@ -70,14 +72,28 @@ if (excludeUserIDs.includes(id) || id in results) { return; } - if ( - communityThreadInfo && - !threadMemberHasPermission( - communityThreadInfo, - id, - threadPermissions.KNOW_OF, - ) - ) { + + // We want to determine if user has `KNOW_OF` permission in community thread. + // 1. Find the `MemberInfo` corresponding to `id` in `communityThreadInfo`. + const memberInfo: ?RelativeMemberInfo = communityThreadInfo?.members.find( + m => m.id === id, + ); + + // 2. Find the role of the `userInfo.id` in the `communityThreadInfo`. + const role: ?RoleInfo = memberInfo?.role + ? communityThreadInfo?.roles[memberInfo.role] + : null; + + // 3. Decode the bitmask array of `role.permissions`. + const decodedRolePermissions: ?ThreadRolePermissionsBlob = role?.permissions + ? decodeThreadRolePermissionsBitmaskArray(role.permissions) + : null; + + // 4. Check whether user has the `KNOW_OF` role permission. + const hasKnowOfPermission = + decodedRolePermissions?.[threadPermissions.KNOW_OF] === true; + + if (communityThreadInfo && !hasKnowOfPermission) { return; } results[id] = { diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js --- a/lib/shared/thread-utils.js +++ b/lib/shared/thread-utils.js @@ -1189,20 +1189,6 @@ } } -function threadMemberHasPermission( - threadInfo: ThreadInfo, - memberID: string, - permission: ThreadPermission, -): boolean { - for (const member of threadInfo.members) { - if (member.id !== memberID) { - continue; - } - return hasPermission(member.permissions, permission); - } - return false; -} - function checkIfDefaultMembersAreVoiced(threadInfo: ThreadInfo): boolean { const defaultRoleID = Object.keys(threadInfo.roles).find(roleID => roleIsDefaultRole(threadInfo.roles[roleID]), @@ -1627,7 +1613,6 @@ threadLabel, useExistingThreadInfoFinder, getThreadTypeParentRequirement, - threadMemberHasPermission, checkIfDefaultMembersAreVoiced, draftKeySuffix, draftKeyFromThreadID,