Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
11 kB
2
Indexable
Never
/**
 * RENAME TO SOMETHING MORE APPROPRIATE InitiationWrapper, SetupMapView
 * Initiates BG plugin,
 * even-listeners -> don't need them here for now !
 * Possible initiation of backgroun-fetch
 * Gets current position
 * Possible to get current state (moving, still) and to track with odometer
 */

import React, { useState, useEffect,} from "react";
import {View} from 'react-native'
import Geolocation from 'react-native-geolocation-service';
import hasLocationPermission from "./LocationPermission";
import PositionedMapView from "../positioned-map-view/PositionedMapView";
import { addCLToStorage, addUserLocationToStorage, getUserLocationFromStorage, setUserLocaton } from "../../helpers/async_storage/AsyncStorage";
import BackgroundGeolocation from 'react-native-background-geolocation'; // Docs for the plugin https://transistorsoft.github.io/react-native-background-geolocation/
import BackgroundFetch from 'react-native-background-fetch';
import MapView from '../../../app/setup/map-view/MapView';
import {useDispatch} from 'react-redux'
import { setUserLocationCoordinates,setUserLocationHeading } from "../../reducers/UserLocationSlice";
import MapboxGL from '@rnmapbox/maps'; // DOCS https://github.com/rnmapbox/maps/tree/main/docs
const BackgroundGeolocationWrapper = ({children}) => {

const dispatch=useDispatch()

  //useEffect which will refresh this part of app so interests that are added/removed from favourites will refresh

 
  // To check if a user is logged in or not
  useEffect(() => {
    // const unsubscribe = auth().onAuthStateChanged(user => {
    //   if (user) {
    //     setIsUserLogged(true);
    //   } else {
    //     setIsUserLogged(false);
    //   }
    // })
    // return unsubscribe;

    //Download(cache) map of Sarajevo so it can be used offline
    //uncomment conosle logs in 2 functions below to see staus/error of maps being downloaded
    const progressListener = (offlineRegion, status) => {//console.log(offlineRegion, status)
    };
    const errorListener = (offlineRegion, err) => {
      //console.log(offlineRegion, err)
    };
    //This part below starts the actual download of map
    try{
         MapboxGL.offlineManager.createPack({
      name: 'offlinePack',//name of the part of map being downloaded, can be anything
      styleURL: MapboxGL.StyleURL.Street,//style of map which is being downloaded
      minZoom: 14,//minimum zoom of downloaded map
      maxZoom: 22,//maximum zoom of downloaded map, 22 max, if increased from 16 to 22 it wont increase number of tiles being downloaded
      // bounds explanation:  point1, point2=>[point1.longtitude,point1.latitude],[point2.longtitude,point2.latitude]
      bounds: [[18.2292, 43.7934], [18.5374, 43.8878]]//area for which map will be downloaded, rectangle defined with these two points
    }, progressListener, errorListener)
  }
  catch(e)
  {

  }

  }, [])


  // const [isMoving, setIsMoving] = React.useState(false);
  // const [location, setLocation] = React.useState(null);
  // const [odometer, setOdometer] = React.useState(0);
  // const [motionActivityEvent, setMotionActivityEvent] = React.useState(null);
  const [currentLocation, setCurrentLocation] = useState([0, 0]);
  const [isDebug, setIsDebug] = useState(true)

  const getBackgroundGeolocationState = async () => {
    let state = await BackgroundGeolocation.getState();
    if (state) {
      setIsDebug(state.debug);
    }
  };

  useEffect(() => {
    //hydrate redux data
   getUserLocationFromStorage().then(data=>{if(data)dispatch(setUserLocationCoordinates(data))}) 
    getBackgroundGeolocationState();
    // Subscribe to events.   -> show in console
    // BackgroundGeolocation.onLocation((location) => {
    //  // console.log('[onLocation]', location);
    // })
    // BackgroundGeolocation.onMotionChange((event) => {
    //  // console.log('[onMotionChange]', event);
    // });
    // BackgroundGeolocation.onActivityChange((event) => {
    //  // console.log('[onMotionChange]', event);
    // })
    // BackgroundGeolocation.onProviderChange((event) => {
    //  // console.log('[onProviderChange]', event);
    // })
    // Register BackgroundGeolocation event-listeners with setted states -> for odometer and stuff
    // const locationSubscriber = BackgroundGeolocation.onLocation(setLocation, (error) => {
    //   console.warn('[onLocation] ERROR: ', error);
    // });
    // const motionChangeSubscriber = BackgroundGeolocation.onMotionChange((location) => {
    //   setIsMoving(location.isMoving);
    // });
    // const activityChangeSubscriber = BackgroundGeolocation.onActivityChange(setMotionActivityEvent);

    // 2. ready the plugin.
    initBackgroundGeolocation();
    // Configure BackgroundFetch -> TO TEST !
    // initBackgroundFetch();
    // getCurrentPosition();
    // Get current position for positioning map
    //getCurrentPosition();
    //getLocation();
    // return () => {
    //   // When view is destroyed (or refreshed with dev live-reload), -> to test
    //   // Remove BackgroundGeolocation event-listeners.
    //   // locationSubscriber.remove();
    //   // motionChangeSubscriber.remove();
    //   // activityChangeSubscriber.remove();
    // }
  }, []);

  useEffect(() => {
    BackgroundGeolocation.setConfig({
      debug: isDebug,
    }).then(state => {
      console.log('[setConfig] success: ', state.debug);
    });
  }, [isDebug]);

  const debugToggle = () => {
    setIsDebug(prevState => !prevState);
  };
  /*  ### ⚠️ Warning:
    Do not execute *any* API method which will require accessing location-services 
    until the callback to [[ready]] executes (eg: [[getCurrentPosition]], [[watchPosition]], [[start]]).
  */
  const initBackgroundGeolocation = async () => {
    // Ready the SDK and fetch the current state.
    const state = await BackgroundGeolocation.ready({
      // Geolocation Config
      desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
      distanceFilter: 10,
      // Activity Recognition
      stopTimeout: 5,
      // Debug
      debug: isDebug, // <-- enable this hear sounds for background-geolocation life-cycle.
      logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
      // Application config
      stopOnTerminate: false, // <-- Allow the background-service to continue tracking when user closes the app.
      startOnBoot: true, // <-- Auto start tracking when device is powered-up.
      enableHeadless: true,
      // Permissions
      locationAuthorizationRequest: 'Always',
      backgroundPermissionRationale: {
        title:
          "Allow MapToBe to access this device's location even when closed or not in use.",
        message:
          'This app collects location data to enable recording your trips to work and calculate distance-travelled.',
        positiveAction: 'Change to "{backgroundPermissionOptionLabel}"',
        negativeAction: 'Cancel',
      },
    });

    // setOdometer(state.odometer);
    // setEnabled(state.enabled);
    // setIsMoving(state.isMoving||false);
    BackgroundGeolocation.start().then(state => {
      console.log('[start] success - ', state);
      getCurrentPosition();
    });
    // if (state.trackingMode == 1) {
    //   BackgroundGeolocation.start();
    // } else {
    //   console.log("dva")
    //   BackgroundGeolocation.startGeofences();
    // }
  };

  const initBackgroundFetch = async () => {
    BackgroundFetch.configure(
      {
        minimumFetchInterval: 15,
        enableHeadless: true,
        stopOnTerminate: false,
      },
      async taskId => {
        console.log('[BackgroundFetch]', taskId);
        BackgroundFetch.finish(taskId);
      },
      taskId => {
        console.log('[BackgroundFetch] TIMEOUT:', taskId);
        BackgroundFetch.finish(taskId);
      },
    );
  };

  // NEW: BG get current position
  // This functionality should be added on the UI also so user can locate himself
  const getCurrentPosition = async () => {
    // this is just for precaution
    //const state = await BackgroundGeolocation.getState();
    if (true) {
      console.log('getting psoitions')
      BackgroundGeolocation.getCurrentPosition({
        persist: true,
        samples: 3,
        timeout: 30,
        maximumAge: 5000, // Accept the last-known-location if not older than 5000 ms.
        desiredAccuracy: 10, // Try to fetch a location with an accuracy of `10` meters.
        extras: {
          getCurrentPosition: true,
        },
      })
        .then(location => {
          console.log(
            '[getCurrentPosition] success: ',
            location.coords.latitude,
            location.coords.longitude,
          );
          setCurrentLocation([
            location.coords.latitude,
            location.coords.longitude,
          ]);
          addUserLocationToStorage([location.coords.longitude,location.coords.latitude ])
          dispatch(setUserLocationCoordinates([location.coords.longitude,location.coords.latitude, ]))
          dispatch(setUserLocationHeading(location.coords.heading))
        })
        .catch(error => {
          console.warn('[getCurrentPosition] error: ', error);
        });
    }
  };

  /**
   ** Invokes hasLocationPermission from LocationPermission.js
   ** Invokes getCurrentPosition from Geolocation module that returns current position
   ** Sets currentLocation state with current position
   ** TODO: move this method in LocationPermission.js, invoke this method in headless task
   */
  const getLocation = async () => {
    const hasPermission = await hasLocationPermission();
    if (!hasPermission) {
      return;
    }

    Geolocation.getCurrentPosition(
      position => {
        setCurrentLocation([
          position.coords.longitude,
          position.coords.latitude,
        ]);
        addUserLocationToStorage([
          position.coords.latitude,
          position.coords.longitude])
        dispatch(setUserLocationCoordinates([
          position.coords.latitude,
          position.coords.longitude,
        ]));
        dispatch(setUserLocationHeading(position.coords.heading));
        // addCLToStorage([position.coords.longitude, position.coords.latitude]);
        console.log('current position', currentLocation);
      },
      error => {
        console.log(error);
      },
      {
        /*  accuracy: {
            android: 'high',
            ios: 'best',
          },*/
        enableHighAccuracy: true,
        //timeout: 5000,
        maximumAge: 3600000,
        distanceFilter: 0,
        forceRequestLocation: true,
        showLocationDialog: true,
      },
    );
  };

  return (
    <View style={{backgroundColor:'red',width:'100%',height:'100%'}}>
   {children}
   </View>);
};

export default BackgroundGeolocationWrapper;