From 2cce1148f9446f87e51f7d635e329b4fd2e9ebf3 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 29 Oct 2021 12:51:41 -0600 Subject: [PATCH 01/18] track view height --- src/components/AddressSearch.js | 110 +++++++++++++++++--------------- 1 file changed, 60 insertions(+), 50 deletions(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index a83534eb05c2..cd7f9aeb7fab 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -1,7 +1,7 @@ import _ from 'underscore'; -import React, {useEffect, useRef} from 'react'; +import React, {useEffect, useState, useRef} from 'react'; import PropTypes from 'prop-types'; -import {LogBox} from 'react-native'; +import {LogBox, View} from 'react-native'; import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete'; import CONFIG from '../CONFIG'; import withLocalize, {withLocalizePropTypes} from './withLocalize'; @@ -37,6 +37,7 @@ const defaultProps = { const AddressSearch = (props) => { const googlePlacesRef = useRef(); + const [display, setDisplay] = useState(false); useEffect(() => { if (!googlePlacesRef.current) { return; @@ -79,55 +80,64 @@ const AddressSearch = (props) => { }; return ( - saveLocationDetails(details)} - query={{ - key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus', - language: props.preferredLocale, - types: 'address', - components: 'country:us', + { + const {height} = event.nativeEvent.layout; + height > 74 ? setDisplay(true) : setDisplay(false);s }} - requestUrl={{ - useOnPlatform: 'web', - url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`, - }} - textInputProps={{ - InputComp: ExpensiTextInput, - label: props.label, - containerStyles: props.containerStyles, - errorText: props.errorText, - onChangeText: (text) => { - const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value); - - // Ensure whether an address is selected already or has address value initialized. - if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) { - saveLocationDetails({}); - } - }, - }} - styles={{ - textInputContainer: [styles.flexColumn], - listView: [ - styles.borderTopRounded, - styles.borderBottomRounded, - styles.mt1, - styles.overflowAuto, - styles.borderLeft, - styles.borderRight, - ], - row: [ - styles.pv4, - styles.ph3, - styles.overflowAuto, - ], - description: [styles.googleSearchText], - separator: [styles.googleSearchSeparator], - }} - /> + > + saveLocationDetails(details)} + query={{ + key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus', + language: props.preferredLocale, + types: 'address', + components: 'country:us', + }} + requestUrl={{ + useOnPlatform: 'web', + url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`, + }} + textInputProps={{ + InputComp: ExpensiTextInput, + label: props.label, + containerStyles: props.containerStyles, + errorText: props.errorText, + onChangeText: (text) => { + const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value); + + // Ensure whether an address is selected already or has address value initialized. + if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) { + saveLocationDetails({}); + } + }, + }} + styles={{ + textInputContainer: [styles.flexColumn], + listView: [ + display && styles.borderTopRounded, + display && styles.borderBottomRounded, + display && styles.mt1, + styles.overflowAuto, + styles.borderLeft, + styles.borderRight, + ], + row: [ + styles.pv4, + styles.ph3, + styles.overflowAuto, + ], + description: [styles.googleSearchText], + separator: [styles.googleSearchSeparator], + }} + /> + ); }; From ac9ba8fee4a0679bcf18d2da0fc56e4ea0105dd3 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 29 Oct 2021 12:52:45 -0600 Subject: [PATCH 02/18] remove char --- src/components/AddressSearch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index cd7f9aeb7fab..6f3871d1bc33 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -85,7 +85,7 @@ const AddressSearch = (props) => { // to prevent a lingering border when there are no address suggestions onLayout={(event) => { const {height} = event.nativeEvent.layout; - height > 74 ? setDisplay(true) : setDisplay(false);s + height > 74 ? setDisplay(true) : setDisplay(false); }} > Date: Fri, 29 Oct 2021 13:41:14 -0600 Subject: [PATCH 03/18] fix style --- src/components/AddressSearch.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 6f3871d1bc33..48bf4adfb021 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -80,12 +80,13 @@ const AddressSearch = (props) => { }; return ( - { const {height} = event.nativeEvent.layout; - height > 74 ? setDisplay(true) : setDisplay(false); + return height > 74 ? setDisplay(true) : setDisplay(false); }} > { errorText: props.errorText, onChangeText: (text) => { const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value); - + // Ensure whether an address is selected already or has address value initialized. if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) { saveLocationDetails({}); From d8e24c7817e828eaf976fa4ab3f44022a53aaad3 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 29 Oct 2021 14:35:53 -0600 Subject: [PATCH 04/18] convert to class component --- src/components/AddressSearch.js | 163 +++++++++++++++++--------------- 1 file changed, 86 insertions(+), 77 deletions(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 48bf4adfb021..816b4540f510 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import React, {useEffect, useState, useRef} from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import {LogBox, View} from 'react-native'; import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete'; @@ -35,18 +35,25 @@ const defaultProps = { containerStyles: null, }; -const AddressSearch = (props) => { - const googlePlacesRef = useRef(); - const [display, setDisplay] = useState(false); - useEffect(() => { - if (!googlePlacesRef.current) { +class AddressSearch extends React.Component { + constructor(props) { + super(props); + + this.state = { + displayDropdownBorder: false, + } + this.googlePlacesRef = React.createRef(); + } + + componentDidMount() { + if (!this.googlePlacesRef.current) { return; } - googlePlacesRef.current.setAddressText(props.value); - }, []); + this.googlePlacesRef.current.setAddressText(this.props.value); + } - const saveLocationDetails = (details) => { + saveLocationDetails(details) { const addressComponents = details.address_components; if (isAddressValidForVBA(addressComponents)) { // Gather the values from the Google details @@ -61,10 +68,10 @@ const AddressSearch = (props) => { const zipCode = getAddressComponent(addressComponents, 'postal_code', 'long_name'); // Trigger text change events for each of the individual fields being saved on the server - props.onChangeText('addressStreet', `${streetNumber} ${streetName}`); - props.onChangeText('addressCity', city); - props.onChangeText('addressState', state); - props.onChangeText('addressZipCode', zipCode); + this.props.onChangeText('addressStreet', `${streetNumber} ${streetName}`); + this.props.onChangeText('addressCity', city); + this.props.onChangeText('addressState', state); + this.props.onChangeText('addressZipCode', zipCode); } else { // Clear the values associated to the address, so our validations catch the problem Log.hmmm('[AddressSearch] Search result failed validation: ', { @@ -72,74 +79,76 @@ const AddressSearch = (props) => { address_components: addressComponents, place_id: details.place_id, }); - props.onChangeText('addressStreet', null); - props.onChangeText('addressCity', null); - props.onChangeText('addressState', null); - props.onChangeText('addressZipCode', null); + this.props.onChangeText('addressStreet', null); + this.props.onChangeText('addressCity', null); + this.props.onChangeText('addressState', null); + this.props.onChangeText('addressZipCode', null); } }; - return ( - - // We use the View height to determine if we should hide the border and margin of the listView dropdown - // to prevent a lingering border when there are no address suggestions - { - const {height} = event.nativeEvent.layout; - return height > 74 ? setDisplay(true) : setDisplay(false); - }} - > - saveLocationDetails(details)} - query={{ - key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus', - language: props.preferredLocale, - types: 'address', - components: 'country:us', - }} - requestUrl={{ - useOnPlatform: 'web', - url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`, - }} - textInputProps={{ - InputComp: ExpensiTextInput, - label: props.label, - containerStyles: props.containerStyles, - errorText: props.errorText, - onChangeText: (text) => { - const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value); - - // Ensure whether an address is selected already or has address value initialized. - if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) { - saveLocationDetails({}); - } - }, - }} - styles={{ - textInputContainer: [styles.flexColumn], - listView: [ - display && styles.borderTopRounded, - display && styles.borderBottomRounded, - display && styles.mt1, - styles.overflowAuto, - styles.borderLeft, - styles.borderRight, - ], - row: [ - styles.pv4, - styles.ph3, - styles.overflowAuto, - ], - description: [styles.googleSearchText], - separator: [styles.googleSearchSeparator], + render() { + return ( + + // We use the View height to determine if we should hide the border and margin of the listView dropdown + // to prevent a lingering border when there are no address suggestions + { + const {height} = event.nativeEvent.layout; + return height > 74 ? this.setState({displayDropdownBorder: true}) : this.setState({displayDropdownBorder: false}); }} - /> - - ); + > + this.saveLocationDetails(details)} + query={{ + key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus', + language: this.props.preferredLocale, + types: 'address', + components: 'country:us', + }} + requestUrl={{ + useOnPlatform: 'web', + url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`, + }} + textInputProps={{ + InputComp: ExpensiTextInput, + label: this.props.label, + containerStyles: this.props.containerStyles, + errorText: this.props.errorText, + onChangeText: (text) => { + const isTextValid = !_.isEmpty(text) && _.isEqual(text, this.props.value); + + // Ensure whether an address is selected already or has address value initialized. + if (!_.isEmpty(this.googlePlacesRef.current.getAddressText()) && !isTextValid) { + this.saveLocationDetails({}); + } + }, + }} + styles={{ + textInputContainer: [styles.flexColumn], + listView: [ + this.state.displayDropdownBorder && styles.borderTopRounded, + this.state.displayDropdownBorder && styles.borderBottomRounded, + this.state.displayDropdownBorder && styles.mt1, + styles.overflowAuto, + styles.borderLeft, + styles.borderRight, + ], + row: [ + styles.pv4, + styles.ph3, + styles.overflowAuto, + ], + description: [styles.googleSearchText], + separator: [styles.googleSearchSeparator], + }} + /> + + ); + } }; AddressSearch.propTypes = propTypes; From 7cf6954292721e90055c903a8556b40e9487c696 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 29 Oct 2021 14:37:22 -0600 Subject: [PATCH 05/18] fix style --- src/components/AddressSearch.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 816b4540f510..c1fdd134af06 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -41,7 +41,7 @@ class AddressSearch extends React.Component { this.state = { displayDropdownBorder: false, - } + }; this.googlePlacesRef = React.createRef(); } @@ -84,11 +84,11 @@ class AddressSearch extends React.Component { this.props.onChangeText('addressState', null); this.props.onChangeText('addressZipCode', null); } - }; + } render() { return ( - + // We use the View height to determine if we should hide the border and margin of the listView dropdown // to prevent a lingering border when there are no address suggestions { const isTextValid = !_.isEmpty(text) && _.isEqual(text, this.props.value); - + // Ensure whether an address is selected already or has address value initialized. if (!_.isEmpty(this.googlePlacesRef.current.getAddressText()) && !isTextValid) { this.saveLocationDetails({}); @@ -149,7 +149,7 @@ class AddressSearch extends React.Component { ); } -}; +} AddressSearch.propTypes = propTypes; AddressSearch.defaultProps = defaultProps; From 3355b5ee69037e2c25509c4543c0b8e0a278fc28 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 29 Oct 2021 14:38:52 -0600 Subject: [PATCH 06/18] rename state variable --- src/components/AddressSearch.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index c1fdd134af06..5f8329fafe37 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -40,7 +40,7 @@ class AddressSearch extends React.Component { super(props); this.state = { - displayDropdownBorder: false, + displayListViewBorder: false, }; this.googlePlacesRef = React.createRef(); } @@ -94,7 +94,7 @@ class AddressSearch extends React.Component { { const {height} = event.nativeEvent.layout; - return height > 74 ? this.setState({displayDropdownBorder: true}) : this.setState({displayDropdownBorder: false}); + return height > 74 ? this.setState({displayListViewBorder: true}) : this.setState({displayListViewBorder: false}); }} > Date: Fri, 29 Oct 2021 14:54:43 -0600 Subject: [PATCH 07/18] componentDidMount to componentDidUpdate --- src/components/AddressSearch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 5f8329fafe37..7bf4162aa385 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -45,7 +45,7 @@ class AddressSearch extends React.Component { this.googlePlacesRef = React.createRef(); } - componentDidMount() { + componentDidUpdate() { if (!this.googlePlacesRef.current) { return; } From bb496a6dd4b230b394eebe86257452c83c4dfc21 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 29 Oct 2021 14:57:15 -0600 Subject: [PATCH 08/18] revert change --- src/components/AddressSearch.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 7bf4162aa385..ac991e1276cb 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -45,10 +45,10 @@ class AddressSearch extends React.Component { this.googlePlacesRef = React.createRef(); } - componentDidUpdate() { - if (!this.googlePlacesRef.current) { - return; - } + componentDidMount() { + // if (!this.googlePlacesRef.current) { + // return; + // } this.googlePlacesRef.current.setAddressText(this.props.value); } From a6862893171dff4173af8dff4c2e3ebcdbfcb587 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 29 Oct 2021 15:17:28 -0600 Subject: [PATCH 09/18] convert to functional component --- src/components/AddressSearch.js | 175 +++++++++++++++----------------- 1 file changed, 83 insertions(+), 92 deletions(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index ac991e1276cb..2ba89e1d1c03 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import React from 'react'; +import React, {useEffect, useState, useRef} from 'react'; import PropTypes from 'prop-types'; import {LogBox, View} from 'react-native'; import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete'; @@ -35,25 +35,18 @@ const defaultProps = { containerStyles: null, }; -class AddressSearch extends React.Component { - constructor(props) { - super(props); - - this.state = { - displayListViewBorder: false, - }; - this.googlePlacesRef = React.createRef(); - } - - componentDidMount() { - // if (!this.googlePlacesRef.current) { - // return; - // } +const AddressSearch = (props) => { + const googlePlacesRef = useRef(); + const [display, setDisplay] = useState(false); + useEffect(() => { + if (!googlePlacesRef.current) { + return; + } - this.googlePlacesRef.current.setAddressText(this.props.value); - } + googlePlacesRef.current.setAddressText(props.value); + }, []); - saveLocationDetails(details) { + const saveLocationDetails = (details) => { const addressComponents = details.address_components; if (isAddressValidForVBA(addressComponents)) { // Gather the values from the Google details @@ -68,10 +61,10 @@ class AddressSearch extends React.Component { const zipCode = getAddressComponent(addressComponents, 'postal_code', 'long_name'); // Trigger text change events for each of the individual fields being saved on the server - this.props.onChangeText('addressStreet', `${streetNumber} ${streetName}`); - this.props.onChangeText('addressCity', city); - this.props.onChangeText('addressState', state); - this.props.onChangeText('addressZipCode', zipCode); + props.onChangeText('addressStreet', `${streetNumber} ${streetName}`); + props.onChangeText('addressCity', city); + props.onChangeText('addressState', state); + props.onChangeText('addressZipCode', zipCode); } else { // Clear the values associated to the address, so our validations catch the problem Log.hmmm('[AddressSearch] Search result failed validation: ', { @@ -79,79 +72,77 @@ class AddressSearch extends React.Component { address_components: addressComponents, place_id: details.place_id, }); - this.props.onChangeText('addressStreet', null); - this.props.onChangeText('addressCity', null); - this.props.onChangeText('addressState', null); - this.props.onChangeText('addressZipCode', null); + props.onChangeText('addressStreet', null); + props.onChangeText('addressCity', null); + props.onChangeText('addressState', null); + props.onChangeText('addressZipCode', null); } - } - - render() { - return ( - - // We use the View height to determine if we should hide the border and margin of the listView dropdown - // to prevent a lingering border when there are no address suggestions - { - const {height} = event.nativeEvent.layout; - return height > 74 ? this.setState({displayListViewBorder: true}) : this.setState({displayListViewBorder: false}); + }; + + return ( + + // We use the View height to determine if we should hide the border and margin of the listView dropdown + // to prevent a lingering border when there are no address suggestions + { + const {height} = event.nativeEvent.layout; + return height > 74 ? setDisplay(true) : setDisplay(false); + }} + > + saveLocationDetails(details)} + query={{ + key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus', + language: props.preferredLocale, + types: 'address', + components: 'country:us', }} - > - this.saveLocationDetails(details)} - query={{ - key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus', - language: this.props.preferredLocale, - types: 'address', - components: 'country:us', - }} - requestUrl={{ - useOnPlatform: 'web', - url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`, - }} - textInputProps={{ - InputComp: ExpensiTextInput, - label: this.props.label, - containerStyles: this.props.containerStyles, - errorText: this.props.errorText, - onChangeText: (text) => { - const isTextValid = !_.isEmpty(text) && _.isEqual(text, this.props.value); - - // Ensure whether an address is selected already or has address value initialized. - if (!_.isEmpty(this.googlePlacesRef.current.getAddressText()) && !isTextValid) { - this.saveLocationDetails({}); - } - }, - }} - styles={{ - textInputContainer: [styles.flexColumn], - listView: [ - this.state.displayListViewBorder && styles.borderTopRounded, - this.state.displayListViewBorder && styles.borderBottomRounded, - this.state.displayListViewBorder && styles.mt1, - styles.overflowAuto, - styles.borderLeft, - styles.borderRight, - ], - row: [ - styles.pv4, - styles.ph3, - styles.overflowAuto, - ], - description: [styles.googleSearchText], - separator: [styles.googleSearchSeparator], - }} - /> - - ); - } -} + requestUrl={{ + useOnPlatform: 'web', + url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`, + }} + textInputProps={{ + InputComp: ExpensiTextInput, + label: props.label, + containerStyles: props.containerStyles, + errorText: props.errorText, + onChangeText: (text) => { + const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value); + + // Ensure whether an address is selected already or has address value initialized. + if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) { + saveLocationDetails({}); + } + }, + }} + styles={{ + textInputContainer: [styles.flexColumn], + listView: [ + display && styles.borderTopRounded, + display && styles.borderBottomRounded, + display && styles.mt1, + styles.overflowAuto, + styles.borderLeft, + styles.borderRight, + ], + row: [ + styles.pv4, + styles.ph3, + styles.overflowAuto, + ], + description: [styles.googleSearchText], + separator: [styles.googleSearchSeparator], + }} + /> + + ); +}; AddressSearch.propTypes = propTypes; AddressSearch.defaultProps = defaultProps; -export default withLocalize(AddressSearch); +export default withLocalize(AddressSearch); \ No newline at end of file From 10746c29c81950425eb0547662ba94969abcc6d2 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 29 Oct 2021 15:22:13 -0600 Subject: [PATCH 10/18] adjust height --- src/components/AddressSearch.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 2ba89e1d1c03..d332872410d6 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -9,6 +9,7 @@ import styles from '../styles/styles'; import ExpensiTextInput from './ExpensiTextInput'; import Log from '../libs/Log'; import {getAddressComponent, isAddressValidForVBA} from '../libs/GooglePlacesUtils'; +import display from '../styles/utilities/display'; // The error that's being thrown below will be ignored until we fork the // react-native-google-places-autocomplete repo and replace the @@ -37,7 +38,7 @@ const defaultProps = { const AddressSearch = (props) => { const googlePlacesRef = useRef(); - const [display, setDisplay] = useState(false); + const [displayListViewBorder, setDisplayListViewBorder] = useState(false); useEffect(() => { if (!googlePlacesRef.current) { return; @@ -82,11 +83,12 @@ const AddressSearch = (props) => { return ( // We use the View height to determine if we should hide the border and margin of the listView dropdown - // to prevent a lingering border when there are no address suggestions + // to prevent a lingering border when there are no address suggestions. + // The height of the input + error message is 94 pixels { const {height} = event.nativeEvent.layout; - return height > 74 ? setDisplay(true) : setDisplay(false); + return height > 94 ? setDisplayListViewBorder(true) : setDisplayListViewBorder(false); }} > { styles={{ textInputContainer: [styles.flexColumn], listView: [ - display && styles.borderTopRounded, - display && styles.borderBottomRounded, - display && styles.mt1, + displayListViewBorder && styles.borderTopRounded, + displayListViewBorder && styles.borderBottomRounded, + displayListViewBorder && styles.mt1, styles.overflowAuto, styles.borderLeft, styles.borderRight, @@ -145,4 +147,4 @@ const AddressSearch = (props) => { AddressSearch.propTypes = propTypes; AddressSearch.defaultProps = defaultProps; -export default withLocalize(AddressSearch); \ No newline at end of file +export default withLocalize(AddressSearch); From bff165e802b8e2327aaa704382b7e25de9fa59ae Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 29 Oct 2021 15:23:42 -0600 Subject: [PATCH 11/18] fix style --- src/components/AddressSearch.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index d332872410d6..739a33201833 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -9,7 +9,6 @@ import styles from '../styles/styles'; import ExpensiTextInput from './ExpensiTextInput'; import Log from '../libs/Log'; import {getAddressComponent, isAddressValidForVBA} from '../libs/GooglePlacesUtils'; -import display from '../styles/utilities/display'; // The error that's being thrown below will be ignored until we fork the // react-native-google-places-autocomplete repo and replace the @@ -83,7 +82,7 @@ const AddressSearch = (props) => { return ( // We use the View height to determine if we should hide the border and margin of the listView dropdown - // to prevent a lingering border when there are no address suggestions. + // to prevent a lingering border when there are no address suggestions. // The height of the input + error message is 94 pixels { From 20a6050bc00fa8d88eff0eacddd5fb77702462b7 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 29 Oct 2021 16:20:30 -0600 Subject: [PATCH 12/18] add comment and adjust height; --- src/components/AddressSearch.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 739a33201833..4f8f7e35af2d 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -35,6 +35,9 @@ const defaultProps = { containerStyles: null, }; +// Do not convert to class component! setAddressText only works in functional components! +// Reference: https://github.com/FaridSafi/react-native-google-places-autocomplete/issues/609#issuecomment-886133839 + const AddressSearch = (props) => { const googlePlacesRef = useRef(); const [displayListViewBorder, setDisplayListViewBorder] = useState(false); @@ -87,7 +90,7 @@ const AddressSearch = (props) => { { const {height} = event.nativeEvent.layout; - return height > 94 ? setDisplayListViewBorder(true) : setDisplayListViewBorder(false); + return height > 112 ? setDisplayListViewBorder(true) : setDisplayListViewBorder(false); }} > Date: Fri, 29 Oct 2021 16:21:17 -0600 Subject: [PATCH 13/18] update comment --- src/components/AddressSearch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 4f8f7e35af2d..63cc2fa7fb9c 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -86,7 +86,7 @@ const AddressSearch = (props) => { // We use the View height to determine if we should hide the border and margin of the listView dropdown // to prevent a lingering border when there are no address suggestions. - // The height of the input + error message is 94 pixels + // The height of the input + wrapped error message is 112 pixels { const {height} = event.nativeEvent.layout; From a018166eb5b8118c72cced68fe2e243a16685396 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 29 Oct 2021 16:22:44 -0600 Subject: [PATCH 14/18] remove line --- src/components/AddressSearch.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 63cc2fa7fb9c..6d60ec64b5c3 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -37,7 +37,6 @@ const defaultProps = { // Do not convert to class component! setAddressText only works in functional components! // Reference: https://github.com/FaridSafi/react-native-google-places-autocomplete/issues/609#issuecomment-886133839 - const AddressSearch = (props) => { const googlePlacesRef = useRef(); const [displayListViewBorder, setDisplayListViewBorder] = useState(false); From 40b428fd779975e2bf1cefce077ecffd9bcdc972 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 1 Nov 2021 10:59:04 -0600 Subject: [PATCH 15/18] move height tracking to google component --- src/components/AddressSearch.js | 123 +++++++++++++++++--------------- 1 file changed, 65 insertions(+), 58 deletions(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 6d60ec64b5c3..a8ba3ff5879c 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -1,7 +1,7 @@ import _ from 'underscore'; import React, {useEffect, useState, useRef} from 'react'; import PropTypes from 'prop-types'; -import {LogBox, View} from 'react-native'; +import {LogBox} from 'react-native'; import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete'; import CONFIG from '../CONFIG'; import withLocalize, {withLocalizePropTypes} from './withLocalize'; @@ -35,7 +35,8 @@ const defaultProps = { containerStyles: null, }; -// Do not convert to class component! setAddressText only works in functional components! +// Do not convert to class component! It's been tried before and presents more challenges than it's worth. +// Relevant thread: https://expensify.slack.com/archives/C03TQ48KC/p1634088400387400 // Reference: https://github.com/FaridSafi/react-native-google-places-autocomplete/issues/609#issuecomment-886133839 const AddressSearch = (props) => { const googlePlacesRef = useRef(); @@ -82,66 +83,72 @@ const AddressSearch = (props) => { }; return ( + { + saveLocationDetails(details); - // We use the View height to determine if we should hide the border and margin of the listView dropdown - // to prevent a lingering border when there are no address suggestions. - // The height of the input + wrapped error message is 112 pixels - { + const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value); + + // Ensure whether an address is selected already or has address value initialized. + if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) { + saveLocationDetails({}); + } + + // If the text is empty, we set displayListViewBorder to false to prevent UI flickering + if (_.isEmpty(text)) { + setDisplayListViewBorder(false); + } + }, + }} + styles={{ + textInputContainer: [styles.flexColumn], + listView: [ + displayListViewBorder && styles.borderTopRounded, + displayListViewBorder && styles.borderBottomRounded, + displayListViewBorder && styles.mt1, + styles.overflowAuto, + styles.borderLeft, + styles.borderRight, + ], + row: [ + styles.pv4, + styles.ph3, + styles.overflowAuto, + ], + description: [styles.googleSearchText], + separator: [styles.googleSearchSeparator], + }} onLayout={(event) => { + // We use the height of the element to determine if we should hide the border of the listView dropdown + // to prevent a lingering border when there are no address suggestions. + // The height of the empty element is 2px (1px height for each top and bottom borders) const {height} = event.nativeEvent.layout; - return height > 112 ? setDisplayListViewBorder(true) : setDisplayListViewBorder(false); + setDisplayListViewBorder(height > 2); }} - > - saveLocationDetails(details)} - query={{ - key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus', - language: props.preferredLocale, - types: 'address', - components: 'country:us', - }} - requestUrl={{ - useOnPlatform: 'web', - url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`, - }} - textInputProps={{ - InputComp: ExpensiTextInput, - label: props.label, - containerStyles: props.containerStyles, - errorText: props.errorText, - onChangeText: (text) => { - const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value); - - // Ensure whether an address is selected already or has address value initialized. - if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) { - saveLocationDetails({}); - } - }, - }} - styles={{ - textInputContainer: [styles.flexColumn], - listView: [ - displayListViewBorder && styles.borderTopRounded, - displayListViewBorder && styles.borderBottomRounded, - displayListViewBorder && styles.mt1, - styles.overflowAuto, - styles.borderLeft, - styles.borderRight, - ], - row: [ - styles.pv4, - styles.ph3, - styles.overflowAuto, - ], - description: [styles.googleSearchText], - separator: [styles.googleSearchSeparator], - }} - /> - + /> ); }; From 191cbbce03f43126b4593ad992f282a77877aa7f Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 1 Nov 2021 12:52:46 -0600 Subject: [PATCH 16/18] remove destructuring --- src/components/AddressSearch.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index a8ba3ff5879c..c9631ccd2709 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -145,8 +145,7 @@ const AddressSearch = (props) => { // We use the height of the element to determine if we should hide the border of the listView dropdown // to prevent a lingering border when there are no address suggestions. // The height of the empty element is 2px (1px height for each top and bottom borders) - const {height} = event.nativeEvent.layout; - setDisplayListViewBorder(height > 2); + setDisplayListViewBorder(event.nativeEvent.layout.height > 2); }} /> ); From 0db98c5b96427341e6de6d5481a1e77424ba67e9 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 1 Nov 2021 13:14:52 -0600 Subject: [PATCH 17/18] remove flickering --- src/components/AddressSearch.js | 1 + src/styles/styles.js | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index c9631ccd2709..158e3829779b 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -126,6 +126,7 @@ const AddressSearch = (props) => { styles={{ textInputContainer: [styles.flexColumn], listView: [ + !displayListViewBorder && styles.googleListView, displayListViewBorder && styles.borderTopRounded, displayListViewBorder && styles.borderBottomRounded, displayListViewBorder && styles.mt1, diff --git a/src/styles/styles.js b/src/styles/styles.js index 4488a4643d4a..39d573fa31a1 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -2108,6 +2108,10 @@ const styles = { fontFamily: fontFamily.GTA, flex: 1, }, + + googleListView: { + transform: [{scale: 0}], + } }; const baseCodeTagStyles = { From 6ecacd572f88b18ad7d96b75dec8493a5bab5a5b Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 1 Nov 2021 13:19:51 -0600 Subject: [PATCH 18/18] fix style --- src/styles/styles.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/styles.js b/src/styles/styles.js index 39d573fa31a1..8ba0faae2143 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -2111,7 +2111,7 @@ const styles = { googleListView: { transform: [{scale: 0}], - } + }, }; const baseCodeTagStyles = {