UNPKG

expo-realtime-maps-navigation

Version:

JavaScript-pure React Native navigation package with Google Places + HERE Routing APIs, dual maps support, and complete customization - No native modules required!

263 lines (262 loc) 11.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPermissionGuidance = exports.getPermissionStatusMessage = exports.ensureNavigationPermissions = exports.requestBatteryOptimizationExemption = exports.isBatteryOptimizationDisabled = exports.stopForegroundService = exports.ensureForegroundService = exports.openLocationSettings = exports.requestAlwaysAuthorizationWithRationale = exports.requestLocationPermissionsWithRationale = void 0; const react_native_1 = require("react-native"); const navigation_1 = require("../api/navigation"); const requestLocationPermissionsWithRationale = async (options = {}) => { const { title = 'Location Permission Required', message = 'This app needs location access to provide navigation services.', showSettingsOption = true, } = options; try { const status = await (0, navigation_1.requestLocationPermissions)(); if (status === 'granted') { return status; } if (status === 'denied' && showSettingsOption) { return new Promise(resolve => { react_native_1.Alert.alert(title, `${message}\n\nPlease enable location access in Settings.`, [ { text: 'Cancel', style: 'cancel', onPress: () => resolve(status), }, { text: 'Open Settings', onPress: async () => { await (0, exports.openLocationSettings)(); resolve(status); }, }, ]); }); } return status; } catch (error) { console.error('Error requesting location permissions:', error); return 'denied'; } }; exports.requestLocationPermissionsWithRationale = requestLocationPermissionsWithRationale; const requestAlwaysAuthorizationWithRationale = async (options = {}) => { const { title = 'Background Location Access', message = react_native_1.Platform.select({ ios: 'To continue providing navigation while the app is in the background, please select "Always Allow" in the next dialog.', android: 'To provide navigation in the background, this app needs "Allow all the time" location permission.', default: 'Background location access is required for continuous navigation.', }), showSettingsOption = true, } = options; try { const basicPermission = await (0, exports.requestLocationPermissionsWithRationale)({ title: 'Location Permission Required', message: 'Basic location access is required before requesting background access.', showSettingsOption: false, }); if (basicPermission !== 'granted') { return basicPermission; } return new Promise(resolve => { react_native_1.Alert.alert(title, message, [ { text: 'Cancel', style: 'cancel', onPress: () => resolve('denied'), }, { text: react_native_1.Platform.select({ ios: 'Continue', android: 'Grant Permission', default: 'OK' }), onPress: async () => { try { const backgroundStatus = await (0, navigation_1.requestBackgroundLocationPermission)(); if (backgroundStatus === 'denied' && showSettingsOption) { react_native_1.Alert.alert('Permission Required', react_native_1.Platform.select({ ios: 'Please go to Settings > Privacy & Security > Location Services > [App Name] and select "Always".', android: 'Please go to Settings > Apps > [App Name] > Permissions > Location and select "Allow all the time".', default: 'Please enable background location access in Settings.', }), [ { text: 'Cancel', style: 'cancel' }, { text: 'Open Settings', onPress: exports.openLocationSettings }, ]); } resolve(backgroundStatus); } catch (error) { console.error('Error requesting background permission:', error); resolve('denied'); } }, }, ]); }); } catch (error) { console.error('Error in always authorization flow:', error); return 'denied'; } }; exports.requestAlwaysAuthorizationWithRationale = requestAlwaysAuthorizationWithRationale; const openLocationSettings = async () => { try { if (react_native_1.Platform.OS === 'ios') { await react_native_1.Linking.openURL('app-settings:'); } else { await react_native_1.Linking.openSettings(); } } catch (error) { console.error('Error opening settings:', error); try { await react_native_1.Linking.openSettings(); } catch (fallbackError) { console.error('Error opening fallback settings:', fallbackError); } } }; exports.openLocationSettings = openLocationSettings; const ensureForegroundService = async (options = {}) => { if (react_native_1.Platform.OS !== 'android') { console.warn('Foreground service is only supported on Android'); return true; } const { channelId = 'navigation_service', notificationTitle = 'Navigation Active', notificationMessage = 'HERE Navigation is running in the background', importance = 'default', } = options; try { console.warn('Starting foreground service with options:', { channelId, notificationTitle, notificationMessage, importance, }); return true; } catch (error) { console.error('Error starting foreground service:', error); return false; } }; exports.ensureForegroundService = ensureForegroundService; const stopForegroundService = async () => { if (react_native_1.Platform.OS !== 'android') { return; } try { console.warn('Stopping foreground service'); } catch (error) { console.error('Error stopping foreground service:', error); } }; exports.stopForegroundService = stopForegroundService; const isBatteryOptimizationDisabled = async () => { if (react_native_1.Platform.OS !== 'android') { return true; } return false; }; exports.isBatteryOptimizationDisabled = isBatteryOptimizationDisabled; const requestBatteryOptimizationExemption = async () => { if (react_native_1.Platform.OS !== 'android') { return; } try { react_native_1.Alert.alert('Battery Optimization', 'For reliable background navigation, please disable battery optimization for this app.', [ { text: 'Cancel', style: 'cancel' }, { text: 'Open Settings', onPress: async () => { try { await react_native_1.Linking.sendIntent('android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS'); } catch (error) { await react_native_1.Linking.openSettings(); } }, }, ]); } catch (error) { console.error('Error requesting battery optimization exemption:', error); } }; exports.requestBatteryOptimizationExemption = requestBatteryOptimizationExemption; const ensureNavigationPermissions = async (backgroundNavigation = false) => { try { const locationStatus = await (0, exports.requestLocationPermissionsWithRationale)({ title: 'Location Required', message: 'Navigation requires location access to function properly.', }); let backgroundLocationStatus; if (backgroundNavigation && locationStatus === 'granted') { backgroundLocationStatus = await (0, exports.requestAlwaysAuthorizationWithRationale)({ title: 'Background Navigation', message: 'To provide navigation while the app is in the background, continuous location access is required.', }); } const allGranted = locationStatus === 'granted' && (!backgroundNavigation || backgroundLocationStatus === 'granted'); return { location: locationStatus, ...(backgroundLocationStatus ? { backgroundLocation: backgroundLocationStatus } : {}), allGranted, }; } catch (error) { console.error('Error ensuring navigation permissions:', error); return { location: 'denied', ...(backgroundNavigation ? { backgroundLocation: 'denied' } : {}), allGranted: false, }; } }; exports.ensureNavigationPermissions = ensureNavigationPermissions; const getPermissionStatusMessage = (status, isBackground = false) => { const permissionType = isBackground ? 'background location' : 'location'; switch (status) { case 'granted': return `${permissionType} access granted`; case 'denied': return `${permissionType} access denied`; case 'restricted': return `${permissionType} access restricted by device policy`; case 'undetermined': return `${permissionType} permission not yet requested`; default: return `Unknown ${permissionType} permission status`; } }; exports.getPermissionStatusMessage = getPermissionStatusMessage; const getPermissionGuidance = (backgroundRequired = false) => { if (react_native_1.Platform.OS === 'ios') { return { title: 'iOS Location Permission Setup', steps: backgroundRequired ? [ '1. Allow location access when prompted', '2. For background navigation, select "Always Allow"', '3. Or go to Settings > Privacy & Security > Location Services', '4. Find your app and select "Always"', ] : [ '1. Allow location access when prompted', '2. Or go to Settings > Privacy & Security > Location Services', '3. Find your app and enable location access', ], }; } else { return { title: 'Android Location Permission Setup', steps: backgroundRequired ? [ '1. Allow location access when prompted', '2. For background navigation, select "Allow all the time"', '3. Or go to Settings > Apps > [App Name] > Permissions', '4. Select Location and choose "Allow all the time"', '5. Disable battery optimization for best performance', ] : [ '1. Allow location access when prompted', '2. Or go to Settings > Apps > [App Name] > Permissions', '3. Enable Location permission', ], }; } }; exports.getPermissionGuidance = getPermissionGuidance;