From 0ca7dcb9197720b6825f3465dcb3f32323fba271 Mon Sep 17 00:00:00 2001 From: Pavlo Tsimura Date: Tue, 17 Oct 2023 19:30:39 +0200 Subject: [PATCH 1/6] Try build an iOS workaround --- .../ReportActionCompose/SuggestionMention.js | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionCompose/SuggestionMention.js b/src/pages/home/report/ReportActionCompose/SuggestionMention.js index 67d87bdbce6f..16180bf77e37 100644 --- a/src/pages/home/report/ReportActionCompose/SuggestionMention.js +++ b/src/pages/home/report/ReportActionCompose/SuggestionMention.js @@ -1,6 +1,7 @@ import React, {useState, useCallback, useRef, useImperativeHandle, useEffect} from 'react'; import PropTypes from 'prop-types'; import _ from 'underscore'; +import lodashGet from 'lodash/get'; import {withOnyx} from 'react-native-onyx'; import CONST from '../../../../CONST'; import useArrowKeyFocusManager from '../../../../hooks/useArrowKeyFocusManager'; @@ -57,6 +58,7 @@ function SuggestionMention({ }) { const {translate} = useLocalize(); const [suggestionValues, setSuggestionValues] = useState(defaultSuggestionsValues); + const [shouldRecalculateSuggestions, setShouldRecalculateSuggestions] = useState(false); const isMentionSuggestionsMenuVisible = !_.isEmpty(suggestionValues.suggestedMentions) && suggestionValues.shouldShowSuggestionMenu; @@ -233,8 +235,35 @@ function SuggestionMention({ ); useEffect(() => { + console.log(`[Selection Handler] value: ${value}, selection: ${selection.end}`); + + if (selection.end > 0 && !lodashGet(value, 'length', 0)) { + // This is a workaround for a known issue with iOS' first input. + // See: https://github.com/facebook/react-native/pull/36930#issuecomment-1593028467 + setShouldRecalculateSuggestions(true); + } + calculateMentionSuggestion(selection.end); + + // We want this hook to run only on selection change. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selection]); + + useEffect(() => { + console.log(`[Value Handler] value: ${value}, selection: ${selection.end}, shouldRecalculateSuggestions: ${shouldRecalculateSuggestions}`); + + // This hook solves the issue with iOS' first input: + // It enables showing the mention suggestions after the user enters '@' as a first char in the Composer. + // See: https://github.com/facebook/react-native/pull/36930#issuecomment-1593028467 + if (!shouldRecalculateSuggestions) { + return; + } + + setShouldRecalculateSuggestions(false); calculateMentionSuggestion(selection.end); - }, [selection, calculateMentionSuggestion]); + + // We want this hook to run only on value change. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [value]); const updateShouldShowSuggestionMenuToFalse = useCallback(() => { setSuggestionValues((prevState) => { From ff4bfdb48da1dc69178180e1fa14fa3af5bb3ad2 Mon Sep 17 00:00:00 2001 From: Pavlo Tsimura Date: Tue, 17 Oct 2023 23:33:34 +0200 Subject: [PATCH 2/6] Try build an iOS workaround --- .../ReportActionCompose/SuggestionMention.js | 33 ++++--------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose/SuggestionMention.js b/src/pages/home/report/ReportActionCompose/SuggestionMention.js index 16180bf77e37..b677646f3656 100644 --- a/src/pages/home/report/ReportActionCompose/SuggestionMention.js +++ b/src/pages/home/report/ReportActionCompose/SuggestionMention.js @@ -1,7 +1,6 @@ import React, {useState, useCallback, useRef, useImperativeHandle, useEffect} from 'react'; import PropTypes from 'prop-types'; import _ from 'underscore'; -import lodashGet from 'lodash/get'; import {withOnyx} from 'react-native-onyx'; import CONST from '../../../../CONST'; import useArrowKeyFocusManager from '../../../../hooks/useArrowKeyFocusManager'; @@ -10,6 +9,7 @@ import * as UserUtils from '../../../../libs/UserUtils'; import * as Expensicons from '../../../../components/Icon/Expensicons'; import * as SuggestionsUtils from '../../../../libs/SuggestionUtils'; import useLocalize from '../../../../hooks/useLocalize'; +import usePrevious from "../../../../hooks/usePrevious"; import ONYXKEYS from '../../../../ONYXKEYS'; import personalDetailsPropType from '../../../personalDetailsPropType'; import * as SuggestionProps from './suggestionProps'; @@ -58,7 +58,7 @@ function SuggestionMention({ }) { const {translate} = useLocalize(); const [suggestionValues, setSuggestionValues] = useState(defaultSuggestionsValues); - const [shouldRecalculateSuggestions, setShouldRecalculateSuggestions] = useState(false); + const previousValue = usePrevious(value); const isMentionSuggestionsMenuVisible = !_.isEmpty(suggestionValues.suggestedMentions) && suggestionValues.shouldShowSuggestionMenu; @@ -235,35 +235,14 @@ function SuggestionMention({ ); useEffect(() => { - console.log(`[Selection Handler] value: ${value}, selection: ${selection.end}`); - - if (selection.end > 0 && !lodashGet(value, 'length', 0)) { - // This is a workaround for a known issue with iOS' first input. - // See: https://github.com/facebook/react-native/pull/36930#issuecomment-1593028467 - setShouldRecalculateSuggestions(true); - } - calculateMentionSuggestion(selection.end); - - // We want this hook to run only on selection change. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [selection]); - - useEffect(() => { - console.log(`[Value Handler] value: ${value}, selection: ${selection.end}, shouldRecalculateSuggestions: ${shouldRecalculateSuggestions}`); - - // This hook solves the issue with iOS' first input: - // It enables showing the mention suggestions after the user enters '@' as a first char in the Composer. - // See: https://github.com/facebook/react-native/pull/36930#issuecomment-1593028467 - if (!shouldRecalculateSuggestions) { + if (value.length < previousValue.length) { + console.log(`[Skipping] value: '${value}', selection: ${selection.end}`); return; } - setShouldRecalculateSuggestions(false); + console.log(`[Processing] value: '${value}', selection: ${selection.end}`); calculateMentionSuggestion(selection.end); - - // We want this hook to run only on value change. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [value]); + }, [selection, calculateMentionSuggestion]); const updateShouldShowSuggestionMenuToFalse = useCallback(() => { setSuggestionValues((prevState) => { From a6c8519a56f7ab729be76867bf25957b92d82141 Mon Sep 17 00:00:00 2001 From: Pavlo Tsimura Date: Wed, 18 Oct 2023 20:21:21 +0200 Subject: [PATCH 3/6] Remove logs --- .../home/report/ReportActionCompose/SuggestionMention.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose/SuggestionMention.js b/src/pages/home/report/ReportActionCompose/SuggestionMention.js index b677646f3656..9a9182e0edab 100644 --- a/src/pages/home/report/ReportActionCompose/SuggestionMention.js +++ b/src/pages/home/report/ReportActionCompose/SuggestionMention.js @@ -57,8 +57,8 @@ function SuggestionMention({ measureParentContainer, }) { const {translate} = useLocalize(); - const [suggestionValues, setSuggestionValues] = useState(defaultSuggestionsValues); const previousValue = usePrevious(value); + const [suggestionValues, setSuggestionValues] = useState(defaultSuggestionsValues); const isMentionSuggestionsMenuVisible = !_.isEmpty(suggestionValues.suggestedMentions) && suggestionValues.shouldShowSuggestionMenu; @@ -236,11 +236,12 @@ function SuggestionMention({ useEffect(() => { if (value.length < previousValue.length) { - console.log(`[Skipping] value: '${value}', selection: ${selection.end}`); + // A workaround to not show the suggestions list when the user deletes a character before the mention. + // It is caused by a buggy behavior of the TextInput on iOS. + // See: https://github.com/facebook/react-native/pull/36930#issuecomment-1593028467 return; } - console.log(`[Processing] value: '${value}', selection: ${selection.end}`); calculateMentionSuggestion(selection.end); }, [selection, calculateMentionSuggestion]); From f40138539e6eb83118aae1c521778a410e5fcaaa Mon Sep 17 00:00:00 2001 From: Pavlo Tsimura Date: Thu, 19 Oct 2023 13:39:54 +0200 Subject: [PATCH 4/6] Fix dependencies list --- .../home/report/ReportActionCompose/SuggestionMention.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose/SuggestionMention.js b/src/pages/home/report/ReportActionCompose/SuggestionMention.js index 9a9182e0edab..c500cb012794 100644 --- a/src/pages/home/report/ReportActionCompose/SuggestionMention.js +++ b/src/pages/home/report/ReportActionCompose/SuggestionMention.js @@ -237,13 +237,13 @@ function SuggestionMention({ useEffect(() => { if (value.length < previousValue.length) { // A workaround to not show the suggestions list when the user deletes a character before the mention. - // It is caused by a buggy behavior of the TextInput on iOS. + // It is caused by a buggy behavior of the TextInput on iOS. Should be fixed after migration to the Fabric Arc. // See: https://github.com/facebook/react-native/pull/36930#issuecomment-1593028467 return; } calculateMentionSuggestion(selection.end); - }, [selection, calculateMentionSuggestion]); + }, [selection, value, previousValue, calculateMentionSuggestion]); const updateShouldShowSuggestionMenuToFalse = useCallback(() => { setSuggestionValues((prevState) => { From 1cb6ba62e4319876b7314c139e2ae485fda22ba5 Mon Sep 17 00:00:00 2001 From: Pavlo Tsimura Date: Thu, 19 Oct 2023 13:58:03 +0200 Subject: [PATCH 5/6] Lint fix --- src/pages/home/report/ReportActionCompose/SuggestionMention.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionCompose/SuggestionMention.js b/src/pages/home/report/ReportActionCompose/SuggestionMention.js index c500cb012794..7d92ed474a6f 100644 --- a/src/pages/home/report/ReportActionCompose/SuggestionMention.js +++ b/src/pages/home/report/ReportActionCompose/SuggestionMention.js @@ -9,7 +9,7 @@ import * as UserUtils from '../../../../libs/UserUtils'; import * as Expensicons from '../../../../components/Icon/Expensicons'; import * as SuggestionsUtils from '../../../../libs/SuggestionUtils'; import useLocalize from '../../../../hooks/useLocalize'; -import usePrevious from "../../../../hooks/usePrevious"; +import usePrevious from '../../../../hooks/usePrevious'; import ONYXKEYS from '../../../../ONYXKEYS'; import personalDetailsPropType from '../../../personalDetailsPropType'; import * as SuggestionProps from './suggestionProps'; From 54d1bafbb3ac8a4499981226f3da227572c18eba Mon Sep 17 00:00:00 2001 From: Pavlo Tsimura Date: Mon, 23 Oct 2023 11:36:11 +0200 Subject: [PATCH 6/6] Fix Fabric-related comment --- src/pages/home/report/ReportActionCompose/SuggestionMention.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionCompose/SuggestionMention.js b/src/pages/home/report/ReportActionCompose/SuggestionMention.js index e2a80f8c87f2..59221f57fd4b 100644 --- a/src/pages/home/report/ReportActionCompose/SuggestionMention.js +++ b/src/pages/home/report/ReportActionCompose/SuggestionMention.js @@ -238,7 +238,7 @@ function SuggestionMention({ useEffect(() => { if (value.length < previousValue.length) { // A workaround to not show the suggestions list when the user deletes a character before the mention. - // It is caused by a buggy behavior of the TextInput on iOS. Should be fixed after migration to the Fabric Arc. + // It is caused by a buggy behavior of the TextInput on iOS. Should be fixed after migration to Fabric. // See: https://github.com/facebook/react-native/pull/36930#issuecomment-1593028467 return; }