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 @@ -17,6 +17,7 @@ searchUsers, searchUsersActionTypes, } from '../actions/user-actions.js'; +import { ENSCacheContext } from '../components/ens-cache-provider.react.js'; import genesis from '../facts/genesis.js'; import type { ChatMessageInfoItem, @@ -37,6 +38,7 @@ useServerCall, useDispatchActionPromise, } from '../utils/action-utils.js'; +import { isValidENSName } from '../utils/ens-helpers.js'; import { values } from '../utils/objects.js'; import { useSelector } from '../utils/redux-utils.js'; @@ -278,12 +280,40 @@ ); } +function useForwardLookupSearchText(originalText: string): string { + const cacheContext = React.useContext(ENSCacheContext); + const { ensCache } = cacheContext; + const lowercaseText = originalText.toLowerCase(); + + const [usernameToSearch, setUsernameToSearch] = + React.useState(lowercaseText); + + React.useEffect(() => { + (async () => { + if (!ensCache || !isValidENSName(lowercaseText)) { + setUsernameToSearch(lowercaseText); + return; + } + + const address = await ensCache.getAddressForName(lowercaseText); + if (address) { + setUsernameToSearch(address); + } else { + setUsernameToSearch(lowercaseText); + } + })(); + }, [ensCache, lowercaseText]); + + return usernameToSearch; +} + function useSearchUsers( usernameInputText: string, ): $ReadOnlyArray { const currentUserID = useSelector( state => state.currentUserInfo && state.currentUserInfo.id, ); + const forwardLookupSearchText = useForwardLookupSearchText(usernameInputText); const [serverSearchResults, setServerSearchResults] = React.useState< $ReadOnlyArray, @@ -292,11 +322,11 @@ const dispatchActionPromise = useDispatchActionPromise(); React.useEffect(() => { const searchUsersPromise = (async () => { - if (usernameInputText.length === 0) { + if (forwardLookupSearchText.length === 0) { setServerSearchResults([]); } else { try { - const { userInfos } = await callSearchUsers(usernameInputText); + const { userInfos } = await callSearchUsers(forwardLookupSearchText); setServerSearchResults( userInfos.filter(({ id }) => id !== currentUserID), ); @@ -310,7 +340,7 @@ callSearchUsers, currentUserID, dispatchActionPromise, - usernameInputText, + forwardLookupSearchText, ]); return serverSearchResults; @@ -354,4 +384,5 @@ useSearchMessages, useSearchUsers, filterChatMessageInfosForSearch, + useForwardLookupSearchText, }; 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 @@ -11,6 +11,7 @@ import { extractUserMentionsFromText } from './mention-utils.js'; import { getMessageTitle, isInvalidSidebarSource } from './message-utils.js'; import { relationshipBlockedInEitherDirection } from './relationship-utils.js'; +import { useForwardLookupSearchText } from './search-utils.js'; import threadWatcher from './thread-watcher.js'; import { fetchMostRecentMessagesActionTypes, @@ -1513,6 +1514,7 @@ ): ThreadListSearchResult { const callSearchUsers = useServerCall(searchUserCall); const usersWithPersonalThread = useSelector(usersWithPersonalThreadSelector); + const forwardLookupSearchText = useForwardLookupSearchText(searchText); const searchUsers = React.useCallback( async (usernamePrefix: string) => { if (usernamePrefix.length === 0) { @@ -1538,10 +1540,10 @@ (async () => { const results = threadSearchIndex.getSearchResults(searchText); setThreadSearchResults(new Set(results)); - const usersResults = await searchUsers(searchText); + const usersResults = await searchUsers(forwardLookupSearchText); setUsersSearchResults(usersResults); })(); - }, [searchText, threadSearchIndex, searchUsers]); + }, [searchText, forwardLookupSearchText, threadSearchIndex, searchUsers]); return { threadSearchResults, usersSearchResults }; }