Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
7 changes: 4 additions & 3 deletions src/components/MapView/GPSMapView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type {MapState} from '@rnmapbox/maps';

import {useFocusEffect} from '@react-navigation/native';
import Mapbox, {MarkerView} from '@rnmapbox/maps';
import {getForegroundPermissionsAsync, requestForegroundPermissionsAsync} from 'expo-location';
import {getForegroundPermissionsAsync} from 'expo-location';
import {useEffect, useRef, useState} from 'react';
import {View} from 'react-native';
import {useSharedValue} from 'react-native-reanimated';
Expand Down Expand Up @@ -55,14 +55,15 @@ function GPSMapView({accessToken, style, mapPadding, styleURL, pitchEnabled, way

const [foregroundLocationPermissionsGranted, setForegroundLocationPermissionsGranted] = useState<boolean | null>(null);

// Request foreground location permissions if not granted yet to determine if we can use followUserLocation prop on the map camera
// Check (never request) foreground location permissions to determine if we can use the followUserLocation prop on the map camera.
// Requesting here would trigger an OS prompt on open without a prior explicit user action, so we only read the current status.
useFocusEffect(() => {
if (isOffline) {
return;
}

let ignore = false;
requestForegroundPermissionsAsync().then(({granted}) => {
getForegroundPermissionsAsync().then(({granted}) => {
if (ignore) {
return;
}
Expand Down
36 changes: 32 additions & 4 deletions src/components/MapView/MapView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type {MapState} from '@rnmapbox/maps';

import {useFocusEffect, useNavigation} from '@react-navigation/native';
import Mapbox, {MarkerView} from '@rnmapbox/maps';
import {getForegroundPermissionsAsync} from 'expo-location';
import {memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react';
import {View} from 'react-native';
import {useSharedValue} from 'react-native-reanimated';
Expand Down Expand Up @@ -114,10 +115,37 @@ function MapView({
return;
}

getCurrentPosition((params) => {
const currentCoords = {longitude: params.coords.longitude, latitude: params.coords.latitude};
setUserLocation(currentCoords);
}, setCurrentPositionToInitialState);
// Only read the device location when permission is ALREADY granted. We never request it here,
// so opening the map cannot trigger an OS permission prompt without a prior explicit user action.
let ignore = false;
getForegroundPermissionsAsync().then(({granted}) => {
Comment thread
DylanDylann marked this conversation as resolved.
if (ignore) {
return;
}
if (!granted) {
// Pass the permission-denied error so any stale cached location is cleared and the map falls back to initialState.
setCurrentPositionToInitialState({
code: GeolocationErrorCode.PERMISSION_DENIED,
message: 'User denied access to location.',
});
return;
}

getCurrentPosition((params) => {
if (ignore) {
return;
}
const currentCoords = {
longitude: params.coords.longitude,
latitude: params.coords.latitude,
};
setUserLocation(currentCoords);
}, setCurrentPositionToInitialState);
});

return () => {
ignore = true;
};
}, [isOffline, shouldPanMapToCurrentPosition, setCurrentPositionToInitialState]),
);

Expand Down
Loading