Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3323270
D10229.id34555.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
22 KB
Referenced Files
None
Subscribers
None
D10229.id34555.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D10229: [lib] Convert getPotentialMemberItems into a hook
Attached
Detach File
Event Timeline
Log In to Comment