import { Platform, PermissionsAndroid, Alert, Linking } from 'react-native'; import Geolocation from 'react-native-geolocation-service'; import type { GeoPosition, GeoError } from 'react-native-geolocation-service'; // --------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------- export interface LatLng { latitude: number; longitude: number; } export interface LocationResult { coords: LatLng; address: string; } // --------------------------------------------------------------------------- // Constants // --------------------------------------------------------------------------- const GOOGLE_MAPS_API_KEY = 'AIzaSyDKaKVyQCmSpHMXcMkNCccSXpILpuvwsVM'; /** Default region (Bengaluru) used as a fallback before the user's location loads. */ export const DEFAULT_LOCATION: LatLng = { latitude: 12.9352, longitude: 77.6245, }; // --------------------------------------------------------------------------- // Permission helpers // --------------------------------------------------------------------------- /** * Request location permission from the user. * Returns `true` if permission was granted, `false` otherwise. */ export const requestLocationPermission = async (): Promise => { if (Platform.OS === 'ios') { try { const result = await Geolocation.requestAuthorization('whenInUse'); return result === 'granted'; } catch { return false; } } // Android try { const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, { title: 'Location Permission', message: 'This app needs access to your location to set it on the map.', buttonNeutral: 'Ask Me Later', buttonNegative: 'Cancel', buttonPositive: 'OK', }, ); console.log('granted', granted); return granted === PermissionsAndroid.RESULTS.GRANTED; } catch { return false; } }; /** * Show an alert when the user denies location permission, with an option * to open app settings. */ export const showPermissionDeniedAlert = (): void => { Alert.alert( 'Location Permission Required', 'Please enable location permission in your device settings to use this feature.', [ { text: 'Cancel', style: 'cancel' }, { text: 'Open Settings', onPress: () => Linking.openSettings() }, ], ); }; // --------------------------------------------------------------------------- // Position helpers // --------------------------------------------------------------------------- /** * Get the device's current GPS position. * Wraps the callback-based Geolocation API in a Promise. */ export const getCurrentPosition = async (): Promise => { try { console.log('get current position'); console.log('Geolocation:', Geolocation); console.log('getCurrentPosition:', Geolocation?.getCurrentPosition); const location = await new Promise((resolve, reject) => { Geolocation.getCurrentPosition( (position: GeoPosition) => { resolve({ latitude: position.coords.latitude, longitude: position.coords.longitude, }); }, (error: GeoError) => { console.log('Geolocation Error:', error); reject(error); }, { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000, forceRequestLocation: true, showLocationDialog: true, }, ); }); return location; } catch (error) { console.error('Failed to get current position:', error); throw error; } }; // --------------------------------------------------------------------------- // Geocoding // --------------------------------------------------------------------------- /** * Reverse-geocode a lat/lng pair into a human-readable address string * using the Google Maps Geocoding API. */ export const reverseGeocode = async (coords: LatLng): Promise => { try { const url = `https://maps.googleapis.com/maps/api/geocode/json` + `?latlng=${coords.latitude},${coords.longitude}` + `&key=${GOOGLE_MAPS_API_KEY}`; const response = await fetch(url); const data = await response.json(); if (data.status === 'OK' && data.results.length > 0) { // Return the most specific formatted address. return data.results[0].formatted_address; } return 'Address not found'; } catch (error) { console.log('reverseGeocode error', error); return 'Unable to fetch address'; } }; // --------------------------------------------------------------------------- // Combined helper // --------------------------------------------------------------------------- /** * All-in-one helper: request permissions → get position → reverse geocode. * Returns both the coordinates and the human-readable address. * * Throws if permission is denied or position cannot be obtained. */ export const getCurrentLocationWithAddress = async (): Promise => { const hasPermission = await requestLocationPermission(); if (!hasPermission) { showPermissionDeniedAlert(); throw new Error('Location permission denied'); } const coords = await getCurrentPosition(); const address = await reverseGeocode(coords); console.log('coords', coords); console.log('address', address); return { coords, address }; };