From c4d5eae9ce86d1b218f7f6415e7ddb1b73ca6864 Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Tue, 19 Dec 2023 13:09:10 +0530 Subject: [PATCH 1/6] draft version with logs --- src/components/AddressSearch/index.js | 10 +- .../request/step/IOURequestStepWaypoint.js | 95 +++++++++++++++++++ 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index d9e4ef2c0f6e..277ecc3fd2b8 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -111,6 +111,9 @@ const propTypes = { /** Information about the network */ network: networkPropTypes.isRequired, + /** location bias based on rectangular format */ + locationBias: PropTypes.string, + ...withLocalizePropTypes, }; @@ -138,6 +141,7 @@ const defaultProps = { maxInputLength: undefined, predefinedPlaces: [], resultTypes: 'address', + locationBias: undefined, }; function AddressSearch({ @@ -162,6 +166,7 @@ function AddressSearch({ shouldSaveDraft, translate, value, + locationBias, }) { const theme = useTheme(); const styles = useThemeStyles(); @@ -179,11 +184,12 @@ function AddressSearch({ language: preferredLocale, types: resultTypes, components: isLimitedToUSA ? 'country:us' : undefined, + locationbias: locationBias ? locationBias : 'ipbias', }), - [preferredLocale, resultTypes, isLimitedToUSA], + [preferredLocale, resultTypes, isLimitedToUSA, locationBias], ); const shouldShowCurrentLocationButton = canUseCurrentLocation && searchValue.trim().length === 0 && isFocused; - + // console.log("AddressSearch:locationBias["+locationBias+"]"); const saveLocationDetails = (autocompleteData, details) => { const addressComponents = details.address_components; if (!addressComponents) { diff --git a/src/pages/iou/request/step/IOURequestStepWaypoint.js b/src/pages/iou/request/step/IOURequestStepWaypoint.js index dc5b9f7d6275..be43d9e2ca89 100644 --- a/src/pages/iou/request/step/IOURequestStepWaypoint.js +++ b/src/pages/iou/request/step/IOURequestStepWaypoint.js @@ -1,5 +1,6 @@ import {useNavigation} from '@react-navigation/native'; import lodashGet from 'lodash/get'; +import lodashIsNil from 'lodash/isNil'; import PropTypes from 'prop-types'; import React, {useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; @@ -38,6 +39,15 @@ const propTypes = { /** The optimistic transaction for this request */ transaction: transactionPropTypes, + /* Current location coordinates of the user*/ + userLocation: PropTypes.shape({ + /** Latitude of the location */ + latitude: PropTypes.number, + + /** Longitude of the location */ + longitude: PropTypes.number, + }), + /** Recent waypoints that the user has selected */ recentWaypoints: PropTypes.arrayOf( PropTypes.shape({ @@ -65,6 +75,7 @@ const propTypes = { const defaultProps = { recentWaypoints: [], transaction: {}, + userLocation: {}, }; function IOURequestStepWaypoint({ @@ -73,6 +84,7 @@ function IOURequestStepWaypoint({ params: {iouType, pageIndex, reportID, transactionID}, }, transaction, + userLocation, }) { const styles = useThemeStyles(); const {windowWidth} = useWindowDimensions(); @@ -83,12 +95,16 @@ function IOURequestStepWaypoint({ const {isOffline} = useNetwork(); const textInput = useRef(null); const parsedWaypointIndex = parseInt(pageIndex, 10); + const directionCoordinates = lodashGet(transaction, 'routes.route0.geometry.coordinates', []); const allWaypoints = lodashGet(transaction, 'comment.waypoints', {}); const currentWaypoint = lodashGet(allWaypoints, `waypoint${pageIndex}`, {}); const waypointCount = _.size(allWaypoints); const filledWaypointCount = _.size(_.filter(allWaypoints, (waypoint) => !_.isEmpty(waypoint))); + const directionCoordinatesSize = _.size(directionCoordinates); + console.log('**** IOUREQUESTSTEPWAYPOINT **** ==> [' + filledWaypointCount + '], directionCoordinatesCount[' + directionCoordinatesSize + ']'); + const waypointDescriptionKey = useMemo(() => { switch (parsedWaypointIndex) { case 0: @@ -100,6 +116,81 @@ function IOURequestStepWaypoint({ } }, [parsedWaypointIndex, waypointCount]); + // Construct the rectangular boundary based on user location, waypoints and direction coordinates + const locationBias = useMemo(() => { + // If there are no filled wayPoints and if user's current location cannot be retrieved, + // it is futile to arrive at a biased location. Let's return + if (filledWaypointCount === 0 && _.isEmpty(userLocation)) { + console.log('Use Case 1: There are no filled waypoints. Also, current location of the user cannot be retrieved. The App will behave like it was before this feature.'); + return null; + } + + // Gather the longitudes and latitudes from filled waypoints. + const longitudes = _.filter( + _.map(allWaypoints, (waypoint) => { + if (!waypoint || lodashIsNil(waypoint.lng)) { + return; + } + return waypoint.lng; + }), + (lng) => lng, + ); + const latitudes = _.filter( + _.map(allWaypoints, (waypoint) => { + if (!waypoint || lodashIsNil(waypoint.lat)) { + return; + } + return waypoint.lat; + }), + (lat) => lat, + ); + + // We will get direction coordinates when user is adding a stop after filling the Start and Finish waypoints. + // Include direction coordinates when available. + if (_.size(directionCoordinates) > 0) { + console.log('Use Case 5: Additional stops after Start and Finish waypoints will give us direction coordinates. Include this to arrive at rectangular boundary'); + console.dir(directionCoordinates); + longitudes.push(..._.map(directionCoordinates, (coordinate) => coordinate[0])); + latitudes.push(..._.map(directionCoordinates, (coordinate) => coordinate[1])); + } + + // When no filled waypoints are available but the current location of the user is available, + // let us consider the current user's location to construct a rectangular bound + if (filledWaypointCount === 0 && !_.isEmpty(userLocation)) { + console.log('Use Case 2: There are no filled waypoints. But, we have the current location of the user. Let us bias location around the current location.'); + longitudes.push(userLocation.longitude); + latitudes.push(userLocation.latitude); + } + + if (filledWaypointCount === 1) { + console.log('Use Case 3: There is exactly one waypoint. Let us bias location around this waypoint: lat[' + latitudes[0] + '],lng[' + longitudes[0] + ']'); + } + + // Extend the rectangular bound by 0.5 degree (roughly around 25-30 miles in US) + const minLat = Math.min(...latitudes) - 0.5; + const minLng = Math.min(...longitudes) - 0.5; + const maxLat = Math.max(...latitudes) + 0.5; + const maxLng = Math.max(...longitudes) + 0.5; + + // Ensuring coordinates do not go out of range. + const south = minLat > -90 ? minLat : -90; + const west = minLng > -180 ? minLng : -180; + const north = maxLat < 90 ? maxLat : 90; + const east = maxLng < 180 ? maxLng : 180; + + const rectFormat = `rectangle:${south},${west}|${north},${east}`; + + if (filledWaypointCount === 2) { + console.log('Use Case 4: There two waypoints. Let us bias location around this waypoint'); + console.dir(latitudes); + console.dir(longitudes); + } + console.log('NEW RECTANGULAR BOUNDARY[' + rectFormat + ']'); + + // Format: rectangle:south,west|north,east + return rectFormat; + }, [userLocation, directionCoordinates, filledWaypointCount]); + const waypointAddress = lodashGet(currentWaypoint, 'address', ''); // Hide the menu when there is only start and finish waypoint const shouldShowThreeDotsButton = waypointCount > 2; @@ -219,6 +310,7 @@ function IOURequestStepWaypoint({ (textInput.current = e)} @@ -257,6 +349,9 @@ export default compose( withWritableReportOrNotFound, withFullTransactionOrNotFound, withOnyx({ + userLocation: { + key: ONYXKEYS.USER_LOCATION, + }, recentWaypoints: { key: ONYXKEYS.NVP_RECENT_WAYPOINTS, From bb6ccfcb7881f87642285d65e67088fd7eaf86e1 Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Wed, 20 Dec 2023 13:33:33 +0530 Subject: [PATCH 2/6] lint fixes --- src/components/AddressSearch/index.js | 3 +-- .../request/step/IOURequestStepWaypoint.js | 25 +++---------------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 277ecc3fd2b8..71ac0edf7958 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -184,12 +184,11 @@ function AddressSearch({ language: preferredLocale, types: resultTypes, components: isLimitedToUSA ? 'country:us' : undefined, - locationbias: locationBias ? locationBias : 'ipbias', + locationbias: locationBias || 'ipbias', }), [preferredLocale, resultTypes, isLimitedToUSA, locationBias], ); const shouldShowCurrentLocationButton = canUseCurrentLocation && searchValue.trim().length === 0 && isFocused; - // console.log("AddressSearch:locationBias["+locationBias+"]"); const saveLocationDetails = (autocompleteData, details) => { const addressComponents = details.address_components; if (!addressComponents) { diff --git a/src/pages/iou/request/step/IOURequestStepWaypoint.js b/src/pages/iou/request/step/IOURequestStepWaypoint.js index be43d9e2ca89..323021032ecc 100644 --- a/src/pages/iou/request/step/IOURequestStepWaypoint.js +++ b/src/pages/iou/request/step/IOURequestStepWaypoint.js @@ -39,7 +39,7 @@ const propTypes = { /** The optimistic transaction for this request */ transaction: transactionPropTypes, - /* Current location coordinates of the user*/ + /* Current location coordinates of the user */ userLocation: PropTypes.shape({ /** Latitude of the location */ latitude: PropTypes.number, @@ -102,9 +102,6 @@ function IOURequestStepWaypoint({ const waypointCount = _.size(allWaypoints); const filledWaypointCount = _.size(_.filter(allWaypoints, (waypoint) => !_.isEmpty(waypoint))); - const directionCoordinatesSize = _.size(directionCoordinates); - console.log('**** IOUREQUESTSTEPWAYPOINT **** ==> [' + filledWaypointCount + '], directionCoordinatesCount[' + directionCoordinatesSize + ']'); - const waypointDescriptionKey = useMemo(() => { switch (parsedWaypointIndex) { case 0: @@ -121,7 +118,6 @@ function IOURequestStepWaypoint({ // If there are no filled wayPoints and if user's current location cannot be retrieved, // it is futile to arrive at a biased location. Let's return if (filledWaypointCount === 0 && _.isEmpty(userLocation)) { - console.log('Use Case 1: There are no filled waypoints. Also, current location of the user cannot be retrieved. The App will behave like it was before this feature.'); return null; } @@ -148,8 +144,6 @@ function IOURequestStepWaypoint({ // We will get direction coordinates when user is adding a stop after filling the Start and Finish waypoints. // Include direction coordinates when available. if (_.size(directionCoordinates) > 0) { - console.log('Use Case 5: Additional stops after Start and Finish waypoints will give us direction coordinates. Include this to arrive at rectangular boundary'); - console.dir(directionCoordinates); longitudes.push(..._.map(directionCoordinates, (coordinate) => coordinate[0])); latitudes.push(..._.map(directionCoordinates, (coordinate) => coordinate[1])); } @@ -157,15 +151,10 @@ function IOURequestStepWaypoint({ // When no filled waypoints are available but the current location of the user is available, // let us consider the current user's location to construct a rectangular bound if (filledWaypointCount === 0 && !_.isEmpty(userLocation)) { - console.log('Use Case 2: There are no filled waypoints. But, we have the current location of the user. Let us bias location around the current location.'); longitudes.push(userLocation.longitude); latitudes.push(userLocation.latitude); } - if (filledWaypointCount === 1) { - console.log('Use Case 3: There is exactly one waypoint. Let us bias location around this waypoint: lat[' + latitudes[0] + '],lng[' + longitudes[0] + ']'); - } - // Extend the rectangular bound by 0.5 degree (roughly around 25-30 miles in US) const minLat = Math.min(...latitudes) - 0.5; const minLng = Math.min(...longitudes) - 0.5; @@ -178,18 +167,10 @@ function IOURequestStepWaypoint({ const north = maxLat < 90 ? maxLat : 90; const east = maxLng < 180 ? maxLng : 180; - const rectFormat = `rectangle:${south},${west}|${north},${east}`; - - if (filledWaypointCount === 2) { - console.log('Use Case 4: There two waypoints. Let us bias location around this waypoint'); - console.dir(latitudes); - console.dir(longitudes); - } - console.log('NEW RECTANGULAR BOUNDARY[' + rectFormat + ']'); - // Format: rectangle:south,west|north,east + const rectFormat = `rectangle:${south},${west}|${north},${east}`; return rectFormat; - }, [userLocation, directionCoordinates, filledWaypointCount]); + }, [userLocation, directionCoordinates, filledWaypointCount, allWaypoints]); const waypointAddress = lodashGet(currentWaypoint, 'address', ''); // Hide the menu when there is only start and finish waypoint From 00ace7f73c8f6997eaf77d363ef9c53b6fba8484 Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Thu, 21 Dec 2023 17:36:03 +0530 Subject: [PATCH 3/6] use undefined as default for userLocation Co-authored-by: Rajat --- src/pages/iou/request/step/IOURequestStepWaypoint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/iou/request/step/IOURequestStepWaypoint.js b/src/pages/iou/request/step/IOURequestStepWaypoint.js index 323021032ecc..714f9ce7ff77 100644 --- a/src/pages/iou/request/step/IOURequestStepWaypoint.js +++ b/src/pages/iou/request/step/IOURequestStepWaypoint.js @@ -75,7 +75,7 @@ const propTypes = { const defaultProps = { recentWaypoints: [], transaction: {}, - userLocation: {}, + userLocation: undefined, }; function IOURequestStepWaypoint({ From af1259fa5ea98c69de19a688d939c376b50169c8 Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Fri, 22 Dec 2023 08:07:52 +0530 Subject: [PATCH 4/6] optimize usage of locationbias in query --- src/components/AddressSearch/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 71ac0edf7958..3ca49d4cf2b6 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -184,7 +184,7 @@ function AddressSearch({ language: preferredLocale, types: resultTypes, components: isLimitedToUSA ? 'country:us' : undefined, - locationbias: locationBias || 'ipbias', + ...(locationBias && {locationbias: locationBias}), }), [preferredLocale, resultTypes, isLimitedToUSA, locationBias], ); From dbfda572571e3c93e0f49de1da7c620e83716637 Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Fri, 22 Dec 2023 22:36:56 +0530 Subject: [PATCH 5/6] removed direction coordinates --- src/pages/iou/request/step/IOURequestStepWaypoint.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepWaypoint.js b/src/pages/iou/request/step/IOURequestStepWaypoint.js index 714f9ce7ff77..3c361acd3233 100644 --- a/src/pages/iou/request/step/IOURequestStepWaypoint.js +++ b/src/pages/iou/request/step/IOURequestStepWaypoint.js @@ -95,7 +95,6 @@ function IOURequestStepWaypoint({ const {isOffline} = useNetwork(); const textInput = useRef(null); const parsedWaypointIndex = parseInt(pageIndex, 10); - const directionCoordinates = lodashGet(transaction, 'routes.route0.geometry.coordinates', []); const allWaypoints = lodashGet(transaction, 'comment.waypoints', {}); const currentWaypoint = lodashGet(allWaypoints, `waypoint${pageIndex}`, {}); @@ -113,7 +112,7 @@ function IOURequestStepWaypoint({ } }, [parsedWaypointIndex, waypointCount]); - // Construct the rectangular boundary based on user location, waypoints and direction coordinates + // Construct the rectangular boundary based on user location and waypoints const locationBias = useMemo(() => { // If there are no filled wayPoints and if user's current location cannot be retrieved, // it is futile to arrive at a biased location. Let's return @@ -141,13 +140,6 @@ function IOURequestStepWaypoint({ (lat) => lat, ); - // We will get direction coordinates when user is adding a stop after filling the Start and Finish waypoints. - // Include direction coordinates when available. - if (_.size(directionCoordinates) > 0) { - longitudes.push(..._.map(directionCoordinates, (coordinate) => coordinate[0])); - latitudes.push(..._.map(directionCoordinates, (coordinate) => coordinate[1])); - } - // When no filled waypoints are available but the current location of the user is available, // let us consider the current user's location to construct a rectangular bound if (filledWaypointCount === 0 && !_.isEmpty(userLocation)) { @@ -170,7 +162,7 @@ function IOURequestStepWaypoint({ // Format: rectangle:south,west|north,east const rectFormat = `rectangle:${south},${west}|${north},${east}`; return rectFormat; - }, [userLocation, directionCoordinates, filledWaypointCount, allWaypoints]); + }, [userLocation, filledWaypointCount, allWaypoints]); const waypointAddress = lodashGet(currentWaypoint, 'address', ''); // Hide the menu when there is only start and finish waypoint From 29959086e7e3247c6fa33f861e2c816a81f9d339 Mon Sep 17 00:00:00 2001 From: Roji Philip Date: Fri, 22 Dec 2023 22:57:02 +0530 Subject: [PATCH 6/6] update to comment text Co-authored-by: Rajat --- src/components/AddressSearch/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 3ca49d4cf2b6..c2ee21eaa0cb 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -111,7 +111,7 @@ const propTypes = { /** Information about the network */ network: networkPropTypes.isRequired, - /** location bias based on rectangular format */ + /** Location bias for querying search results. */ locationBias: PropTypes.string, ...withLocalizePropTypes,