@@ -6,9 +6,12 @@ import {View} from 'react-native';
6
6
import { useOnyx } from 'react-native-onyx' ;
7
7
import Button from '@components/Button' ;
8
8
import * as Expensicons from '@components/Icon/Expensicons' ;
9
+ import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback' ;
10
+ import Text from '@components/Text' ;
9
11
import useTheme from '@hooks/useTheme' ;
10
12
import useThemeStyles from '@hooks/useThemeStyles' ;
11
- import * as UserLocation from '@libs/actions/UserLocation' ;
13
+ import { clearUserLocation , setUserLocation } from '@libs/actions/UserLocation' ;
14
+ import DistanceRequestUtils from '@libs/DistanceRequestUtils' ;
12
15
import getCurrentPosition from '@libs/getCurrentPosition' ;
13
16
import type { GeolocationErrorCallback } from '@libs/getCurrentPosition/getCurrentPosition.types' ;
14
17
import { GeolocationErrorCode } from '@libs/getCurrentPosition/getCurrentPosition.types' ;
@@ -24,7 +27,7 @@ import responder from './responder';
24
27
import utils from './utils' ;
25
28
26
29
const MapView = forwardRef < MapViewHandle , MapViewProps > (
27
- ( { accessToken, style, mapPadding, styleURL, pitchEnabled, initialState, waypoints, directionCoordinates, onMapReady, interactive = true } , ref ) => {
30
+ ( { accessToken, style, mapPadding, styleURL, pitchEnabled, initialState, waypoints, directionCoordinates, onMapReady, interactive = true , distanceInMeters , unit } , ref ) => {
28
31
const [ userLocation ] = useOnyx ( ONYXKEYS . USER_LOCATION ) ;
29
32
const navigation = useNavigation ( ) ;
30
33
const { isOffline} = useNetwork ( ) ;
@@ -39,6 +42,25 @@ const MapView = forwardRef<MapViewHandle, MapViewProps>(
39
42
const shouldInitializeCurrentPosition = useRef ( true ) ;
40
43
const [ isAccessTokenSet , setIsAccessTokenSet ] = useState ( false ) ;
41
44
45
+ const [ distanceUnit , setDistanceUnit ] = useState ( unit ) ;
46
+ useEffect ( ( ) => {
47
+ if ( ! unit || distanceUnit ) {
48
+ return ;
49
+ }
50
+ setDistanceUnit ( unit ) ;
51
+ } , [ unit , distanceUnit ] ) ;
52
+
53
+ const toggleDistanceUnit = useCallback ( ( ) => {
54
+ setDistanceUnit ( ( currentUnit ) =>
55
+ currentUnit === CONST . CUSTOM_UNITS . DISTANCE_UNIT_KILOMETERS ? CONST . CUSTOM_UNITS . DISTANCE_UNIT_MILES : CONST . CUSTOM_UNITS . DISTANCE_UNIT_KILOMETERS ,
56
+ ) ;
57
+ } , [ ] ) ;
58
+
59
+ const distanceLabelText = useMemo (
60
+ ( ) => DistanceRequestUtils . getDistanceForDisplayLabel ( distanceInMeters ?? 0 , distanceUnit ?? CONST . CUSTOM_UNITS . DISTANCE_UNIT_KILOMETERS ) ,
61
+ [ distanceInMeters , distanceUnit ] ,
62
+ ) ;
63
+
42
64
// Determines if map can be panned to user's detected
43
65
// location without bothering the user. It will return
44
66
// false if user has already started dragging the map or
@@ -50,7 +72,7 @@ const MapView = forwardRef<MapViewHandle, MapViewProps>(
50
72
if ( error ?. code !== GeolocationErrorCode . PERMISSION_DENIED || ! initialLocation ) {
51
73
return ;
52
74
}
53
- UserLocation . clearUserLocation ( ) ;
75
+ clearUserLocation ( ) ;
54
76
} ,
55
77
[ initialLocation ] ,
56
78
) ;
@@ -74,7 +96,7 @@ const MapView = forwardRef<MapViewHandle, MapViewProps>(
74
96
75
97
getCurrentPosition ( ( params ) => {
76
98
const currentCoords = { longitude : params . coords . longitude , latitude : params . coords . latitude } ;
77
- UserLocation . setUserLocation ( currentCoords ) ;
99
+ setUserLocation ( currentCoords ) ;
78
100
} , setCurrentPositionToInitialState ) ;
79
101
} , [ isOffline , shouldPanMapToCurrentPosition , setCurrentPositionToInitialState ] ) ,
80
102
) ;
@@ -205,6 +227,20 @@ const MapView = forwardRef<MapViewHandle, MapViewProps>(
205
227
const initCenterCoordinate = useMemo ( ( ) => ( interactive ? centerCoordinate : undefined ) , [ interactive , centerCoordinate ] ) ;
206
228
const initBounds = useMemo ( ( ) => ( interactive ? undefined : waypointsBounds ) , [ interactive , waypointsBounds ] ) ;
207
229
230
+ const distanceSymbolCoorinate = useMemo ( ( ) => {
231
+ const length = directionCoordinates ?. length ;
232
+ // If the array is empty, return undefined
233
+ if ( ! length ) {
234
+ return undefined ;
235
+ }
236
+
237
+ // Find the index of the middle element
238
+ const middleIndex = Math . floor ( length / 2 ) ;
239
+
240
+ // Return the middle element
241
+ return directionCoordinates . at ( middleIndex ) ;
242
+ } , [ directionCoordinates ] ) ;
243
+
208
244
return ! isOffline && isAccessTokenSet && ! ! defaultSettings ? (
209
245
< View style = { [ style , ! interactive ? styles . pointerEventsNone : { } ] } >
210
246
< Mapbox . MapView
@@ -258,7 +294,6 @@ const MapView = forwardRef<MapViewHandle, MapViewProps>(
258
294
/>
259
295
</ Mapbox . ShapeSource >
260
296
) }
261
-
262
297
{ waypoints ?. map ( ( { coordinate, markerComponent, id} ) => {
263
298
const MarkerComponent = markerComponent ;
264
299
if ( utils . areSameCoordinate ( [ coordinate [ 0 ] , coordinate [ 1 ] ] , [ currentPosition ?. longitude ?? 0 , currentPosition ?. latitude ?? 0 ] ) && interactive ) {
@@ -276,6 +311,25 @@ const MapView = forwardRef<MapViewHandle, MapViewProps>(
276
311
} ) }
277
312
278
313
{ ! ! directionCoordinates && < Direction coordinates = { directionCoordinates } /> }
314
+ { ! ! distanceSymbolCoorinate && ! ! distanceInMeters && ! ! distanceUnit && (
315
+ < MarkerView
316
+ coordinate = { distanceSymbolCoorinate }
317
+ id = "distance-label"
318
+ key = "distance-label"
319
+ >
320
+ < View style = { { zIndex : 1 } } >
321
+ < PressableWithoutFeedback
322
+ accessibilityRole = { CONST . ROLE . BUTTON }
323
+ accessibilityLabel = "distance-label"
324
+ onPress = { toggleDistanceUnit }
325
+ >
326
+ < View style = { [ styles . distanceLabelWrapper ] } >
327
+ < Text style = { styles . distanceLabelText } > { distanceLabelText } </ Text >
328
+ </ View >
329
+ </ PressableWithoutFeedback >
330
+ </ View >
331
+ </ MarkerView >
332
+ ) }
279
333
</ Mapbox . MapView >
280
334
{ interactive && (
281
335
< View style = { [ styles . pAbsolute , styles . p5 , styles . t0 , styles . r0 , { zIndex : 1 } ] } >
0 commit comments