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 @@ -19,6 +19,7 @@ } from '../actions/user-actions.js'; import { ENSCacheContext } from '../components/ens-cache-provider.react.js'; import genesis from '../facts/genesis.js'; +import { useIdentitySearch } from '../identity-search/identity-search-context.js'; import type { ChatMessageInfoItem, MessageListData, @@ -40,6 +41,7 @@ import { values } from '../utils/objects.js'; import { useDispatchActionPromise } from '../utils/redux-promise-utils.js'; import { useSelector } from '../utils/redux-utils.js'; +import { usingCommServicesAccessToken } from '../utils/services-utils.js'; const notFriendNotice = 'not friend'; @@ -377,36 +379,65 @@ ); const forwardLookupSearchText = useForwardLookupSearchText(usernameInputText); - const [serverSearchResults, setServerSearchResults] = React.useState< + const [searchResults, setSearchResults] = React.useState< $ReadOnlyArray, >([]); - const callSearchUsers = useLegacyAshoatKeyserverCall(searchUsers); + const callServerSearchUsers = useLegacyAshoatKeyserverCall(searchUsers); + const { connected, sendPrefixQuery: callIdentitySearchUsers } = + useIdentitySearch(); + const dispatchActionPromise = useDispatchActionPromise(); + React.useEffect(() => { if (forwardLookupSearchText.length === 0) { - setServerSearchResults([]); + setSearchResults([]); return; } - const searchUsersPromise = (async () => { + const searchServer = async () => { try { - const { userInfos } = await callSearchUsers(forwardLookupSearchText); - setServerSearchResults( - userInfos.filter(({ id }) => id !== currentUserID), + const { userInfos: serverSearchResult } = await callServerSearchUsers( + forwardLookupSearchText, ); + return serverSearchResult; } catch (err) { - setServerSearchResults([]); + console.error(err); + return []; + } + }; + + const searchUsersPromise = (async () => { + let userInfos; + if (usingCommServicesAccessToken && connected) { + try { + const identitySearchResult = await callIdentitySearchUsers( + forwardLookupSearchText, + ); + userInfos = identitySearchResult.map(user => ({ + id: user.userID, + username: user.username, + avatar: null, + })); + } catch (err) { + console.error(err); + userInfos = await searchServer(); + } + } else { + userInfos = await searchServer(); } + setSearchResults(userInfos.filter(({ id }) => id !== currentUserID)); })(); void dispatchActionPromise(searchUsersActionTypes, searchUsersPromise); }, [ - callSearchUsers, + callServerSearchUsers, + callIdentitySearchUsers, currentUserID, + connected, dispatchActionPromise, forwardLookupSearchText, ]); - return serverSearchResults; + return searchResults; } function filterChatMessageInfosForSearch( diff --git a/web/app.react.js b/web/app.react.js --- a/web/app.react.js +++ b/web/app.react.js @@ -21,6 +21,7 @@ useModalContext, } from 'lib/components/modal-provider.react.js'; import { StaffContextProvider } from 'lib/components/staff-provider.react.js'; +import { IdentitySearchProvider } from 'lib/identity-search/identity-search-context.js'; import { createLoadingStatusSelector, combineLoadingStatuses, @@ -67,6 +68,7 @@ import VisibilityHandler from './redux/visibility-handler.react.js'; import history from './router-history.js'; import { MessageSearchStateProvider } from './search/message-search-state-provider.react.js'; +import { createIdentitySearchAuthMessage } from './selectors/identity-search-selectors.js'; import { createTunnelbrokerInitMessage } from './selectors/tunnelbroker-selectors.js'; import AccountSettings from './settings/account-settings.react.js'; import DangerZone from './settings/danger-zone.react.js'; @@ -420,10 +422,16 @@ ); function AppWithProvider(props: BaseProps): React.Node { + const identitySearchAuthMessage = useSelector( + createIdentitySearchAuthMessage, + ); + return ( - - - + + + + + ); } 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 @@ -55,13 +55,13 @@ [userInfoInputArray], ); - const serverSearchResults = useSearchUsers(usernameInputText); + const searchResults = useSearchUsers(usernameInputText); const userListItems = usePotentialMemberItems({ text: usernameInputText, userInfos: otherUserInfos, excludeUserIDs: userInfoInputIDs, - includeServerSearchUsers: serverSearchResults, + includeServerSearchUsers: searchResults, }); const userListItemsWithENSNames = useENSNames(userListItems); diff --git a/web/selectors/identity-search-selectors.js b/web/selectors/identity-search-selectors.js new file mode 100644 --- /dev/null +++ b/web/selectors/identity-search-selectors.js @@ -0,0 +1,29 @@ +// @flow + +import { createSelector } from 'reselect'; + +import type { AuthMessage } from 'lib/types/identity-search/auth-message-types.js'; + +import type { AppState } from '../redux/redux-setup.js'; + +export const createIdentitySearchAuthMessage: AppState => ?AuthMessage = + createSelector( + (state: AppState) => state.cryptoStore?.primaryIdentityKeys?.ed25519, + (state: AppState) => state.commServicesAccessToken, + (state: AppState) => state.currentUserInfo?.id, + ( + deviceID: ?string, + accessToken: ?string, + userID: ?string, + ): ?AuthMessage => { + if (!deviceID || !accessToken || !userID) { + return null; + } + return ({ + type: 'AuthMessage', + deviceID, + accessToken, + userID, + }: AuthMessage); + }, + ); diff --git a/web/settings/relationship/add-users-list.react.js b/web/settings/relationship/add-users-list.react.js --- a/web/settings/relationship/add-users-list.react.js +++ b/web/settings/relationship/add-users-list.react.js @@ -67,14 +67,14 @@ ); }, [searchText, userStoreSearchIndex]); - const serverSearchResults = useSearchUsers(searchText); + const searchResults = useSearchUsers(searchText); const searchTextPresent = searchText.length > 0; const mergedUserInfos = React.useMemo(() => { const mergedInfos: { [string]: GlobalAccountUserInfo | AccountUserInfo } = {}; - for (const userInfo of serverSearchResults) { + for (const userInfo of searchResults) { mergedInfos[userInfo.id] = userInfo; } @@ -89,12 +89,7 @@ } return mergedInfos; - }, [ - searchTextPresent, - serverSearchResults, - userInfos, - userStoreSearchResults, - ]); + }, [searchTextPresent, searchResults, userInfos, userStoreSearchResults]); const sortedUsers = React.useMemo( () =>