From 770dcf4ceed8203dfccaa1ddb40ae28407320a6f Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Wed, 17 May 2023 00:47:16 +0500 Subject: [PATCH 01/12] feat: add here and yourself mentions --- src/libs/OptionsListUtils.js | 62 ++++++++++++++++++++ src/pages/home/report/ReportActionCompose.js | 6 +- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/libs/OptionsListUtils.js b/src/libs/OptionsListUtils.js index e1ab2145189..2126b7d4ca4 100644 --- a/src/libs/OptionsListUtils.js +++ b/src/libs/OptionsListUtils.js @@ -549,6 +549,7 @@ function getOptions( forcePolicyNamePreview = false, includeOwnedWorkspaceChats = false, includeThreads = false, + includeMoneyRequestReports = true, }, ) { if (!isPersonalDetailsReady(personalDetails)) { @@ -589,6 +590,7 @@ function getOptions( } const isThread = ReportUtils.isThread(report); + const isMoneyRequestReport = ReportUtils.isMoneyRequestReport(report); const isChatRoom = ReportUtils.isChatRoom(report); const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report); const logins = report.participants || []; @@ -601,6 +603,10 @@ function getOptions( return; } + if (isMoneyRequestReport && !includeMoneyRequestReports) { + return; + } + // Save the report in the map if this is a single participant so we can associate the reportID with the // personal detail option later. Individuals should not be associated with single participant // policyExpenseChats or chatRooms since those are not people. @@ -839,6 +845,61 @@ function getNewChatOptions(reports, personalDetails, betas = [], searchValue = ' }); } +/** + * Build the suggestions for mentions + * @param {Object} reports + * @param {Object} personalDetails + * @param {Array} [betas] + * @param {String} [searchValue] + * @returns {Object} + */ +function getMentionOptions(reports, personalDetails, betas = [], searchValue = '') { + const currentUser = _.find(personalDetails, isCurrentUser); + const suggestions = []; + if (searchValue && `${currentUser.displayName} ${currentUser.login}`.includes(searchValue)) { + suggestions.push({ + text: currentUser.displayName, + alternateText: currentUser.login, + icons: [ + { + name: currentUser.login, + type: 'avatar', + source: currentUser.avatar, + }, + ], + }); + } + + if ('here'.includes(searchValue)) { + suggestions.push({ + text: '@here', + alternateText: 'Notify everyone online in this room', + icons: [ + { + name: '', + source: () => {}, + type: 'avatar', + }, + ], + }); + } + const {recentReports, userToInvite} = getOptions(reports, personalDetails, { + betas, + searchInputValue: searchValue.trim(), + selectedOptions: [], + includeRecentReports: true, + includePersonalDetails: true, + maxRecentReportsToShow: 5 - suggestions.length, + excludeLogins: [{login: currentUser.login}], + includeOwnedWorkspaceChats: false, + includeMoneyRequestReports: false, + }); + + suggestions.push(...recentReports); + suggestions.push(userToInvite); + return _.filter(suggestions, (x) => !!x); +} + /** * Build the options for the Share Destination for a Task * * @@ -933,6 +994,7 @@ export { isPersonalDetailsReady, getSearchOptions, getNewChatOptions, + getMentionOptions, getShareDestinationOptions, getMemberInviteOptions, getHeaderMessage, diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index d329ae455a1..1dfed1ac880 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -550,9 +550,7 @@ 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 suggestions = OptionsListUtils.getMentionOptions(this.props.reports, this.props.personalDetails, this.props.betas, prefix); nextState.suggestedMentions = suggestions; nextState.shouldShowMentionSuggestionMenu = !_.isEmpty(suggestions); } @@ -610,7 +608,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}`; + const mentionCode = `@${mentionObject.text === '@here' ? 'here' : mentionObject.alternateText}`; const commentAfterAtSignWithMentionRemoved = this.state.value.slice(this.state.atSignIndex).replace(CONST.REGEX.MENTION_REPLACER, ''); this.updateComment(`${commentBeforeAtSign}${mentionCode} ${commentAfterAtSignWithMentionRemoved}`, true); From 77b4d2f28455f941520de1122d2fa3a08fe8b92c Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Wed, 17 May 2023 16:51:35 +0500 Subject: [PATCH 02/12] feat: update get mentions function --- src/libs/OptionsListUtils.js | 48 ++++++++------------ src/pages/home/report/ReportActionCompose.js | 9 +--- 2 files changed, 19 insertions(+), 38 deletions(-) diff --git a/src/libs/OptionsListUtils.js b/src/libs/OptionsListUtils.js index 2126b7d4ca4..9edef1c910e 100644 --- a/src/libs/OptionsListUtils.js +++ b/src/libs/OptionsListUtils.js @@ -847,57 +847,45 @@ function getNewChatOptions(reports, personalDetails, betas = [], searchValue = ' /** * Build the suggestions for mentions - * @param {Object} reports * @param {Object} personalDetails - * @param {Array} [betas] * @param {String} [searchValue] + * @param {Number} [maxRecords] * @returns {Object} */ -function getMentionOptions(reports, personalDetails, betas = [], searchValue = '') { - const currentUser = _.find(personalDetails, isCurrentUser); +function getMentionOptions(personalDetails, searchValue = '', maxRecords = 5) { const suggestions = []; - if (searchValue && `${currentUser.displayName} ${currentUser.login}`.includes(searchValue)) { + + if ('here'.includes(searchValue)) { suggestions.push({ - text: currentUser.displayName, - alternateText: currentUser.login, + text: '@here', + alternateText: 'Notify everyone online in this room', icons: [ { - name: currentUser.login, + name: '', + source: () => {}, type: 'avatar', - source: currentUser.avatar, }, ], }); } + _.each(_.values(personalDetails), (detail) => { + if (searchValue && !`${detail.displayName} ${detail.login}`.includes(searchValue)) { + return; + }; - if ('here'.includes(searchValue)) { suggestions.push({ - text: '@here', - alternateText: 'Notify everyone online in this room', + text: detail.displayName, + alternateText: detail.login, icons: [ { - name: '', - source: () => {}, + name: detail.login, + source: detail.avatar, type: 'avatar', }, - ], + ] }); - } - const {recentReports, userToInvite} = getOptions(reports, personalDetails, { - betas, - searchInputValue: searchValue.trim(), - selectedOptions: [], - includeRecentReports: true, - includePersonalDetails: true, - maxRecentReportsToShow: 5 - suggestions.length, - excludeLogins: [{login: currentUser.login}], - includeOwnedWorkspaceChats: false, - includeMoneyRequestReports: false, }); - - suggestions.push(...recentReports); - suggestions.push(userToInvite); - return _.filter(suggestions, (x) => !!x); + return suggestions.slice(0, maxRecords); } /** diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 1dfed1ac880..c9ae294cdd6 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -117,9 +117,6 @@ 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, ...withLocalizePropTypes, ...withCurrentUserPersonalDetailsPropTypes, @@ -138,7 +135,6 @@ const defaultProps = { preferredSkinTone: CONST.EMOJI_DEFAULT_SKIN_TONE, isComposerFullSize: false, pendingAction: null, - reports: {}, shouldShowComposeInput: true, ...withCurrentUserPersonalDetailsDefaultProps, }; @@ -550,7 +546,7 @@ class ReportActionCompose extends React.Component { const isCursorBeforeTheMention = valueAfterTheCursor.startsWith(lastWord); if (!isCursorBeforeTheMention && this.isMentionCode(lastWord)) { - const suggestions = OptionsListUtils.getMentionOptions(this.props.reports, this.props.personalDetails, this.props.betas, prefix); + const suggestions = OptionsListUtils.getMentionOptions(this.props.personalDetails, prefix); nextState.suggestedMentions = suggestions; nextState.shouldShowMentionSuggestionMenu = !_.isEmpty(suggestions); } @@ -1193,9 +1189,6 @@ export default compose( preferredSkinTone: { key: ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE, }, - reports: { - key: ONYXKEYS.COLLECTION.REPORT, - }, personalDetails: { key: ONYXKEYS.PERSONAL_DETAILS, }, From 9dde3d5d0cb0bd191ee1982ea962e699cb73ab79 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Fri, 19 May 2023 02:22:53 +0500 Subject: [PATCH 03/12] feat: removed optionutil changes and moves the mention calculator to ReportActionCompose --- src/CONST.js | 3 + src/languages/en.js | 3 + src/languages/es.js | 3 + src/libs/OptionsListUtils.js | 45 ------- src/pages/home/report/ReportActionCompose.js | 122 +++++++++++++------ 5 files changed, 91 insertions(+), 85 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 988ded81a73..4d7869b9bd8 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -801,6 +801,9 @@ const CONST = { MIN_AMOUNT_OF_ITEMS: 3, MAX_AMOUNT_OF_ITEMS: 5, }, + MENTION_SUGGESTER: { + HERE_TEXT: '@here', + }, COMPOSER_MAX_HEIGHT: 125, CHAT_FOOTER_MIN_HEIGHT: 65, CHAT_SKELETON_VIEW: { diff --git a/src/languages/en.js b/src/languages/en.js index 77d5d229a32..6822ac536b9 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -285,6 +285,9 @@ export default { sayHello: 'Say hello!', usePlusButton: '\n\nYou can also use the + button below to send or request money!', }, + mentionSuggestions: { + hereAlternateText: 'Notify everyone online in this room', + }, newMessages: 'New messages', reportTypingIndicator: { isTyping: 'is typing...', diff --git a/src/languages/es.js b/src/languages/es.js index 31852fc89b0..24c3d2a8103 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -284,6 +284,9 @@ export default { sayHello: '¡Saluda!', usePlusButton: '\n\n¡También puedes usar el botón + de abajo para enviar o pedir dinero!', }, + mentionSuggestions: { + hereAlternateText: 'Notificar a todos los que estén en linea de esta sala', + }, newMessages: 'Mensajes nuevos', reportTypingIndicator: { isTyping: 'está escribiendo...', diff --git a/src/libs/OptionsListUtils.js b/src/libs/OptionsListUtils.js index 01de28506e2..0b3c4bd35b5 100644 --- a/src/libs/OptionsListUtils.js +++ b/src/libs/OptionsListUtils.js @@ -591,7 +591,6 @@ function getOptions( } const isThread = ReportUtils.isThread(report); - const isMoneyRequestReport = ReportUtils.isMoneyRequestReport(report); const isChatRoom = ReportUtils.isChatRoom(report); const isTaskReport = ReportUtils.isTaskReport(report); const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report); @@ -847,49 +846,6 @@ function getNewChatOptions(reports, personalDetails, betas = [], searchValue = ' }); } -/** - * Build the suggestions for mentions - * @param {Object} personalDetails - * @param {String} [searchValue] - * @param {Number} [maxRecords] - * @returns {Object} - */ -function getMentionOptions(personalDetails, searchValue = '', maxRecords = 5) { - const suggestions = []; - - if ('here'.includes(searchValue)) { - suggestions.push({ - text: '@here', - alternateText: 'Notify everyone online in this room', - icons: [ - { - name: '', - source: () => {}, - type: 'avatar', - }, - ], - }); - } - _.each(_.values(personalDetails), (detail) => { - if (searchValue && !`${detail.displayName} ${detail.login}`.includes(searchValue)) { - return; - }; - - suggestions.push({ - text: detail.displayName, - alternateText: detail.login, - icons: [ - { - name: detail.login, - source: detail.avatar, - type: 'avatar', - }, - ] - }); - }); - return suggestions.slice(0, maxRecords); -} - /** * Build the options for the Share Destination for a Task * * @@ -984,7 +940,6 @@ export { isPersonalDetailsReady, getSearchOptions, getNewChatOptions, - getMentionOptions, getShareDestinationOptions, getMemberInviteOptions, getHeaderMessage, diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 4752274d172..fab40e7705a 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -53,7 +53,6 @@ import * as ComposerActions from '../../../libs/actions/Composer'; import * as Welcome from '../../../libs/actions/Welcome'; import Permissions from '../../../libs/Permissions'; import * as TaskUtils from '../../../libs/actions/Task'; -import * as OptionsListUtils from '../../../libs/OptionsListUtils'; const propTypes = { /** Beta features list */ @@ -443,51 +442,94 @@ class ReportActionCompose extends React.Component { } /** - * Clean data related to EmojiSuggestions and MentionSuggestions + * Build the suggestions for mentions + * @param {Object} personalDetails + * @param {String} [searchValue] + * @param {Number} [maxRecords] + * @returns {Object} */ - resetSuggestions() { - this.setState({ - ...this.getDefaultSuggestionsValues(), + getMentionOptions(personalDetails, searchValue = '', maxRecords = 5) { + const suggestions = []; + + if (CONST.MENTION_SUGGESTER.HERE_TEXT.includes(searchValue)) { + suggestions.push({ + text: CONST.MENTION_SUGGESTER.HERE_TEXT, + alternateText: this.props.translate('mentionSuggestions.hereAlternateText'), + icons: [ + { + source: Expensicons.Megaphone, + type: 'avatar', + }, + ], + }); + } + const sortedPersonalDetails = _.sortBy(_.values(personalDetails), (detail) => detail.displayName || detail.login); + _.each(sortedPersonalDetails, (detail) => { + if (searchValue && !`${detail.displayName} ${detail.login}`.trim().includes(searchValue)) { + return; + }; + + suggestions.push({ + text: detail.displayName, + alternateText: detail.login, + icons: [ + { + name: detail.login, + source: detail.avatar, + type: 'avatar', + }, + ] + }); }); + return suggestions.slice(0, maxRecords); } - /** - * Calculates and cares about the content of an Emoji Suggester + /** + * Clean data related to EmojiSuggestions and MentionSuggestions */ - calculateEmojiSuggestion() { - if (!this.state.value) { - this.resetSuggestions(); - return; - } - if (this.state.shouldBlockEmojiCalc) { - this.setState({shouldBlockEmojiCalc: false}); - return; + resetSuggestions() { + this.setState({ + ...this.getDefaultSuggestionsValues(), + }); } - const leftString = this.state.value.substring(0, this.state.selection.end); - const colonIndex = leftString.lastIndexOf(':'); - const isCurrentlyShowingEmojiSuggestion = this.isEmojiCode(this.state.value, this.state.selection.end); - - // 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 isAutoSuggestionPickerLarge = !this.props.isSmallScreenWidth || (this.props.isSmallScreenWidth && hasEnoughSpaceForLargeSuggestion); - - const nextState = { - suggestedEmojis: [], - highlightedEmojiIndex: 0, - colonIndex, - shouldShowEmojiSuggestionMenu: false, - isAutoSuggestionPickerLarge, - }; - const newSuggestedEmojis = EmojiUtils.suggestEmojis(leftString); - - if (newSuggestedEmojis.length && isCurrentlyShowingEmojiSuggestion) { - nextState.suggestedEmojis = newSuggestedEmojis; - nextState.shouldShowEmojiSuggestionMenu = !_.isEmpty(newSuggestedEmojis); + + /** + * Calculates and cares about the content of an Emoji Suggester + */ + calculateEmojiSuggestion() { + if (!this.state.value) { + this.resetSuggestions(); + return; + } + if (this.state.shouldBlockEmojiCalc) { + this.setState({shouldBlockEmojiCalc: false}); + return; + } + const leftString = this.state.value.substring(0, this.state.selection.end); + const colonIndex = leftString.lastIndexOf(':'); + const isCurrentlyShowingEmojiSuggestion = this.isEmojiCode(this.state.value, this.state.selection.end); + + // 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 isAutoSuggestionPickerLarge = !this.props.isSmallScreenWidth || (this.props.isSmallScreenWidth && hasEnoughSpaceForLargeSuggestion); + + const nextState = { + suggestedEmojis: [], + highlightedEmojiIndex: 0, + colonIndex, + shouldShowEmojiSuggestionMenu: false, + isAutoSuggestionPickerLarge, + }; + const newSuggestedEmojis = EmojiUtils.suggestEmojis(leftString); + + if (newSuggestedEmojis.length && isCurrentlyShowingEmojiSuggestion) { + nextState.suggestedEmojis = newSuggestedEmojis; + nextState.shouldShowEmojiSuggestionMenu = !_.isEmpty(newSuggestedEmojis); + } + + this.setState(nextState); } - this.setState(nextState); - } - calculateMentionSuggestion() { if (this.state.selection.end < 1) { return; @@ -525,7 +567,7 @@ class ReportActionCompose extends React.Component { const isCursorBeforeTheMention = valueAfterTheCursor.startsWith(lastWord); if (!isCursorBeforeTheMention && this.isMentionCode(lastWord)) { - const suggestions = OptionsListUtils.getMentionOptions(this.props.personalDetails, prefix); + const suggestions = this.getMentionOptions(this.props.personalDetails, prefix); nextState.suggestedMentions = suggestions; nextState.shouldShowMentionSuggestionMenu = !_.isEmpty(suggestions); } @@ -590,7 +632,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.text === '@here' ? 'here' : mentionObject.alternateText}`; + const mentionCode = `@${mentionObject.text === `@${CONST.MENTION_SUGGESTER.HERE_TEXT}` ? CONST.MENTION_SUGGESTER.HERE_TEXT : mentionObject.alternateText}`; const commentAfterAtSignWithMentionRemoved = this.state.value.slice(this.state.atSignIndex).replace(CONST.REGEX.MENTION_REPLACER, ''); this.updateComment(`${commentBeforeAtSign}${mentionCode} ${commentAfterAtSignWithMentionRemoved}`, true); From 0021f3678cd9f39b6e7b7ea3b34033b7ebfc0a4f Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Fri, 19 May 2023 02:40:42 +0500 Subject: [PATCH 04/12] feat: show here text after mention selection --- 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 fab40e7705a..3125f9da2e6 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -632,7 +632,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.text === `@${CONST.MENTION_SUGGESTER.HERE_TEXT}` ? CONST.MENTION_SUGGESTER.HERE_TEXT : mentionObject.alternateText}`; + const mentionCode = `@${mentionObject.text === CONST.MENTION_SUGGESTER.HERE_TEXT ? CONST.MENTION_SUGGESTER.HERE_TEXT.replace('@', '') : mentionObject.alternateText}`; const commentAfterAtSignWithMentionRemoved = this.state.value.slice(this.state.atSignIndex).replace(CONST.REGEX.MENTION_REPLACER, ''); this.updateComment(`${commentBeforeAtSign}${mentionCode} ${commentAfterAtSignWithMentionRemoved}`, true); From 93bd1115497c6b4e18f3c40d0558e5127b23f0c9 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Fri, 19 May 2023 02:58:36 +0500 Subject: [PATCH 05/12] feat: update prettier styles --- src/pages/home/report/ReportActionCompose.js | 86 ++++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 3125f9da2e6..92ffeb8143b 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -467,7 +467,7 @@ class ReportActionCompose extends React.Component { _.each(sortedPersonalDetails, (detail) => { if (searchValue && !`${detail.displayName} ${detail.login}`.trim().includes(searchValue)) { return; - }; + } suggestions.push({ text: detail.displayName, @@ -478,58 +478,58 @@ class ReportActionCompose extends React.Component { source: detail.avatar, type: 'avatar', }, - ] + ], }); }); return suggestions.slice(0, maxRecords); } - /** + /** * Clean data related to EmojiSuggestions and MentionSuggestions */ - resetSuggestions() { - this.setState({ - ...this.getDefaultSuggestionsValues(), - }); + resetSuggestions() { + this.setState({ + ...this.getDefaultSuggestionsValues(), + }); + } + + /** + * Calculates and cares about the content of an Emoji Suggester + */ + calculateEmojiSuggestion() { + if (!this.state.value) { + this.resetSuggestions(); + return; } - - /** - * Calculates and cares about the content of an Emoji Suggester - */ - calculateEmojiSuggestion() { - if (!this.state.value) { - this.resetSuggestions(); - return; - } - if (this.state.shouldBlockEmojiCalc) { - this.setState({shouldBlockEmojiCalc: false}); - return; - } - const leftString = this.state.value.substring(0, this.state.selection.end); - const colonIndex = leftString.lastIndexOf(':'); - const isCurrentlyShowingEmojiSuggestion = this.isEmojiCode(this.state.value, this.state.selection.end); - - // 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 isAutoSuggestionPickerLarge = !this.props.isSmallScreenWidth || (this.props.isSmallScreenWidth && hasEnoughSpaceForLargeSuggestion); - - const nextState = { - suggestedEmojis: [], - highlightedEmojiIndex: 0, - colonIndex, - shouldShowEmojiSuggestionMenu: false, - isAutoSuggestionPickerLarge, - }; - const newSuggestedEmojis = EmojiUtils.suggestEmojis(leftString); - - if (newSuggestedEmojis.length && isCurrentlyShowingEmojiSuggestion) { - nextState.suggestedEmojis = newSuggestedEmojis; - nextState.shouldShowEmojiSuggestionMenu = !_.isEmpty(newSuggestedEmojis); - } - - this.setState(nextState); + if (this.state.shouldBlockEmojiCalc) { + this.setState({shouldBlockEmojiCalc: false}); + return; + } + const leftString = this.state.value.substring(0, this.state.selection.end); + const colonIndex = leftString.lastIndexOf(':'); + const isCurrentlyShowingEmojiSuggestion = this.isEmojiCode(this.state.value, this.state.selection.end); + + // 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 isAutoSuggestionPickerLarge = !this.props.isSmallScreenWidth || (this.props.isSmallScreenWidth && hasEnoughSpaceForLargeSuggestion); + + const nextState = { + suggestedEmojis: [], + highlightedEmojiIndex: 0, + colonIndex, + shouldShowEmojiSuggestionMenu: false, + isAutoSuggestionPickerLarge, + }; + const newSuggestedEmojis = EmojiUtils.suggestEmojis(leftString); + + if (newSuggestedEmojis.length && isCurrentlyShowingEmojiSuggestion) { + nextState.suggestedEmojis = newSuggestedEmojis; + nextState.shouldShowEmojiSuggestionMenu = !_.isEmpty(newSuggestedEmojis); } + this.setState(nextState); + } + calculateMentionSuggestion() { if (this.state.selection.end < 1) { return; From 38ce21aac304a0324946cf749941ca7998c18656 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Fri, 19 May 2023 21:26:09 +0500 Subject: [PATCH 06/12] feat: remove max records --- src/pages/home/report/ReportActionCompose.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 92ffeb8143b..84a96c8462f 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -445,10 +445,9 @@ class ReportActionCompose extends React.Component { * Build the suggestions for mentions * @param {Object} personalDetails * @param {String} [searchValue] - * @param {Number} [maxRecords] * @returns {Object} */ - getMentionOptions(personalDetails, searchValue = '', maxRecords = 5) { + getMentionOptions(personalDetails, searchValue = '') { const suggestions = []; if (CONST.MENTION_SUGGESTER.HERE_TEXT.includes(searchValue)) { @@ -481,7 +480,7 @@ class ReportActionCompose extends React.Component { ], }); }); - return suggestions.slice(0, maxRecords); + return suggestions.slice(0, 5); } /** From dd631edc8fc519259f52fc43b0db6dfb239f1da1 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Mon, 22 May 2023 19:15:35 +0500 Subject: [PATCH 07/12] feat: replace static max amount by a const --- 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 84a96c8462f..bb60096f32d 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -480,7 +480,7 @@ class ReportActionCompose extends React.Component { ], }); }); - return suggestions.slice(0, 5); + return suggestions.slice(0, CONST.AUTO_COMPLETE_SUGGESTER.MAX_AMOUNT_OF_ITEMS); } /** From 2a03a825aa731baa7854f7659b82180992c909c6 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Tue, 23 May 2023 00:11:00 +0500 Subject: [PATCH 08/12] Update src/pages/home/report/ReportActionCompose.js Co-authored-by: Eugene Voloshchak --- 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 bb60096f32d..9267596a670 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -631,7 +631,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.text === CONST.MENTION_SUGGESTER.HERE_TEXT ? CONST.MENTION_SUGGESTER.HERE_TEXT.replace('@', '') : mentionObject.alternateText}`; + const mentionCode = mentionObject.text === CONST.MENTION_SUGGESTER.HERE_TEXT ? CONST.MENTION_SUGGESTER.HERE_TEXT : `@${mentionObject.alternateText}`; const commentAfterAtSignWithMentionRemoved = this.state.value.slice(this.state.atSignIndex).replace(CONST.REGEX.MENTION_REPLACER, ''); this.updateComment(`${commentBeforeAtSign}${mentionCode} ${commentAfterAtSignWithMentionRemoved}`, true); From e87cff683b7c84b4d78db178e71dc8a93936cc5d Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Tue, 23 May 2023 00:26:49 +0500 Subject: [PATCH 09/12] fix: make search case insensitive --- src/pages/home/report/ReportActionCompose.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 9267596a670..76a03265c99 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -463,8 +463,9 @@ class ReportActionCompose extends React.Component { }); } const sortedPersonalDetails = _.sortBy(_.values(personalDetails), (detail) => detail.displayName || detail.login); + const searchRegex = new RegExp(searchValue, 'i'); _.each(sortedPersonalDetails, (detail) => { - if (searchValue && !`${detail.displayName} ${detail.login}`.trim().includes(searchValue)) { + if (searchValue && !searchRegex.test(`${detail.displayName} ${detail.login}`.trim())) { return; } From fd082fbc8d4d337861d8328de7f71509a01ec269 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Tue, 23 May 2023 00:53:39 +0500 Subject: [PATCH 10/12] fix: refactor the mention function --- src/pages/home/report/ReportActionCompose.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 76a03265c99..de91006e0be 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -462,13 +462,19 @@ class ReportActionCompose extends React.Component { ], }); } - const sortedPersonalDetails = _.sortBy(_.values(personalDetails), (detail) => detail.displayName || detail.login); + const searchRegex = new RegExp(searchValue, 'i'); - _.each(sortedPersonalDetails, (detail) => { + + const filteredPersonalDetails = _.filter(_.values(personalDetails), (detail) => { if (searchValue && !searchRegex.test(`${detail.displayName} ${detail.login}`.trim())) { - return; + return false; } + return true; + }); + + const sortedPersonalDetails = _.sortBy(filteredPersonalDetails, (detail) => detail.displayName || detail.login); + _.each(sortedPersonalDetails, (detail) => { suggestions.push({ text: detail.displayName, alternateText: detail.login, @@ -481,6 +487,7 @@ class ReportActionCompose extends React.Component { ], }); }); + return suggestions.slice(0, CONST.AUTO_COMPLETE_SUGGESTER.MAX_AMOUNT_OF_ITEMS); } From 1b918826227bd6b238d336d80e36d711290875e4 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Tue, 23 May 2023 04:25:50 +0500 Subject: [PATCH 11/12] fix: further optimize the mention options function --- src/pages/home/report/ReportActionCompose.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index de91006e0be..2ffe2e090ee 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -463,18 +463,15 @@ class ReportActionCompose extends React.Component { }); } - const searchRegex = new RegExp(searchValue, 'i'); - const filteredPersonalDetails = _.filter(_.values(personalDetails), (detail) => { - if (searchValue && !searchRegex.test(`${detail.displayName} ${detail.login}`.trim())) { + if (searchValue && !`${detail.displayName} ${detail.login}`.toLowerCase().includes(searchValue.toLowerCase())) { return false; } return true; }); const sortedPersonalDetails = _.sortBy(filteredPersonalDetails, (detail) => detail.displayName || detail.login); - - _.each(sortedPersonalDetails, (detail) => { + _.each(_.first(sortedPersonalDetails, CONST.AUTO_COMPLETE_SUGGESTER.MAX_AMOUNT_OF_ITEMS - suggestions.length), (detail) => { suggestions.push({ text: detail.displayName, alternateText: detail.login, @@ -488,7 +485,7 @@ class ReportActionCompose extends React.Component { }); }); - return suggestions.slice(0, CONST.AUTO_COMPLETE_SUGGESTER.MAX_AMOUNT_OF_ITEMS); + return suggestions; } /** From 3334ef5cb0684f876bf5e9f4a1bf64418932981d Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Tue, 23 May 2023 19:38:17 +0500 Subject: [PATCH 12/12] fix: move here text inside auto complete suggester --- src/CONST.js | 2 -- src/pages/home/report/ReportActionCompose.js | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 21a934e555b..12a6c41fc8d 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -801,8 +801,6 @@ const CONST = { SMALL_CONTAINER_HEIGHT_FACTOR: 2.5, MIN_AMOUNT_OF_ITEMS: 3, MAX_AMOUNT_OF_ITEMS: 5, - }, - MENTION_SUGGESTER: { HERE_TEXT: '@here', }, COMPOSER_MAX_HEIGHT: 125, diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 2ffe2e090ee..12bc13119cf 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -450,9 +450,9 @@ class ReportActionCompose extends React.Component { getMentionOptions(personalDetails, searchValue = '') { const suggestions = []; - if (CONST.MENTION_SUGGESTER.HERE_TEXT.includes(searchValue)) { + if (CONST.AUTO_COMPLETE_SUGGESTER.HERE_TEXT.includes(searchValue)) { suggestions.push({ - text: CONST.MENTION_SUGGESTER.HERE_TEXT, + text: CONST.AUTO_COMPLETE_SUGGESTER.HERE_TEXT, alternateText: this.props.translate('mentionSuggestions.hereAlternateText'), icons: [ { @@ -636,7 +636,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.text === CONST.MENTION_SUGGESTER.HERE_TEXT ? CONST.MENTION_SUGGESTER.HERE_TEXT : `@${mentionObject.alternateText}`; + const mentionCode = mentionObject.text === CONST.AUTO_COMPLETE_SUGGESTER.HERE_TEXT ? CONST.AUTO_COMPLETE_SUGGESTER.HERE_TEXT : `@${mentionObject.alternateText}`; const commentAfterAtSignWithMentionRemoved = this.state.value.slice(this.state.atSignIndex).replace(CONST.REGEX.MENTION_REPLACER, ''); this.updateComment(`${commentBeforeAtSign}${mentionCode} ${commentAfterAtSignWithMentionRemoved}`, true);