From 4a5f3d727bce80e208ee20cac373c122c649d6a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Fri, 19 Jul 2024 19:00:56 +0200 Subject: [PATCH 1/4] fix: suggestions causing excessive updates --- .../ComposerWithSuggestions.tsx | 1 - .../ReportActionCompose/SuggestionEmoji.tsx | 19 ++++++++++++------- .../ReportActionCompose/SuggestionMention.tsx | 17 +++++++++++------ .../ReportActionCompose/Suggestions.tsx | 7 +------ 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx index 72d387b07f52c..8673e2dafa84d 100644 --- a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx +++ b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx @@ -809,7 +809,6 @@ function ComposerWithSuggestions( policyID={policyID} // Input value={value} - setValue={setValue} selection={selection} setSelection={setSelection} resetKeyboardInput={resetKeyboardInput} diff --git a/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx b/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx index 8d5a544afd42c..e26681943bb83 100644 --- a/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx +++ b/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx @@ -149,15 +149,15 @@ function SuggestionEmoji( * Calculates and cares about the content of an Emoji Suggester */ const calculateEmojiSuggestion = useCallback( - (selectionStart?: number, selectionEnd?: number) => { - if (selectionStart !== selectionEnd || !selectionEnd || shouldBlockCalc.current || !value || (selectionStart === 0 && selectionEnd === 0)) { + (newValue: string, selectionStart?: number, selectionEnd?: number) => { + if (selectionStart !== selectionEnd || !selectionEnd || shouldBlockCalc.current || !newValue || (selectionStart === 0 && selectionEnd === 0)) { shouldBlockCalc.current = false; resetSuggestions(); return; } - const leftString = value.substring(0, selectionEnd); + const leftString = newValue.substring(0, selectionEnd); const colonIndex = leftString.lastIndexOf(':'); - const isCurrentlyShowingEmojiSuggestion = isEmojiCode(value, selectionEnd); + const isCurrentlyShowingEmojiSuggestion = isEmojiCode(newValue, selectionEnd); const nextState: SuggestionsValue = { suggestedEmojis: [], @@ -171,10 +171,15 @@ function SuggestionEmoji( nextState.shouldShowSuggestionMenu = !isEmptyObject(newSuggestedEmojis); } + // Early return if there is no update + if (nextState.suggestedEmojis.length === 0 && !nextState.shouldShowSuggestionMenu) { + return; + } + setSuggestionValues((prevState) => ({...prevState, ...nextState})); setHighlightedEmojiIndex(0); }, - [value, preferredLocale, setHighlightedEmojiIndex, resetSuggestions], + [preferredLocale, setHighlightedEmojiIndex, resetSuggestions], ); useEffect(() => { @@ -182,8 +187,8 @@ function SuggestionEmoji( return; } - calculateEmojiSuggestion(selection.start, selection.end); - }, [selection, calculateEmojiSuggestion, isComposerFocused]); + calculateEmojiSuggestion(value, selection.start, selection.end); + }, [value, selection, calculateEmojiSuggestion, isComposerFocused]); const setShouldBlockSuggestionCalc = useCallback( (shouldBlockSuggestionCalc: boolean) => { diff --git a/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx b/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx index 86a05bad19943..ded55d7f0faef 100644 --- a/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx +++ b/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx @@ -317,15 +317,15 @@ function SuggestionMention( ); const calculateMentionSuggestion = useCallback( - (selectionStart?: number, selectionEnd?: number) => { + (newValue: string, selectionStart?: number, selectionEnd?: number) => { if (selectionEnd !== selectionStart || !selectionEnd || shouldBlockCalc.current || selectionEnd < 1 || !isComposerFocused) { shouldBlockCalc.current = false; resetSuggestions(); return; } - const afterLastBreakLineIndex = value.lastIndexOf('\n', selectionEnd - 1) + 1; - const leftString = value.substring(afterLastBreakLineIndex, selectionEnd); + const afterLastBreakLineIndex = newValue.lastIndexOf('\n', selectionEnd - 1) + 1; + const leftString = newValue.substring(afterLastBreakLineIndex, selectionEnd); const words = leftString.split(CONST.REGEX.SPACE_OR_EMOJI); const lastWord: string = words.at(-1) ?? ''; const secondToLastWord = words[words.length - 3]; @@ -374,18 +374,23 @@ function SuggestionMention( nextState.shouldShowSuggestionMenu = true; } + // Early return if there is no update + if (nextState.suggestedMentions === undefined || (nextState.suggestedMentions.length === 0 && !nextState.shouldShowSuggestionMenu)) { + return; + } + setSuggestionValues((prevState) => ({ ...prevState, ...nextState, })); setHighlightedMentionIndex(0); }, - [isComposerFocused, value, isGroupPolicyReport, setHighlightedMentionIndex, resetSuggestions, getUserMentionOptions, weightedPersonalDetails, getRoomMentionOptions, reports], + [isComposerFocused, isGroupPolicyReport, setHighlightedMentionIndex, resetSuggestions, getUserMentionOptions, weightedPersonalDetails, getRoomMentionOptions, reports], ); useEffect(() => { - calculateMentionSuggestion(selection.start, selection.end); - }, [selection, calculateMentionSuggestion]); + calculateMentionSuggestion(value, selection.start, selection.end); + }, [value, selection, calculateMentionSuggestion]); useEffect(() => { debouncedSearchInServer(); diff --git a/src/pages/home/report/ReportActionCompose/Suggestions.tsx b/src/pages/home/report/ReportActionCompose/Suggestions.tsx index 158c60b0e89a7..a15b7c6055655 100644 --- a/src/pages/home/report/ReportActionCompose/Suggestions.tsx +++ b/src/pages/home/report/ReportActionCompose/Suggestions.tsx @@ -7,16 +7,13 @@ import type {TextSelection} from '@components/Composer/types'; import {DragAndDropContext} from '@components/DragAndDrop/Provider'; import usePrevious from '@hooks/usePrevious'; import type {SuggestionsRef} from './ReportActionCompose'; -import SuggestionEmoji from './SuggestionEmoji'; +import SuggestionEmoji from './SuggestionEmoji' import SuggestionMention from './SuggestionMention'; type SuggestionProps = { /** The current input value */ value: string; - /** Callback to update the current input value */ - setValue: (newValue: string) => void; - /** The current selection value */ selection: TextSelection; @@ -56,7 +53,6 @@ type SuggestionProps = { function Suggestions( { value, - setValue, selection, setSelection, updateComment, @@ -153,7 +149,6 @@ function Suggestions( const baseProps = { value, - setValue, setSelection, selection, updateComment, From c6ef6b895dfb3206cdfe43bbc9eff840f6d3ea25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 5 Aug 2024 15:57:58 +0200 Subject: [PATCH 2/4] fix: use refs and compare --- .../home/report/ReportActionCompose/SuggestionEmoji.tsx | 7 +++++-- .../home/report/ReportActionCompose/SuggestionMention.tsx | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx b/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx index 360408d84944f..3051bfb1689eb 100644 --- a/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx +++ b/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx @@ -60,6 +60,8 @@ function SuggestionEmoji( ref: ForwardedRef, ) { const [suggestionValues, setSuggestionValues] = useState(defaultSuggestionsValues); + const suggestionValuesRef = useRef(suggestionValues); + suggestionValuesRef.current = suggestionValues; const isEmojiSuggestionsMenuVisible = suggestionValues.suggestedEmojis.length > 0 && suggestionValues.shouldShowSuggestionMenu; @@ -171,8 +173,9 @@ function SuggestionEmoji( nextState.shouldShowSuggestionMenu = !isEmptyObject(newSuggestedEmojis); } - // Early return if there is no update - if (nextState.suggestedEmojis.length === 0 && !nextState.shouldShowSuggestionMenu) { + // Early return if there is no update + const currentState = suggestionValuesRef.current; + if (nextState.suggestedEmojis.length === 0 && currentState.suggestedEmojis.length === 0) { return; } diff --git a/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx b/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx index c3849f15f7747..8d37a1915cbd2 100644 --- a/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx +++ b/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx @@ -88,6 +88,8 @@ function SuggestionMention( const personalDetails = usePersonalDetails() ?? CONST.EMPTY_OBJECT; const {translate, formatPhoneNumber} = useLocalize(); const [suggestionValues, setSuggestionValues] = useState(defaultSuggestionsValues); + const suggestionValuesRef = useRef(suggestionValues); + suggestionValuesRef.current = suggestionValues; const [reports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); @@ -402,7 +404,8 @@ function SuggestionMention( } // Early return if there is no update - if (nextState.suggestedMentions === undefined || (nextState.suggestedMentions.length === 0 && !nextState.shouldShowSuggestionMenu)) { + const currentState = suggestionValuesRef.current; + if (currentState.suggestedMentions.length === 0 && nextState.suggestedMentions?.length === 0) { return; } From 9351535ba0dc3696e447239abb77c62debecfb18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 5 Aug 2024 16:12:08 +0200 Subject: [PATCH 3/4] fix lint --- src/pages/home/report/ReportActionCompose/Suggestions.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionCompose/Suggestions.tsx b/src/pages/home/report/ReportActionCompose/Suggestions.tsx index a15b7c6055655..8b7171340b637 100644 --- a/src/pages/home/report/ReportActionCompose/Suggestions.tsx +++ b/src/pages/home/report/ReportActionCompose/Suggestions.tsx @@ -7,7 +7,7 @@ import type {TextSelection} from '@components/Composer/types'; import {DragAndDropContext} from '@components/DragAndDrop/Provider'; import usePrevious from '@hooks/usePrevious'; import type {SuggestionsRef} from './ReportActionCompose'; -import SuggestionEmoji from './SuggestionEmoji' +import SuggestionEmoji from './SuggestionEmoji'; import SuggestionMention from './SuggestionMention'; type SuggestionProps = { From dce25894a9c7f384ab00fd7b8b439cddec47ea7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 5 Aug 2024 16:15:29 +0200 Subject: [PATCH 4/4] remove unused prop --- src/pages/home/report/ReportActionItemMessageEdit.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/home/report/ReportActionItemMessageEdit.tsx b/src/pages/home/report/ReportActionItemMessageEdit.tsx index 0ca9cf0b1a3ae..15b901689ddc6 100644 --- a/src/pages/home/report/ReportActionItemMessageEdit.tsx +++ b/src/pages/home/report/ReportActionItemMessageEdit.tsx @@ -534,7 +534,6 @@ function ReportActionItemMessageEdit( measureParentContainerAndReportCursor={measureParentContainerAndReportCursor} isGroupPolicyReport={false} value={draft} - setValue={setDraft} selection={selection} setSelection={setSelection} />