diff --git a/src/components/form/services/geoLocation.service.ts b/src/components/form/services/geoLocation.service.ts index 720aecac..23032138 100644 --- a/src/components/form/services/geoLocation.service.ts +++ b/src/components/form/services/geoLocation.service.ts @@ -36,7 +36,6 @@ export class CaptureGeolocation { //to make it singleton } private static setCapturing(caseId: string, isCapturing: boolean) { - CaptureGeolocation.capturedLocation = { ...CaptureGeolocation.capturedLocation, [caseId]: { @@ -47,19 +46,19 @@ export class CaptureGeolocation { } static async fetchLocation( forCaseId: string, + cacheTTL: number = FIVE_MIN, ): Promise { - + return new Promise(async (resolve, reject) => { let cachedLocation = CaptureGeolocation.capturedLocation?.[forCaseId]; if ( cachedLocation && - Date.now() - (cachedLocation?.location?.timestamp || 0) < FIVE_MIN + Date.now() - (cachedLocation?.location?.timestamp || 0) < cacheTTL ) { - - return cachedLocation?.location?.coords; + return resolve(cachedLocation?.location?.coords); } if (cachedLocation && cachedLocation?.isCapturing) { console.info('Capture already in progress. Returning'); - return; + resolve(undefined); } CaptureGeolocation.setCapturing(forCaseId, true); const isLocationOn = await requestLocationPermission(); @@ -69,15 +68,16 @@ export class CaptureGeolocation { type: 'error', text1: 'Please enable location to continue.', }); - return; + resolve(undefined); } Geolocation.getCurrentPosition( - position => { + position => { CaptureGeolocation.capturedLocation = { ...(CaptureGeolocation.capturedLocation || {}), [forCaseId]: { location: position, isCapturing: false }, }; - return position.coords; + CaptureGeolocation.setCapturing(forCaseId, false); + resolve(position.coords); }, error => { toast({ @@ -86,9 +86,10 @@ export class CaptureGeolocation { }); CaptureGeolocation.setCapturing(forCaseId, false); logError(error as any, 'Unable to get location'); - return; + reject(undefined); }, { enableHighAccuracy: true, timeout: 1e4, maximumAge: 1e4 }, ); + }); } } diff --git a/src/components/utlis/apiHelper.ts b/src/components/utlis/apiHelper.ts index 2e2b5eb1..0a626b0f 100644 --- a/src/components/utlis/apiHelper.ts +++ b/src/components/utlis/apiHelper.ts @@ -28,6 +28,7 @@ export enum ApiKeys { CASE_UNIFIED_DETAILS, EMI_SCHEDULES, PAST_FEEDBACK, + SEND_LOCATION, } export const API_URLS: Record = {} as Record; @@ -47,6 +48,7 @@ API_URLS[ApiKeys.GET_SIGNED_URL] = '/cases/get-signed-urls'; API_URLS[ApiKeys.CASE_UNIFIED_DETAILS] = '/collection-cases/unified-details/{loanAccountNumber}'; API_URLS[ApiKeys.EMI_SCHEDULES] = '/collection-cases/emi-schedules'; API_URLS[ApiKeys.PAST_FEEDBACK] = '/feedback'; +API_URLS[ApiKeys.SEND_LOCATION] = '/geolocations/agents'; export const API_STATUS_CODE = { OK: 200, diff --git a/src/hooks/capturingApi.ts b/src/hooks/capturingApi.ts new file mode 100644 index 00000000..6169ce40 --- /dev/null +++ b/src/hooks/capturingApi.ts @@ -0,0 +1,28 @@ +import { GeoCoordinates } from 'react-native-geolocation-service'; +import axiosInstance, { + ApiKeys, + getApiUrl, +} from '../components/utlis/apiHelper'; + +export const sendLocationToServer = async (location: GeoCoordinates) => { + try { + const response = await axiosInstance.post( + getApiUrl(ApiKeys.SEND_LOCATION), + [ + { + latitude: location?.latitude, + longitude: location?.longitude, + accuracy: location?.accuracy, + timestamp: new Date().getTime(), + }, + ], + { + headers: { + donotHandleError: 'true', + }, + }, + ); + } catch (error) { + console.log(error); + } +}; diff --git a/src/hooks/useNativeButton.tsx b/src/hooks/useNativeButton.tsx index 249e2b99..3d976283 100644 --- a/src/hooks/useNativeButton.tsx +++ b/src/hooks/useNativeButton.tsx @@ -1,22 +1,38 @@ import React, { useEffect, useRef, useState } from 'react'; import { BackHandler, AppState, AppStateStatus } from 'react-native'; +import { GeoCoordinates } from 'react-native-geolocation-service'; import { CLICKSTREAM_EVENT_NAMES } from '../common/Constants'; +import { CaptureGeolocation } from '../components/form/services/geoLocation.service'; import { addClickstreamEvent } from '../services/clickstreamEventService'; +import { sendLocationToServer } from './capturingApi'; +const THREE_MINUTES = 3 * 60 * 1000; const useNativeButtons = () => { const appState = useRef(AppState.currentState); + const intervalRef = useRef(0); const handleBackButton = () => { addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_NATIVE_BACK_PRESSED); return false; }; - const handleAppStateChange = (nextAppState: AppStateStatus) => { + const fetchAndSendToserver = async () => { + const location = await CaptureGeolocation.fetchLocation( + 'FETCH_LOCATION', + 0, + ); + if (location) { + sendLocationToServer(location); + } + }; + + const handleAppStateChange = async (nextAppState: AppStateStatus) => { if ( appState.current.match(/inactive|background/) && nextAppState === 'active' ) { addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_APP_FOREGROUND); + fetchAndSendToserver(); } if ( appState.current === 'active' && @@ -36,10 +52,15 @@ const useNativeButtons = () => { 'change', handleAppStateChange, ); + fetchAndSendToserver(); + intervalRef.current = setInterval(() => { + fetchAndSendToserver(); + }, THREE_MINUTES); return () => { backHandler.remove(); appStateSubscription.remove(); + clearInterval(intervalRef.current); }; }, []); };