Changeset View
Changeset View
Standalone View
Standalone View
native/chat/chat-input-bar.react.js
Show All 40 Lines | |||||
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, | getMentionTypeaheadUserSuggestions, | ||||
getMentionTypeaheadChatSuggestions, | getMentionTypeaheadChatSuggestions, | ||||
getTypeaheadRegexMatches, | getTypeaheadRegexMatches, | ||||
type Selection, | type Selection, | ||||
getUserMentionsCandidates, | getUserMentionsCandidates, | ||||
type MentionTypeaheadSuggestionItem, | |||||
type TypeaheadMatchedStrings, | |||||
} from 'lib/shared/mention-utils.js'; | } from 'lib/shared/mention-utils.js'; | ||||
import { | import { | ||||
useNextLocalID, | useNextLocalID, | ||||
trimMessage, | trimMessage, | ||||
useMessagePreview, | useMessagePreview, | ||||
messageKey, | messageKey, | ||||
type MessagePreviewResult, | type MessagePreviewResult, | ||||
} from 'lib/shared/message-utils.js'; | } from 'lib/shared/message-utils.js'; | ||||
▲ Show 20 Lines • Show All 249 Lines • ▼ Show 20 Lines | +editMessage: ( | ||||
messageID: string, | messageID: string, | ||||
text: string, | text: string, | ||||
) => Promise<SendEditMessageResponse>, | ) => Promise<SendEditMessageResponse>, | ||||
+navigation: ?ChatNavigationProp<'MessageList'>, | +navigation: ?ChatNavigationProp<'MessageList'>, | ||||
+overlayContext: ?OverlayContextType, | +overlayContext: ?OverlayContextType, | ||||
+messageEditingContext: ?MessageEditingContextType, | +messageEditingContext: ?MessageEditingContextType, | ||||
+selectionState: SyncedSelectionData, | +selectionState: SyncedSelectionData, | ||||
+setSelectionState: SetState<SyncedSelectionData>, | +setSelectionState: SetState<SyncedSelectionData>, | ||||
+suggestions: $ReadOnlyArray<MentionTypeaheadSuggestionItem>, | |||||
+typeaheadMatchedStrings: ?TypeaheadMatchedStrings, | |||||
}; | }; | ||||
type State = { | type State = { | ||||
+text: string, | +text: string, | ||||
+textEdited: boolean, | +textEdited: boolean, | ||||
+buttonsExpanded: boolean, | +buttonsExpanded: boolean, | ||||
+isExitingDuringEditMode: boolean, | +isExitingDuringEditMode: boolean, | ||||
}; | }; | ||||
class ChatInputBar extends React.PureComponent<Props, State> { | class ChatInputBar extends React.PureComponent<Props, State> { | ||||
▲ Show 20 Lines • Show All 344 Lines • ▼ Show 20 Lines | if (!isMember && canJoin && !this.props.threadCreationInProgress) { | ||||
]} | ]} | ||||
> | > | ||||
{buttonContent} | {buttonContent} | ||||
</Button> | </Button> | ||||
</View> | </View> | ||||
); | ); | ||||
} | } | ||||
const typeaheadRegexMatches = getTypeaheadRegexMatches( | |||||
this.props.selectionState.text, | |||||
this.props.selectionState.selection, | |||||
nativeMentionTypeaheadRegex, | |||||
); | |||||
let typeaheadTooltip = null; | let typeaheadTooltip = null; | ||||
if (typeaheadRegexMatches && !isEditMode) { | if ( | ||||
const typeaheadMatchedStrings = { | this.props.suggestions.length > 0 && | ||||
textBeforeAtSymbol: typeaheadRegexMatches[1] ?? '', | this.props.typeaheadMatchedStrings && | ||||
query: typeaheadRegexMatches[4] ?? '', | !isEditMode | ||||
}; | ) { | ||||
const suggestedUsers = getMentionTypeaheadUserSuggestions( | |||||
this.props.userSearchIndex, | |||||
this.props.userMentionsCandidates, | |||||
this.props.viewerID, | |||||
typeaheadMatchedStrings.query, | |||||
); | |||||
const suggestedChats = getMentionTypeaheadChatSuggestions( | |||||
this.props.chatMentionSearchIndex, | |||||
this.props.chatMentionCandidates, | |||||
typeaheadMatchedStrings.query, | |||||
); | |||||
const suggestions = [...suggestedUsers, ...suggestedChats]; | |||||
if (suggestions.length > 0) { | |||||
typeaheadTooltip = ( | typeaheadTooltip = ( | ||||
<TypeaheadTooltip | <TypeaheadTooltip | ||||
text={this.state.text} | text={this.state.text} | ||||
matchedStrings={typeaheadMatchedStrings} | matchedStrings={this.props.typeaheadMatchedStrings} | ||||
suggestions={suggestions} | suggestions={this.props.suggestions} | ||||
focusAndUpdateTextAndSelection={this.focusAndUpdateTextAndSelection} | focusAndUpdateTextAndSelection={this.focusAndUpdateTextAndSelection} | ||||
typeaheadTooltipActionsGetter={mentionTypeaheadTooltipActions} | typeaheadTooltipActionsGetter={mentionTypeaheadTooltipActions} | ||||
TypeaheadTooltipButtonComponent={MentionTypeaheadTooltipButton} | TypeaheadTooltipButtonComponent={MentionTypeaheadTooltipButton} | ||||
/> | /> | ||||
); | ); | ||||
} | } | ||||
} | |||||
let content; | let content; | ||||
const defaultMembersAreVoiced = checkIfDefaultMembersAreVoiced( | const defaultMembersAreVoiced = checkIfDefaultMembersAreVoiced( | ||||
this.props.threadInfo, | this.props.threadInfo, | ||||
); | ); | ||||
if (this.shouldShowTextInput) { | if (this.shouldShowTextInput) { | ||||
content = this.renderInput(); | content = this.renderInput(); | ||||
} else if ( | } else if ( | ||||
▲ Show 20 Lines • Show All 584 Lines • ▼ Show 20 Lines | function ConnectedChatInputBarBase(props: ConnectedChatInputBarBaseProps) { | ||||
const editMessage = useEditMessage(); | const editMessage = useEditMessage(); | ||||
const [selectionState, setSelectionState] = | const [selectionState, setSelectionState] = | ||||
React.useState<SyncedSelectionData>({ | React.useState<SyncedSelectionData>({ | ||||
text: draft, | text: draft, | ||||
selection: { start: 0, end: 0 }, | selection: { start: 0, end: 0 }, | ||||
}); | }); | ||||
const typeaheadRegexMatches = React.useMemo( | |||||
() => | |||||
getTypeaheadRegexMatches( | |||||
selectionState.text, | |||||
selectionState.selection, | |||||
nativeMentionTypeaheadRegex, | |||||
), | |||||
[selectionState.text, selectionState.selection], | |||||
); | |||||
const typeaheadResults: { | |||||
typeaheadMatchedStrings: ?TypeaheadMatchedStrings, | |||||
suggestions: $ReadOnlyArray<MentionTypeaheadSuggestionItem>, | |||||
} = React.useMemo(() => { | |||||
if (!typeaheadRegexMatches) { | |||||
return { | |||||
typeaheadMatchedStrings: null, | |||||
suggestions: [], | |||||
}; | |||||
} | |||||
const typeaheadMatchedStrings: TypeaheadMatchedStrings = { | |||||
textBeforeAtSymbol: typeaheadRegexMatches[1] ?? '', | |||||
query: typeaheadRegexMatches[4] ?? '', | |||||
}; | |||||
const suggestedUsers = getMentionTypeaheadUserSuggestions( | |||||
userSearchIndex, | |||||
userMentionsCandidates, | |||||
viewerID, | |||||
typeaheadMatchedStrings.query, | |||||
); | |||||
const suggestedChats = getMentionTypeaheadChatSuggestions( | |||||
chatMentionSearchIndex, | |||||
chatMentionCandidates, | |||||
typeaheadMatchedStrings.query, | |||||
); | |||||
const suggestions: $ReadOnlyArray<MentionTypeaheadSuggestionItem> = [ | |||||
...suggestedUsers, | |||||
...suggestedChats, | |||||
]; | |||||
return { | |||||
typeaheadMatchedStrings, | |||||
suggestions, | |||||
}; | |||||
}, [ | |||||
chatMentionCandidates, | |||||
chatMentionSearchIndex, | |||||
typeaheadRegexMatches, | |||||
userMentionsCandidates, | |||||
userSearchIndex, | |||||
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} | ||||
Show All 15 Lines | <ChatInputBar | ||||
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} | |||||
typeaheadMatchedStrings={typeaheadResults.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 |