Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New places api support #47085

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1322,6 +1322,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',
Expand Down
32 changes: 16 additions & 16 deletions src/components/AddressSearch/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@
lat: 'addressLat',
lng: 'addressLng',
},
resultTypes = 'address',
shouldSaveDraft = false,
value,
locationBias,
Expand All @@ -97,26 +96,25 @@
const containerRef = useRef<View>(null);
const query = useMemo(
() => ({
language: preferredLocale,
types: resultTypes,
components: isLimitedToUSA ? 'country:us' : undefined,
...(locationBias && {locationbias: locationBias}),
languageCode: preferredLocale,
includedRegionCodes: isLimitedToUSA ? ['us'] : undefined,
...(locationBias && {locationBias}),
}),
[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;

Check failure on line 107 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Unsafe assignment of an `any` value

Check failure on line 107 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Unsafe assignment of an `any` value

Check failure on line 107 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Property 'addressComponents' does not exist on type 'GooglePlaceDetail'. Did you mean 'address_components'?
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
// amount of data massaging needs to happen for what the parent expects to get from this function.
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,

Check failure on line 115 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Unsafe assignment of an `any` value

Check failure on line 115 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Unsafe member access .latitude on an `error` typed value

Check failure on line 115 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Unsafe assignment of an `any` value

Check failure on line 115 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Unsafe member access .latitude on an `error` typed value

Check failure on line 115 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Property 'location' does not exist on type 'GooglePlaceDetail'.
lng: details.location?.longitude ?? details.geometry.location?.lng ?? 0,

Check failure on line 116 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Unsafe assignment of an `any` value

Check failure on line 116 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Unsafe member access .longitude on an `error` typed value

Check failure on line 116 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Unsafe assignment of an `any` value

Check failure on line 116 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Unsafe member access .longitude on an `error` typed value

Check failure on line 116 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Property 'location' does not exist on type 'GooglePlaceDetail'.
name: autocompleteData?.structured_formatting?.main_text ?? details?.name ?? '',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

details.name isn't the same as it was in the old API, the format here is places/<id> so not really good to use here. The next closest thing is details?. shortFormattedAddress

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this context, the details.name is not used from old API. Instead, it indicates a predefined option i.e. saved places in our app. So, I think we need to keep
details.name

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what you mean, can you show me? The way I understand this code, the value in autocompleteData.structured_formatting.main_text in the new API is most similar to details.name from the old api. However, details.name is no longer a good fallback, as in the new API, it does not contain a short version of the address, but something else entirely

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what you mean, can you show me?

Please find the test video that demonstrates the use of predefined places. This is the reason why I think we need to keep details.name.

47085-predefined-places.mp4

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm ok. Can you take a look at how this is utilized when changing your address on the profile settings page as well? I wonder if we need different values in the two places.

});
}
return;
Expand All @@ -134,7 +132,7 @@
administrative_area_level_1: state,
administrative_area_level_2: stateFallback,
country: countryPrimary,
} = GooglePlacesUtils.getAddressComponents(addressComponents, {

Check failure on line 135 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Unsafe argument of type `any` assigned to a parameter of type `AddressComponent[]`

Check failure on line 135 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Unsafe argument of type `any` assigned to a parameter of type `AddressComponent[]`
// eslint-disable-next-line @typescript-eslint/naming-convention
street_number: 'long_name',
route: 'long_name',
Expand All @@ -154,7 +152,7 @@

// 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.
const {administrative_area_level_1: longStateName} = GooglePlacesUtils.getAddressComponents(addressComponents, {

Check failure on line 155 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Unsafe argument of type `any` assigned to a parameter of type `AddressComponent[]`

Check failure on line 155 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Unsafe argument of type `any` assigned to a parameter of type `AddressComponent[]`
// eslint-disable-next-line @typescript-eslint/naming-convention
administrative_area_level_1: 'long_name',
});
Expand All @@ -174,7 +172,7 @@

const values = {
street: `${streetNumber} ${streetName}`.trim(),
name: details.name ?? '',
name: autocompleteData?.structured_formatting?.main_text ?? details?.name ?? '',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here as above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

// 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
Expand All @@ -187,9 +185,9 @@
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,

Check failure on line 188 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Unsafe assignment of an `any` value

Check failure on line 188 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Unsafe member access .latitude on an `error` typed value

Check failure on line 188 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Unsafe assignment of an `any` value

Check failure on line 188 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Unsafe member access .latitude on an `error` typed value

Check failure on line 188 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Property 'location' does not exist on type 'GooglePlaceDetail'.
lng: details.location?.longitude ?? details.geometry.location?.lng ?? 0,

Check failure on line 189 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Unsafe assignment of an `any` value

Check failure on line 189 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Unsafe assignment of an `any` value

Check failure on line 189 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Property 'location' does not exist on type 'GooglePlaceDetail'.
address: autocompleteData.description || details.formattedAddress || '',

Check failure on line 190 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Property 'formattedAddress' does not exist on type 'GooglePlaceDetail'. Did you mean 'formatted_address'?
};

// If the address is not in the US, use the full length state name since we're displaying the address's
Expand All @@ -211,9 +209,9 @@

// 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) {

Check failure on line 212 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Property 'adrFormatAddress' does not exist on type 'GooglePlaceDetail'.
const streetAddressRegex = /<span class="street-address">([^<]*)<\/span>/;
const adrAddress = details.adr_address.match(streetAddressRegex);
const adrAddress = details.adrFormatAddress.match(streetAddressRegex);

Check failure on line 214 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Property 'adrFormatAddress' does not exist on type 'GooglePlaceDetail'.
const streetAddressFallback = adrAddress ? adrAddress?.[1] : null;
if (streetAddressFallback) {
values.street = streetAddressFallback;
Expand Down Expand Up @@ -473,6 +471,8 @@
}
placeholder=""
listViewDisplayed
fields={CONST.GOOGLE_PLACES_API.FIELDS_MASK}

Check failure on line 474 in src/components/AddressSearch/index.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Type '{ children: Element; disableScroll: true; fetchDetails: true; suppressDefaultStyles: true; enablePoweredByContainer: false; predefinedPlaces: PredefinedPlace[]; ... 18 more ...; isNewPlacesAPI: true; }' is not assignable to type 'IntrinsicAttributes & GooglePlacesAutocompleteProps & RefAttributes<GooglePlacesAutocompleteRef>'.
isNewPlacesAPI
>
<LocationErrorMessage
onClose={() => setLocationErrorCode(null)}
Expand Down
15 changes: 14 additions & 1 deletion src/components/AddressSearch/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
19 changes: 16 additions & 3 deletions src/hooks/useLocationBias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}
Loading