diff --git a/lib/selectors/user-selectors.js b/lib/selectors/user-selectors.js --- a/lib/selectors/user-selectors.js +++ b/lib/selectors/user-selectors.js @@ -11,12 +11,12 @@ import SentencePrefixSearchIndex from '../shared/sentence-prefix-search-index.js'; import { getSingleOtherUser } from '../shared/thread-utils.js'; import type { ClientEmojiAvatar } from '../types/avatar-types'; +import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js'; import type { BaseAppState } from '../types/redux-types.js'; import { userRelationshipStatus } from '../types/relationship-types.js'; import { threadTypes } from '../types/thread-types-enum.js'; import type { LegacyRawThreadInfo, - LegacyRelativeMemberInfo, RelativeMemberInfo, RawThreadInfos, } from '../types/thread-types.js'; @@ -54,46 +54,64 @@ return relativeUserInfos; } -function getRelativeMemberInfos( - threadInfo: ?LegacyRawThreadInfo, +type ExtractArrayParam = (arr: $ReadOnlyArray) => T; + +function getRelativeMemberInfos< + TI: MinimallyEncodedRawThreadInfo | LegacyRawThreadInfo, +>( + threadInfo: ?TI, currentUserID: ?string, userInfos: UserInfos, -): $ReadOnlyArray { - const relativeMemberInfos = []; +): $ReadOnlyArray< + $ReadOnly<{ + ...$Call>, + +username: ?string, + +isViewer: boolean, + }>, +> { + const relativeMemberInfos: Array< + $ReadOnly<{ + ...$Call>, + +username: ?string, + +isViewer: boolean, + }>, + > = []; if (!threadInfo) { return relativeMemberInfos; } const memberInfos = threadInfo.members; - for (const memberInfo of memberInfos) { + for (const memberInfoInput of memberInfos) { + const memberInfo: $Call< + ExtractArrayParam, + $PropertyType, + > = memberInfoInput; if (!memberInfo.role) { continue; } - const username = userInfos[memberInfo.id] + const username: ?string = userInfos[memberInfo.id] ? userInfos[memberInfo.id].username : null; - if (memberInfo.id === currentUserID) { - relativeMemberInfos.unshift({ - ...memberInfo, - username, - isViewer: true, - }); - } else { - relativeMemberInfos.push({ - ...memberInfo, - username, - isViewer: false, - }); - } + const isViewer: boolean = memberInfo.id === currentUserID; + const relativeMemberInfo: $ReadOnly<{ + ...$Call>, + +username: ?string, + +isViewer: boolean, + }> = { + ...memberInfo, + username, + isViewer, + }; + relativeMemberInfos.unshift(relativeMemberInfo); } return relativeMemberInfos; } -const emptyArray: $ReadOnlyArray = []; +const emptyArray: $ReadOnlyArray = []; // Includes current user at the start const baseRelativeMemberInfoSelectorForMembersOfThread: ( threadID: ?string, -) => (state: BaseAppState<>) => $ReadOnlyArray = ( +) => (state: BaseAppState<>) => $ReadOnlyArray = ( threadID: ?string, ) => { if (!threadID) {