From a4365403dad974c8aafcdcc9271841ca673a2d08 Mon Sep 17 00:00:00 2001 From: Konrad Bochnia Date: Fri, 5 May 2023 11:16:19 +0200 Subject: [PATCH 01/14] Add mention suggestions --- src/CONST.js | 5 + src/components/MentionSuggestions.js | 104 ++++++++++++ src/pages/home/report/ReportActionCompose.js | 160 +++++++++++++++++-- src/styles/styles.js | 4 + 4 files changed, 258 insertions(+), 15 deletions(-) create mode 100644 src/components/MentionSuggestions.js diff --git a/src/CONST.js b/src/CONST.js index a45c6c91240e..025c2db7bfb9 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -1002,12 +1002,17 @@ const CONST = { CODE_2FA: /^\d{6}$/, ATTACHMENT_ID: /chat-attachments\/(\d+)/, HAS_COLON_ONLY_AT_THE_BEGINNING: /^:[^:]+$/, + HAS_AT_MOST_TWO_AT_SIGNS: /^@[^@]+@?[^@]+$/, // eslint-disable-next-line no-misleading-character-class NEW_LINE_OR_WHITE_SPACE_OR_EMOJI: /[\n\s\p{Extended_Pictographic}\u200d\u{1f1e6}-\u{1f1ff}\u{1f3fb}-\u{1f3ff}\u{e0020}-\u{e007f}\u20E3\uFE0F]|[#*0-9]\uFE0F?\u20E3/gu, // Define the regular expression pattern to match a string starting with a colon and ending with a space or newline character EMOJI_REPLACER: /^:[^\n\r]+?(?=$|\s)/, + + // Define the regular expression pattern to match a string starting with an at sign and ending with a space or newline character + MENTION_REPLACER: /^@[^\n\r]+?(?=$|\s)/, + MERGED_ACCOUNT_PREFIX: /^(MERGED_\d+@)/, }, diff --git a/src/components/MentionSuggestions.js b/src/components/MentionSuggestions.js new file mode 100644 index 000000000000..6f921c23cfbf --- /dev/null +++ b/src/components/MentionSuggestions.js @@ -0,0 +1,104 @@ +import React from 'react'; +import {View} from 'react-native'; +import PropTypes from 'prop-types'; +import _ from 'underscore'; +import styles from '../styles/styles'; +import * as StyleUtils from '../styles/StyleUtils'; +import Text from './Text'; +import CONST from '../CONST'; +import Avatar from './Avatar'; +import AutoCompleteSuggestions from './AutoCompleteSuggestions'; +import getStyledTextArray from '../libs/GetStyledTextArray'; +import avatarPropTypes from './avatarPropTypes'; + +const propTypes = { + /** The index of the highlighted mention */ + highlightedMentionIndex: PropTypes.number, + + /** Array of suggested mentions */ + mentions: PropTypes.arrayOf(PropTypes.shape({ + /** Display name of the user */ + text: PropTypes.string, + + /** Email/phone number of the user */ + alternateText: PropTypes.string, + + /** Array of icons of the user. We use the first element of this array */ + icons: PropTypes.arrayOf(avatarPropTypes), + })).isRequired, + + /** Fired when the user selects an mention */ + onSelect: PropTypes.func.isRequired, + + /** Mention prefix that follows the @ sign */ + prefix: PropTypes.string.isRequired, + + /** Show that we can use large mention picker. + * Depending on available space and whether the input is expanded, we can have a small or large mention suggester. + * When this value is false, the suggester will have a height of 2.5 items. When this value is true, the height can be up to 5 items. */ + isMentionPickerLarge: PropTypes.bool.isRequired, + + /** Show that we should include ReportRecipientLocalTime view height */ + shouldIncludeReportRecipientLocalTimeHeight: PropTypes.bool.isRequired, +}; + +const defaultProps = { + highlightedMentionIndex: 0, +}; + +/** + * Create unique keys for each mention item + * @param {Object} item + * @param {Number} index + * @returns {String} + */ +const keyExtractor = item => item.alternateText; + +const MentionSuggestions = (props) => { + /** + * Render a suggestion menu item component. + * @param {Object} item + * @returns {JSX.Element} + */ + const renderSuggestionMenuItem = (item) => { + const displayedText = _.uniq([item.text, item.alternateText]).join(' - '); + const styledTextArray = getStyledTextArray(displayedText, props.prefix); + + return ( + + + + {_.map(styledTextArray, ({text, isColored}, i) => ( + + {text} + + ))} + + + ); + }; + + return ( + + ); +}; + +MentionSuggestions.propTypes = propTypes; +MentionSuggestions.defaultProps = defaultProps; +MentionSuggestions.displayName = 'MentionSuggestions'; + +export default MentionSuggestions; diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 556a0b624412..89bc6e1056e0 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -49,6 +49,7 @@ import ReportDropUI from './ReportDropUI'; import DragAndDrop from '../../../components/DragAndDrop'; import reportPropTypes from '../../reportPropTypes'; import EmojiSuggestions from '../../../components/EmojiSuggestions'; +import MentionSuggestions from '../../../components/MentionSuggestions'; import withKeyboardState, {keyboardStatePropTypes} from '../../../components/withKeyboardState'; import ArrowKeyFocusManager from '../../../components/ArrowKeyFocusManager'; import OfflineWithFeedback from '../../../components/OfflineWithFeedback'; @@ -56,6 +57,7 @@ import KeyboardShortcut from '../../../libs/KeyboardShortcut'; import * as ComposerUtils from '../../../libs/ComposerUtils'; import * as Welcome from '../../../libs/actions/Welcome'; import Permissions from '../../../libs/Permissions'; +import * as OptionsListUtils from '../../../libs/OptionsListUtils'; const propTypes = { /** Beta features list */ @@ -121,6 +123,8 @@ const propTypes = { /** The type of action that's pending */ pendingAction: PropTypes.oneOf(['add', 'update', 'delete']), + reports: PropTypes.objectOf(reportPropTypes), + ...windowDimensionsPropTypes, ...withLocalizePropTypes, ...withCurrentUserPersonalDetailsPropTypes, @@ -140,6 +144,7 @@ const defaultProps = { frequentlyUsedEmojis: [], isComposerFullSize: false, pendingAction: null, + reports: {}, ...withCurrentUserPersonalDetailsDefaultProps, }; @@ -163,6 +168,7 @@ class ReportActionCompose extends React.Component { constructor(props) { super(props); this.calculateEmojiSuggestion = _.debounce(this.calculateEmojiSuggestion, 10, false); + this.calculateMentionSuggestion = _.debounce(this.calculateMentionSuggestion, 10, false); this.updateComment = this.updateComment.bind(this); this.debouncedSaveReportComment = _.debounce(this.debouncedSaveReportComment.bind(this), 1000, false); this.debouncedBroadcastUserIsTyping = _.debounce(this.debouncedBroadcastUserIsTyping.bind(this), 100, true); @@ -174,12 +180,14 @@ class ReportActionCompose extends React.Component { this.addEmojiToTextBox = this.addEmojiToTextBox.bind(this); this.onSelectionChange = this.onSelectionChange.bind(this); this.isEmojiCode = this.isEmojiCode.bind(this); + this.isMentionCode = this.isMentionCode.bind(this); this.setTextInputRef = this.setTextInputRef.bind(this); this.getInputPlaceholder = this.getInputPlaceholder.bind(this); this.getMoneyRequestOptions = this.getMoneyRequestOptions.bind(this); this.getTaskOption = this.getTaskOption.bind(this); this.addAttachment = this.addAttachment.bind(this); this.insertSelectedEmoji = this.insertSelectedEmoji.bind(this); + this.insertSelectedMention = this.insertSelectedMention.bind(this); this.setExceededMaxCommentLength = this.setExceededMaxCommentLength.bind(this); this.updateNumberOfLines = this.updateNumberOfLines.bind(this); this.showPopoverMenu = this.showPopoverMenu.bind(this); @@ -209,7 +217,12 @@ class ReportActionCompose extends React.Component { suggestedEmojis: [], highlightedEmojiIndex: 0, colonIndex: -1, - shouldShowSuggestionMenu: false, + shouldShowEmojiSuggestionMenu: true, + shouldShowMentionSuggestionMenu: true, + suggestedMentions: [], + highlightedMentionIndex: 0, + mentionPrefix: '', + atSignIndex: -1, isEmojiPickerLarge: false, composerHeight: 0, hasExceededMaxCommentLength: false, @@ -290,6 +303,7 @@ class ReportActionCompose extends React.Component { onSelectionChange(e) { this.setState({selection: e.nativeEvent.selection}); this.calculateEmojiSuggestion(); + this.calculateMentionSuggestion(); } /** @@ -401,8 +415,11 @@ class ReportActionCompose extends React.Component { // eslint-disable-next-line rulesdir/prefer-early-return setShouldShowSuggestionMenuToFalse() { - if (this.state && this.state.shouldShowSuggestionMenu) { - this.setState({shouldShowSuggestionMenu: false}); + if (this.state && this.state.shouldShowEmojiSuggestionMenu) { + this.setState({shouldShowEmojiSuggestionMenu: false}); + } + if (this.state && this.state.shouldShowMentionSuggestionMenu) { + this.setState({shouldShowMentionSuggestionMenu: false}); } } @@ -437,14 +454,17 @@ class ReportActionCompose extends React.Component { } /** - * Clean data related to EmojiSuggestions + * Clean data related to EmojiSuggestions and MentionSuggestions */ - resetSuggestedEmojis() { + resetSuggestions() { this.setState({ suggestedEmojis: [], + suggestedMentions: [], highlightedEmojiIndex: 0, colonIndex: -1, - shouldShowSuggestionMenu: false, + atSignIndex: -1, + shouldShowEmojiSuggestionMenu: false, + shouldShowMentionSuggestionMenu: false, isEmojiPickerLarge: true, }); } @@ -454,7 +474,7 @@ class ReportActionCompose extends React.Component { */ calculateEmojiSuggestion() { if (!this.state.value) { - this.resetSuggestedEmojis(); + this.resetSuggestions(); return; } if (this.state.shouldBlockEmojiCalc) { @@ -473,14 +493,14 @@ class ReportActionCompose extends React.Component { suggestedEmojis: [], highlightedEmojiIndex: 0, colonIndex, - shouldShowSuggestionMenu: false, + shouldShowEmojiSuggestionMenu: false, isEmojiPickerLarge, }; const newSuggestedEmojis = EmojiUtils.suggestEmojis(leftString); if (newSuggestedEmojis.length && isCurrentlyShowingEmojiSuggestion) { nextState.suggestedEmojis = newSuggestedEmojis; - nextState.shouldShowSuggestionMenu = !_.isEmpty(newSuggestedEmojis); + nextState.shouldShowEmojiSuggestionMenu = !_.isEmpty(newSuggestedEmojis); } LayoutAnimation.configureNext(LayoutAnimation.create(50, LayoutAnimation.Types.easeInEaseOut, LayoutAnimation.Properties.opacity)); @@ -488,6 +508,54 @@ class ReportActionCompose extends React.Component { this.setState(nextState); } + calculateMentionSuggestion() { + if (this.state.selection.end < 1) { + return; + } + + const valueAfterTheCursor = this.state.value.substring(this.state.selection.end); + const indexOfFirstWhitespaceCharAfterTheCursor = valueAfterTheCursor.search(CONST.REGEX.NEW_LINE_OR_WHITE_SPACE_OR_EMOJI); + + let indexOfLastNonWhitespaceCharAfterTheCursor; + if (indexOfFirstWhitespaceCharAfterTheCursor === -1) { + // we didn't find a whitespace/emoji after the cursor, so we will use the entire string + indexOfLastNonWhitespaceCharAfterTheCursor = this.state.value.length; + } else { + indexOfLastNonWhitespaceCharAfterTheCursor = indexOfFirstWhitespaceCharAfterTheCursor + this.state.selection.end; + } + + const leftString = this.state.value.substring(0, indexOfLastNonWhitespaceCharAfterTheCursor); + const words = leftString.split(CONST.REGEX.NEW_LINE_OR_WHITE_SPACE_OR_EMOJI); + const lastWord = _.last(words); + + let atSignIndex; + if (lastWord.startsWith('@')) { + atSignIndex = leftString.lastIndexOf(lastWord); + } + + const prefix = lastWord.substring(1); + + const nextState = { + suggestedMentions: [], + atSignIndex, + mentionPrefix: prefix, + }; + + if (this.isMentionCode(lastWord)) { + const options = OptionsListUtils.getNewChatOptions( + this.props.reports, + this.props.personalDetails, + this.props.betas, prefix, + ); + const suggestions = _.filter([...options.recentReports, options.userToInvite], x => !!x); + + nextState.suggestedMentions = suggestions; + nextState.shouldShowMentionSuggestionMenu = !_.isEmpty(suggestions); + } + + this.setState(nextState); + } + /** * Check if this piece of string looks like an emoji * @param {String} str @@ -501,6 +569,15 @@ class ReportActionCompose extends React.Component { return CONST.REGEX.HAS_COLON_ONLY_AT_THE_BEGINNING.test(leftWord) && leftWord.length > 2; } + /** + * Check if this piece of string looks like a mention + * @param {String} str + * @returns {Boolean} + */ + isMentionCode(str) { + return CONST.REGEX.HAS_AT_MOST_TWO_AT_SIGNS.test(str) && str.length > 2; + } + /** * Replace the code of emoji and update selection * @param {Number} highlightedEmojiIndex @@ -522,6 +599,22 @@ class ReportActionCompose extends React.Component { EmojiUtils.addToFrequentlyUsedEmojis(this.props.frequentlyUsedEmojis, emojiObject); } + insertSelectedMention(highlightedMentionIndex) { + const commentBeforeAtSign = this.state.value.slice(0, this.state.atSignIndex); + const mentionObject = this.state.suggestedMentions[highlightedMentionIndex]; + const mentionCode = `@${mentionObject.alternateText}`; // TODO: @expensify.sms + const commentAfterAtSignWithMentionRemoved = this.state.value.slice(this.state.atSignIndex).replace(CONST.REGEX.MENTION_REPLACER, ''); + + this.updateComment(`${commentBeforeAtSign}${mentionCode} ${commentAfterAtSignWithMentionRemoved}`, true); + this.setState(prevState => ({ + selection: { + start: prevState.atSignIndex + mentionCode.length + CONST.SPACE_LENGTH, + end: prevState.atSignIndex + mentionCode.length + CONST.SPACE_LENGTH, + }, + suggestedMentions: [], + })); + } + isEmptyChat() { return _.size(this.props.reportActions) === 1; } @@ -646,14 +739,22 @@ class ReportActionCompose extends React.Component { return; } - if ((e.key === CONST.KEYBOARD_SHORTCUTS.ENTER.shortcutKey || e.key === CONST.KEYBOARD_SHORTCUTS.TAB.shortcutKey) && this.state.suggestedEmojis.length) { + const suggestionsExist = this.state.suggestedEmojis.length > 0 + || this.state.suggestedMentions.length > 0; + + if ((e.key === CONST.KEYBOARD_SHORTCUTS.ENTER.shortcutKey || e.key === CONST.KEYBOARD_SHORTCUTS.TAB.shortcutKey) && suggestionsExist) { e.preventDefault(); - this.insertSelectedEmoji(this.state.highlightedEmojiIndex); + if (this.state.suggestedEmojis.length > 0) { + this.insertSelectedEmoji(this.state.highlightedEmojiIndex); + } + if (this.state.suggestedMentions.length > 0) { + this.insertSelectedMention(this.state.highlightedMentionIndex); + } return; } - if (e.key === CONST.KEYBOARD_SHORTCUTS.ESCAPE.shortcutKey && this.state.suggestedEmojis.length) { + if (e.key === CONST.KEYBOARD_SHORTCUTS.ESCAPE.shortcutKey && suggestionsExist) { e.preventDefault(); - this.resetSuggestedEmojis(); + this.resetSuggestions(); return; } @@ -914,7 +1015,7 @@ class ReportActionCompose extends React.Component { onFocus={() => this.setIsFocused(true)} onBlur={() => { this.setIsFocused(false); - this.resetSuggestedEmojis(); + this.resetSuggestions(); }} onClick={this.setShouldBlockEmojiCalcToFalse} onPasteFile={displayFileInModal} @@ -986,7 +1087,7 @@ class ReportActionCompose extends React.Component { {this.state.isDraggingOver && } - {!_.isEmpty(this.state.suggestedEmojis) && this.state.shouldShowSuggestionMenu && ( + {!_.isEmpty(this.state.suggestedEmojis) && this.state.shouldShowEmojiSuggestionMenu && ( )} + {!_.isEmpty(this.state.suggestedMentions) && this.state.shouldShowMentionSuggestionMenu && ( + this.setState({highlightedMentionIndex: index})} + > + this.setState({suggestedMentions: []})} + highlightedMentionIndex={this.state.highlightedMentionIndex} + mentions={this.state.suggestedMentions} + comment={this.state.value} + updateComment={newComment => this.setState({value: newComment})} + colonIndex={this.state.colonIndex} + prefix={this.state.mentionPrefix} + onSelect={this.insertSelectedMention} + isComposerFullSize={this.props.isComposerFullSize} + isMentionPickerLarge={this.state.isEmojiPickerLarge} + composerHeight={this.state.composerHeight} + shouldIncludeReportRecipientLocalTimeHeight={shouldShowReportRecipientLocalTime} + /> + + )} ); } @@ -1050,5 +1174,11 @@ export default compose( preferredSkinTone: { key: ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE, }, + reports: { + key: ONYXKEYS.COLLECTION.REPORT, + }, + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS, + }, }), )(ReportActionCompose); diff --git a/src/styles/styles.js b/src/styles/styles.js index 6497238882b8..ae0784a7ba54 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -197,6 +197,10 @@ const styles = { fontSize: variables.fontSizeMedium, }, + mentionSuggestionsText: { + fontSize: variables.fontSizeMedium, + }, + unitCol: { margin: 0, padding: 0, From 32e775de5f57b0f64a0fe9dcbdd1eab440e3d7d6 Mon Sep 17 00:00:00 2001 From: Konrad Bochnia Date: Mon, 8 May 2023 11:43:52 +0200 Subject: [PATCH 02/14] Remove TODO comment --- src/pages/home/report/ReportActionCompose.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 89bc6e1056e0..aacd6be4c824 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -547,7 +547,7 @@ class ReportActionCompose extends React.Component { this.props.personalDetails, this.props.betas, prefix, ); - const suggestions = _.filter([...options.recentReports, options.userToInvite], x => !!x); + const suggestions = _.filter([...options.recentReports, options.userToInvite], (x) => !!x); nextState.suggestedMentions = suggestions; nextState.shouldShowMentionSuggestionMenu = !_.isEmpty(suggestions); @@ -602,7 +602,7 @@ class ReportActionCompose extends React.Component { insertSelectedMention(highlightedMentionIndex) { const commentBeforeAtSign = this.state.value.slice(0, this.state.atSignIndex); const mentionObject = this.state.suggestedMentions[highlightedMentionIndex]; - const mentionCode = `@${mentionObject.alternateText}`; // TODO: @expensify.sms + const mentionCode = `@${mentionObject.alternateText}`; const commentAfterAtSignWithMentionRemoved = this.state.value.slice(this.state.atSignIndex).replace(CONST.REGEX.MENTION_REPLACER, ''); this.updateComment(`${commentBeforeAtSign}${mentionCode} ${commentAfterAtSignWithMentionRemoved}`, true); From c8bf61e6e5677ae56e165d1c9dfcf3b145269a2a Mon Sep 17 00:00:00 2001 From: Konrad Bochnia Date: Mon, 8 May 2023 14:38:29 +0200 Subject: [PATCH 03/14] Fix lint --- src/pages/home/report/ReportActionCompose.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index aacd6be4c824..a4040aba239b 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -547,7 +547,7 @@ class ReportActionCompose extends React.Component { this.props.personalDetails, this.props.betas, prefix, ); - const suggestions = _.filter([...options.recentReports, options.userToInvite], (x) => !!x); + const suggestions = _.filter([...options.recentReports, options.userToInvite], x => !!x); nextState.suggestedMentions = suggestions; nextState.shouldShowMentionSuggestionMenu = !_.isEmpty(suggestions); From 3bb620806d14f68c6a932d5e7a7a82254a135170 Mon Sep 17 00:00:00 2001 From: Konrad Bochnia Date: Tue, 9 May 2023 11:51:22 +0200 Subject: [PATCH 04/14] Fix overflowing text --- ios/Podfile.lock | 4 ++-- src/components/MentionSuggestions.js | 6 +++--- src/libs/GetStyledTextArray.js | 2 +- src/styles/styles.js | 2 ++ 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e81f2d2c640c..08ae362a7b6a 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1014,7 +1014,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Airship: c70eed50e429f97f5adb285423c7291fb7a032ae AirshipFrameworkProxy: 2eefb77bb77b5120b0f48814b0d44439aa3ad415 - boost: a7c83b31436843459a1961bfd74b96033dc77234 + boost: 57d2868c099736d80fcd648bf211b4431e51a558 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 FBLazyVector: ff54429f0110d3c722630a98096ba689c39f6d5f @@ -1057,7 +1057,7 @@ SPEC CHECKSUMS: Permission-LocationWhenInUse: 3ba99e45c852763f730eabecec2870c2382b7bd4 Plaid: 7d340abeadb46c7aa1a91f896c5b22395a31fcf2 PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef - RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda + RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 RCTRequired: e9e7b8b45aa9bedb2fdad71740adf07a7265b9be RCTTypeSafety: 9ae0e9206625e995f0df4d5b9ddc94411929fb30 React: a71c8e1380f07e01de721ccd52bcf9c03e81867d diff --git a/src/components/MentionSuggestions.js b/src/components/MentionSuggestions.js index 6f921c23cfbf..d8a2404b42f3 100644 --- a/src/components/MentionSuggestions.js +++ b/src/components/MentionSuggestions.js @@ -10,6 +10,7 @@ import Avatar from './Avatar'; import AutoCompleteSuggestions from './AutoCompleteSuggestions'; import getStyledTextArray from '../libs/GetStyledTextArray'; import avatarPropTypes from './avatarPropTypes'; +import spacing from '../styles/utilities/spacing'; const propTypes = { /** The index of the highlighted mention */ @@ -65,15 +66,14 @@ const MentionSuggestions = (props) => { const styledTextArray = getStyledTextArray(displayedText, props.prefix); return ( - + - + {_.map(styledTextArray, ({text, isColored}, i) => ( {text} diff --git a/src/libs/GetStyledTextArray.js b/src/libs/GetStyledTextArray.js index 795c8dfc41d2..a62e12b6c4bd 100644 --- a/src/libs/GetStyledTextArray.js +++ b/src/libs/GetStyledTextArray.js @@ -9,7 +9,7 @@ import Str from 'expensify-common/lib/str'; const getStyledTextArray = (name, prefix) => { const texts = []; const prefixLowercase = prefix.toLowerCase(); - const prefixLocation = name.search(Str.escapeForRegExp(prefixLowercase)); + const prefixLocation = name.toLowerCase().search(Str.escapeForRegExp(prefixLowercase)); if (prefixLocation === 0 && prefix.length === name.length) { texts.push({text: prefixLowercase, isColored: true}); diff --git a/src/styles/styles.js b/src/styles/styles.js index ae0784a7ba54..c4fd70cc8553 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -199,6 +199,8 @@ const styles = { mentionSuggestionsText: { fontSize: variables.fontSizeMedium, + flex: 1, + ...spacing.ml2, }, unitCol: { From a7b37bbc02f9f067ee51f20246dfd8955503dc4c Mon Sep 17 00:00:00 2001 From: Konrad Bochnia Date: Tue, 9 May 2023 14:34:00 +0200 Subject: [PATCH 05/14] Implement feedback --- ios/Podfile.lock | 4 ++-- src/CONST.js | 2 +- src/components/MentionSuggestions.js | 3 +-- src/pages/home/report/ReportActionCompose.js | 7 +++++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 08ae362a7b6a..e81f2d2c640c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1014,7 +1014,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Airship: c70eed50e429f97f5adb285423c7291fb7a032ae AirshipFrameworkProxy: 2eefb77bb77b5120b0f48814b0d44439aa3ad415 - boost: 57d2868c099736d80fcd648bf211b4431e51a558 + boost: a7c83b31436843459a1961bfd74b96033dc77234 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 FBLazyVector: ff54429f0110d3c722630a98096ba689c39f6d5f @@ -1057,7 +1057,7 @@ SPEC CHECKSUMS: Permission-LocationWhenInUse: 3ba99e45c852763f730eabecec2870c2382b7bd4 Plaid: 7d340abeadb46c7aa1a91f896c5b22395a31fcf2 PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef - RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 + RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda RCTRequired: e9e7b8b45aa9bedb2fdad71740adf07a7265b9be RCTTypeSafety: 9ae0e9206625e995f0df4d5b9ddc94411929fb30 React: a71c8e1380f07e01de721ccd52bcf9c03e81867d diff --git a/src/CONST.js b/src/CONST.js index 85b94f96b151..511320c7614d 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -1010,7 +1010,7 @@ const CONST = { CODE_2FA: /^\d{6}$/, ATTACHMENT_ID: /chat-attachments\/(\d+)/, HAS_COLON_ONLY_AT_THE_BEGINNING: /^:[^:]+$/, - HAS_AT_MOST_TWO_AT_SIGNS: /^@[^@]+@?[^@]+$/, + HAS_AT_MOST_TWO_AT_SIGNS: /^@[^@]*@?[^@]*$/, // eslint-disable-next-line no-misleading-character-class NEW_LINE_OR_WHITE_SPACE_OR_EMOJI: /[\n\s\p{Extended_Pictographic}\u200d\u{1f1e6}-\u{1f1ff}\u{1f3fb}-\u{1f3ff}\u{e0020}-\u{e007f}\u20E3\uFE0F]|[#*0-9]\uFE0F?\u20E3/gu, diff --git a/src/components/MentionSuggestions.js b/src/components/MentionSuggestions.js index d8a2404b42f3..e62201a31000 100644 --- a/src/components/MentionSuggestions.js +++ b/src/components/MentionSuggestions.js @@ -10,7 +10,6 @@ import Avatar from './Avatar'; import AutoCompleteSuggestions from './AutoCompleteSuggestions'; import getStyledTextArray from '../libs/GetStyledTextArray'; import avatarPropTypes from './avatarPropTypes'; -import spacing from '../styles/utilities/spacing'; const propTypes = { /** The index of the highlighted mention */ @@ -66,7 +65,7 @@ const MentionSuggestions = (props) => { const styledTextArray = getStyledTextArray(displayedText, props.prefix); return ( - + { - if (!this.state.isFocused || this.comment.length === 0) { + const suggestionsExist = this.state.suggestedEmojis.length > 0 + || this.state.suggestedMentions.length > 0; + + if (!this.state.isFocused || this.comment.length === 0 || suggestionsExist) { return; } @@ -576,7 +579,7 @@ class ReportActionCompose extends React.Component { * @returns {Boolean} */ isMentionCode(str) { - return CONST.REGEX.HAS_AT_MOST_TWO_AT_SIGNS.test(str) && str.length > 2; + return CONST.REGEX.HAS_AT_MOST_TWO_AT_SIGNS.test(str); } /** From ddaf323fbf569d7e9b9a5f8b7276e18e19e6fae6 Mon Sep 17 00:00:00 2001 From: Konrad Bochnia Date: Tue, 9 May 2023 14:41:31 +0200 Subject: [PATCH 06/14] Fix insertion of the mention --- src/CONST.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CONST.js b/src/CONST.js index 511320c7614d..aee7c5cb0bc2 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -1019,7 +1019,7 @@ const CONST = { EMOJI_REPLACER: /^:[^\n\r]+?(?=$|\s)/, // Define the regular expression pattern to match a string starting with an at sign and ending with a space or newline character - MENTION_REPLACER: /^@[^\n\r]+?(?=$|\s)/, + MENTION_REPLACER: /^@[^\n\r]*?(?=$|\s)/, MERGED_ACCOUNT_PREFIX: /^(MERGED_\d+@)/, }, From 6fdf6e73aae6cdba41957fa77b2b61ddba7a1094 Mon Sep 17 00:00:00 2001 From: Konrad Bochnia Date: Tue, 9 May 2023 19:01:43 +0200 Subject: [PATCH 07/14] Don't show suggestions when the cursor is before the @ sign --- src/pages/home/report/ReportActionCompose.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 3b3e528e9fe6..33c39ef129f9 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -545,7 +545,9 @@ class ReportActionCompose extends React.Component { mentionPrefix: prefix, }; - if (this.isMentionCode(lastWord)) { + const isCursorBeforeTheMention = valueAfterTheCursor.startsWith(lastWord); + + if (!isCursorBeforeTheMention && this.isMentionCode(lastWord)) { const options = OptionsListUtils.getNewChatOptions( this.props.reports, this.props.personalDetails, From a0a0a009a116336a105c3a43fc3f0d376423ea8f Mon Sep 17 00:00:00 2001 From: Konrad Bochnia Date: Wed, 10 May 2023 11:01:33 +0200 Subject: [PATCH 08/14] Run prettier --- src/components/MentionSuggestions.js | 30 +++++++++++++------- src/pages/home/report/ReportActionCompose.js | 22 ++++++-------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/components/MentionSuggestions.js b/src/components/MentionSuggestions.js index e62201a31000..d1a6441e1d33 100644 --- a/src/components/MentionSuggestions.js +++ b/src/components/MentionSuggestions.js @@ -16,16 +16,18 @@ const propTypes = { highlightedMentionIndex: PropTypes.number, /** Array of suggested mentions */ - mentions: PropTypes.arrayOf(PropTypes.shape({ - /** Display name of the user */ - text: PropTypes.string, + mentions: PropTypes.arrayOf( + PropTypes.shape({ + /** Display name of the user */ + text: PropTypes.string, - /** Email/phone number of the user */ - alternateText: PropTypes.string, + /** Email/phone number of the user */ + alternateText: PropTypes.string, - /** Array of icons of the user. We use the first element of this array */ - icons: PropTypes.arrayOf(avatarPropTypes), - })).isRequired, + /** Array of icons of the user. We use the first element of this array */ + icons: PropTypes.arrayOf(avatarPropTypes), + }), + ).isRequired, /** Fired when the user selects an mention */ onSelect: PropTypes.func.isRequired, @@ -52,7 +54,7 @@ const defaultProps = { * @param {Number} index * @returns {String} */ -const keyExtractor = item => item.alternateText; +const keyExtractor = (item) => item.alternateText; const MentionSuggestions = (props) => { /** @@ -72,9 +74,15 @@ const MentionSuggestions = (props) => { name={item.icons[0].name} type={item.icons[0].type} /> - + {_.map(styledTextArray, ({text, isColored}, i) => ( - + {text} ))} diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 3b487c57380e..ed3b7c93f48c 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -242,9 +242,8 @@ class ReportActionCompose extends React.Component { this.unsubscribeEscapeKey = KeyboardShortcut.subscribe( shortcutConfig.shortcutKey, () => { - const suggestionsExist = this.state.suggestedEmojis.length > 0 - || this.state.suggestedMentions.length > 0; - + const suggestionsExist = this.state.suggestedEmojis.length > 0 || this.state.suggestedMentions.length > 0; + if (!this.state.isFocused || this.comment.length === 0 || suggestionsExist) { return; } @@ -551,12 +550,8 @@ class ReportActionCompose extends React.Component { const isCursorBeforeTheMention = valueAfterTheCursor.startsWith(lastWord); if (!isCursorBeforeTheMention && this.isMentionCode(lastWord)) { - const options = OptionsListUtils.getNewChatOptions( - this.props.reports, - this.props.personalDetails, - this.props.betas, prefix, - ); - const suggestions = _.filter([...options.recentReports, options.userToInvite], x => !!x); + const options = OptionsListUtils.getNewChatOptions(this.props.reports, this.props.personalDetails, this.props.betas, prefix); + const suggestions = _.filter([...options.recentReports, options.userToInvite], (x) => !!x); nextState.suggestedMentions = suggestions; nextState.shouldShowMentionSuggestionMenu = !_.isEmpty(suggestions); @@ -615,7 +610,7 @@ class ReportActionCompose extends React.Component { const commentAfterAtSignWithMentionRemoved = this.state.value.slice(this.state.atSignIndex).replace(CONST.REGEX.MENTION_REPLACER, ''); this.updateComment(`${commentBeforeAtSign}${mentionCode} ${commentAfterAtSignWithMentionRemoved}`, true); - this.setState(prevState => ({ + this.setState((prevState) => ({ selection: { start: prevState.atSignIndex + mentionCode.length + CONST.SPACE_LENGTH, end: prevState.atSignIndex + mentionCode.length + CONST.SPACE_LENGTH, @@ -748,8 +743,7 @@ class ReportActionCompose extends React.Component { return; } - const suggestionsExist = this.state.suggestedEmojis.length > 0 - || this.state.suggestedMentions.length > 0; + const suggestionsExist = this.state.suggestedEmojis.length > 0 || this.state.suggestedMentions.length > 0; if ((e.key === CONST.KEYBOARD_SHORTCUTS.ENTER.shortcutKey || e.key === CONST.KEYBOARD_SHORTCUTS.TAB.shortcutKey) && suggestionsExist) { e.preventDefault(); @@ -1145,14 +1139,14 @@ class ReportActionCompose extends React.Component { focusedIndex={this.state.highlightedMentionIndex} maxIndex={getMaxArrowIndex(this.state.suggestedMentions.length, this.state.isEmojiPickerLarge)} shouldExcludeTextAreaNodes={false} - onFocusedIndexChanged={index => this.setState({highlightedMentionIndex: index})} + onFocusedIndexChanged={(index) => this.setState({highlightedMentionIndex: index})} > this.setState({suggestedMentions: []})} highlightedMentionIndex={this.state.highlightedMentionIndex} mentions={this.state.suggestedMentions} comment={this.state.value} - updateComment={newComment => this.setState({value: newComment})} + updateComment={(newComment) => this.setState({value: newComment})} colonIndex={this.state.colonIndex} prefix={this.state.mentionPrefix} onSelect={this.insertSelectedMention} From d6bd21fbfbb34dbbe925e1f981cc61c9b3484a37 Mon Sep 17 00:00:00 2001 From: Konrad Bochnia Date: Wed, 10 May 2023 11:16:17 +0200 Subject: [PATCH 09/14] Implement feedback --- src/pages/home/report/ReportActionCompose.js | 29 ++++++++++++-------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index ed3b7c93f48c..aefbd843146e 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -121,6 +121,7 @@ const propTypes = { /** The type of action that's pending */ pendingAction: PropTypes.oneOf(['add', 'update', 'delete']), + /** Collection of recent reports, used to calculate the mention suggestions */ reports: PropTypes.objectOf(reportPropTypes), ...windowDimensionsPropTypes, @@ -149,12 +150,14 @@ const defaultProps = { /** * Return the max available index for arrow manager. * @param {Number} numRows - * @param {Boolean} isEmojiPickerLarge + * @param {Boolean} isAutoSuggestionPickerLarge * @returns {Number} */ -const getMaxArrowIndex = (numRows, isEmojiPickerLarge) => { +const getMaxArrowIndex = (numRows, isAutoSuggestionPickerLarge) => { // EmojiRowCount is number of emoji suggestions. For small screen we can fit 3 items and for large we show up to 5 items - const emojiRowCount = isEmojiPickerLarge ? Math.max(numRows, CONST.AUTO_COMPLETE_SUGGESTER.MAX_AMOUNT_OF_ITEMS) : Math.max(numRows, CONST.AUTO_COMPLETE_SUGGESTER.MIN_AMOUNT_OF_ITEMS); + const emojiRowCount = isAutoSuggestionPickerLarge + ? Math.max(numRows, CONST.AUTO_COMPLETE_SUGGESTER.MAX_AMOUNT_OF_ITEMS) + : Math.max(numRows, CONST.AUTO_COMPLETE_SUGGESTER.MIN_AMOUNT_OF_ITEMS); // -1 because we start at 0 return emojiRowCount - 1; @@ -220,7 +223,7 @@ class ReportActionCompose extends React.Component { highlightedMentionIndex: 0, mentionPrefix: '', atSignIndex: -1, - isEmojiPickerLarge: false, + isAutoSuggestionPickerLarge: false, composerHeight: 0, hasExceededMaxCommentLength: false, isAttachmentPreviewActive: false, @@ -471,7 +474,7 @@ class ReportActionCompose extends React.Component { atSignIndex: -1, shouldShowEmojiSuggestionMenu: false, shouldShowMentionSuggestionMenu: false, - isEmojiPickerLarge: true, + isAutoSuggestionPickerLarge: true, }); } @@ -493,14 +496,14 @@ class ReportActionCompose extends React.Component { // the larger composerHeight the less space for EmojiPicker, Pixel 2 has pretty small screen and this value equal 5.3 const hasEnoughSpaceForLargeSuggestion = this.props.windowHeight / this.state.composerHeight >= 6.8; - const isEmojiPickerLarge = !this.props.isSmallScreenWidth || (this.props.isSmallScreenWidth && hasEnoughSpaceForLargeSuggestion); + const isAutoSuggestionPickerLarge = !this.props.isSmallScreenWidth || (this.props.isSmallScreenWidth && hasEnoughSpaceForLargeSuggestion); const nextState = { suggestedEmojis: [], highlightedEmojiIndex: 0, colonIndex, shouldShowEmojiSuggestionMenu: false, - isEmojiPickerLarge, + isAutoSuggestionPickerLarge, }; const newSuggestedEmojis = EmojiUtils.suggestEmojis(leftString); @@ -603,6 +606,10 @@ class ReportActionCompose extends React.Component { EmojiUtils.addToFrequentlyUsedEmojis(this.props.frequentlyUsedEmojis, emojiObject); } + /** + * Replace the code of mention and update selection + * @param {Number} highlightedEmojiIndex + */ insertSelectedMention(highlightedMentionIndex) { const commentBeforeAtSign = this.state.value.slice(0, this.state.atSignIndex); const mentionObject = this.state.suggestedMentions[highlightedMentionIndex]; @@ -1113,7 +1120,7 @@ class ReportActionCompose extends React.Component { {!_.isEmpty(this.state.suggestedEmojis) && this.state.shouldShowEmojiSuggestionMenu && ( this.setState({highlightedEmojiIndex: index})} > @@ -1128,7 +1135,7 @@ class ReportActionCompose extends React.Component { onSelect={this.insertSelectedEmoji} isComposerFullSize={this.props.isComposerFullSize} preferredSkinToneIndex={this.props.preferredSkinTone} - isEmojiPickerLarge={this.state.isEmojiPickerLarge} + isEmojiPickerLarge={this.state.isAutoSuggestionPickerLarge} composerHeight={this.state.composerHeight} shouldIncludeReportRecipientLocalTimeHeight={shouldShowReportRecipientLocalTime} /> @@ -1137,7 +1144,7 @@ class ReportActionCompose extends React.Component { {!_.isEmpty(this.state.suggestedMentions) && this.state.shouldShowMentionSuggestionMenu && ( this.setState({highlightedMentionIndex: index})} > @@ -1151,7 +1158,7 @@ class ReportActionCompose extends React.Component { prefix={this.state.mentionPrefix} onSelect={this.insertSelectedMention} isComposerFullSize={this.props.isComposerFullSize} - isMentionPickerLarge={this.state.isEmojiPickerLarge} + isMentionPickerLarge={this.state.isAutoSuggestionPickerLarge} composerHeight={this.state.composerHeight} shouldIncludeReportRecipientLocalTimeHeight={shouldShowReportRecipientLocalTime} /> From 74889f3e9885b7eebde9105e15dc8dd14f46e9af Mon Sep 17 00:00:00 2001 From: Konrad Bochnia Date: Wed, 10 May 2023 11:31:38 +0200 Subject: [PATCH 10/14] Fix JSDoc --- src/pages/home/report/ReportActionCompose.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index aefbd843146e..3b4961f5a4cb 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -608,7 +608,7 @@ class ReportActionCompose extends React.Component { /** * Replace the code of mention and update selection - * @param {Number} highlightedEmojiIndex + * @param {Number} highlightedMentionIndex */ insertSelectedMention(highlightedMentionIndex) { const commentBeforeAtSign = this.state.value.slice(0, this.state.atSignIndex); From 3f1ef8afca8084c552542031904cc444f2519d07 Mon Sep 17 00:00:00 2001 From: Konrad Bochnia Date: Wed, 10 May 2023 16:28:38 +0200 Subject: [PATCH 11/14] Change default value of `shouldShow{Emoji,Mention}SuggestionMenu` back to false --- src/pages/home/report/ReportActionCompose.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 3b4961f5a4cb..3b03cad83c8a 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -217,8 +217,8 @@ class ReportActionCompose extends React.Component { suggestedEmojis: [], highlightedEmojiIndex: 0, colonIndex: -1, - shouldShowEmojiSuggestionMenu: true, - shouldShowMentionSuggestionMenu: true, + shouldShowEmojiSuggestionMenu: false, + shouldShowMentionSuggestionMenu: false, suggestedMentions: [], highlightedMentionIndex: 0, mentionPrefix: '', From ecc88e20f8b076dabdbc958da718dd21ceec7788 Mon Sep 17 00:00:00 2001 From: Konrad Bochnia Date: Wed, 10 May 2023 16:37:18 +0200 Subject: [PATCH 12/14] Rename variable --- src/pages/home/report/ReportActionCompose.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 3b03cad83c8a..17c07bccdad9 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -523,14 +523,14 @@ class ReportActionCompose extends React.Component { } const valueAfterTheCursor = this.state.value.substring(this.state.selection.end); - const indexOfFirstWhitespaceCharAfterTheCursor = valueAfterTheCursor.search(CONST.REGEX.NEW_LINE_OR_WHITE_SPACE_OR_EMOJI); + const indexOfFirstWhitespaceCharOrEmojiAfterTheCursor = valueAfterTheCursor.search(CONST.REGEX.NEW_LINE_OR_WHITE_SPACE_OR_EMOJI); let indexOfLastNonWhitespaceCharAfterTheCursor; - if (indexOfFirstWhitespaceCharAfterTheCursor === -1) { + if (indexOfFirstWhitespaceCharOrEmojiAfterTheCursor === -1) { // we didn't find a whitespace/emoji after the cursor, so we will use the entire string indexOfLastNonWhitespaceCharAfterTheCursor = this.state.value.length; } else { - indexOfLastNonWhitespaceCharAfterTheCursor = indexOfFirstWhitespaceCharAfterTheCursor + this.state.selection.end; + indexOfLastNonWhitespaceCharAfterTheCursor = indexOfFirstWhitespaceCharOrEmojiAfterTheCursor + this.state.selection.end; } const leftString = this.state.value.substring(0, indexOfLastNonWhitespaceCharAfterTheCursor); From 3bb69d153a85b799865d6b8b4252e889802fca60 Mon Sep 17 00:00:00 2001 From: Puneet Lath Date: Wed, 10 May 2023 12:38:50 -0400 Subject: [PATCH 13/14] Add getDefaultSuggestionsValues --- src/pages/home/report/ReportActionCompose.js | 35 ++++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 17c07bccdad9..4dae7e05c861 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -214,19 +214,10 @@ class ReportActionCompose extends React.Component { // If we are on a small width device then don't show last 3 items from conciergePlaceholderOptions conciergePlaceholderRandomIndex: _.random(this.props.translate('reportActionCompose.conciergePlaceholderOptions').length - (this.props.isSmallScreenWidth ? 4 : 1)), - suggestedEmojis: [], - highlightedEmojiIndex: 0, - colonIndex: -1, - shouldShowEmojiSuggestionMenu: false, - shouldShowMentionSuggestionMenu: false, - suggestedMentions: [], - highlightedMentionIndex: 0, - mentionPrefix: '', - atSignIndex: -1, - isAutoSuggestionPickerLarge: false, composerHeight: 0, hasExceededMaxCommentLength: false, isAttachmentPreviewActive: false, + ...this.getDefaultSuggestionsValues(), }; } @@ -315,6 +306,21 @@ class ReportActionCompose extends React.Component { this.calculateMentionSuggestion(); } + getDefaultSuggestionsValues() { + return { + suggestedEmojis: [], + suggestedMentions: [], + highlightedEmojiIndex: 0, + highlightedMentionIndex: 0, + colonIndex: -1, + atSignIndex: -1, + shouldShowEmojiSuggestionMenu: false, + shouldShowMentionSuggestionMenu: false, + mentionPrefix: '', + isAutoSuggestionPickerLarge: false, + } + } + /** * Updates the Highlight state of the composer * @@ -467,14 +473,7 @@ class ReportActionCompose extends React.Component { */ resetSuggestions() { this.setState({ - suggestedEmojis: [], - suggestedMentions: [], - highlightedEmojiIndex: 0, - colonIndex: -1, - atSignIndex: -1, - shouldShowEmojiSuggestionMenu: false, - shouldShowMentionSuggestionMenu: false, - isAutoSuggestionPickerLarge: true, + ...this.getDefaultSuggestionsValues(), }); } From 4d18ef64f9dd157dc40620cff8841d7b5052d5b5 Mon Sep 17 00:00:00 2001 From: Puneet Lath Date: Wed, 10 May 2023 18:52:33 +0200 Subject: [PATCH 14/14] Update src/pages/home/report/ReportActionCompose.js Co-authored-by: Miroslav Stevanovic <97473779+0xmiroslav@users.noreply.github.com> --- src/pages/home/report/ReportActionCompose.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 4dae7e05c861..d257e9a3de53 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -318,7 +318,7 @@ class ReportActionCompose extends React.Component { shouldShowMentionSuggestionMenu: false, mentionPrefix: '', isAutoSuggestionPickerLarge: false, - } + }; } /**