Page MenuHomePhabricator

D10229.id34555.diff
No OneTemporary

D10229.id34555.diff

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
@@ -23,6 +23,7 @@
ChatMessageInfoItem,
MessageListData,
} from '../selectors/chat-selectors.js';
+import { relationshipBlockedInEitherDirection } from '../shared/relationship-utils.js';
import type { MessageInfo, RawMessageInfo } from '../types/message-types.js';
import { userRelationshipStatus } from '../types/relationship-types.js';
import { threadPermissions } from '../types/thread-permission-types.js';
@@ -43,7 +44,49 @@
const notFriendNotice = 'not friend';
-function getPotentialMemberItems({
+function appendUserInfo({
+ results,
+ excludeUserIDs,
+ userInfo,
+ parentThreadInfo,
+ communityThreadInfo,
+ containingThreadInfo,
+}: {
+ +results: {
+ [id: string]: {
+ ...AccountUserInfo | GlobalAccountUserInfo,
+ isMemberOfParentThread: boolean,
+ isMemberOfContainingThread: boolean,
+ },
+ },
+ +excludeUserIDs: $ReadOnlyArray<string>,
+ +userInfo: AccountUserInfo | GlobalAccountUserInfo,
+ +parentThreadInfo: ?ThreadInfo,
+ +communityThreadInfo: ?ThreadInfo,
+ +containingThreadInfo: ?ThreadInfo,
+}) {
+ const { id } = userInfo;
+ if (excludeUserIDs.includes(id) || id in results) {
+ return;
+ }
+ if (
+ communityThreadInfo &&
+ !threadMemberHasPermission(
+ communityThreadInfo,
+ id,
+ threadPermissions.KNOW_OF,
+ )
+ ) {
+ return;
+ }
+ results[id] = {
+ ...userInfo,
+ isMemberOfParentThread: userIsMember(parentThreadInfo, id),
+ isMemberOfContainingThread: userIsMember(containingThreadInfo, id),
+ };
+}
+
+function usePotentialMemberItems({
text,
userInfos,
searchIndex,
@@ -62,185 +105,202 @@
+inputCommunityThreadInfo?: ?ThreadInfo,
+threadType?: ?ThreadType,
}): UserListItem[] {
- const communityThreadInfo =
- inputCommunityThreadInfo && inputCommunityThreadInfo.id !== genesis.id
- ? inputCommunityThreadInfo
- : null;
- const parentThreadInfo =
- inputParentThreadInfo && inputParentThreadInfo.id !== genesis.id
- ? inputParentThreadInfo
- : null;
+ const communityThreadInfo = React.useMemo(
+ () =>
+ inputCommunityThreadInfo && inputCommunityThreadInfo.id !== genesis.id
+ ? inputCommunityThreadInfo
+ : null,
+ [inputCommunityThreadInfo],
+ );
+ const parentThreadInfo = React.useMemo(
+ () =>
+ inputParentThreadInfo && inputParentThreadInfo.id !== genesis.id
+ ? inputParentThreadInfo
+ : null,
+ [inputParentThreadInfo],
+ );
const containgThreadID = threadType
? getContainingThreadID(parentThreadInfo, threadType)
: null;
- let containingThreadInfo = null;
- if (containgThreadID === parentThreadInfo?.id) {
- containingThreadInfo = parentThreadInfo;
- } else if (containgThreadID === communityThreadInfo?.id) {
- containingThreadInfo = communityThreadInfo;
- }
-
- const results: {
- [id: string]: {
- ...AccountUserInfo | GlobalAccountUserInfo,
- isMemberOfParentThread: boolean,
- isMemberOfContainingThread: boolean,
- },
- } = {};
- const appendUserInfo = (
- userInfo: AccountUserInfo | GlobalAccountUserInfo,
- ) => {
- const { id } = userInfo;
- if (excludeUserIDs.includes(id) || id in results) {
- return;
+ const containingThreadInfo = React.useMemo(() => {
+ if (containgThreadID === parentThreadInfo?.id) {
+ return parentThreadInfo;
+ } else if (containgThreadID === communityThreadInfo?.id) {
+ return communityThreadInfo;
}
- if (
- communityThreadInfo &&
- !threadMemberHasPermission(
- communityThreadInfo,
- id,
- threadPermissions.KNOW_OF,
- )
- ) {
- return;
- }
- results[id] = {
- ...userInfo,
- isMemberOfParentThread: userIsMember(parentThreadInfo, id),
- isMemberOfContainingThread: userIsMember(containingThreadInfo, id),
- };
- };
- if (text === '') {
- for (const id in userInfos) {
- appendUserInfo(userInfos[id]);
+ return null;
+ }, [containgThreadID, communityThreadInfo, parentThreadInfo]);
+
+ const filteredUserResults = React.useMemo(() => {
+ const results: {
+ [id: string]: {
+ ...AccountUserInfo | GlobalAccountUserInfo,
+ isMemberOfParentThread: boolean,
+ isMemberOfContainingThread: boolean,
+ },
+ } = {};
+ if (text === '') {
+ for (const id in userInfos) {
+ appendUserInfo({
+ results,
+ excludeUserIDs,
+ userInfo: userInfos[id],
+ parentThreadInfo,
+ communityThreadInfo,
+ containingThreadInfo,
+ });
+ }
+ } else {
+ const ids = searchIndex.getSearchResults(text);
+ for (const id of ids) {
+ appendUserInfo({
+ results,
+ excludeUserIDs,
+ userInfo: userInfos[id],
+ parentThreadInfo,
+ communityThreadInfo,
+ containingThreadInfo,
+ });
+ }
}
- } else {
- const ids = searchIndex.getSearchResults(text);
- for (const id of ids) {
- appendUserInfo(userInfos[id]);
+
+ if (includeServerSearchUsers) {
+ for (const userInfo of includeServerSearchUsers) {
+ appendUserInfo({
+ results,
+ excludeUserIDs,
+ userInfo,
+ parentThreadInfo,
+ communityThreadInfo,
+ containingThreadInfo,
+ });
+ }
}
- }
- if (includeServerSearchUsers) {
- for (const userInfo of includeServerSearchUsers) {
- appendUserInfo(userInfo);
+ let userResults = values(results);
+ if (text === '') {
+ userResults = userResults.filter(userInfo => {
+ if (!containingThreadInfo) {
+ return userInfo.relationshipStatus === userRelationshipStatus.FRIEND;
+ }
+ if (!userInfo.isMemberOfContainingThread) {
+ return false;
+ }
+ const { relationshipStatus } = userInfo;
+ if (!relationshipStatus) {
+ return true;
+ }
+ return !relationshipBlockedInEitherDirection(relationshipStatus);
+ });
}
- }
- const blockedRelationshipsStatuses = new Set([
- userRelationshipStatus.BLOCKED_BY_VIEWER,
- userRelationshipStatus.BLOCKED_VIEWER,
- userRelationshipStatus.BOTH_BLOCKED,
+ return userResults;
+ }, [
+ text,
+ userInfos,
+ searchIndex,
+ excludeUserIDs,
+ includeServerSearchUsers,
+ parentThreadInfo,
+ containingThreadInfo,
+ communityThreadInfo,
]);
- let userResults = values(results);
- if (text === '') {
- userResults = userResults.filter(userInfo => {
- if (!containingThreadInfo) {
- return userInfo.relationshipStatus === userRelationshipStatus.FRIEND;
- }
- if (!userInfo.isMemberOfContainingThread) {
- return false;
- }
- const { relationshipStatus } = userInfo;
- if (!relationshipStatus) {
- return true;
- }
- return !blockedRelationshipsStatuses.has(relationshipStatus);
- });
- }
-
- const nonFriends = [];
- const blockedUsers = [];
- const friends = [];
- const containingThreadMembers = [];
- const parentThreadMembers = [];
-
- for (const userResult of userResults) {
- const { relationshipStatus } = userResult;
- if (
- relationshipStatus &&
- blockedRelationshipsStatuses.has(relationshipStatus)
- ) {
- blockedUsers.push(userResult);
- } else if (userResult.isMemberOfParentThread) {
- parentThreadMembers.push(userResult);
- } else if (userResult.isMemberOfContainingThread) {
- containingThreadMembers.push(userResult);
- } else if (relationshipStatus === userRelationshipStatus.FRIEND) {
- friends.push(userResult);
- } else {
- nonFriends.push(userResult);
- }
- }
+ const sortedMembers = React.useMemo(() => {
+ const nonFriends = [];
+ const blockedUsers = [];
+ const friends = [];
+ const containingThreadMembers = [];
+ const parentThreadMembers = [];
- const sortedResults = parentThreadMembers
- .concat(containingThreadMembers)
- .concat(friends)
- .concat(nonFriends)
- .concat(blockedUsers);
-
- return sortedResults.map(
- ({
- isMemberOfContainingThread,
- isMemberOfParentThread,
- relationshipStatus,
- ...result
- }) => {
- let notice, alert;
- const username = result.username;
+ for (const userResult of filteredUserResults) {
+ const { relationshipStatus } = userResult;
if (
relationshipStatus &&
- blockedRelationshipsStatuses.has(relationshipStatus)
+ relationshipBlockedInEitherDirection(relationshipStatus)
) {
- notice = 'user is blocked';
- alert = {
- title: 'User is blocked',
- text:
- `Before you add ${username} to this chat, ` +
- 'you’ll need to unblock them. You can do this from the Block List ' +
- 'in the Profile tab.',
- };
- } else if (!isMemberOfContainingThread && containingThreadInfo) {
- if (threadType !== threadTypes.SIDEBAR) {
- notice = 'not in community';
+ blockedUsers.push(userResult);
+ } else if (userResult.isMemberOfParentThread) {
+ parentThreadMembers.push(userResult);
+ } else if (userResult.isMemberOfContainingThread) {
+ containingThreadMembers.push(userResult);
+ } else if (relationshipStatus === userRelationshipStatus.FRIEND) {
+ friends.push(userResult);
+ } else {
+ nonFriends.push(userResult);
+ }
+ }
+
+ const sortedResults = parentThreadMembers
+ .concat(containingThreadMembers)
+ .concat(friends)
+ .concat(nonFriends)
+ .concat(blockedUsers);
+
+ return sortedResults.map(
+ ({
+ isMemberOfContainingThread,
+ isMemberOfParentThread,
+ relationshipStatus,
+ ...result
+ }) => {
+ let notice, alert;
+ const username = result.username;
+ if (
+ relationshipStatus &&
+ relationshipBlockedInEitherDirection(relationshipStatus)
+ ) {
+ notice = 'user is blocked';
alert = {
- title: 'Not in community',
- text: 'You can only add members of the community to this chat',
+ title: 'User is blocked',
+ text:
+ `Before you add ${username} to this chat, ` +
+ 'you’ll need to unblock them. You can do this from the Block List ' +
+ 'in the Profile tab.',
};
- } else {
- notice = 'not in parent chat';
+ } else if (!isMemberOfContainingThread && containingThreadInfo) {
+ if (threadType !== threadTypes.SIDEBAR) {
+ notice = 'not in community';
+ alert = {
+ title: 'Not in community',
+ text: 'You can only add members of the community to this chat',
+ };
+ } else {
+ notice = 'not in parent chat';
+ alert = {
+ title: 'Not in parent chat',
+ text: 'You can only add members of the parent chat to a thread',
+ };
+ }
+ } else if (
+ !containingThreadInfo &&
+ relationshipStatus !== userRelationshipStatus.FRIEND
+ ) {
+ notice = notFriendNotice;
alert = {
- title: 'Not in parent chat',
- text: 'You can only add members of the parent chat to a thread',
+ title: 'Not a friend',
+ text:
+ `Before you add ${username} to this chat, ` +
+ 'you’ll need to send them a friend request. ' +
+ 'You can do this from the Friend List in the Profile tab.',
};
+ } else if (parentThreadInfo && !isMemberOfParentThread) {
+ notice = 'not in parent chat';
}
- } else if (
- !containingThreadInfo &&
- relationshipStatus !== userRelationshipStatus.FRIEND
- ) {
- notice = notFriendNotice;
- alert = {
- title: 'Not a friend',
- text:
- `Before you add ${username} to this chat, ` +
- 'you’ll need to send them a friend request. ' +
- 'You can do this from the Friend List in the Profile tab.',
- };
- } else if (parentThreadInfo && !isMemberOfParentThread) {
- notice = 'not in parent chat';
- }
- if (notice) {
- result = { ...result, notice };
- }
- if (alert) {
- result = { ...result, alert };
- }
- return result;
- },
- );
+ if (notice) {
+ result = { ...result, notice };
+ }
+ if (alert) {
+ result = { ...result, alert };
+ }
+ return result;
+ },
+ );
+ }, [containingThreadInfo, filteredUserResults, parentThreadInfo, threadType]);
+
+ return sortedMembers;
}
function useSearchMessages(): (
@@ -381,7 +441,7 @@
}
export {
- getPotentialMemberItems,
+ usePotentialMemberItems,
notFriendNotice,
useSearchMessages,
useSearchUsers,
diff --git a/native/chat/compose-subchannel.react.js b/native/chat/compose-subchannel.react.js
--- a/native/chat/compose-subchannel.react.js
+++ b/native/chat/compose-subchannel.react.js
@@ -17,7 +17,7 @@
userInfoSelectorForPotentialMembers,
userSearchIndexForPotentialMembers,
} from 'lib/selectors/user-selectors.js';
-import { getPotentialMemberItems } from 'lib/shared/search-utils.js';
+import { usePotentialMemberItems } from 'lib/shared/search-utils.js';
import { threadInFilterList, userIsMember } from 'lib/shared/thread-utils.js';
import { type ThreadType, threadTypes } from 'lib/types/thread-types-enum.js';
import type { ThreadInfo } from 'lib/types/thread-types.js';
@@ -200,27 +200,15 @@
const communityThreadInfo = useSelector(state =>
community ? threadInfoSelector(state)[community] : null,
);
- const userSearchResults = React.useMemo(
- () =>
- getPotentialMemberItems({
- text: usernameInputText,
- userInfos: otherUserInfos,
- searchIndex: userSearchIndex,
- excludeUserIDs: userInfoInputIDs,
- inputParentThreadInfo: parentThreadInfo,
- inputCommunityThreadInfo: communityThreadInfo,
- threadType,
- }),
- [
- usernameInputText,
- otherUserInfos,
- userSearchIndex,
- userInfoInputIDs,
- parentThreadInfo,
- communityThreadInfo,
- threadType,
- ],
- );
+ const userSearchResults = usePotentialMemberItems({
+ text: usernameInputText,
+ userInfos: otherUserInfos,
+ searchIndex: userSearchIndex,
+ excludeUserIDs: userInfoInputIDs,
+ inputParentThreadInfo: parentThreadInfo,
+ inputCommunityThreadInfo: communityThreadInfo,
+ threadType,
+ });
const existingThreads: $ReadOnlyArray<ThreadInfo> = React.useMemo(() => {
if (userInfoInputIDs.length === 0) {
diff --git a/native/chat/message-list-container.react.js b/native/chat/message-list-container.react.js
--- a/native/chat/message-list-container.react.js
+++ b/native/chat/message-list-container.react.js
@@ -13,7 +13,7 @@
userSearchIndexForPotentialMembers,
} from 'lib/selectors/user-selectors.js';
import {
- getPotentialMemberItems,
+ usePotentialMemberItems,
useSearchUsers,
} from 'lib/shared/search-utils.js';
import {
@@ -253,21 +253,13 @@
const serverSearchResults = useSearchUsers(usernameInputText);
- const userSearchResults = React.useMemo(() => {
- return getPotentialMemberItems({
- text: usernameInputText,
- userInfos: otherUserInfos,
- searchIndex: userSearchIndex,
- excludeUserIDs: userInfoInputArray.map(userInfo => userInfo.id),
- includeServerSearchUsers: serverSearchResults,
- });
- }, [
- usernameInputText,
- otherUserInfos,
- userSearchIndex,
- userInfoInputArray,
- serverSearchResults,
- ]);
+ const userSearchResults = usePotentialMemberItems({
+ text: usernameInputText,
+ userInfos: otherUserInfos,
+ searchIndex: userSearchIndex,
+ excludeUserIDs: userInfoInputArray.map(userInfo => userInfo.id),
+ includeServerSearchUsers: serverSearchResults,
+ });
const [baseThreadInfo, setBaseThreadInfo] = React.useState(
props.route.params.threadInfo,
diff --git a/native/chat/settings/add-users-modal.react.js b/native/chat/settings/add-users-modal.react.js
--- a/native/chat/settings/add-users-modal.react.js
+++ b/native/chat/settings/add-users-modal.react.js
@@ -14,7 +14,7 @@
userInfoSelectorForPotentialMembers,
userSearchIndexForPotentialMembers,
} from 'lib/selectors/user-selectors.js';
-import { getPotentialMemberItems } from 'lib/shared/search-utils.js';
+import { usePotentialMemberItems } from 'lib/shared/search-utils.js';
import { threadActualMembers } from 'lib/shared/thread-utils.js';
import type { ThreadInfo } from 'lib/types/thread-types.js';
import { type AccountUserInfo } from 'lib/types/user-types.js';
@@ -173,27 +173,15 @@
const communityThreadInfo = useSelector(state =>
community ? threadInfoSelector(state)[community] : null,
);
- const userSearchResults = React.useMemo(
- () =>
- getPotentialMemberItems({
- text: usernameInputText,
- userInfos: otherUserInfos,
- searchIndex: userSearchIndex,
- excludeUserIDs,
- inputParentThreadInfo: parentThreadInfo,
- inputCommunityThreadInfo: communityThreadInfo,
- threadType: threadInfo.type,
- }),
- [
- usernameInputText,
- otherUserInfos,
- userSearchIndex,
- excludeUserIDs,
- parentThreadInfo,
- communityThreadInfo,
- threadInfo.type,
- ],
- );
+ const userSearchResults = usePotentialMemberItems({
+ text: usernameInputText,
+ userInfos: otherUserInfos,
+ searchIndex: userSearchIndex,
+ excludeUserIDs,
+ inputParentThreadInfo: parentThreadInfo,
+ inputCommunityThreadInfo: communityThreadInfo,
+ threadType: threadInfo.type,
+ });
const onChangeTagInput = React.useCallback(
(newUserInfoInputArray: $ReadOnlyArray<AccountUserInfo>) => {
diff --git a/native/community-creation/community-creation-members.react.js b/native/community-creation/community-creation-members.react.js
--- a/native/community-creation/community-creation-members.react.js
+++ b/native/community-creation/community-creation-members.react.js
@@ -13,7 +13,7 @@
userInfoSelectorForPotentialMembers,
userSearchIndexForPotentialMembers,
} from 'lib/selectors/user-selectors.js';
-import { getPotentialMemberItems } from 'lib/shared/search-utils.js';
+import { usePotentialMemberItems } from 'lib/shared/search-utils.js';
import type { LoadingStatus } from 'lib/types/loading-types.js';
import { threadTypes } from 'lib/types/thread-types-enum.js';
import type { AccountUserInfo } from 'lib/types/user-types.js';
@@ -144,25 +144,15 @@
setOptions,
]);
- const userSearchResults = React.useMemo(
- () =>
- getPotentialMemberItems({
- text: usernameInputText,
- userInfos: otherUserInfos,
- searchIndex: userSearchIndex,
- excludeUserIDs: selectedUserIDs,
- threadType: announcement
- ? threadTypes.COMMUNITY_ANNOUNCEMENT_ROOT
- : threadTypes.COMMUNITY_ROOT,
- }),
- [
- announcement,
- otherUserInfos,
- selectedUserIDs,
- userSearchIndex,
- usernameInputText,
- ],
- );
+ const userSearchResults = usePotentialMemberItems({
+ text: usernameInputText,
+ userInfos: otherUserInfos,
+ searchIndex: userSearchIndex,
+ excludeUserIDs: selectedUserIDs,
+ threadType: announcement
+ ? threadTypes.COMMUNITY_ANNOUNCEMENT_ROOT
+ : threadTypes.COMMUNITY_ROOT,
+ });
const onSelectUser = React.useCallback(
({ id }: AccountUserInfo) => {
diff --git a/web/chat/chat-thread-composer.react.js b/web/chat/chat-thread-composer.react.js
--- a/web/chat/chat-thread-composer.react.js
+++ b/web/chat/chat-thread-composer.react.js
@@ -11,7 +11,7 @@
import { useENSNames } from 'lib/hooks/ens-cache.js';
import { userSearchIndexForPotentialMembers } from 'lib/selectors/user-selectors.js';
import {
- getPotentialMemberItems,
+ usePotentialMemberItems,
useSearchUsers,
notFriendNotice,
} from 'lib/shared/search-utils.js';
@@ -60,23 +60,13 @@
const serverSearchResults = useSearchUsers(usernameInputText);
- const userListItems = React.useMemo(
- () =>
- getPotentialMemberItems({
- text: usernameInputText,
- userInfos: otherUserInfos,
- searchIndex: userSearchIndex,
- excludeUserIDs: userInfoInputIDs,
- includeServerSearchUsers: serverSearchResults,
- }),
- [
- usernameInputText,
- otherUserInfos,
- userSearchIndex,
- userInfoInputIDs,
- serverSearchResults,
- ],
- );
+ const userListItems = usePotentialMemberItems({
+ text: usernameInputText,
+ userInfos: otherUserInfos,
+ searchIndex: userSearchIndex,
+ excludeUserIDs: userInfoInputIDs,
+ includeServerSearchUsers: serverSearchResults,
+ });
const userListItemsWithENSNames = useENSNames(userListItems);
diff --git a/web/modals/threads/members/add-members-modal.react.js b/web/modals/threads/members/add-members-modal.react.js
--- a/web/modals/threads/members/add-members-modal.react.js
+++ b/web/modals/threads/members/add-members-modal.react.js
@@ -12,7 +12,7 @@
userSearchIndexForPotentialMembers,
userInfoSelectorForPotentialMembers,
} from 'lib/selectors/user-selectors.js';
-import { getPotentialMemberItems } from 'lib/shared/search-utils.js';
+import { usePotentialMemberItems } from 'lib/shared/search-utils.js';
import { threadActualMembers } from 'lib/shared/thread-utils.js';
import { useDispatchActionPromise } from 'lib/utils/action-utils.js';
@@ -54,27 +54,15 @@
[pendingUsersToAdd, threadInfo.members],
);
- const userSearchResults = React.useMemo(
- () =>
- getPotentialMemberItems({
- text: searchText,
- userInfos: otherUserInfos,
- searchIndex: userSearchIndex,
- excludeUserIDs,
- inputParentThreadInfo: parentThreadInfo,
- inputCommunityThreadInfo: communityThreadInfo,
- threadType: threadInfo.type,
- }),
- [
- communityThreadInfo,
- excludeUserIDs,
- otherUserInfos,
- parentThreadInfo,
- searchText,
- threadInfo.type,
- userSearchIndex,
- ],
- );
+ const userSearchResults = usePotentialMemberItems({
+ text: searchText,
+ userInfos: otherUserInfos,
+ searchIndex: userSearchIndex,
+ excludeUserIDs,
+ inputParentThreadInfo: parentThreadInfo,
+ inputCommunityThreadInfo: communityThreadInfo,
+ threadType: threadInfo.type,
+ });
const userSearchResultsWithENSNames = useENSNames(userSearchResults);
const onSwitchUser = React.useCallback(

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 21, 3:28 AM (21 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2552419
Default Alt Text
D10229.id34555.diff (22 KB)

Event Timeline