Changeset View
Changeset View
Standalone View
Standalone View
lib/shared/mention-utils.js
// @flow | // @flow | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { markdownUserMentionRegexString } from './account-utils.js'; | import { markdownUserMentionRegexString } from './account-utils.js'; | ||||
import SentencePrefixSearchIndex from './sentence-prefix-search-index.js'; | import SentencePrefixSearchIndex from './sentence-prefix-search-index.js'; | ||||
import { threadOtherMembers } from './thread-utils.js'; | |||||
import { stringForUserExplicit } from './user-utils.js'; | import { stringForUserExplicit } from './user-utils.js'; | ||||
import { useENSNames } from '../hooks/ens-cache.js'; | import { useENSNames } from '../hooks/ens-cache.js'; | ||||
import { useUserSearchIndex } from '../selectors/nav-selectors.js'; | import { useUserSearchIndex } from '../selectors/nav-selectors.js'; | ||||
import { threadTypes } from '../types/thread-types-enum.js'; | import { threadTypes } from '../types/thread-types-enum.js'; | ||||
import type { | import type { | ||||
ChatMentionCandidates, | ChatMentionCandidates, | ||||
RelativeMemberInfo, | RelativeMemberInfo, | ||||
ThreadInfo, | ThreadInfo, | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | ) { | ||||
return text.slice(0, selection.start).match(regex); | return text.slice(0, selection.start).match(regex); | ||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
const useENSNamesOptions = { allAtOnce: true }; | const useENSNamesOptions = { allAtOnce: true }; | ||||
function useMentionTypeaheadUserSuggestions( | function useMentionTypeaheadUserSuggestions( | ||||
threadMembers: $ReadOnlyArray<RelativeMemberInfo>, | threadMembers: $ReadOnlyArray<RelativeMemberInfo>, | ||||
viewerID: ?string, | |||||
typeaheadMatchedStrings: ?TypeaheadMatchedStrings, | typeaheadMatchedStrings: ?TypeaheadMatchedStrings, | ||||
): $ReadOnlyArray<MentionTypeaheadUserSuggestionItem> { | ): $ReadOnlyArray<MentionTypeaheadUserSuggestionItem> { | ||||
const userSearchIndex = useUserSearchIndex(threadMembers); | const userSearchIndex = useUserSearchIndex(threadMembers); | ||||
const resolvedThreadMembers = useENSNames(threadMembers, useENSNamesOptions); | const resolvedThreadMembers = useENSNames(threadMembers, useENSNamesOptions); | ||||
const usernamePrefix: ?string = typeaheadMatchedStrings?.query; | const usernamePrefix: ?string = typeaheadMatchedStrings?.query; | ||||
return React.useMemo(() => { | return React.useMemo(() => { | ||||
// If typeaheadMatchedStrings is undefined, we want to return no results | // If typeaheadMatchedStrings is undefined, we want to return no results | ||||
if (usernamePrefix === undefined || usernamePrefix === null) { | if (usernamePrefix === undefined || usernamePrefix === null) { | ||||
return []; | return []; | ||||
} | } | ||||
const userIDs = userSearchIndex.getSearchResults(usernamePrefix); | const userIDs = userSearchIndex.getSearchResults(usernamePrefix); | ||||
const usersInThread = threadOtherMembers(resolvedThreadMembers, viewerID); | const usersInThread = resolvedThreadMembers.filter(member => member.role); | ||||
return usersInThread | return usersInThread | ||||
.filter(user => usernamePrefix.length === 0 || userIDs.includes(user.id)) | .filter(user => usernamePrefix.length === 0 || userIDs.includes(user.id)) | ||||
.sort((userA, userB) => | .sort((userA, userB) => | ||||
stringForUserExplicit(userA).localeCompare( | stringForUserExplicit(userA).localeCompare( | ||||
stringForUserExplicit(userB), | stringForUserExplicit(userB), | ||||
), | ), | ||||
) | ) | ||||
.map(userInfo => ({ type: 'user', userInfo })); | .map(userInfo => ({ type: 'user', userInfo })); | ||||
}, [userSearchIndex, resolvedThreadMembers, usernamePrefix, viewerID]); | }, [userSearchIndex, resolvedThreadMembers, usernamePrefix]); | ||||
} | } | ||||
function useMentionTypeaheadChatSuggestions( | function useMentionTypeaheadChatSuggestions( | ||||
chatSearchIndex: SentencePrefixSearchIndex, | chatSearchIndex: SentencePrefixSearchIndex, | ||||
chatMentionCandidates: ChatMentionCandidates, | chatMentionCandidates: ChatMentionCandidates, | ||||
typeaheadMatchedStrings: ?TypeaheadMatchedStrings, | typeaheadMatchedStrings: ?TypeaheadMatchedStrings, | ||||
): $ReadOnlyArray<MentionTypeaheadChatSuggestionItem> { | ): $ReadOnlyArray<MentionTypeaheadChatSuggestionItem> { | ||||
const chatNamePrefix: ?string = typeaheadMatchedStrings?.query; | const chatNamePrefix: ?string = typeaheadMatchedStrings?.query; | ||||
▲ Show 20 Lines • Show All 76 Lines • Show Last 20 Lines |