diff --git a/lib/permissions/minimally-encoded-thread-permissions-validators.js b/lib/permissions/minimally-encoded-thread-permissions-validators.js --- a/lib/permissions/minimally-encoded-thread-permissions-validators.js +++ b/lib/permissions/minimally-encoded-thread-permissions-validators.js @@ -10,7 +10,7 @@ import type { MinimallyEncodedMemberInfo, RawThreadInfo, - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, MinimallyEncodedRoleInfo, MinimallyEncodedThreadCurrentUserInfo, ThreadInfo, @@ -47,8 +47,8 @@ permissions: tHexEncodedPermissionsBitmask, }); -const minimallyEncodedRelativeMemberInfoValidator: TInterface = - tShape({ +const minimallyEncodedRelativeMemberInfoValidator: TInterface = + tShape({ ...minimallyEncodedMemberInfoValidator.meta.props, username: t.maybe(t.String), isViewer: t.Boolean, diff --git a/lib/selectors/nav-selectors.js b/lib/selectors/nav-selectors.js --- a/lib/selectors/nav-selectors.js +++ b/lib/selectors/nav-selectors.js @@ -14,7 +14,7 @@ import type { CalendarFilter } from '../types/filter-types.js'; import type { ThreadInfo, - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, RawThreadInfo, } from '../types/minimally-encoded-thread-permissions-types.js'; import type { BaseNavInfo } from '../types/nav-types.js'; @@ -83,15 +83,12 @@ const useENSNamesOptions = { allAtOnce: true }; function useUserSearchIndex( - userInfos: $ReadOnlyArray, + userInfos: $ReadOnlyArray, ): SearchIndex { const membersWithENSNames = useENSNames(userInfos, useENSNamesOptions); const memberMap = React.useMemo(() => { - const result = new Map< - string, - UserInfo | MinimallyEncodedRelativeMemberInfo, - >(); + const result = new Map(); for (const userInfo of membersWithENSNames) { result.set(userInfo.id, userInfo); } diff --git a/lib/selectors/thread-selectors.js b/lib/selectors/thread-selectors.js --- a/lib/selectors/thread-selectors.js +++ b/lib/selectors/thread-selectors.js @@ -40,7 +40,7 @@ import type { EntryInfo } from '../types/entry-types.js'; import type { MessageStore, RawMessageInfo } from '../types/message-types.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ThreadInfo, RawThreadInfo, } from '../types/minimally-encoded-thread-permissions-types.js'; @@ -351,7 +351,7 @@ relativeMemberInfoSelectorForMembersOfThread(threadID), ( threadInfo: ?RawThreadInfo, - members: $ReadOnlyArray, + members: $ReadOnlyArray, ): boolean => { if (!threadInfo) { return false; 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 @@ -10,7 +10,7 @@ import { getSingleOtherUser } from '../shared/thread-utils.js'; import type { ClientEmojiAvatar } from '../types/avatar-types'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, RawThreadInfo, } from '../types/minimally-encoded-thread-permissions-types.js'; import type { BaseAppState } from '../types/redux-types.js'; @@ -108,14 +108,12 @@ 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) { @@ -132,9 +130,7 @@ const relativeMemberInfoSelectorForMembersOfThread: ( threadID: ?string, -) => ( - state: BaseAppState<>, -) => $ReadOnlyArray = _memoize( +) => (state: BaseAppState<>) => $ReadOnlyArray = _memoize( baseRelativeMemberInfoSelectorForMembersOfThread, ); diff --git a/lib/shared/markdown.js b/lib/shared/markdown.js --- a/lib/shared/markdown.js +++ b/lib/shared/markdown.js @@ -9,7 +9,7 @@ } from './mention-utils.js'; import { useENSNames } from '../hooks/ens-cache.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ResolvedThreadInfo, } from '../types/minimally-encoded-thread-permissions-types.js'; import type { ChatMentionCandidates } from '../types/thread-types.js'; @@ -201,7 +201,7 @@ const useENSNamesOptions = { allAtOnce: true }; function useMemberMapForUserMentions( - members: $ReadOnlyArray, + members: $ReadOnlyArray, ): $ReadOnlyMap { const membersWithRole = React.useMemo( () => members.filter(member => member.role), @@ -209,13 +209,11 @@ ); const resolvedMembers = useENSNames(membersWithRole, useENSNamesOptions); - const resolvedMembersMap: $ReadOnlyMap< - string, - MinimallyEncodedRelativeMemberInfo, - > = React.useMemo( - () => new Map(resolvedMembers.map(member => [member.id, member])), - [resolvedMembers], - ); + const resolvedMembersMap: $ReadOnlyMap = + React.useMemo( + () => new Map(resolvedMembers.map(member => [member.id, member])), + [resolvedMembers], + ); const membersMap = React.useMemo(() => { const map = new Map(); diff --git a/lib/shared/mention-utils.js b/lib/shared/mention-utils.js --- a/lib/shared/mention-utils.js +++ b/lib/shared/mention-utils.js @@ -8,7 +8,7 @@ import { useENSNames } from '../hooks/ens-cache.js'; import { useUserSearchIndex } from '../selectors/nav-selectors.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ResolvedThreadInfo, ThreadInfo, } from '../types/minimally-encoded-thread-permissions-types.js'; @@ -28,7 +28,7 @@ type MentionTypeaheadUserSuggestionItem = { +type: 'user', - +userInfo: MinimallyEncodedRelativeMemberInfo, + +userInfo: RelativeMemberInfo, }; type MentionTypeaheadChatSuggestionItem = { @@ -105,7 +105,7 @@ const useENSNamesOptions = { allAtOnce: true }; function useMentionTypeaheadUserSuggestions( - threadMembers: $ReadOnlyArray, + threadMembers: $ReadOnlyArray, typeaheadMatchedStrings: ?TypeaheadMatchedStrings, ): $ReadOnlyArray { const userSearchIndex = useUserSearchIndex(threadMembers); @@ -184,7 +184,7 @@ function useUserMentionsCandidates( threadInfo: ThreadInfo, parentThreadInfo: ?ThreadInfo, -): $ReadOnlyArray { +): $ReadOnlyArray { return React.useMemo(() => { if (threadInfo.type !== threadTypes.SIDEBAR) { return threadInfo.members; 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 @@ -58,7 +58,7 @@ type ComposableMessageInfo, } from '../types/message-types.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, MinimallyEncodedRoleInfo, RawThreadInfo, MinimallyEncodedThreadCurrentUserInfo, @@ -219,14 +219,14 @@ } function threadActualMembers( - memberInfos: $ReadOnlyArray, + memberInfos: $ReadOnlyArray, ): $ReadOnlyArray { return memberInfos .filter(memberInfo => memberInfo.role) .map(memberInfo => memberInfo.id); } -function threadOtherMembers( +function threadOtherMembers( memberInfos: $ReadOnlyArray, viewerID: ?string, ): $ReadOnlyArray { @@ -459,7 +459,7 @@ // Returns map from lowercase username to AccountUserInfo function memberLowercaseUsernameMap( - members: $ReadOnlyArray, + members: $ReadOnlyArray, ): Map { const memberMap = new Map(); for (const member of members) { @@ -877,7 +877,7 @@ return firstLine(threadInfo.name); } - const threadMembers: $ReadOnlyArray = + const threadMembers: $ReadOnlyArray = threadInfo.members.filter(memberInfo => memberInfo.role); const memberEntities: $ReadOnlyArray = threadMembers.map(member => ET.user({ userInfo: member }), @@ -1030,10 +1030,7 @@ // Since we don't have access to all of the ancestor ThreadInfos, we approximate // "parent admin" as anybody with CHANGE_ROLE permissions. function memberHasAdminPowers( - memberInfo: - | MinimallyEncodedRelativeMemberInfo - | MemberInfo - | ServerMemberInfo, + memberInfo: RelativeMemberInfo | MemberInfo | ServerMemberInfo, ): boolean { if (memberInfo.minimallyEncoded) { return hasPermission(memberInfo.permissions, threadPermissions.CHANGE_ROLE); @@ -1514,7 +1511,7 @@ function removeMemberFromThread( threadInfo: ThreadInfo, - memberInfo: MinimallyEncodedRelativeMemberInfo, + memberInfo: RelativeMemberInfo, dispatchActionPromise: DispatchActionPromise, removeUserFromThreadServerCall: ( input: RemoveUsersFromThreadInput, @@ -1532,7 +1529,7 @@ } function getAvailableThreadMemberActions( - memberInfo: MinimallyEncodedRelativeMemberInfo, + memberInfo: RelativeMemberInfo, threadInfo: ThreadInfo, canEdit: ?boolean = true, ): $ReadOnlyArray<'change_role' | 'remove_user'> { diff --git a/lib/types/minimally-encoded-thread-permissions-types.js b/lib/types/minimally-encoded-thread-permissions-types.js --- a/lib/types/minimally-encoded-thread-permissions-types.js +++ b/lib/types/minimally-encoded-thread-permissions-types.js @@ -115,7 +115,7 @@ }; }; -export type MinimallyEncodedRelativeMemberInfo = $ReadOnly<{ +export type RelativeMemberInfo = $ReadOnly<{ ...MinimallyEncodedMemberInfo, +username: ?string, +isViewer: boolean, @@ -172,7 +172,7 @@ +parentThreadID: ?string, +containingThreadID: ?string, +community: ?string, - +members: $ReadOnlyArray, + +members: $ReadOnlyArray, +roles: { +[id: string]: MinimallyEncodedRoleInfo }, +currentUser: MinimallyEncodedThreadCurrentUserInfo, +sourceMessageID?: string, 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 @@ -5,7 +5,7 @@ import { useSelector } from './redux-utils.js'; import { threadInfoSelector } from '../selectors/thread-selectors.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ThreadInfo, } from '../types/minimally-encoded-thread-permissions-types.js'; import { @@ -57,7 +57,7 @@ function useRolesFromCommunityThreadInfo( threadInfo: ThreadInfo, - memberInfos: $ReadOnlyArray, + memberInfos: $ReadOnlyArray, ): $ReadOnlyMap { // Our in-code system has chat-specific roles, while the // user-surfaced system has roles only for communities. We retrieve roles diff --git a/native/chat/chat-input-bar.react.js b/native/chat/chat-input-bar.react.js --- a/native/chat/chat-input-bar.react.js +++ b/native/chat/chat-input-bar.react.js @@ -74,7 +74,7 @@ SendEditMessageResponse, } from 'lib/types/message-types.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ThreadInfo, } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import type { Dispatch } from 'lib/types/redux-types.js'; @@ -296,7 +296,7 @@ +dispatchActionPromise: DispatchActionPromise, +joinThread: (request: ClientThreadJoinRequest) => Promise, +inputState: ?InputState, - +userMentionsCandidates: $ReadOnlyArray, + +userMentionsCandidates: $ReadOnlyArray, +chatMentionSearchIndex: SentencePrefixSearchIndex, +chatMentionCandidates: ChatMentionCandidates, +parentThreadInfo: ?ThreadInfo, diff --git a/native/chat/settings/thread-settings-member-tooltip-modal.react.js b/native/chat/settings/thread-settings-member-tooltip-modal.react.js --- a/native/chat/settings/thread-settings-member-tooltip-modal.react.js +++ b/native/chat/settings/thread-settings-member-tooltip-modal.react.js @@ -6,7 +6,7 @@ import { removeMemberFromThread } from 'lib/shared/thread-utils.js'; import { stringForUser } from 'lib/shared/user-utils.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ThreadInfo, } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; @@ -24,7 +24,7 @@ import Alert from '../../utils/alert.js'; export type ThreadSettingsMemberTooltipModalParams = TooltipParams<{ - +memberInfo: MinimallyEncodedRelativeMemberInfo, + +memberInfo: RelativeMemberInfo, +threadInfo: ThreadInfo, }>; diff --git a/native/chat/settings/thread-settings-member.react.js b/native/chat/settings/thread-settings-member.react.js --- a/native/chat/settings/thread-settings-member.react.js +++ b/native/chat/settings/thread-settings-member.react.js @@ -20,7 +20,7 @@ import { stringForUser } from 'lib/shared/user-utils.js'; import type { LoadingStatus } from 'lib/types/loading-types.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ThreadInfo, } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import { useRolesFromCommunityThreadInfo } from 'lib/utils/role-utils.js'; @@ -89,7 +89,7 @@ }; type BaseProps = { - +memberInfo: MinimallyEncodedRelativeMemberInfo, + +memberInfo: RelativeMemberInfo, +threadInfo: ThreadInfo, +canEdit: boolean, +navigate: ThreadSettingsNavigate, diff --git a/native/chat/settings/thread-settings.react.js b/native/chat/settings/thread-settings.react.js --- a/native/chat/settings/thread-settings.react.js +++ b/native/chat/settings/thread-settings.react.js @@ -34,7 +34,7 @@ } from 'lib/shared/thread-utils.js'; import threadWatcher from 'lib/shared/thread-watcher.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ResolvedThreadInfo, ThreadInfo, } from 'lib/types/minimally-encoded-thread-permissions-types.js'; @@ -203,7 +203,7 @@ | { +itemType: 'member', +key: string, - +memberInfo: MinimallyEncodedRelativeMemberInfo, + +memberInfo: RelativeMemberInfo, +threadInfo: ResolvedThreadInfo, +canEdit: boolean, +navigate: ThreadSettingsNavigate, @@ -1123,7 +1123,7 @@ const threadMembersChangeIsSaving = ( state: AppState, - threadMembers: $ReadOnlyArray, + threadMembers: $ReadOnlyArray, ) => { for (const threadMember of threadMembers) { const removeUserLoadingStatus = createLoadingStatusSelector( diff --git a/native/roles/change-roles-screen.react.js b/native/roles/change-roles-screen.react.js --- a/native/roles/change-roles-screen.react.js +++ b/native/roles/change-roles-screen.react.js @@ -13,7 +13,7 @@ import { roleIsAdminRole } from 'lib/shared/thread-utils.js'; import type { LoadingStatus } from 'lib/types/loading-types.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ThreadInfo, } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import { values } from 'lib/utils/objects.js'; @@ -28,7 +28,7 @@ export type ChangeRolesScreenParams = { +threadInfo: ThreadInfo, - +memberInfo: MinimallyEncodedRelativeMemberInfo, + +memberInfo: RelativeMemberInfo, +role: ?string, }; diff --git a/web/input/input-state.js b/web/input/input-state.js --- a/web/input/input-state.js +++ b/web/input/input-state.js @@ -10,7 +10,7 @@ } from 'lib/types/media-types.js'; import type { RawTextMessageInfo } from 'lib/types/messages/text.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ThreadInfo, } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import type { ChatMentionCandidates } from 'lib/types/thread-types.js'; @@ -47,7 +47,7 @@ export type TypeaheadState = { +canBeVisible: boolean, +keepUpdatingThreadMembers: boolean, - +frozenUserMentionsCandidates: $ReadOnlyArray, + +frozenUserMentionsCandidates: $ReadOnlyArray, +frozenChatMentionsCandidates: ChatMentionCandidates, +moveChoiceUp: ?() => void, +moveChoiceDown: ?() => void, diff --git a/web/modals/threads/create/steps/subchannel-members-list.react.js b/web/modals/threads/create/steps/subchannel-members-list.react.js --- a/web/modals/threads/create/steps/subchannel-members-list.react.js +++ b/web/modals/threads/create/steps/subchannel-members-list.react.js @@ -5,7 +5,7 @@ import { useENSNames } from 'lib/hooks/ens-cache.js'; import { stringForUser } from 'lib/shared/user-utils.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ThreadInfo, } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import type { UserListItem } from 'lib/types/user-types.js'; @@ -42,7 +42,7 @@ ); const filterOutParentMembersWithENSNames = React.useCallback( - (members: $ReadOnlyArray) => + (members: $ReadOnlyArray) => members .filter( user => @@ -63,7 +63,7 @@ ); const filterOutOtherMembersWithENSNames = React.useCallback( - (members: $ReadOnlyArray) => + (members: $ReadOnlyArray) => members .filter( user => diff --git a/web/modals/threads/members/change-member-role-modal.react.js b/web/modals/threads/members/change-member-role-modal.react.js --- a/web/modals/threads/members/change-member-role-modal.react.js +++ b/web/modals/threads/members/change-member-role-modal.react.js @@ -12,7 +12,7 @@ import { otherUsersButNoOtherAdmins } from 'lib/selectors/thread-selectors.js'; import { roleIsAdminRole } from 'lib/shared/thread-utils.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ThreadInfo, } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import { values } from 'lib/utils/objects.js'; @@ -27,7 +27,7 @@ import UnsavedChangesModal from '../../unsaved-changes-modal.react.js'; type ChangeMemberRoleModalProps = { - +memberInfo: MinimallyEncodedRelativeMemberInfo, + +memberInfo: RelativeMemberInfo, +threadInfo: ThreadInfo, }; diff --git a/web/modals/threads/members/member.react.js b/web/modals/threads/members/member.react.js --- a/web/modals/threads/members/member.react.js +++ b/web/modals/threads/members/member.react.js @@ -12,7 +12,7 @@ import { stringForUser } from 'lib/shared/user-utils.js'; import type { SetState } from 'lib/types/hook-types.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ThreadInfo, } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; @@ -30,7 +30,7 @@ const commIconComponent = ; type Props = { - +memberInfo: MinimallyEncodedRelativeMemberInfo, + +memberInfo: RelativeMemberInfo, +threadInfo: ThreadInfo, +setOpenMenu: SetState, }; diff --git a/web/modals/threads/members/members-list.react.js b/web/modals/threads/members/members-list.react.js --- a/web/modals/threads/members/members-list.react.js +++ b/web/modals/threads/members/members-list.react.js @@ -8,7 +8,7 @@ import { useENSNames } from 'lib/hooks/ens-cache.js'; import { stringForUser } from 'lib/shared/user-utils.js'; import type { - MinimallyEncodedRelativeMemberInfo, + RelativeMemberInfo, ThreadInfo, } from 'lib/types/minimally-encoded-thread-permissions-types.js'; @@ -17,7 +17,7 @@ type Props = { +threadInfo: ThreadInfo, - +threadMembers: $ReadOnlyArray, + +threadMembers: $ReadOnlyArray, }; function ThreadMembersList(props: Props): React.Node { @@ -42,7 +42,7 @@ .map(([letter, users]) => { const userList = users .sort((a, b) => stringForUser(a).localeCompare(stringForUser(b))) - .map((user: MinimallyEncodedRelativeMemberInfo) => ( + .map((user: RelativeMemberInfo) => ( threadMembersNotFiltered.filter( - (member: MinimallyEncodedRelativeMemberInfo) => + (member: RelativeMemberInfo) => searchText.length === 0 || userIDs.includes(member.id), ), [searchText.length, threadMembersNotFiltered, userIDs], @@ -64,7 +64,7 @@ const roles = useRolesFromCommunityThreadInfo(threadInfo, allMembers); const adminMembers = React.useMemo( () => - allMembers.filter((member: MinimallyEncodedRelativeMemberInfo) => + allMembers.filter((member: RelativeMemberInfo) => roleIsAdminRole(roles.get(member.id)), ), [allMembers, roles],