From 42c8220bc3309253a4749b330a04adeb46e952f3 Mon Sep 17 00:00:00 2001 From: christianwenifr Date: Sat, 1 Apr 2023 15:52:27 +0700 Subject: [PATCH 01/69] fix: issue --- src/components/AddressSearch.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 683d3556dec4..65a2d030e74d 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import React, {useState} from 'react'; +import React, {useRef, useState} from 'react'; import PropTypes from 'prop-types'; import {LogBox, ScrollView, View} from 'react-native'; import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete'; @@ -90,6 +90,7 @@ const defaultProps = { // Reference: https://github.com/FaridSafi/react-native-google-places-autocomplete/issues/609#issuecomment-886133839 const AddressSearch = (props) => { const [displayListViewBorder, setDisplayListViewBorder] = useState(false); + const containerRef = useRef(); const query = {language: props.preferredLocale, types: 'address'}; if (props.isLimitedToUSA) { query.components = 'country:us'; @@ -193,7 +194,7 @@ const AddressSearch = (props) => { // here: https://github.com/FaridSafi/react-native-google-places-autocomplete#use-inside-a-scrollview-or-flatlist keyboardShouldPersistTaps="always" > - + { defaultValue: props.defaultValue, inputID: props.inputID, shouldSaveDraft: props.shouldSaveDraft, - onBlur: props.onBlur, + onBlur: (event) => { + if (!(containerRef.current && event.target && containerRef.current.contains(event.relatedTarget))) { + setDisplayListViewBorder(false); + } + props.onBlur(event); + }, autoComplete: 'off', onInputChange: (text) => { if (props.inputID) { From a2e9c80914221228ee91e4a8129d9a513ca95d9c Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 4 Apr 2023 21:40:07 +0700 Subject: [PATCH 02/69] fix: do not add new logic on native --- src/components/AddressSearch.js | 5 ++--- src/libs/resetDisplayListViewborderWhenBlur/index.js | 10 ++++++++++ .../resetDisplayListViewborderWhenBlur/index.native.js | 8 ++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 src/libs/resetDisplayListViewborderWhenBlur/index.js create mode 100644 src/libs/resetDisplayListViewborderWhenBlur/index.native.js diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 5c854bc2981b..e35d879dccf0 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -11,6 +11,7 @@ import TextInput from './TextInput'; import * as ApiUtils from '../libs/ApiUtils'; import * as GooglePlacesUtils from '../libs/GooglePlacesUtils'; import CONST from '../CONST'; +import DisplayListViewborder from '../libs/resetDisplayListViewborderWhenBlur'; // The error that's being thrown below will be ignored until we fork the // react-native-google-places-autocomplete repo and replace the @@ -240,9 +241,7 @@ const AddressSearch = (props) => { inputID: props.inputID, shouldSaveDraft: props.shouldSaveDraft, onBlur: (event) => { - if (!(containerRef.current && event.target && containerRef.current.contains(event.relatedTarget))) { - setDisplayListViewBorder(false); - } + DisplayListViewborder.resetDisplayListViewborderWhenBlur(event, containerRef, setDisplayListViewBorder); props.onBlur(event); }, autoComplete: 'off', diff --git a/src/libs/resetDisplayListViewborderWhenBlur/index.js b/src/libs/resetDisplayListViewborderWhenBlur/index.js new file mode 100644 index 000000000000..af70655eacbc --- /dev/null +++ b/src/libs/resetDisplayListViewborderWhenBlur/index.js @@ -0,0 +1,10 @@ +const resetDisplayListViewborderWhenBlur = (event, containerRef, setDisplayListViewBorder) => { + if (containerRef.current && event.target && containerRef.current.contains(event.relatedTarget)) { + return; + } + setDisplayListViewBorder(false); +}; + +export default { + resetDisplayListViewborderWhenBlur, +}; diff --git a/src/libs/resetDisplayListViewborderWhenBlur/index.native.js b/src/libs/resetDisplayListViewborderWhenBlur/index.native.js new file mode 100644 index 000000000000..16a0197af88b --- /dev/null +++ b/src/libs/resetDisplayListViewborderWhenBlur/index.native.js @@ -0,0 +1,8 @@ +const resetDisplayListViewborderWhenBlur = (event, containerRef, setDisplayListViewBorder) => { + console.log('native', setDisplayListViewBorder); + setDisplayListViewBorder(false); +}; + +export default { + resetDisplayListViewborderWhenBlur, +}; From 6ebf65b7479198c9d3715e4827752172d3fcee82 Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 4 Apr 2023 21:48:15 +0700 Subject: [PATCH 03/69] fix: remove log --- src/libs/resetDisplayListViewborderWhenBlur/index.native.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/resetDisplayListViewborderWhenBlur/index.native.js b/src/libs/resetDisplayListViewborderWhenBlur/index.native.js index 16a0197af88b..789c0cbe2df6 100644 --- a/src/libs/resetDisplayListViewborderWhenBlur/index.native.js +++ b/src/libs/resetDisplayListViewborderWhenBlur/index.native.js @@ -1,5 +1,4 @@ const resetDisplayListViewborderWhenBlur = (event, containerRef, setDisplayListViewBorder) => { - console.log('native', setDisplayListViewBorder); setDisplayListViewBorder(false); }; From c51901b412f910084a976da281cc678d6567e481 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Apr 2023 10:05:00 +0700 Subject: [PATCH 04/69] fix: add comment and move the logic correctly --- .../{ => AddressSearch}/AddressSearch.js | 20 ++++++++++--------- .../index.js | 14 +++++++++++++ .../index.native.js | 10 ++++++++++ src/pages/ReimbursementAccount/AddressForm.js | 2 +- .../settings/Payments/AddDebitCardPage.js | 2 +- .../Profile/PersonalDetails/AddressPage.js | 2 +- src/stories/AddressSearch.stories.js | 2 +- src/stories/Form.stories.js | 2 +- 8 files changed, 40 insertions(+), 14 deletions(-) rename src/components/{ => AddressSearch}/AddressSearch.js (94%) create mode 100644 src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.js create mode 100644 src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.native.js diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch/AddressSearch.js similarity index 94% rename from src/components/AddressSearch.js rename to src/components/AddressSearch/AddressSearch.js index e35d879dccf0..e676f4eb67ea 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch/AddressSearch.js @@ -4,14 +4,14 @@ import PropTypes from 'prop-types'; import {LogBox, ScrollView, View} from 'react-native'; import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete'; import lodashGet from 'lodash/get'; -import withLocalize, {withLocalizePropTypes} from './withLocalize'; -import styles from '../styles/styles'; -import themeColors from '../styles/themes/default'; -import TextInput from './TextInput'; -import * as ApiUtils from '../libs/ApiUtils'; -import * as GooglePlacesUtils from '../libs/GooglePlacesUtils'; -import CONST from '../CONST'; -import DisplayListViewborder from '../libs/resetDisplayListViewborderWhenBlur'; +import withLocalize, {withLocalizePropTypes} from '../withLocalize'; +import styles from '../../styles/styles'; +import themeColors from '../../styles/themes/default'; +import TextInput from '../TextInput'; +import * as ApiUtils from '../../libs/ApiUtils'; +import * as GooglePlacesUtils from '../../libs/GooglePlacesUtils'; +import CONST from '../../CONST'; +import resetDisplayListViewBorderWhenBlur from './resetDisplayListViewBorderWhenBlur'; // The error that's being thrown below will be ignored until we fork the // react-native-google-places-autocomplete repo and replace the @@ -207,6 +207,7 @@ const AddressSearch = (props) => { suppressDefaultStyles enablePoweredByContainer={false} onPress={(data, details) => { + console.log('onPress'); saveLocationDetails(data, details); // After we select an option, we set displayListViewBorder to false to prevent UI flickering @@ -241,7 +242,8 @@ const AddressSearch = (props) => { inputID: props.inputID, shouldSaveDraft: props.shouldSaveDraft, onBlur: (event) => { - DisplayListViewborder.resetDisplayListViewborderWhenBlur(event, containerRef, setDisplayListViewBorder); + console.log(resetDisplayListViewBorderWhenBlur); + resetDisplayListViewBorderWhenBlur(event, containerRef, setDisplayListViewBorder); props.onBlur(event); }, autoComplete: 'off', diff --git a/src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.js b/src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.js new file mode 100644 index 000000000000..35dc820d649c --- /dev/null +++ b/src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.js @@ -0,0 +1,14 @@ +const resetDisplayListViewBorderWhenBlur = (event, containerRef, setDisplayListViewBorder) => { + // The related target check is required here + // because without it when we select an option, the onBlur will still trigger setting displayListViewBorder to false + // it will make the auto complete component re-render before onPress is called making selecting an option not working. + if (containerRef.current && event.target && containerRef.current.contains(event.relatedTarget)) { + return; + } + setDisplayListViewBorder(false); +}; + +resetDisplayListViewBorderWhenBlur.displayName = 'resetDisplayListViewBorderWhenBlur'; + +export default resetDisplayListViewBorderWhenBlur; + diff --git a/src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.native.js b/src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.native.js new file mode 100644 index 000000000000..aaef369af85b --- /dev/null +++ b/src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.native.js @@ -0,0 +1,10 @@ +const resetDisplayListViewBorderWhenBlur = (event, containerRef, setDisplayListViewBorder) => { + // The related target check is not required here because in native there is no race condition rendering like on the web + // onPress still called when cliking the option + setDisplayListViewBorder(false); +}; + +resetDisplayListViewBorderWhenBlur.displayName = 'resetDisplayListViewBorderWhenBlur'; + +export default resetDisplayListViewBorderWhenBlur; + diff --git a/src/pages/ReimbursementAccount/AddressForm.js b/src/pages/ReimbursementAccount/AddressForm.js index 997ed10d2b4f..008915d2e254 100644 --- a/src/pages/ReimbursementAccount/AddressForm.js +++ b/src/pages/ReimbursementAccount/AddressForm.js @@ -2,10 +2,10 @@ import React from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import TextInput from '../../components/TextInput'; -import AddressSearch from '../../components/AddressSearch'; import styles from '../../styles/styles'; import CONST from '../../CONST'; import StatePicker from '../../components/StatePicker'; +import AddressSearch from '../../components/AddressSearch/AddressSearch'; const propTypes = { diff --git a/src/pages/settings/Payments/AddDebitCardPage.js b/src/pages/settings/Payments/AddDebitCardPage.js index a8862154221a..ec76db28b10b 100644 --- a/src/pages/settings/Payments/AddDebitCardPage.js +++ b/src/pages/settings/Payments/AddDebitCardPage.js @@ -18,10 +18,10 @@ import StatePicker from '../../../components/StatePicker'; import TextInput from '../../../components/TextInput'; import CONST from '../../../CONST'; import ONYXKEYS from '../../../ONYXKEYS'; -import AddressSearch from '../../../components/AddressSearch'; import * as ComponentUtils from '../../../libs/ComponentUtils'; import Form from '../../../components/Form'; import Permissions from '../../../libs/Permissions'; +import AddressSearch from '../../../components/AddressSearch/AddressSearch'; const propTypes = { /* Onyx Props */ diff --git a/src/pages/settings/Profile/PersonalDetails/AddressPage.js b/src/pages/settings/Profile/PersonalDetails/AddressPage.js index b594cd09f3a1..5a6295c4363d 100644 --- a/src/pages/settings/Profile/PersonalDetails/AddressPage.js +++ b/src/pages/settings/Profile/PersonalDetails/AddressPage.js @@ -18,9 +18,9 @@ import Navigation from '../../../../libs/Navigation/Navigation'; import * as PersonalDetails from '../../../../libs/actions/PersonalDetails'; import * as ValidationUtils from '../../../../libs/ValidationUtils'; import compose from '../../../../libs/compose'; -import AddressSearch from '../../../../components/AddressSearch'; import CountryPicker from '../../../../components/CountryPicker'; import StatePicker from '../../../../components/StatePicker'; +import AddressSearch from '../../../../components/AddressSearch/AddressSearch'; const propTypes = { /* Onyx Props */ diff --git a/src/stories/AddressSearch.stories.js b/src/stories/AddressSearch.stories.js index b19d3ac46b3a..dd696890410f 100644 --- a/src/stories/AddressSearch.stories.js +++ b/src/stories/AddressSearch.stories.js @@ -1,5 +1,5 @@ import React, {useState} from 'react'; -import AddressSearch from '../components/AddressSearch'; +import AddressSearch from '../components/AddressSearch/AddressSearch'; /** * We use the Component Story Format for writing stories. Follow the docs here: diff --git a/src/stories/Form.stories.js b/src/stories/Form.stories.js index da684206f204..921852addb8a 100644 --- a/src/stories/Form.stories.js +++ b/src/stories/Form.stories.js @@ -3,7 +3,6 @@ import {View} from 'react-native'; import TextInput from '../components/TextInput'; import Picker from '../components/Picker'; import StatePicker from '../components/StatePicker'; -import AddressSearch from '../components/AddressSearch'; import DatePicker from '../components/DatePicker'; import Form from '../components/Form'; import * as FormActions from '../libs/actions/FormActions'; @@ -11,6 +10,7 @@ import styles from '../styles/styles'; import CheckboxWithLabel from '../components/CheckboxWithLabel'; import Text from '../components/Text'; import NetworkConnection from '../libs/NetworkConnection'; +import AddressSearch from '../components/AddressSearch/AddressSearch'; /** * We use the Component Story Format for writing stories. Follow the docs here: From 192c6e9229fcdf3125f2a32edae7b8edcc3eb6c6 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Apr 2023 10:08:20 +0700 Subject: [PATCH 05/69] fix: remove log --- src/components/AddressSearch/AddressSearch.js | 2 -- src/libs/resetDisplayListViewborderWhenBlur/index.js | 10 ---------- .../resetDisplayListViewborderWhenBlur/index.native.js | 7 ------- 3 files changed, 19 deletions(-) delete mode 100644 src/libs/resetDisplayListViewborderWhenBlur/index.js delete mode 100644 src/libs/resetDisplayListViewborderWhenBlur/index.native.js diff --git a/src/components/AddressSearch/AddressSearch.js b/src/components/AddressSearch/AddressSearch.js index e676f4eb67ea..b2f6c89f0fb3 100644 --- a/src/components/AddressSearch/AddressSearch.js +++ b/src/components/AddressSearch/AddressSearch.js @@ -207,7 +207,6 @@ const AddressSearch = (props) => { suppressDefaultStyles enablePoweredByContainer={false} onPress={(data, details) => { - console.log('onPress'); saveLocationDetails(data, details); // After we select an option, we set displayListViewBorder to false to prevent UI flickering @@ -242,7 +241,6 @@ const AddressSearch = (props) => { inputID: props.inputID, shouldSaveDraft: props.shouldSaveDraft, onBlur: (event) => { - console.log(resetDisplayListViewBorderWhenBlur); resetDisplayListViewBorderWhenBlur(event, containerRef, setDisplayListViewBorder); props.onBlur(event); }, diff --git a/src/libs/resetDisplayListViewborderWhenBlur/index.js b/src/libs/resetDisplayListViewborderWhenBlur/index.js deleted file mode 100644 index af70655eacbc..000000000000 --- a/src/libs/resetDisplayListViewborderWhenBlur/index.js +++ /dev/null @@ -1,10 +0,0 @@ -const resetDisplayListViewborderWhenBlur = (event, containerRef, setDisplayListViewBorder) => { - if (containerRef.current && event.target && containerRef.current.contains(event.relatedTarget)) { - return; - } - setDisplayListViewBorder(false); -}; - -export default { - resetDisplayListViewborderWhenBlur, -}; diff --git a/src/libs/resetDisplayListViewborderWhenBlur/index.native.js b/src/libs/resetDisplayListViewborderWhenBlur/index.native.js deleted file mode 100644 index 789c0cbe2df6..000000000000 --- a/src/libs/resetDisplayListViewborderWhenBlur/index.native.js +++ /dev/null @@ -1,7 +0,0 @@ -const resetDisplayListViewborderWhenBlur = (event, containerRef, setDisplayListViewBorder) => { - setDisplayListViewBorder(false); -}; - -export default { - resetDisplayListViewborderWhenBlur, -}; From 1502b855ef6419bf6af88bf0e26a316d2daf386a Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Apr 2023 18:35:26 +0700 Subject: [PATCH 06/69] fix: rename file --- .../AddressSearch/{AddressSearch.js => index.js} | 4 ++-- .../index.js => resetDisplayListViewBorderOnBlur.js} | 6 +++--- .../resetDisplayListViewBorderOnBlur.native.js | 10 ++++++++++ .../resetDisplayListViewBorderWhenBlur/index.native.js | 10 ---------- src/pages/ReimbursementAccount/AddressForm.js | 2 +- src/pages/settings/Payments/AddDebitCardPage.js | 2 +- .../settings/Profile/PersonalDetails/AddressPage.js | 2 +- src/stories/AddressSearch.stories.js | 2 +- src/stories/Form.stories.js | 2 +- 9 files changed, 20 insertions(+), 20 deletions(-) rename src/components/AddressSearch/{AddressSearch.js => index.js} (98%) rename src/components/AddressSearch/{resetDisplayListViewBorderWhenBlur/index.js => resetDisplayListViewBorderOnBlur.js} (66%) create mode 100644 src/components/AddressSearch/resetDisplayListViewBorderOnBlur.native.js delete mode 100644 src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.native.js diff --git a/src/components/AddressSearch/AddressSearch.js b/src/components/AddressSearch/index.js similarity index 98% rename from src/components/AddressSearch/AddressSearch.js rename to src/components/AddressSearch/index.js index b2f6c89f0fb3..185ac12c3e92 100644 --- a/src/components/AddressSearch/AddressSearch.js +++ b/src/components/AddressSearch/index.js @@ -11,7 +11,7 @@ import TextInput from '../TextInput'; import * as ApiUtils from '../../libs/ApiUtils'; import * as GooglePlacesUtils from '../../libs/GooglePlacesUtils'; import CONST from '../../CONST'; -import resetDisplayListViewBorderWhenBlur from './resetDisplayListViewBorderWhenBlur'; +import resetDisplayListViewBorderOnBlur from './resetDisplayListViewBorderOnBlur'; // The error that's being thrown below will be ignored until we fork the // react-native-google-places-autocomplete repo and replace the @@ -241,7 +241,7 @@ const AddressSearch = (props) => { inputID: props.inputID, shouldSaveDraft: props.shouldSaveDraft, onBlur: (event) => { - resetDisplayListViewBorderWhenBlur(event, containerRef, setDisplayListViewBorder); + resetDisplayListViewBorderOnBlur(event, containerRef, setDisplayListViewBorder); props.onBlur(event); }, autoComplete: 'off', diff --git a/src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.js b/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.js similarity index 66% rename from src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.js rename to src/components/AddressSearch/resetDisplayListViewBorderOnBlur.js index 35dc820d649c..eb79e14e0913 100644 --- a/src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.js +++ b/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.js @@ -1,4 +1,4 @@ -const resetDisplayListViewBorderWhenBlur = (event, containerRef, setDisplayListViewBorder) => { +const resetDisplayListViewBorderOnBlur = (event, containerRef, setDisplayListViewBorder) => { // The related target check is required here // because without it when we select an option, the onBlur will still trigger setting displayListViewBorder to false // it will make the auto complete component re-render before onPress is called making selecting an option not working. @@ -8,7 +8,7 @@ const resetDisplayListViewBorderWhenBlur = (event, containerRef, setDisplayListV setDisplayListViewBorder(false); }; -resetDisplayListViewBorderWhenBlur.displayName = 'resetDisplayListViewBorderWhenBlur'; +resetDisplayListViewBorderOnBlur.displayName = 'resetDisplayListViewBorderOnBlur'; -export default resetDisplayListViewBorderWhenBlur; +export default resetDisplayListViewBorderOnBlur; diff --git a/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.native.js b/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.native.js new file mode 100644 index 000000000000..ab2282cff90d --- /dev/null +++ b/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.native.js @@ -0,0 +1,10 @@ +const resetDisplayListViewBorderOnBlur = (event, containerRef, setDisplayListViewBorder) => { + // The related target check is not required here because in native there is no race condition rendering like on the web + // onPress still called when cliking the option + setDisplayListViewBorder(false); +}; + +resetDisplayListViewBorderOnBlur.displayName = 'resetDisplayListViewBorderOnBlur'; + +export default resetDisplayListViewBorderOnBlur; + diff --git a/src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.native.js b/src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.native.js deleted file mode 100644 index aaef369af85b..000000000000 --- a/src/components/AddressSearch/resetDisplayListViewBorderWhenBlur/index.native.js +++ /dev/null @@ -1,10 +0,0 @@ -const resetDisplayListViewBorderWhenBlur = (event, containerRef, setDisplayListViewBorder) => { - // The related target check is not required here because in native there is no race condition rendering like on the web - // onPress still called when cliking the option - setDisplayListViewBorder(false); -}; - -resetDisplayListViewBorderWhenBlur.displayName = 'resetDisplayListViewBorderWhenBlur'; - -export default resetDisplayListViewBorderWhenBlur; - diff --git a/src/pages/ReimbursementAccount/AddressForm.js b/src/pages/ReimbursementAccount/AddressForm.js index 008915d2e254..9004552ef466 100644 --- a/src/pages/ReimbursementAccount/AddressForm.js +++ b/src/pages/ReimbursementAccount/AddressForm.js @@ -5,7 +5,7 @@ import TextInput from '../../components/TextInput'; import styles from '../../styles/styles'; import CONST from '../../CONST'; import StatePicker from '../../components/StatePicker'; -import AddressSearch from '../../components/AddressSearch/AddressSearch'; +import AddressSearch from '../../components/AddressSearch'; const propTypes = { diff --git a/src/pages/settings/Payments/AddDebitCardPage.js b/src/pages/settings/Payments/AddDebitCardPage.js index ec76db28b10b..6a6799e662f7 100644 --- a/src/pages/settings/Payments/AddDebitCardPage.js +++ b/src/pages/settings/Payments/AddDebitCardPage.js @@ -21,7 +21,7 @@ import ONYXKEYS from '../../../ONYXKEYS'; import * as ComponentUtils from '../../../libs/ComponentUtils'; import Form from '../../../components/Form'; import Permissions from '../../../libs/Permissions'; -import AddressSearch from '../../../components/AddressSearch/AddressSearch'; +import AddressSearch from '../../../components/AddressSearch'; const propTypes = { /* Onyx Props */ diff --git a/src/pages/settings/Profile/PersonalDetails/AddressPage.js b/src/pages/settings/Profile/PersonalDetails/AddressPage.js index 5a6295c4363d..82cc70e9c92d 100644 --- a/src/pages/settings/Profile/PersonalDetails/AddressPage.js +++ b/src/pages/settings/Profile/PersonalDetails/AddressPage.js @@ -20,7 +20,7 @@ import * as ValidationUtils from '../../../../libs/ValidationUtils'; import compose from '../../../../libs/compose'; import CountryPicker from '../../../../components/CountryPicker'; import StatePicker from '../../../../components/StatePicker'; -import AddressSearch from '../../../../components/AddressSearch/AddressSearch'; +import AddressSearch from '../../../../components/AddressSearch'; const propTypes = { /* Onyx Props */ diff --git a/src/stories/AddressSearch.stories.js b/src/stories/AddressSearch.stories.js index dd696890410f..b19d3ac46b3a 100644 --- a/src/stories/AddressSearch.stories.js +++ b/src/stories/AddressSearch.stories.js @@ -1,5 +1,5 @@ import React, {useState} from 'react'; -import AddressSearch from '../components/AddressSearch/AddressSearch'; +import AddressSearch from '../components/AddressSearch'; /** * We use the Component Story Format for writing stories. Follow the docs here: diff --git a/src/stories/Form.stories.js b/src/stories/Form.stories.js index 921852addb8a..8770dbbce309 100644 --- a/src/stories/Form.stories.js +++ b/src/stories/Form.stories.js @@ -10,7 +10,7 @@ import styles from '../styles/styles'; import CheckboxWithLabel from '../components/CheckboxWithLabel'; import Text from '../components/Text'; import NetworkConnection from '../libs/NetworkConnection'; -import AddressSearch from '../components/AddressSearch/AddressSearch'; +import AddressSearch from '../components/AddressSearch'; /** * We use the Component Story Format for writing stories. Follow the docs here: From 7a3ea9ab60df64a5f2be5a328d1822aad7405663 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Apr 2023 18:39:00 +0700 Subject: [PATCH 07/69] fix: remove redundant change --- src/pages/ReimbursementAccount/AddressForm.js | 2 +- src/pages/settings/Payments/AddDebitCardPage.js | 2 +- src/pages/settings/Profile/PersonalDetails/AddressPage.js | 2 +- src/stories/Form.stories.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/ReimbursementAccount/AddressForm.js b/src/pages/ReimbursementAccount/AddressForm.js index 9004552ef466..997ed10d2b4f 100644 --- a/src/pages/ReimbursementAccount/AddressForm.js +++ b/src/pages/ReimbursementAccount/AddressForm.js @@ -2,10 +2,10 @@ import React from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import TextInput from '../../components/TextInput'; +import AddressSearch from '../../components/AddressSearch'; import styles from '../../styles/styles'; import CONST from '../../CONST'; import StatePicker from '../../components/StatePicker'; -import AddressSearch from '../../components/AddressSearch'; const propTypes = { diff --git a/src/pages/settings/Payments/AddDebitCardPage.js b/src/pages/settings/Payments/AddDebitCardPage.js index 6a6799e662f7..a8862154221a 100644 --- a/src/pages/settings/Payments/AddDebitCardPage.js +++ b/src/pages/settings/Payments/AddDebitCardPage.js @@ -18,10 +18,10 @@ import StatePicker from '../../../components/StatePicker'; import TextInput from '../../../components/TextInput'; import CONST from '../../../CONST'; import ONYXKEYS from '../../../ONYXKEYS'; +import AddressSearch from '../../../components/AddressSearch'; import * as ComponentUtils from '../../../libs/ComponentUtils'; import Form from '../../../components/Form'; import Permissions from '../../../libs/Permissions'; -import AddressSearch from '../../../components/AddressSearch'; const propTypes = { /* Onyx Props */ diff --git a/src/pages/settings/Profile/PersonalDetails/AddressPage.js b/src/pages/settings/Profile/PersonalDetails/AddressPage.js index 82cc70e9c92d..b594cd09f3a1 100644 --- a/src/pages/settings/Profile/PersonalDetails/AddressPage.js +++ b/src/pages/settings/Profile/PersonalDetails/AddressPage.js @@ -18,9 +18,9 @@ import Navigation from '../../../../libs/Navigation/Navigation'; import * as PersonalDetails from '../../../../libs/actions/PersonalDetails'; import * as ValidationUtils from '../../../../libs/ValidationUtils'; import compose from '../../../../libs/compose'; +import AddressSearch from '../../../../components/AddressSearch'; import CountryPicker from '../../../../components/CountryPicker'; import StatePicker from '../../../../components/StatePicker'; -import AddressSearch from '../../../../components/AddressSearch'; const propTypes = { /* Onyx Props */ diff --git a/src/stories/Form.stories.js b/src/stories/Form.stories.js index 8770dbbce309..da684206f204 100644 --- a/src/stories/Form.stories.js +++ b/src/stories/Form.stories.js @@ -3,6 +3,7 @@ import {View} from 'react-native'; import TextInput from '../components/TextInput'; import Picker from '../components/Picker'; import StatePicker from '../components/StatePicker'; +import AddressSearch from '../components/AddressSearch'; import DatePicker from '../components/DatePicker'; import Form from '../components/Form'; import * as FormActions from '../libs/actions/FormActions'; @@ -10,7 +11,6 @@ import styles from '../styles/styles'; import CheckboxWithLabel from '../components/CheckboxWithLabel'; import Text from '../components/Text'; import NetworkConnection from '../libs/NetworkConnection'; -import AddressSearch from '../components/AddressSearch'; /** * We use the Component Story Format for writing stories. Follow the docs here: From ceace1449aa5e2593349a26181c492dfccd3a794 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Apr 2023 21:57:35 +0700 Subject: [PATCH 08/69] fix: remove redundant change --- src/components/AddressSearch/index.js | 2 +- .../AddressSearch/resetDisplayListViewBorderOnBlur.js | 6 ++---- .../resetDisplayListViewBorderOnBlur.native.js | 6 ++---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 185ac12c3e92..5b3db865a072 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -242,7 +242,7 @@ const AddressSearch = (props) => { shouldSaveDraft: props.shouldSaveDraft, onBlur: (event) => { resetDisplayListViewBorderOnBlur(event, containerRef, setDisplayListViewBorder); - props.onBlur(event); + props.onBlur(); }, autoComplete: 'off', onInputChange: (text) => { diff --git a/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.js b/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.js index eb79e14e0913..b0e7c3fe65ad 100644 --- a/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.js +++ b/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.js @@ -1,4 +1,4 @@ -const resetDisplayListViewBorderOnBlur = (event, containerRef, setDisplayListViewBorder) => { +function resetDisplayListViewBorderOnBlur(event, containerRef, setDisplayListViewBorder) { // The related target check is required here // because without it when we select an option, the onBlur will still trigger setting displayListViewBorder to false // it will make the auto complete component re-render before onPress is called making selecting an option not working. @@ -6,9 +6,7 @@ const resetDisplayListViewBorderOnBlur = (event, containerRef, setDisplayListVie return; } setDisplayListViewBorder(false); -}; - -resetDisplayListViewBorderOnBlur.displayName = 'resetDisplayListViewBorderOnBlur'; +} export default resetDisplayListViewBorderOnBlur; diff --git a/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.native.js b/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.native.js index ab2282cff90d..e95f1f9c2550 100644 --- a/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.native.js +++ b/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.native.js @@ -1,10 +1,8 @@ -const resetDisplayListViewBorderOnBlur = (event, containerRef, setDisplayListViewBorder) => { +function resetDisplayListViewBorderOnBlur(setDisplayListViewBorder) { // The related target check is not required here because in native there is no race condition rendering like on the web // onPress still called when cliking the option setDisplayListViewBorder(false); -}; - -resetDisplayListViewBorderOnBlur.displayName = 'resetDisplayListViewBorderOnBlur'; +} export default resetDisplayListViewBorderOnBlur; From 245761824eaefec3a18de78ba47bf671038f75e8 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Apr 2023 22:03:13 +0700 Subject: [PATCH 09/69] fix: change the order of params --- src/components/AddressSearch/index.js | 2 +- .../AddressSearch/resetDisplayListViewBorderOnBlur.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 5b3db865a072..afce1f66bc8f 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -241,7 +241,7 @@ const AddressSearch = (props) => { inputID: props.inputID, shouldSaveDraft: props.shouldSaveDraft, onBlur: (event) => { - resetDisplayListViewBorderOnBlur(event, containerRef, setDisplayListViewBorder); + resetDisplayListViewBorderOnBlur(setDisplayListViewBorder, event, containerRef); props.onBlur(); }, autoComplete: 'off', diff --git a/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.js b/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.js index b0e7c3fe65ad..a4ebdcf5d8c1 100644 --- a/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.js +++ b/src/components/AddressSearch/resetDisplayListViewBorderOnBlur.js @@ -1,4 +1,4 @@ -function resetDisplayListViewBorderOnBlur(event, containerRef, setDisplayListViewBorder) { +function resetDisplayListViewBorderOnBlur(setDisplayListViewBorder, event, containerRef) { // The related target check is required here // because without it when we select an option, the onBlur will still trigger setting displayListViewBorder to false // it will make the auto complete component re-render before onPress is called making selecting an option not working. From 1ea1f7a0863ddd3efed8d69abb979f462f82d500 Mon Sep 17 00:00:00 2001 From: David Bondy Date: Fri, 14 Apr 2023 16:50:50 -0600 Subject: [PATCH 10/69] import hook methods and create new state/ref variables --- .../Profile/Contacts/NewContactMethodPage.js | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/pages/settings/Profile/Contacts/NewContactMethodPage.js b/src/pages/settings/Profile/Contacts/NewContactMethodPage.js index 70e0860feb95..e32380f08015 100644 --- a/src/pages/settings/Profile/Contacts/NewContactMethodPage.js +++ b/src/pages/settings/Profile/Contacts/NewContactMethodPage.js @@ -1,4 +1,4 @@ -import React, {Component} from 'react'; +import React, {useCallback, useRef, useState} from 'react'; import PropTypes from 'prop-types'; import {View} from 'react-native'; import {ScrollView} from 'react-native-gesture-handler'; @@ -52,22 +52,10 @@ const defaultProps = { loginList: {}, }; -class NewContactMethodPage extends Component { - constructor(props) { - super(props); - - this.state = { - login: '', - password: '', - }; - this.onLoginChange = this.onLoginChange.bind(this); - this.validateForm = this.validateForm.bind(this); - this.submitForm = this.submitForm.bind(this); - } - - onLoginChange(login) { - this.setState({login}); - } +function NewContactMethodPage(props) { + const [login, setLogin] = useState(''); + const [password, setPassword] = useState(''); + const loginInputRef = useRef(null); /** * Determine whether the form is valid From 2cd76d101abbd2ab191c198d5d6f1dba72d3dc9a Mon Sep 17 00:00:00 2001 From: David Bondy Date: Fri, 14 Apr 2023 16:52:13 -0600 Subject: [PATCH 11/69] port methods to new format --- .../Profile/Contacts/NewContactMethodPage.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/pages/settings/Profile/Contacts/NewContactMethodPage.js b/src/pages/settings/Profile/Contacts/NewContactMethodPage.js index e32380f08015..dd3d6e377801 100644 --- a/src/pages/settings/Profile/Contacts/NewContactMethodPage.js +++ b/src/pages/settings/Profile/Contacts/NewContactMethodPage.js @@ -62,22 +62,21 @@ function NewContactMethodPage(props) { * * @returns {Boolean} */ - validateForm() { - const login = this.state.login.trim(); - const phoneLogin = LoginUtils.getPhoneNumberWithoutSpecialChars(login); + const validateForm = useCallback(() => { + const phoneLogin = LoginUtils.getPhoneNumberWithoutSpecialChars(login.trim()); - return (Permissions.canUsePasswordlessLogins(this.props.betas) || this.state.password) + return (Permissions.canUsePasswordlessLogins(props.betas) || this.state.password) && (Str.isValidEmail(login) || Str.isValidPhone(phoneLogin)); - } + }, [login, password, props.betas]); - submitForm() { + const submitForm = useCallback(() => { // If this login already exists, just go back. - if (lodashGet(this.props.loginList, this.state.login)) { + if (lodashGet(props.loginList, login)) { Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHODS); return; } - User.addNewContactMethodAndNavigate(this.state.login, this.state.password); - } + User.addNewContactMethodAndNavigate(login, password); + }, [login, props.loginList, password]); render() { return ( From a7768f0b478f3215727da871f34068c410a394c8 Mon Sep 17 00:00:00 2001 From: David Bondy Date: Fri, 14 Apr 2023 16:52:50 -0600 Subject: [PATCH 12/69] update remaining component body to work with functional component --- .../Profile/Contacts/NewContactMethodPage.js | 104 +++++++++--------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/src/pages/settings/Profile/Contacts/NewContactMethodPage.js b/src/pages/settings/Profile/Contacts/NewContactMethodPage.js index dd3d6e377801..582ff07cbbb8 100644 --- a/src/pages/settings/Profile/Contacts/NewContactMethodPage.js +++ b/src/pages/settings/Profile/Contacts/NewContactMethodPage.js @@ -78,60 +78,58 @@ function NewContactMethodPage(props) { User.addNewContactMethodAndNavigate(login, password); }, [login, props.loginList, password]); - render() { - return ( - { - if (!this.loginInputRef) { - return; - } - this.loginInputRef.focus(); - }} - > - Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHODS)} - onCloseButtonPress={() => Navigation.dismissModal(true)} - /> - - - {this.props.translate('common.pleaseEnterEmailOrPhoneNumber')} - - - this.loginInputRef = el} - value={this.state.login} - onChangeText={this.onLoginChange} - autoCapitalize="none" - returnKeyType={Permissions.canUsePasswordlessLogins(this.props.betas) ? 'done' : 'next'} - /> - - {!Permissions.canUsePasswordlessLogins(this.props.betas) - && ( - - this.setState({password})} - returnKeyType="done" - /> - - )} - - -