Files
iNaturalistReactNative/src/sharedHelpers/fetchUserLocation.ts
Johannes Klein a52996f535 Changes to the way permissions are asked for (#1793)
* Replace name in permission requests

* TakePhoto TS

* PermissionGate TS

* Type

* PermissionGateContainer TS

* Interface

* Types

* LocationGate TS

* Remove LocationPermissionGate from Camera

* Remove write only permission

* Type

* ObsPhotoSelectionList TS

* Code style

* Show the improve with location button

* Create useLocationPermission.tsx

* Use new hook on suggestions

* Doc comment

* Use new hook in camera view

* Add strings

* Refactor Explore main content

* Use permission hook on RootExplore

* Add no location permission component

* Rename function

* Prop request permissions and use with button

* Default to Nearby label

* Remove Node type

* Projects TS

* Use useLocationPermission hook in projects screen

* Add string

* Prop permission down

* Refactor list render

* Refactor tab id into enum

* Tab type

* On nearby tab if without permission show button to prompt

* Leftovers

* Remove location permission gate from ObsEdit

* Use location permission hook on evidence section

* SearchBar TS

* Do not autoFocus on search bar in location picker.

Closes #1743

* Update type

* LocationSearch TS

* Show location permission gate on location picker's mount

* Add location permission to CurrentLocationButton

* Remove unused props of Map

* Remove unused exports from useMapLocation

* Migration

* Revert "Show location permission gate on location picker's mount"

This reverts commit 30ff75698c53d54d0b14cd2bd629f7155b743bf8.

* Add callbacks to useLocationPermission hook

* Show location permission ask on Obs Edit

* Remove unused string

* Reset explore filters should set location always to worldwide

* Add helper function to show place text in Explore

* Remove unused state of filter modal

* Show place text in filters modal with helper

* Show location permission button only for Nearby explore state

* Add a placeMode state

* Do not send placeMode to API

* Also treat limited permission as yes

* useLocationPermission in ExploreLocationSearch

* Refactor to setting place mode

Instead of logic based on the translated text of the place_guess string that is stored in ExploreContext, we are switching to an enum state that signifies which mode to show on explore:
1.) Nearby: Filters explore results based on the user's location. This also has a state without location permission that does not query the API.
2.) Place: Filtering by a specific place (as retrieved by /places API).
3.) Worldwide: Retrieve worldwide results, i.e. not having a place filter set.
4.) Map area: Filtering explore results precisely to the map rectangle shown on the explore map.

* Remove import from test

* Remove export

* Use blocked title only for blocked permission asks

* Move gallery permission container to Tab navigator as are the others

* Add gallery save title

* Split location permission explanation into two

* Update strings.ftl

* Only nav to location picker if permission was not  granted

* Check permission on app being foregrounded

* The location permission part is handled by useLocationPermission

* Do not store permission result in hook

* Use hasPermission from permissions hook

* Update fetchUserLocation.e2e-mock

* Move hook one higher

* Show user location if permission is given

* PermissionGate callbacks should use useCallback

* Add permission hook to map usage

* Fix test

* Update layout to be asserted

* Add location permission hook to Explore

* Remove console.log

* Few TS fixes

* Indentation

* Remove superficial check

* Update Podfile.lock
2024-07-12 11:00:24 +02:00

55 lines
1.4 KiB
TypeScript

import Geolocation, { GeolocationResponse } from "@react-native-community/geolocation";
import {
LOCATION_PERMISSIONS,
permissionResultFromMultiple
} from "components/SharedComponents/PermissionGateContainer.tsx";
import { Platform } from "react-native";
import {
checkMultiple,
RESULTS
} from "react-native-permissions";
const options = {
enableHighAccuracy: true,
maximumAge: 0,
timeout: 2000
} as const;
const getCurrentPosition = ( ): Promise<GeolocationResponse> => new Promise(
( resolve, error ) => {
Geolocation.getCurrentPosition( resolve, error, options );
}
);
interface UserLocation {
latitude: number;
longitude: number;
positional_accuracy: number;
}
const fetchUserLocation = async ( ): Promise<UserLocation | null> => {
const permissionResult = permissionResultFromMultiple(
await checkMultiple( LOCATION_PERMISSIONS )
);
// TODO: handle case where iOS permissions are not granted
if ( Platform.OS !== "android" && permissionResult !== RESULTS.GRANTED ) {
return null;
}
try {
const { coords } = await getCurrentPosition( );
const userLocation = {
latitude: coords.latitude,
longitude: coords.longitude,
positional_accuracy: coords.accuracy
};
return userLocation;
} catch ( e ) {
console.warn( e, "couldn't get latLng" );
}
return null;
};
export default fetchUserLocation;