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 @@ -5,6 +5,7 @@ import { userSearchIndexForPotentialMembers } from 'lib/selectors/user-selectors'; import { getPotentialMemberItems } from 'lib/shared/search-utils'; +import { threadIsPending } from 'lib/shared/thread-utils'; import type { AccountUserInfo, UserListItem } from 'lib/types/user-types'; import Label from '../components/label.react'; @@ -22,6 +23,10 @@ +inputState: InputState, }; +type ActiveThreadBehavior = + | 'reset-active-thread-if-pending' + | 'keep-active-thread'; + function ChatThreadComposer(props: Props): React.Node { const { userInfoInputArray, otherUserInfos, threadID, inputState } = props; @@ -105,15 +110,26 @@ usernameInputText, ]); - const hideSearch = React.useCallback(() => { - dispatch({ - type: updateNavInfoActionType, - payload: { - chatMode: 'view', - activeChatThreadID: threadID, - }, - }); - }, [dispatch, threadID]); + const hideSearch = React.useCallback( + (threadBehavior: ActiveThreadBehavior = 'keep-active-thread') => { + dispatch({ + type: updateNavInfoActionType, + payload: { + chatMode: 'view', + activeChatThreadID: + threadBehavior === 'keep-active-thread' || + !threadIsPending(threadID) + ? threadID + : null, + }, + }); + }, + [dispatch, threadID], + ); + + const onCloseSearch = React.useCallback(() => { + hideSearch('reset-active-thread-if-pending'); + }, [hideSearch]); const tagsList = React.useMemo(() => { if (!userInfoInputArray?.length) { @@ -155,7 +171,7 @@ placeholder="Select users for chat" /> -
+
diff --git a/web/chat/chat-thread-list-item.react.js b/web/chat/chat-thread-list-item.react.js --- a/web/chat/chat-thread-list-item.react.js +++ b/web/chat/chat-thread-list-item.react.js @@ -33,7 +33,6 @@ const { id: threadID, currentUser } = threadInfo; const ancestorThreads = useAncestorThreads(threadInfo); - const onClick = useOnClickThread(item.threadInfo); const timeZone = useSelector(state => state.timeZone); const lastActivity = shortAbsoluteDate( @@ -42,6 +41,21 @@ ); const active = useThreadIsActive(threadID); + const isCreateMode = useSelector( + state => state.navInfo.chatMode === 'create', + ); + + const onClick = useOnClickThread(item.threadInfo); + + const selectItemIfNotActiveCreation = React.useCallback( + (event: SyntheticEvent) => { + if (!isCreateMode || !active) { + onClick(event); + } + }, + [isCreateMode, active, onClick], + ); + const containerClassName = React.useMemo( () => classNames({ @@ -130,7 +144,10 @@ return ( <> -
+
{unreadDot}
diff --git a/web/selectors/nav-selectors.js b/web/selectors/nav-selectors.js --- a/web/selectors/nav-selectors.js +++ b/web/selectors/nav-selectors.js @@ -140,24 +140,22 @@ ); event.preventDefault(); const { id: threadID } = thread; + + let payload; if (threadID.includes('pending')) { - dispatch({ - type: updateNavInfoActionType, - payload: { - chatMode: 'view', - activeChatThreadID: threadID, - pendingThread: thread, - }, - }); + payload = { + chatMode: 'view', + activeChatThreadID: threadID, + pendingThread: thread, + }; } else { - dispatch({ - type: updateNavInfoActionType, - payload: { - chatMode: 'view', - activeChatThreadID: threadID, - }, - }); + payload = { + chatMode: 'view', + activeChatThreadID: threadID, + }; } + + dispatch({ type: updateNavInfoActionType, payload }); }, [dispatch, thread], );