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 @@ -1027,7 +1027,7 @@ +searching: boolean, +userInfoInputArray: $ReadOnlyArray, }; -type ExistingThreadInfoFinder = ( +export type ExistingThreadInfoFinder = ( params: ExistingThreadInfoFinderParams, ) => ?ThreadInfo; function useExistingThreadInfoFinder( diff --git a/web/chat/chat-message-list-container.react.js b/web/chat/chat-message-list-container.react.js --- a/web/chat/chat-message-list-container.react.js +++ b/web/chat/chat-message-list-container.react.js @@ -215,6 +215,9 @@ ); }, [ + existingThreadInfoFinderForCreatingThread, inputState, isChatCreation, otherUserInfos, 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 @@ -1,13 +1,19 @@ // @flow import classNames from 'classnames'; +import invariant from 'invariant'; import * as React from 'react'; import { useDispatch } from 'react-redux'; import { searchUsers } from 'lib/actions/user-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { filterPotentialMembers } from 'lib/selectors/user-selectors'; import SearchIndex from 'lib/shared/search-index'; -import { getPotentialMemberItems } from 'lib/shared/search-utils'; +import { + getPotentialMemberItems, + notFriendNotice, +} from 'lib/shared/search-utils'; import { threadIsPending } from 'lib/shared/thread-utils'; +import type { ExistingThreadInfoFinder } from 'lib/shared/thread-utils'; import type { AccountUserInfo, UserListItem } from 'lib/types/user-types'; import { useServerCall } from 'lib/utils/action-utils'; @@ -15,6 +21,7 @@ import Label from '../components/label.react'; import Search from '../components/search.react'; import type { InputState } from '../input/input-state'; +import Alert from '../modals/alert.react'; import { updateNavInfoActionType } from '../redux/action-types'; import { useSelector } from '../redux/redux-utils'; import SWMansionIcon from '../SWMansionIcon.react'; @@ -23,8 +30,10 @@ type Props = { +userInfoInputArray: $ReadOnlyArray, +setUserInfoInputArray: ( - ($ReadOnlyArray) => $ReadOnlyArray, + | (($ReadOnlyArray) => $ReadOnlyArray) + | $ReadOnlyArray, ) => void, + +existingThreadInfoFinderForCreatingThread: ExistingThreadInfoFinder, +otherUserInfos: { [id: string]: AccountUserInfo }, +threadID: string, +inputState: InputState, @@ -38,6 +47,7 @@ const { userInfoInputArray, setUserInfoInputArray, + existingThreadInfoFinderForCreatingThread, otherUserInfos, threadID, inputState, @@ -107,15 +117,50 @@ [usernameInputText, mergedUserInfos, userSearchIndex, userInfoInputIDs], ); + const dispatch = useDispatch(); + const { pushModal } = useModalContext(); const onSelectUserFromSearch = React.useCallback( - (id: string, username: string) => { - setUserInfoInputArray(previousUserInfoInputArray => [ - ...previousUserInfoInputArray, - { id, username }, - ]); + (userItem: UserListItem) => { setUsernameInputText(''); + if (!userItem.alertTitle) { + setUserInfoInputArray(previousUserInfoInputArray => [ + ...previousUserInfoInputArray, + { id: userItem.id, username: userItem.username }, + ]); + } else if ( + userItem.notice === notFriendNotice && + userInfoInputArray.length === 0 + ) { + const newUserInfoInputArray = [ + { id: userItem.id, username: userItem.username }, + ]; + setUserInfoInputArray(newUserInfoInputArray); + const threadInfo = existingThreadInfoFinderForCreatingThread({ + searching: true, + userInfoInputArray: newUserInfoInputArray, + }); + dispatch({ + type: updateNavInfoActionType, + payload: { + chatMode: 'view', + activeChatThreadID: threadInfo?.id, + pendingThread: threadInfo, + }, + }); + } else { + invariant(userItem.alertText, 'alert should have both title and text'); + pushModal( + {userItem.alertText}, + ); + } }, - [setUserInfoInputArray], + [ + dispatch, + existingThreadInfoFinderForCreatingThread, + pushModal, + setUserInfoInputArray, + userInfoInputArray.length, + ], ); const onRemoveUserFromSelected = React.useCallback( @@ -141,16 +186,11 @@
  • ))} @@ -163,7 +203,6 @@ usernameInputText, ]); - const dispatch = useDispatch(); const hideSearch = React.useCallback( (threadBehavior: ActiveThreadBehavior = 'keep-active-thread') => { dispatch({