Skip to content

Commit 191b513

Browse files
committed
Fix layers ordering in GPSMapView
1 parent a8848b1 commit 191b513

6 files changed

Lines changed: 36 additions & 42 deletions

File tree

src/CONST/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9491,6 +9491,9 @@ const CONST = {
94919491
ROUTE_BORDER: 'route-border',
94929492
WAYPOINTS_SOURCE: 'waypoints-source',
94939493
WAYPOINTS: 'waypoints',
9494+
LAYER_ORDER_ANCHOR_SOURCE: 'layer-order-anchor-source',
9495+
ROUTE_ANCHOR: 'route-anchor',
9496+
WAYPOINTS_ANCHOR: 'waypoints-anchor',
94949497
},
94959498

94969499
ALTERNATE_DIRECTIONS_MAP_VIEW_LAYERS: {

src/components/MapView/GPSMapView.tsx

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import type {GPSMapViewProps} from './MapViewTypes';
2626
import Compass from './Compass';
2727
import GPSDirection from './GPSDirection';
2828
import GPSWaypointLayer from './GPSWaypointLayer';
29-
import LOCATION_PUCK_LAYER_ID from './locationPuckLayerId';
29+
import LayerOrderAnchors from './LayerOrderAnchors';
3030
import PendingMapView from './PendingMapView';
3131
import responder from './responder';
3232
import useAccessToken from './useAccessToken';
@@ -92,8 +92,6 @@ function GPSMapView({accessToken, style, mapPadding, styleURL, pitchEnabled, way
9292
const [userInteractedWithMap, setUserInteractedWithMap] = useState(false);
9393
const [shouldUseImmediateFollowTransition, setShouldUseImmediateFollowTransition] = useState(noWaypoints || isTrackingGPS);
9494
const [lastLocation, setLastLocation] = useState<{longitude: number; latitude: number} | undefined>();
95-
const [isLocationPuckLayerReady, setIsLocationPuckLayerReady] = useState(false);
96-
const hasSetLocationPuckLayerReady = useRef(false);
9795

9896
// Determines if map can be panned to user's detected location without bothering the user. It will return
9997
// false if user has already started dragging the map or if there are one or more waypoints present
@@ -174,25 +172,6 @@ function GPSMapView({accessToken, style, mapPadding, styleURL, pitchEnabled, way
174172
setLastLocation({longitude: coords.longitude, latitude: coords.latitude});
175173
};
176174

177-
// On first render LocationPuck layer is not ready to be used as belowLayerID prop
178-
// for GPSDirection and GPSWaypointLayer, so we need to wait for the layer to be ready
179-
const onDidFinishRenderingFrameFully = () => {
180-
if (hasSetLocationPuckLayerReady.current && foregroundLocationPermissionsGranted) {
181-
return;
182-
}
183-
184-
// We need to reset the state to false to ensure we later remount the components with the new belowLayerID prop
185-
// if user changes location permissions in the meantime (so fallback location marker is shown instead of the location puck)
186-
if (!foregroundLocationPermissionsGranted) {
187-
hasSetLocationPuckLayerReady.current = false;
188-
setIsLocationPuckLayerReady(false);
189-
return;
190-
}
191-
192-
hasSetLocationPuckLayerReady.current = true;
193-
setIsLocationPuckLayerReady(true);
194-
};
195-
196175
const shouldFollowFallbackLocation = noWaypoints && foregroundLocationPermissionsGranted === false;
197176

198177
const cameraPadding: Mapbox.CameraPadding | undefined =
@@ -226,9 +205,10 @@ function GPSMapView({accessToken, style, mapPadding, styleURL, pitchEnabled, way
226205
compassEnabled={false}
227206
onCameraChanged={onCameraChanged}
228207
logoPosition={{...styles.l2, ...styles.b2}}
229-
onDidFinishRenderingFrameFully={onDidFinishRenderingFrameFully}
230208
{...responder.panHandlers}
231209
>
210+
<LayerOrderAnchors />
211+
232212
<Mapbox.Viewport
233213
onStatusChanged={(event) => {
234214
if (!shouldUseImmediateFollowTransition) {
@@ -291,22 +271,15 @@ function GPSMapView({accessToken, style, mapPadding, styleURL, pitchEnabled, way
291271

292272
<GPSWaypointLayer
293273
waypoints={waypoints}
294-
// To ensure that waypoints are shown below the location puck we need to pass belowLayerID prop
295-
// Android does not support dynamic belowLayerID prop change, so we pass key to remount this component with belowLayerID change
296-
key={isLocationPuckLayerReady ? 'below-location-puck' : 'default-waypoints'}
297-
// The native Mapbox SDK renders the user-location puck on its own dedicated layer. We render waypoints below
298-
// that layer so the puck always stays on top of the waypoints. The layer id differs per platform.
299-
belowLayerID={isLocationPuckLayerReady ? LOCATION_PUCK_LAYER_ID : undefined}
274+
belowLayerID={CONST.MAP_VIEW_LAYERS.WAYPOINTS_ANCHOR}
300275
/>
301276

302277
{!noWaypoints && (
303278
<GPSDirection
304279
directionCoordinates={directionCoordinatesProp}
305280
isTrackingGPS={isTrackingGPS}
306281
lastLocation={lastLocation}
307-
// Similarly to GPSWaypointLayer, we want to show the direction below the location puck and also below the waypoints
308-
key={isLocationPuckLayerReady ? 'below-waypoints' : 'default-direction'}
309-
belowLayerID={isLocationPuckLayerReady ? CONST.MAP_VIEW_LAYERS.WAYPOINTS : undefined}
282+
belowLayerID={CONST.MAP_VIEW_LAYERS.ROUTE_ANCHOR}
310283
/>
311284
)}
312285
</Mapbox.MapView>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import CONST from '@src/CONST';
2+
3+
import Mapbox from '@rnmapbox/maps';
4+
5+
// The source has no features, so the anchor layers never render anything - they only exist as positions in the layer stack
6+
const EMPTY_SHAPE = {
7+
type: 'FeatureCollection' as const,
8+
features: [],
9+
};
10+
11+
/**
12+
* Empty layers whose only purpose is to give other layers a stable position to anchor to via `belowLayerID`/`aboveLayerID`.
13+
* This is needed as `belowLayerID`and `aboveLayerID` don't work well on native when they target layers that may not be
14+
* mounted yet and on GPSMapView we have to keep LocationPuck > Waypoints > Route order.
15+
*/
16+
function LayerOrderAnchors() {
17+
return (
18+
<Mapbox.ShapeSource
19+
id={CONST.MAP_VIEW_LAYERS.LAYER_ORDER_ANCHOR_SOURCE}
20+
shape={EMPTY_SHAPE}
21+
>
22+
<Mapbox.CircleLayer id={CONST.MAP_VIEW_LAYERS.ROUTE_ANCHOR} />
23+
<Mapbox.CircleLayer id={CONST.MAP_VIEW_LAYERS.WAYPOINTS_ANCHOR} />
24+
</Mapbox.ShapeSource>
25+
);
26+
}
27+
28+
export default LayerOrderAnchors;

src/components/MapView/locationPuckLayerId/index.android.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/components/MapView/locationPuckLayerId/index.ios.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/components/MapView/locationPuckLayerId/index.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)