Changeset View
Changeset View
Standalone View
Standalone View
native/chat/chat-input-bar.react.js
Show All 31 Lines | import { | ||||
newThreadActionTypes, | newThreadActionTypes, | ||||
} from 'lib/actions/thread-actions.js'; | } from 'lib/actions/thread-actions.js'; | ||||
import { | import { | ||||
useChatMentionContext, | useChatMentionContext, | ||||
useThreadChatMentionCandidates, | useThreadChatMentionCandidates, | ||||
} from 'lib/hooks/chat-mention-hooks.js'; | } from 'lib/hooks/chat-mention-hooks.js'; | ||||
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; | import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; | ||||
import { threadInfoSelector } from 'lib/selectors/thread-selectors.js'; | import { threadInfoSelector } from 'lib/selectors/thread-selectors.js'; | ||||
import { userStoreMentionSearchIndex } from 'lib/selectors/user-selectors.js'; | |||||
import { colorIsDark } from 'lib/shared/color-utils.js'; | import { colorIsDark } from 'lib/shared/color-utils.js'; | ||||
import { useEditMessage } from 'lib/shared/edit-messages-utils.js'; | import { useEditMessage } from 'lib/shared/edit-messages-utils.js'; | ||||
import { | import { | ||||
getMentionTypeaheadUserSuggestions, | useMentionTypeaheadUserSuggestions, | ||||
getMentionTypeaheadChatSuggestions, | getMentionTypeaheadChatSuggestions, | ||||
getTypeaheadRegexMatches, | getTypeaheadRegexMatches, | ||||
type Selection, | type Selection, | ||||
getUserMentionsCandidates, | useUserMentionsCandidates, | ||||
type MentionTypeaheadSuggestionItem, | type MentionTypeaheadSuggestionItem, | ||||
type TypeaheadMatchedStrings, | type TypeaheadMatchedStrings, | ||||
} from 'lib/shared/mention-utils.js'; | } from 'lib/shared/mention-utils.js'; | ||||
import { | import { | ||||
useNextLocalID, | useNextLocalID, | ||||
trimMessage, | trimMessage, | ||||
useMessagePreview, | useMessagePreview, | ||||
messageKey, | messageKey, | ||||
▲ Show 20 Lines • Show All 235 Lines • ▼ Show 20 Lines | type Props = { | ||||
+onInputBarLayout?: (event: LayoutEvent) => mixed, | +onInputBarLayout?: (event: LayoutEvent) => mixed, | ||||
+openCamera: () => mixed, | +openCamera: () => mixed, | ||||
+isActive: boolean, | +isActive: boolean, | ||||
+keyboardState: ?KeyboardState, | +keyboardState: ?KeyboardState, | ||||
+dispatch: Dispatch, | +dispatch: Dispatch, | ||||
+dispatchActionPromise: DispatchActionPromise, | +dispatchActionPromise: DispatchActionPromise, | ||||
+joinThread: (request: ClientThreadJoinRequest) => Promise<ThreadJoinPayload>, | +joinThread: (request: ClientThreadJoinRequest) => Promise<ThreadJoinPayload>, | ||||
+inputState: ?InputState, | +inputState: ?InputState, | ||||
+userSearchIndex: SentencePrefixSearchIndex, | |||||
+userMentionsCandidates: $ReadOnlyArray<RelativeMemberInfo>, | +userMentionsCandidates: $ReadOnlyArray<RelativeMemberInfo>, | ||||
+chatMentionSearchIndex: SentencePrefixSearchIndex, | +chatMentionSearchIndex: SentencePrefixSearchIndex, | ||||
+chatMentionCandidates: ChatMentionCandidates, | +chatMentionCandidates: ChatMentionCandidates, | ||||
+parentThreadInfo: ?ThreadInfo, | +parentThreadInfo: ?ThreadInfo, | ||||
+editedMessagePreview: ?MessagePreviewResult, | +editedMessagePreview: ?MessagePreviewResult, | ||||
+editedMessageInfo: ?MessageInfo, | +editedMessageInfo: ?MessageInfo, | ||||
+editMessage: ( | +editMessage: ( | ||||
messageID: string, | messageID: string, | ||||
▲ Show 20 Lines • Show All 944 Lines • ▼ Show 20 Lines | const isActive = React.useMemo( | ||||
() => props.threadInfo.id === activeThreadSelector(navContext), | () => props.threadInfo.id === activeThreadSelector(navContext), | ||||
[props.threadInfo.id, navContext], | [props.threadInfo.id, navContext], | ||||
); | ); | ||||
const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
const dispatchActionPromise = useDispatchActionPromise(); | const dispatchActionPromise = useDispatchActionPromise(); | ||||
const callJoinThread = useJoinThread(); | const callJoinThread = useJoinThread(); | ||||
const userSearchIndex = useSelector(userStoreMentionSearchIndex); | |||||
const { getChatMentionSearchIndex } = useChatMentionContext(); | const { getChatMentionSearchIndex } = useChatMentionContext(); | ||||
const chatMentionSearchIndex = getChatMentionSearchIndex(props.threadInfo); | const chatMentionSearchIndex = getChatMentionSearchIndex(props.threadInfo); | ||||
const { parentThreadID } = props.threadInfo; | const { parentThreadID } = props.threadInfo; | ||||
const parentThreadInfo = useSelector(state => | const parentThreadInfo = useSelector(state => | ||||
parentThreadID ? threadInfoSelector(state)[parentThreadID] : null, | parentThreadID ? threadInfoSelector(state)[parentThreadID] : null, | ||||
); | ); | ||||
const userMentionsCandidates = getUserMentionsCandidates( | const userMentionsCandidates = useUserMentionsCandidates( | ||||
props.threadInfo, | props.threadInfo, | ||||
parentThreadInfo, | parentThreadInfo, | ||||
); | ); | ||||
const chatMentionCandidates = useThreadChatMentionCandidates( | const chatMentionCandidates = useThreadChatMentionCandidates( | ||||
props.threadInfo, | props.threadInfo, | ||||
); | ); | ||||
Show All 18 Lines | () => | ||||
getTypeaheadRegexMatches( | getTypeaheadRegexMatches( | ||||
selectionState.text, | selectionState.text, | ||||
selectionState.selection, | selectionState.selection, | ||||
nativeMentionTypeaheadRegex, | nativeMentionTypeaheadRegex, | ||||
), | ), | ||||
[selectionState.text, selectionState.selection], | [selectionState.text, selectionState.selection], | ||||
); | ); | ||||
const typeaheadResults: { | const typeaheadMatchedStrings: ?TypeaheadMatchedStrings = | ||||
typeaheadMatchedStrings: ?TypeaheadMatchedStrings, | React.useMemo(() => { | ||||
suggestions: $ReadOnlyArray<MentionTypeaheadSuggestionItem>, | if (typeaheadRegexMatches === null) { | ||||
} = React.useMemo(() => { | return null; | ||||
if (!typeaheadRegexMatches) { | |||||
return { | |||||
typeaheadMatchedStrings: null, | |||||
suggestions: [], | |||||
}; | |||||
} | } | ||||
return { | |||||
const typeaheadMatchedStrings: TypeaheadMatchedStrings = { | |||||
textBeforeAtSymbol: typeaheadRegexMatches[1] ?? '', | textBeforeAtSymbol: typeaheadRegexMatches[1] ?? '', | ||||
query: typeaheadRegexMatches[4] ?? '', | query: typeaheadRegexMatches[4] ?? '', | ||||
}; | }; | ||||
}, [typeaheadRegexMatches]); | |||||
const suggestedUsers = getMentionTypeaheadUserSuggestions( | const suggestedUsers = useMentionTypeaheadUserSuggestions( | ||||
userSearchIndex, | |||||
userMentionsCandidates, | userMentionsCandidates, | ||||
viewerID, | viewerID, | ||||
typeaheadMatchedStrings.query, | typeaheadMatchedStrings, | ||||
); | ); | ||||
const suggestions: $ReadOnlyArray<MentionTypeaheadSuggestionItem> = | |||||
React.useMemo(() => { | |||||
if (!typeaheadRegexMatches || !typeaheadMatchedStrings) { | |||||
return []; | |||||
} | |||||
const suggestedChats = getMentionTypeaheadChatSuggestions( | const suggestedChats = getMentionTypeaheadChatSuggestions( | ||||
chatMentionSearchIndex, | chatMentionSearchIndex, | ||||
chatMentionCandidates, | chatMentionCandidates, | ||||
typeaheadMatchedStrings.query, | typeaheadMatchedStrings.query, | ||||
); | ); | ||||
const suggestions: $ReadOnlyArray<MentionTypeaheadSuggestionItem> = [ | |||||
...suggestedUsers, | |||||
...suggestedChats, | |||||
]; | |||||
return { | return [...suggestedUsers, ...suggestedChats]; | ||||
typeaheadMatchedStrings, | |||||
suggestions, | |||||
}; | |||||
}, [ | }, [ | ||||
chatMentionCandidates, | chatMentionCandidates, | ||||
chatMentionSearchIndex, | chatMentionSearchIndex, | ||||
typeaheadRegexMatches, | typeaheadRegexMatches, | ||||
userMentionsCandidates, | typeaheadMatchedStrings, | ||||
userSearchIndex, | suggestedUsers, | ||||
viewerID, | |||||
]); | ]); | ||||
return ( | return ( | ||||
<ChatInputBar | <ChatInputBar | ||||
{...props} | {...props} | ||||
viewerID={viewerID} | viewerID={viewerID} | ||||
draft={draft} | draft={draft} | ||||
joinThreadLoadingStatus={joinThreadLoadingStatus} | joinThreadLoadingStatus={joinThreadLoadingStatus} | ||||
threadCreationInProgress={threadCreationInProgress} | threadCreationInProgress={threadCreationInProgress} | ||||
calendarQuery={calendarQuery} | calendarQuery={calendarQuery} | ||||
nextLocalID={nextLocalID} | nextLocalID={nextLocalID} | ||||
userInfos={userInfos} | userInfos={userInfos} | ||||
colors={colors} | colors={colors} | ||||
styles={styles} | styles={styles} | ||||
isActive={isActive} | isActive={isActive} | ||||
keyboardState={keyboardState} | keyboardState={keyboardState} | ||||
dispatch={dispatch} | dispatch={dispatch} | ||||
dispatchActionPromise={dispatchActionPromise} | dispatchActionPromise={dispatchActionPromise} | ||||
joinThread={callJoinThread} | joinThread={callJoinThread} | ||||
inputState={inputState} | inputState={inputState} | ||||
userSearchIndex={userSearchIndex} | |||||
userMentionsCandidates={userMentionsCandidates} | userMentionsCandidates={userMentionsCandidates} | ||||
chatMentionSearchIndex={chatMentionSearchIndex} | chatMentionSearchIndex={chatMentionSearchIndex} | ||||
chatMentionCandidates={chatMentionCandidates} | chatMentionCandidates={chatMentionCandidates} | ||||
parentThreadInfo={parentThreadInfo} | parentThreadInfo={parentThreadInfo} | ||||
editedMessagePreview={editedMessagePreview} | editedMessagePreview={editedMessagePreview} | ||||
editedMessageInfo={editedMessageInfo} | editedMessageInfo={editedMessageInfo} | ||||
editMessage={editMessage} | editMessage={editMessage} | ||||
navigation={props.navigation} | navigation={props.navigation} | ||||
overlayContext={overlayContext} | overlayContext={overlayContext} | ||||
messageEditingContext={messageEditingContext} | messageEditingContext={messageEditingContext} | ||||
selectionState={selectionState} | selectionState={selectionState} | ||||
setSelectionState={setSelectionState} | setSelectionState={setSelectionState} | ||||
suggestions={typeaheadResults.suggestions} | suggestions={suggestions} | ||||
typeaheadMatchedStrings={typeaheadResults.typeaheadMatchedStrings} | typeaheadMatchedStrings={typeaheadMatchedStrings} | ||||
/> | /> | ||||
); | ); | ||||
} | } | ||||
type DummyChatInputBarProps = { | type DummyChatInputBarProps = { | ||||
...BaseProps, | ...BaseProps, | ||||
+onHeightMeasured: (height: number) => mixed, | +onHeightMeasured: (height: number) => mixed, | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 109 Lines • Show Last 20 Lines |