From 04ea3a82e634b8b751ba0140f95f1d93c1d1a78d Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Wed, 7 Aug 2024 20:36:11 +0530 Subject: [PATCH 1/9] new places api support --- src/CONST.ts | 4 ++++ src/components/AddressSearch/index.tsx | 32 +++++++++++++------------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index ed4de999c78c..e21e3be55efe 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1189,6 +1189,10 @@ const CONST = { YOUR_LOCATION_TEXT: 'Your Location', + GOOGLE_PLACES_API: { + FIELDS_MASK: 'id,name,addressComponents,adrFormatAddress,formattedAddress,location,plusCode,shortFormattedAddress,types,viewport', + }, + ATTACHMENT_MESSAGE_TEXT: '[Attachment]', ATTACHMENT_SOURCE_ATTRIBUTE: 'data-expensify-source', ATTACHMENT_OPTIMISTIC_SOURCE_ATTRIBUTE: 'data-optimistic-src', diff --git a/src/components/AddressSearch/index.tsx b/src/components/AddressSearch/index.tsx index c7753dccadd7..778fd69766c7 100644 --- a/src/components/AddressSearch/index.tsx +++ b/src/components/AddressSearch/index.tsx @@ -74,7 +74,6 @@ function AddressSearch( lat: 'addressLat', lng: 'addressLng', }, - resultTypes = 'address', shouldSaveDraft = false, value, locationBias, @@ -97,16 +96,16 @@ function AddressSearch( const containerRef = useRef(null); const query = useMemo( () => ({ - language: preferredLocale, - types: resultTypes, - components: isLimitedToUSA ? 'country:us' : undefined, - ...(locationBias && {locationbias: locationBias}), + languageCode: preferredLocale, + includedRegionCodes: isLimitedToUSA ? ['us'] : undefined, + ...(locationBias && {locationBias}), + fields: CONST.GOOGLE_PLACES_API.FIELDS_MASK, }), - [preferredLocale, resultTypes, isLimitedToUSA, locationBias], + [preferredLocale, isLimitedToUSA, locationBias], ); const shouldShowCurrentLocationButton = canUseCurrentLocation && searchValue.trim().length === 0 && isFocused; const saveLocationDetails = (autocompleteData: GooglePlaceData, details: GooglePlaceDetail | null) => { - const addressComponents = details?.address_components; + const addressComponents = details?.addressComponents; if (!addressComponents) { // When there are details, but no address_components, this indicates that some predefined options have been passed // to this component which don't match the usual properties coming from auto-complete. In that case, only a limited @@ -114,9 +113,9 @@ function AddressSearch( if (details) { onPress?.({ address: autocompleteData.description ?? '', - lat: details.geometry.location.lat ?? 0, - lng: details.geometry.location.lng ?? 0, - name: details.name, + lat: details.location?.latitude ?? details.geometry.location?.lat ?? 0, + lng: details.location?.longitude ?? details.geometry.location?.lng ?? 0, + name: autocompleteData?.structured_formatting?.main_text ?? details?.name ?? '', }); } return; @@ -174,7 +173,7 @@ function AddressSearch( const values = { street: `${streetNumber} ${streetName}`.trim(), - name: details.name ?? '', + name: autocompleteData?.structured_formatting?.main_text ?? details?.name ?? '', // Autocomplete returns any additional valid address fragments (e.g. Apt #) as subpremise. street2: subpremise, // Make sure country is updated first, since city and state will be reset if the country changes @@ -187,9 +186,9 @@ function AddressSearch( city: locality || postalTown || sublocality || cityAutocompleteFallback, zipCode, - lat: details.geometry.location.lat ?? 0, - lng: details.geometry.location.lng ?? 0, - address: autocompleteData.description || details.formatted_address || '', + lat: details.location?.latitude ?? details.geometry.location?.lat ?? 0, + lng: details.location?.longitude ?? details.geometry.location?.lng ?? 0, + address: autocompleteData.description || details.formattedAddress || '', }; // If the address is not in the US, use the full length state name since we're displaying the address's @@ -211,9 +210,9 @@ function AddressSearch( // Some edge-case addresses may lack both street_number and route in the API response, resulting in an empty "values.street" // We are setting up a fallback to ensure "values.street" is populated with a relevant value - if (!values.street && details.adr_address) { + if (!values.street && details.adrFormatAddress) { const streetAddressRegex = /([^<]*)<\/span>/; - const adrAddress = details.adr_address.match(streetAddressRegex); + const adrAddress = details.adrFormatAddress.match(streetAddressRegex); const streetAddressFallback = adrAddress ? adrAddress?.[1] : null; if (streetAddressFallback) { values.street = streetAddressFallback; @@ -474,6 +473,7 @@ function AddressSearch( } placeholder="" listViewDisplayed + isNewPlacesAPI > setLocationErrorCode(null)} From 6425853eadcd8a6c19a183217d97c102219b7416 Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Thu, 8 Aug 2024 08:48:39 +0530 Subject: [PATCH 2/9] pass fields as property --- src/components/AddressSearch/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddressSearch/index.tsx b/src/components/AddressSearch/index.tsx index 778fd69766c7..579c68d552b2 100644 --- a/src/components/AddressSearch/index.tsx +++ b/src/components/AddressSearch/index.tsx @@ -99,7 +99,6 @@ function AddressSearch( languageCode: preferredLocale, includedRegionCodes: isLimitedToUSA ? ['us'] : undefined, ...(locationBias && {locationBias}), - fields: CONST.GOOGLE_PLACES_API.FIELDS_MASK, }), [preferredLocale, isLimitedToUSA, locationBias], ); @@ -473,6 +472,7 @@ function AddressSearch( } placeholder="" listViewDisplayed + fields={CONST.GOOGLE_PLACES_API.FIELDS_MASK} isNewPlacesAPI > Date: Sat, 21 Sep 2024 06:41:13 +0530 Subject: [PATCH 3/9] update rectangle object for locationbias --- src/components/AddressSearch/types.ts | 15 ++++++++++++++- src/hooks/useLocationBias.ts | 19 ++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/components/AddressSearch/types.ts b/src/components/AddressSearch/types.ts index b654fcad99da..04ab14eb371c 100644 --- a/src/components/AddressSearch/types.ts +++ b/src/components/AddressSearch/types.ts @@ -27,6 +27,19 @@ type PredefinedPlace = Place & { name?: string; }; +type LocationBias = { + rectangle: { + low: { + latitude: number, + longitude: number, + }, + high: { + latitude: number, + longitude: number, + } + } +}; + type AddressSearchProps = { /** The ID used to uniquely identify the input in a Form */ inputID?: string; @@ -83,7 +96,7 @@ type AddressSearchProps = { resultTypes?: string; /** Location bias for querying search results. */ - locationBias?: string; + locationBias?: LocationBias | undefined; /** The user's preferred locale e.g. 'en', 'es-ES' */ preferredLocale?: Locale; diff --git a/src/hooks/useLocationBias.ts b/src/hooks/useLocationBias.ts index e18aba4a907c..1a56db673f57 100644 --- a/src/hooks/useLocationBias.ts +++ b/src/hooks/useLocationBias.ts @@ -48,8 +48,21 @@ export default function useLocationBias(allWaypoints: WaypointCollection, userLo const north = maxLat < 90 ? maxLat : 90; const east = maxLng < 180 ? maxLng : 180; - // Format: rectangle:south,west|north,east - const rectFormat = `rectangle:${south},${west}|${north},${east}`; - return rectFormat; + if(latitudes.length === 0 || longitudes.length === 0) { + return undefined; + } + const rectangularBoundary = { + rectangle: { + low: { + latitude: south, + longitude: west, + }, + high: { + latitude: north, + longitude: east, + } + } + }; + return rectangularBoundary; }, [userLocation, allWaypoints]); } From ae0ef58a311784daa3ad70e517eef4fecc414752 Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Thu, 3 Oct 2024 18:29:36 +0530 Subject: [PATCH 4/9] using longText and shortText + prettier fix --- src/components/AddressSearch/index.tsx | 24 +- src/components/AddressSearch/types.ts | 14 +- src/hooks/useLocationBias.ts | 6 +- src/libs/GooglePlacesUtils.ts | 10 +- .../perf-test/GooglePlacesUtils.perf-test.ts | 232 +++++++++--------- tests/unit/GooglePlacesUtilsTest.ts | 56 ++--- 6 files changed, 170 insertions(+), 172 deletions(-) diff --git a/src/components/AddressSearch/index.tsx b/src/components/AddressSearch/index.tsx index 712c364b646f..a9243c7c49f7 100644 --- a/src/components/AddressSearch/index.tsx +++ b/src/components/AddressSearch/index.tsx @@ -135,27 +135,27 @@ function AddressSearch( country: countryPrimary, } = GooglePlacesUtils.getAddressComponents(addressComponents, { // eslint-disable-next-line @typescript-eslint/naming-convention - street_number: 'long_name', - route: 'long_name', - subpremise: 'long_name', - locality: 'long_name', - sublocality: 'long_name', + street_number: 'longText', + route: 'longText', + subpremise: 'longText', + locality: 'longText', + sublocality: 'longText', // eslint-disable-next-line @typescript-eslint/naming-convention - postal_town: 'long_name', + postal_town: 'longText', // eslint-disable-next-line @typescript-eslint/naming-convention - postal_code: 'long_name', + postal_code: 'longText', // eslint-disable-next-line @typescript-eslint/naming-convention - administrative_area_level_1: 'short_name', + administrative_area_level_1: 'shortText', // eslint-disable-next-line @typescript-eslint/naming-convention - administrative_area_level_2: 'long_name', - country: 'short_name', + administrative_area_level_2: 'longText', + country: 'shortText', }); // The state's iso code (short_name) is needed for the StatePicker component but we also - // need the state's full name (long_name) when we render the state in a TextInput. + // need the state's full name (longText) when we render the state in a TextInput. const {administrative_area_level_1: longStateName} = GooglePlacesUtils.getAddressComponents(addressComponents, { // eslint-disable-next-line @typescript-eslint/naming-convention - administrative_area_level_1: 'long_name', + administrative_area_level_1: 'longText', }); // Make sure that the order of keys remains such that the country is always set above the state. diff --git a/src/components/AddressSearch/types.ts b/src/components/AddressSearch/types.ts index 04ab14eb371c..f9979d310b65 100644 --- a/src/components/AddressSearch/types.ts +++ b/src/components/AddressSearch/types.ts @@ -30,14 +30,14 @@ type PredefinedPlace = Place & { type LocationBias = { rectangle: { low: { - latitude: number, - longitude: number, - }, + latitude: number; + longitude: number; + }; high: { - latitude: number, - longitude: number, - } - } + latitude: number; + longitude: number; + }; + }; }; type AddressSearchProps = { diff --git a/src/hooks/useLocationBias.ts b/src/hooks/useLocationBias.ts index 1a56db673f57..4c8d5bb1df53 100644 --- a/src/hooks/useLocationBias.ts +++ b/src/hooks/useLocationBias.ts @@ -48,7 +48,7 @@ export default function useLocationBias(allWaypoints: WaypointCollection, userLo const north = maxLat < 90 ? maxLat : 90; const east = maxLng < 180 ? maxLng : 180; - if(latitudes.length === 0 || longitudes.length === 0) { + if (latitudes.length === 0 || longitudes.length === 0) { return undefined; } const rectangularBoundary = { @@ -60,8 +60,8 @@ export default function useLocationBias(allWaypoints: WaypointCollection, userLo high: { latitude: north, longitude: east, - } - } + }, + }, }; return rectangularBoundary; }, [userLocation, allWaypoints]); diff --git a/src/libs/GooglePlacesUtils.ts b/src/libs/GooglePlacesUtils.ts index 312a0dc61c1f..6128d9f13223 100644 --- a/src/libs/GooglePlacesUtils.ts +++ b/src/libs/GooglePlacesUtils.ts @@ -1,8 +1,6 @@ type AddressComponent = { - // eslint-disable-next-line @typescript-eslint/naming-convention - long_name: string; - // eslint-disable-next-line @typescript-eslint/naming-convention - short_name: string; + longText: string; + shortText: string; types: string[]; }; type FieldsToExtract = Record>; @@ -11,8 +9,8 @@ type FieldsToExtract = Record>; * Finds an address component by type, and returns the value associated to key. Each address component object * inside the addressComponents array has the following structure: * [{ - * long_name: "New York", - * short_name: "New York", + * longText: "New York", + * shortText: "New York", * types: [ "locality", "political" ] * }] */ diff --git a/tests/perf-test/GooglePlacesUtils.perf-test.ts b/tests/perf-test/GooglePlacesUtils.perf-test.ts index 1dd64feb23e0..00b5fcb01ec4 100644 --- a/tests/perf-test/GooglePlacesUtils.perf-test.ts +++ b/tests/perf-test/GooglePlacesUtils.perf-test.ts @@ -4,142 +4,142 @@ import * as GooglePlacesUtils from '@src/libs/GooglePlacesUtils'; const addressComponents: GooglePlacesUtils.AddressComponent[] = [ { - long_name: 'Bushwick', - short_name: 'Bushwick', + longText: 'Bushwick', + shortText: 'Bushwick', types: ['neighborhood', 'political'], }, { - long_name: 'Brooklyn', - short_name: 'Brooklyn', + longText: 'Brooklyn', + shortText: 'Brooklyn', types: ['sublocality_level_1', 'sublocality', 'political'], }, { - long_name: 'New York', - short_name: 'NY', + longText: 'New York', + shortText: 'NY', types: ['administrative_area_level_1', 'political'], }, { - long_name: 'United States', - short_name: 'US', + longText: 'United States', + shortText: 'US', types: ['country', 'political'], }, { - long_name: '11206', - short_name: '11206', + longText: '11206', + shortText: '11206', types: ['postal_code'], }, { - long_name: 'United Kingdom', - short_name: 'UK', + longText: 'United Kingdom', + shortText: 'UK', types: ['country', 'political'], }, ]; const bigObjectToFind: GooglePlacesUtils.FieldsToExtract = { - sublocality: 'long_name', - administrative_area_level_1: 'short_name', - postal_code: 'long_name', - 'doesnt-exist': 'long_name', - s1ublocality: 'long_name', - a1dministrative_area_level_1: 'short_name', - p1ostal_code: 'long_name', - '1doesnt-exist': 'long_name', - s2ublocality: 'long_name', - a2dministrative_area_level_1: 'short_name', - p2ostal_code: 'long_name', - '2doesnt-exist': 'long_name', - s3ublocality: 'long_name', - a3dministrative_area_level_1: 'short_name', - p3ostal_code: 'long_name', - '3doesnt-exist': 'long_name', - s4ublocality: 'long_name', - a4dministrative_area_level_1: 'short_name', - p4ostal_code: 'long_name', - '4doesnt-exist': 'long_name', - s5ublocality: 'long_name', - a5dministrative_area_level_1: 'short_name', - p5ostal_code: 'long_name', - '5doesnt-exist': 'long_name', - s6ublocality: 'long_name', - a6dministrative_area_level_1: 'short_name', - p6ostal_code: 'long_name', - '6doesnt-exist': 'long_name', - s7ublocality: 'long_name', - a7dministrative_area_level_1: 'short_name', - p7ostal_code: 'long_name', - '7doesnt-exist': 'long_name', - s8ublocality: 'long_name', - a8dministrative_area_level_1: 'short_name', - p8ostal_code: 'long_name', - '8doesnt-exist': 'long_name', - s9ublocality: 'long_name', - a9dministrative_area_level_1: 'short_name', - p9ostal_code: 'long_name', - '9doesnt-exist': 'long_name', - s10ublocality: 'long_name', - a10dministrative_area_level_1: 'short_name', - p10ostal_code: 'long_name', - '10doesnt-exist': 'long_name', - s11ublocality: 'long_name', - a11dministrative_area_level_1: 'short_name', - p11ostal_code: 'long_name', - '11doesnt-exist': 'long_name', - s12ublocality: 'long_name', - a12dministrative_area_level_1: 'short_name', - p12ostal_code: 'long_name', - '12doesnt-exist': 'long_name', - s13ublocality: 'long_name', - a13dministrative_area_level_1: 'short_name', - p13ostal_code: 'long_name', - '13doesnt-exist': 'long_name', - s14ublocality: 'long_name', - a14dministrative_area_level_1: 'short_name', - p14ostal_code: 'long_name', - '14doesnt-exist': 'long_name', - s15ublocality: 'long_name', - a15dministrative_area_level_1: 'short_name', - p15ostal_code: 'long_name', - '15doesnt-exist': 'long_name', - s16ublocality: 'long_name', - a16dministrative_area_level_1: 'short_name', - p16ostal_code: 'long_name', - '16doesnt-exist': 'long_name', - s17ublocality: 'long_name', - a17dministrative_area_level_1: 'short_name', - p17ostal_code: 'long_name', - '17doesnt-exist': 'long_name', - s18ublocality: 'long_name', - a18dministrative_area_level_1: 'short_name', - p18ostal_code: 'long_name', - '18doesnt-exist': 'long_name', - s19ublocality: 'long_name', - a19dministrative_area_level_1: 'short_name', - p19ostal_code: 'long_name', - '19doesnt-exist': 'long_name', - s20ublocality: 'long_name', - a20dministrative_area_level_1: 'short_name', - p20ostal_code: 'long_name', - '20doesnt-exist': 'long_name', - s21ublocality: 'long_name', - a21dministrative_area_level_1: 'short_name', - p21ostal_code: 'long_name', - '21doesnt-exist': 'long_name', - s22ublocality: 'long_name', - a22dministrative_area_level_1: 'short_name', - p22ostal_code: 'long_name', - '22doesnt-exist': 'long_name', - s23ublocality: 'long_name', - a23dministrative_area_level_1: 'short_name', - p23ostal_code: 'long_name', - '23doesnt-exist': 'long_name', - s24ublocality: 'long_name', - a24dministrative_area_level_1: 'short_name', - p24ostal_code: 'long_name', - '24doesnt-exist': 'long_name', - s25ublocality: 'long_name', - a25dministrative_area_level_1: 'short_name', - p25ostal_code: 'long_name', - '25doesnt-exist': 'long_name', + sublocality: 'longText', + administrative_area_level_1: 'shortText', + postal_code: 'longText', + 'doesnt-exist': 'longText', + s1ublocality: 'longText', + a1dministrative_area_level_1: 'shortText', + p1ostal_code: 'longText', + '1doesnt-exist': 'longText', + s2ublocality: 'longText', + a2dministrative_area_level_1: 'shortText', + p2ostal_code: 'longText', + '2doesnt-exist': 'longText', + s3ublocality: 'longText', + a3dministrative_area_level_1: 'shortText', + p3ostal_code: 'longText', + '3doesnt-exist': 'longText', + s4ublocality: 'longText', + a4dministrative_area_level_1: 'shortText', + p4ostal_code: 'longText', + '4doesnt-exist': 'longText', + s5ublocality: 'longText', + a5dministrative_area_level_1: 'shortText', + p5ostal_code: 'longText', + '5doesnt-exist': 'longText', + s6ublocality: 'longText', + a6dministrative_area_level_1: 'shortText', + p6ostal_code: 'longText', + '6doesnt-exist': 'longText', + s7ublocality: 'longText', + a7dministrative_area_level_1: 'shortText', + p7ostal_code: 'longText', + '7doesnt-exist': 'longText', + s8ublocality: 'longText', + a8dministrative_area_level_1: 'shortText', + p8ostal_code: 'longText', + '8doesnt-exist': 'longText', + s9ublocality: 'longText', + a9dministrative_area_level_1: 'shortText', + p9ostal_code: 'longText', + '9doesnt-exist': 'longText', + s10ublocality: 'longText', + a10dministrative_area_level_1: 'shortText', + p10ostal_code: 'longText', + '10doesnt-exist': 'longText', + s11ublocality: 'longText', + a11dministrative_area_level_1: 'shortText', + p11ostal_code: 'longText', + '11doesnt-exist': 'longText', + s12ublocality: 'longText', + a12dministrative_area_level_1: 'shortText', + p12ostal_code: 'longText', + '12doesnt-exist': 'longText', + s13ublocality: 'longText', + a13dministrative_area_level_1: 'shortText', + p13ostal_code: 'longText', + '13doesnt-exist': 'longText', + s14ublocality: 'longText', + a14dministrative_area_level_1: 'shortText', + p14ostal_code: 'longText', + '14doesnt-exist': 'longText', + s15ublocality: 'longText', + a15dministrative_area_level_1: 'shortText', + p15ostal_code: 'longText', + '15doesnt-exist': 'longText', + s16ublocality: 'longText', + a16dministrative_area_level_1: 'shortText', + p16ostal_code: 'longText', + '16doesnt-exist': 'longText', + s17ublocality: 'longText', + a17dministrative_area_level_1: 'shortText', + p17ostal_code: 'longText', + '17doesnt-exist': 'longText', + s18ublocality: 'longText', + a18dministrative_area_level_1: 'shortText', + p18ostal_code: 'longText', + '18doesnt-exist': 'longText', + s19ublocality: 'longText', + a19dministrative_area_level_1: 'shortText', + p19ostal_code: 'longText', + '19doesnt-exist': 'longText', + s20ublocality: 'longText', + a20dministrative_area_level_1: 'shortText', + p20ostal_code: 'longText', + '20doesnt-exist': 'longText', + s21ublocality: 'longText', + a21dministrative_area_level_1: 'shortText', + p21ostal_code: 'longText', + '21doesnt-exist': 'longText', + s22ublocality: 'longText', + a22dministrative_area_level_1: 'shortText', + p22ostal_code: 'longText', + '22doesnt-exist': 'longText', + s23ublocality: 'longText', + a23dministrative_area_level_1: 'shortText', + p23ostal_code: 'longText', + '23doesnt-exist': 'longText', + s24ublocality: 'longText', + a24dministrative_area_level_1: 'shortText', + p24ostal_code: 'longText', + '24doesnt-exist': 'longText', + s25ublocality: 'longText', + a25dministrative_area_level_1: 'shortText', + p25ostal_code: 'longText', + '25doesnt-exist': 'longText', }; /** diff --git a/tests/unit/GooglePlacesUtilsTest.ts b/tests/unit/GooglePlacesUtilsTest.ts index 9a7649158c8f..dd1b5d3fd234 100644 --- a/tests/unit/GooglePlacesUtilsTest.ts +++ b/tests/unit/GooglePlacesUtilsTest.ts @@ -3,44 +3,44 @@ import * as GooglePlacesUtils from '@src/libs/GooglePlacesUtils'; import type {AddressComponent, AddressTerm, FieldsToExtract} from '@src/libs/GooglePlacesUtils'; const standardObjectToFind: FieldsToExtract = { - sublocality: 'long_name', - administrative_area_level_1: 'short_name', - postal_code: 'long_name', - 'doesnt-exist': 'long_name', + sublocality: 'longText', + administrative_area_level_1: 'shortText', + postal_code: 'longText', + 'doesnt-exist': 'longText', }; const objectWithCountryToFind: FieldsToExtract = { - sublocality: 'long_name', - administrative_area_level_1: 'short_name', - postal_code: 'long_name', - 'doesnt-exist': 'long_name', - country: 'long_name', + sublocality: 'longText', + administrative_area_level_1: 'shortText', + postal_code: 'longText', + 'doesnt-exist': 'longText', + country: 'longText', }; const addressComponents: AddressComponent[] = [ { - long_name: 'Bushwick', - short_name: 'Bushwick', + longText: 'Bushwick', + shortText: 'Bushwick', types: ['neighborhood', 'political'], }, { - long_name: 'Brooklyn', - short_name: 'Brooklyn', + longText: 'Brooklyn', + shortText: 'Brooklyn', types: ['sublocality_level_1', 'sublocality', 'political'], }, { - long_name: 'New York', - short_name: 'NY', + longText: 'New York', + shortText: 'NY', types: ['administrative_area_level_1', 'political'], }, { - long_name: 'United States', - short_name: 'US', + longText: 'United States', + shortText: 'US', types: ['country', 'political'], }, { - long_name: '11206', - short_name: '11206', + longText: '11206', + shortText: '11206', types: ['postal_code'], }, ]; @@ -50,10 +50,10 @@ const autoCompleteTerms: AddressTerm[] = [{value: 'Bangladesh Border Road'}, {va describe('GooglePlacesUtilsTest', () => { describe('getAddressComponents', () => { it('should find address components by type', () => { - expect(GooglePlacesUtils.getAddressComponents(addressComponents, {sublocality: 'long_name'})).toStrictEqual({sublocality: 'Brooklyn'}); - expect(GooglePlacesUtils.getAddressComponents(addressComponents, {administrative_area_level_1: 'short_name'})).toStrictEqual({administrative_area_level_1: 'NY'}); - expect(GooglePlacesUtils.getAddressComponents(addressComponents, {postal_code: 'long_name'})).toStrictEqual({postal_code: '11206'}); - expect(GooglePlacesUtils.getAddressComponents(addressComponents, {'doesnt-exist': 'long_name'})).toStrictEqual({'doesnt-exist': ''}); + expect(GooglePlacesUtils.getAddressComponents(addressComponents, {sublocality: 'longText'})).toStrictEqual({sublocality: 'Brooklyn'}); + expect(GooglePlacesUtils.getAddressComponents(addressComponents, {administrative_area_level_1: 'shortText'})).toStrictEqual({administrative_area_level_1: 'NY'}); + expect(GooglePlacesUtils.getAddressComponents(addressComponents, {postal_code: 'longText'})).toStrictEqual({postal_code: '11206'}); + expect(GooglePlacesUtils.getAddressComponents(addressComponents, {'doesnt-exist': 'longText'})).toStrictEqual({'doesnt-exist': ''}); expect(GooglePlacesUtils.getAddressComponents(addressComponents, standardObjectToFind)).toStrictEqual({ sublocality: 'Brooklyn', administrative_area_level_1: 'NY', @@ -64,11 +64,11 @@ describe('GooglePlacesUtilsTest', () => { }); describe('getAddressComponentsWithCountry', () => { it('should find address components by type', () => { - expect(GooglePlacesUtils.getAddressComponents(addressComponents, {sublocality: 'long_name'})).toStrictEqual({sublocality: 'Brooklyn'}); - expect(GooglePlacesUtils.getAddressComponents(addressComponents, {administrative_area_level_1: 'short_name'})).toStrictEqual({administrative_area_level_1: 'NY'}); - expect(GooglePlacesUtils.getAddressComponents(addressComponents, {postal_code: 'long_name'})).toStrictEqual({postal_code: '11206'}); - expect(GooglePlacesUtils.getAddressComponents(addressComponents, {'doesnt-exist': 'long_name'})).toStrictEqual({'doesnt-exist': ''}); - expect(GooglePlacesUtils.getAddressComponents(addressComponents, {country: 'long_name'})).toStrictEqual({country: 'United States'}); + expect(GooglePlacesUtils.getAddressComponents(addressComponents, {sublocality: 'longText'})).toStrictEqual({sublocality: 'Brooklyn'}); + expect(GooglePlacesUtils.getAddressComponents(addressComponents, {administrative_area_level_1: 'shortText'})).toStrictEqual({administrative_area_level_1: 'NY'}); + expect(GooglePlacesUtils.getAddressComponents(addressComponents, {postal_code: 'longText'})).toStrictEqual({postal_code: '11206'}); + expect(GooglePlacesUtils.getAddressComponents(addressComponents, {'doesnt-exist': 'longText'})).toStrictEqual({'doesnt-exist': ''}); + expect(GooglePlacesUtils.getAddressComponents(addressComponents, {country: 'longText'})).toStrictEqual({country: 'United States'}); expect(GooglePlacesUtils.getAddressComponents(addressComponents, objectWithCountryToFind)).toStrictEqual({ sublocality: 'Brooklyn', administrative_area_level_1: 'NY', From 0c07e99cf98d8a4c4adf073065740974454094e9 Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Fri, 4 Oct 2024 13:22:18 +0530 Subject: [PATCH 5/9] use newer version for the autocomplete library --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 527a293a6a9e..2def3cf85f39 100644 --- a/package.json +++ b/package.json @@ -141,7 +141,7 @@ "react-native-draggable-flatlist": "^4.0.1", "react-native-fs": "^2.20.0", "react-native-gesture-handler": "2.18.0", - "react-native-google-places-autocomplete": "2.5.6", + "react-native-google-places-autocomplete": "2.5.7", "react-native-haptic-feedback": "^2.3.3", "react-native-image-picker": "^7.0.3", "react-native-image-size": "git+https://github.com/Expensify/react-native-image-size#cb392140db4953a283590d7cf93b4d0461baa2a9", From 4379632fa56e79c4df800591ab51b8319703da76 Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Fri, 4 Oct 2024 13:45:19 +0530 Subject: [PATCH 6/9] updated package-lock --- package-lock.json | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 33baf6a35084..8f1907ddf026 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,7 +84,7 @@ "react-native-draggable-flatlist": "^4.0.1", "react-native-fs": "^2.20.0", "react-native-gesture-handler": "2.18.0", - "react-native-google-places-autocomplete": "2.5.6", + "react-native-google-places-autocomplete": "2.5.7", "react-native-haptic-feedback": "^2.3.3", "react-native-image-picker": "^7.0.3", "react-native-image-size": "git+https://github.com/Expensify/react-native-image-size#cb392140db4953a283590d7cf93b4d0461baa2a9", @@ -34528,12 +34528,13 @@ } }, "node_modules/react-native-google-places-autocomplete": { - "version": "2.5.6", + "version": "2.5.7", "license": "MIT", "dependencies": { "lodash.debounce": "^4.0.8", "prop-types": "^15.7.2", - "qs": "~6.9.1" + "qs": "~6.9.1", + "uuid": "^10.0.0" }, "peerDependencies": { "react-native": ">= 0.59" @@ -34549,6 +34550,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/react-native-google-places-autocomplete/node_modules/uuid": { + "version": "10.0.0", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/react-native-haptic-feedback": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/react-native-haptic-feedback/-/react-native-haptic-feedback-2.3.3.tgz", From 18d79b065c38819e784ad827991eab432fa32a9b Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Fri, 4 Oct 2024 18:57:37 +0530 Subject: [PATCH 7/9] lint fix --- src/pages/iou/request/step/IOURequestStepWaypoint.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/iou/request/step/IOURequestStepWaypoint.tsx b/src/pages/iou/request/step/IOURequestStepWaypoint.tsx index 4fad55e8fc4a..651322470ce4 100644 --- a/src/pages/iou/request/step/IOURequestStepWaypoint.tsx +++ b/src/pages/iou/request/step/IOURequestStepWaypoint.tsx @@ -268,6 +268,8 @@ export default withWritableReportOrNotFound( location: { lat: waypoint.lat ?? 0, lng: waypoint.lng ?? 0, + latitude: waypoint.lat ?? 0, + longtitude: waypoint.lng ?? 0, }, }, })), From 8f05d04288bb8dae4cb331280a8c2c7fe36623b3 Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Fri, 4 Oct 2024 19:04:32 +0530 Subject: [PATCH 8/9] ts fix --- src/pages/iou/request/step/IOURequestStepWaypoint.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/iou/request/step/IOURequestStepWaypoint.tsx b/src/pages/iou/request/step/IOURequestStepWaypoint.tsx index 651322470ce4..ede3472865c2 100644 --- a/src/pages/iou/request/step/IOURequestStepWaypoint.tsx +++ b/src/pages/iou/request/step/IOURequestStepWaypoint.tsx @@ -269,7 +269,7 @@ export default withWritableReportOrNotFound( lat: waypoint.lat ?? 0, lng: waypoint.lng ?? 0, latitude: waypoint.lat ?? 0, - longtitude: waypoint.lng ?? 0, + longitude: waypoint.lng ?? 0, }, }, })), From 0ad4459f506120c92eabc2d7a7407342a54ae797 Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Fri, 4 Oct 2024 21:04:59 +0530 Subject: [PATCH 9/9] using useOnyx instead of withOnyx - eslint error fix --- .../request/step/IOURequestStepWaypoint.tsx | 66 +++++++------------ 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepWaypoint.tsx b/src/pages/iou/request/step/IOURequestStepWaypoint.tsx index ede3472865c2..60a09988ebb4 100644 --- a/src/pages/iou/request/step/IOURequestStepWaypoint.tsx +++ b/src/pages/iou/request/step/IOURequestStepWaypoint.tsx @@ -3,7 +3,7 @@ import React, {useMemo, useRef, useState} from 'react'; import type {TextInput} from 'react-native'; import {View} from 'react-native'; import type {Place} from 'react-native-google-places-autocomplete'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import AddressSearch from '@components/AddressSearch'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; @@ -37,26 +37,36 @@ import withFullTransactionOrNotFound from './withFullTransactionOrNotFound'; import type {WithWritableReportOrNotFoundProps} from './withWritableReportOrNotFound'; import withWritableReportOrNotFound from './withWritableReportOrNotFound'; -type IOURequestStepWaypointOnyxProps = { - /** List of recent waypoints */ - recentWaypoints: OnyxEntry; - - userLocation: OnyxEntry; +type IOURequestStepWaypointProps = WithWritableReportOrNotFoundProps & { + transaction: OnyxEntry; }; -type IOURequestStepWaypointProps = IOURequestStepWaypointOnyxProps & - WithWritableReportOrNotFoundProps & { - transaction: OnyxEntry; - }; +const recentWaypointsSelector = (waypoints: OnyxEntry): OnyxEntry => + // Only grab the most recent 20 waypoints because that's all that is shown in the UI. This also puts them into the format of data + // that the google autocomplete component expects for it's "predefined places" feature. + (waypoints ? waypoints.slice(0, CONST.RECENT_WAYPOINTS_NUMBER as number) : []) + .filter((waypoint) => waypoint.keyForList?.includes(CONST.YOUR_LOCATION_TEXT) !== true) + .map((waypoint) => ({ + name: waypoint.name, + description: waypoint.address ?? '', + geometry: { + location: { + lat: waypoint.lat ?? 0, + lng: waypoint.lng ?? 0, + latitude: waypoint.lat ?? 0, + longitude: waypoint.lng ?? 0, + }, + }, + })) as OnyxEntry; function IOURequestStepWaypoint({ route: { params: {action, backTo, iouType, pageIndex, reportID, transactionID}, }, transaction, - recentWaypoints = [], - userLocation, }: IOURequestStepWaypointProps) { + const [userLocation] = useOnyx(ONYXKEYS.USER_LOCATION); + const [recentWaypoints] = useOnyx(ONYXKEYS.NVP_RECENT_WAYPOINTS, {selector: recentWaypointsSelector}); const styles = useThemeStyles(); const {windowWidth} = useWindowDimensions(); const [isDeleteStopModalOpen, setIsDeleteStopModalOpen] = useState(false); @@ -247,34 +257,4 @@ function IOURequestStepWaypoint({ IOURequestStepWaypoint.displayName = 'IOURequestStepWaypoint'; -export default withWritableReportOrNotFound( - withFullTransactionOrNotFound( - withOnyx({ - userLocation: { - key: ONYXKEYS.USER_LOCATION, - }, - recentWaypoints: { - key: ONYXKEYS.NVP_RECENT_WAYPOINTS, - - // Only grab the most recent 20 waypoints because that's all that is shown in the UI. This also puts them into the format of data - // that the google autocomplete component expects for it's "predefined places" feature. - selector: (waypoints) => - (waypoints ? waypoints.slice(0, CONST.RECENT_WAYPOINTS_NUMBER as number) : []) - .filter((waypoint) => waypoint.keyForList?.includes(CONST.YOUR_LOCATION_TEXT) !== true) - .map((waypoint) => ({ - name: waypoint.name, - description: waypoint.address ?? '', - geometry: { - location: { - lat: waypoint.lat ?? 0, - lng: waypoint.lng ?? 0, - latitude: waypoint.lat ?? 0, - longitude: waypoint.lng ?? 0, - }, - }, - })), - }, - })(IOURequestStepWaypoint), - ), - true, -); +export default withWritableReportOrNotFound(withFullTransactionOrNotFound(IOURequestStepWaypoint));