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 @@ -23,7 +23,7 @@ } from '../utils/thread-utils.js'; type Props = { - +activeChatThreadID: string, + +activeChatThreadID: ?string, }; function ChatMessageListContainer(props: Props): React.Node { diff --git a/web/chat/chat.react.js b/web/chat/chat.react.js --- a/web/chat/chat.react.js +++ b/web/chat/chat.react.js @@ -15,6 +15,9 @@ const activeChatThreadID = useSelector( state => state.navInfo.activeChatThreadID, ); + const chatModeIsCreate = useSelector( + state => state.navInfo.chatMode === 'create', + ); const chatList = React.useMemo( () => ( @@ -24,11 +27,11 @@ [], ); const messageList = React.useMemo(() => { - if (!activeChatThreadID) { + if (!activeChatThreadID && !chatModeIsCreate) { return null; } return ; - }, [activeChatThreadID]); + }, [activeChatThreadID, chatModeIsCreate]); let threadDraftUpdater = null; if (loggedIn) { diff --git a/web/input/input-state-container.react.js b/web/input/input-state-container.react.js --- a/web/input/input-state-container.react.js +++ b/web/input/input-state-container.react.js @@ -83,7 +83,6 @@ import { type PendingMultimediaUpload, - type InputState, type TypeaheadState, InputStateContext, } from './input-state.js'; @@ -515,13 +514,14 @@ return threadCreationPromise; } - inputBaseStateSelector = _memoize((threadID: string) => + inputBaseStateSelector = _memoize((threadID: ?string) => createSelector( - (propsAndState: PropsAndState) => propsAndState.pendingUploads[threadID], (propsAndState: PropsAndState) => - propsAndState.drafts[draftKeyFromThreadID(threadID)], + threadID ? propsAndState.pendingUploads[threadID] : null, (propsAndState: PropsAndState) => - propsAndState.textCursorPositions[threadID], + threadID ? propsAndState.drafts[draftKeyFromThreadID(threadID)] : null, + (propsAndState: PropsAndState) => + threadID ? propsAndState.textCursorPositions[threadID] : null, ( pendingUploads: ?{ [localUploadID: string]: PendingMultimediaUpload }, draft: ?string, @@ -603,9 +603,11 @@ } async appendFiles( - threadID: string, + threadID: ?string, files: $ReadOnlyArray, ): Promise { + invariant(threadID, 'threadID should be set in appendFiles'); + const selectionTime = Date.now(); const { pushModal } = this.props; @@ -1036,7 +1038,9 @@ this.props.dispatch({ type: queueReportsActionType, payload: { reports } }); } - cancelPendingUpload(threadID: string, localUploadID: string) { + cancelPendingUpload(threadID: ?string, localUploadID: string) { + invariant(threadID, 'threadID should be set in cancelPendingUpload'); + let revokeURL, abortRequest; this.setState( prevState => { @@ -1251,7 +1255,9 @@ }); } - setDraft(threadID: string, draft: string) { + setDraft(threadID: ?string, draft: string) { + invariant(threadID, 'threadID should be set in setDraft'); + const newThreadID = this.getRealizedOrPendingThreadID(threadID); this.props.dispatch({ type: 'UPDATE_DRAFT', @@ -1262,7 +1268,9 @@ }); } - setTextCursorPosition(threadID: string, newPosition: number) { + setTextCursorPosition(threadID: ?string, newPosition: number) { + invariant(threadID, 'threadID should be set in setTextCursorPosition'); + this.setState(prevState => { const newThreadID = this.getRealizedOrPendingThreadID(threadID); return { @@ -1435,23 +1443,20 @@ // we're going with two selectors as we want to avoid // recreation of chat state setter functions on typeahead state updates - let inputState: ?InputState = null; - if (activeChatThreadID) { - const inputBaseState = this.inputBaseStateSelector(activeChatThreadID)({ - ...this.state, - ...this.props, - }); + const inputBaseState = this.inputBaseStateSelector(activeChatThreadID)({ + ...this.state, + ...this.props, + }); - const typeaheadState = this.typeaheadStateSelector({ - ...this.state, - ...this.props, - }); + const typeaheadState = this.typeaheadStateSelector({ + ...this.state, + ...this.props, + }); - inputState = this.inputStateSelector({ - inputBaseState, - typeaheadState, - }); - } + const inputState = this.inputStateSelector({ + inputBaseState, + typeaheadState, + }); return ( diff --git a/web/utils/thread-utils.js b/web/utils/thread-utils.js --- a/web/utils/thread-utils.js +++ b/web/utils/thread-utils.js @@ -74,13 +74,13 @@ ); const baseThreadInfo = useSelector(state => { - if (!activeChatThreadID) { - return null; + if (activeChatThreadID) { + const activeThreadInfo = threadInfoSelector(state)[activeChatThreadID]; + if (activeThreadInfo) { + return activeThreadInfo; + } } - return ( - threadInfoSelector(state)[activeChatThreadID] ?? - state.navInfo.pendingThread - ); + return state.navInfo.pendingThread; }); const existingThreadInfoFinder = useExistingThreadInfoFinder(baseThreadInfo); const threadInfo = React.useMemo(() => {