Skip to content

Commit

Permalink
Merge pull request #45789 from margelo/fix/excesive-suggestion-update…
Browse files Browse the repository at this point in the history
…s-maimum-update-depth-exceeded

fix: suggestions causing excessive updates
  • Loading branch information
neil-marcellini authored Aug 6, 2024
2 parents 7975157 + 0ed014d commit 6263c24
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,6 @@ function ComposerWithSuggestions(
policyID={policyID}
// Input
value={value}
setValue={setValue}
selection={selection}
setSelection={setSelection}
resetKeyboardInput={resetKeyboardInput}
Expand Down
22 changes: 15 additions & 7 deletions src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ function SuggestionEmoji(
ref: ForwardedRef<SuggestionsRef>,
) {
const [suggestionValues, setSuggestionValues] = useState(defaultSuggestionsValues);
const suggestionValuesRef = useRef(suggestionValues);
suggestionValuesRef.current = suggestionValues;

const isEmojiSuggestionsMenuVisible = suggestionValues.suggestedEmojis.length > 0 && suggestionValues.shouldShowSuggestionMenu;

Expand Down Expand Up @@ -149,15 +151,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: [],
Expand All @@ -171,19 +173,25 @@ function SuggestionEmoji(
nextState.shouldShowSuggestionMenu = !isEmptyObject(newSuggestedEmojis);
}

// Early return if there is no update
const currentState = suggestionValuesRef.current;
if (nextState.suggestedEmojis.length === 0 && currentState.suggestedEmojis.length === 0) {
return;
}

setSuggestionValues((prevState) => ({...prevState, ...nextState}));
setHighlightedEmojiIndex(0);
},
[value, preferredLocale, setHighlightedEmojiIndex, resetSuggestions],
[preferredLocale, setHighlightedEmojiIndex, resetSuggestions],
);

useEffect(() => {
if (!isComposerFocused) {
return;
}

calculateEmojiSuggestion(selection.start, selection.end);
}, [selection, calculateEmojiSuggestion, isComposerFocused]);
calculateEmojiSuggestion(value, selection.start, selection.end);
}, [value, selection, calculateEmojiSuggestion, isComposerFocused]);

const setShouldBlockSuggestionCalc = useCallback(
(shouldBlockSuggestionCalc: boolean) => {
Expand Down
20 changes: 14 additions & 6 deletions src/pages/home/report/ReportActionCompose/SuggestionMention.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -344,15 +346,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];
Expand Down Expand Up @@ -401,18 +403,24 @@ function SuggestionMention(
nextState.shouldShowSuggestionMenu = true;
}

// Early return if there is no update
const currentState = suggestionValuesRef.current;
if (currentState.suggestedMentions.length === 0 && nextState.suggestedMentions?.length === 0) {
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();
Expand Down
5 changes: 0 additions & 5 deletions src/pages/home/report/ReportActionCompose/Suggestions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ 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;

Expand Down Expand Up @@ -56,7 +53,6 @@ type SuggestionProps = {
function Suggestions(
{
value,
setValue,
selection,
setSelection,
updateComment,
Expand Down Expand Up @@ -153,7 +149,6 @@ function Suggestions(

const baseProps = {
value,
setValue,
setSelection,
selection,
updateComment,
Expand Down
1 change: 0 additions & 1 deletion src/pages/home/report/ReportActionItemMessageEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,6 @@ function ReportActionItemMessageEdit(
measureParentContainerAndReportCursor={measureParentContainerAndReportCursor}
isGroupPolicyReport={false}
value={draft}
setValue={setDraft}
selection={selection}
setSelection={setSelection}
/>
Expand Down

0 comments on commit 6263c24

Please sign in to comment.