Advertisement
YaBoiSwayZ

React Native Timer Component (with Geolocation)

May 26th, 2024
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 3.05 KB | Source Code | 0 0
  1. import React, { useState, useEffect, useCallback } from 'react';
  2. import { View, Text, Button, PermissionsAndroid, Platform } from 'react-native';
  3. import Geolocation from 'react-native-geolocation-service';
  4.  
  5. const TARGET_LOCATION = { latitude: 28.7041, longitude: 77.1025 };
  6. const DISTANCE_THRESHOLD = 1000;
  7. const TIMER_INTERVAL = 300000;
  8.  
  9. async function requestLocationPermission() {
  10.   if (Platform.OS !== 'android') return true;
  11.   try {
  12.     const granted = await PermissionsAndroid.request(
  13.       PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
  14.       {
  15.         title: 'Location Permission',
  16.         message: 'This app needs access to your location.',
  17.         buttonNeutral: 'Ask Me Later',
  18.         buttonNegative: 'Cancel',
  19.         buttonPositive: 'OK',
  20.       },
  21.     );
  22.     return granted === PermissionsAndroid.RESULTS.GRANTED;
  23.   } catch (err) {
  24.     console.warn(err);
  25.     return false;
  26.   }
  27. }
  28.  
  29. const Timer = () => {
  30.   const [timerState, setTimerState] = useState('stopped');
  31.   const [timerID, setTimerID] = useState(null);
  32.  
  33.   const getDistanceFromLatLonInM = useCallback((lat1, lon1, lat2, lon2) => {
  34.     const deg2rad = deg => (deg * Math.PI) / 180;
  35.     const R = 6371e3;
  36.     const dLat = deg2rad(lat2 - lat1);
  37.     const dLon = deg2rad(lon2 - lon1);
  38.     const a =
  39.       Math.sin(dLat / 2) * Math.sin(dLat / 2) +
  40.       Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
  41.       Math.sin(dLon / 2) * Math.sin(dLon / 2);
  42.     const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  43.     return R * c;
  44.   }, []);
  45.  
  46.   const checkLocation = useCallback(() => {
  47.     Geolocation.getCurrentPosition(
  48.       position => {
  49.         const { latitude, longitude } = position.coords;
  50.         const distance = getDistanceFromLatLonInM(
  51.           latitude,
  52.           longitude,
  53.           TARGET_LOCATION.latitude,
  54.           TARGET_LOCATION.longitude
  55.         );
  56.         if (distance <= DISTANCE_THRESHOLD && timerState !== 'running') {
  57.           setTimerState('running');
  58.         } else if (distance > DISTANCE_THRESHOLD && timerState !== 'stopped') {
  59.           setTimerState('stopped');
  60.         }
  61.       },
  62.       error => {
  63.         console.error(error.code, error.message);
  64.       },
  65.       { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 },
  66.     );
  67.   }, [timerState]);
  68.  
  69.   useEffect(() => {
  70.     let id;
  71.     const createTimer = async () => {
  72.       const hasPermission = await requestLocationPermission();
  73.       if (hasPermission) {
  74.         checkLocation();
  75.         id = setInterval(checkLocation, TIMER_INTERVAL);
  76.         setTimerID(id);
  77.       }
  78.     };
  79.  
  80.     createTimer();
  81.  
  82.     return () => {
  83.       if (id) clearInterval(id);
  84.     };
  85.   }, [checkLocation]);
  86.  
  87.   return (
  88.     <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
  89.       <Text style={{ fontSize: 24, margin: 10 }}>Timer state: {timerState.toUpperCase()}</Text>
  90.       <Button title="Start" onPress={() => setTimerState('running')} />
  91.       <Button title="Stop" onPress={() => setTimerState('stopped')} />
  92.     </View>
  93.   );
  94. };
  95.  
  96. export default Timer;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement