location capture || Aman Singh (#129)
* location capture * askForPermission function else part corrected * askForPermission function else part corrected * added granted from Enum * Removed extra import came form merge conflict
This commit is contained in:
committed by
GitHub Enterprise
parent
d82c740da4
commit
d4b8e018e5
39
App.tsx
39
App.tsx
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { KeyboardAvoidingView,LogBox } from 'react-native';
|
||||
import { LogBox, PermissionsAndroid, Platform , KeyboardAvoidingView, PermissionStatus} from 'react-native';
|
||||
import {Provider} from 'react-redux';
|
||||
import store, {persistor} from './src/store/store';
|
||||
import {PersistGate} from 'redux-persist/integration/react';
|
||||
@@ -8,7 +8,7 @@ import {NavigationContainer} from '@react-navigation/native';
|
||||
import {navigationRef} from './src/components/utlis/navigationUtlis';
|
||||
import FullScreenLoader from './RN-UI-LIB/src/components/FullScreenLoader';
|
||||
import ProtectedRouter from './ProtectedRouter';
|
||||
import { toastConfigs, ToastContainer } from './RN-UI-LIB/src/components/toast';
|
||||
import { toast, toastConfigs, ToastContainer } from './RN-UI-LIB/src/components/toast';
|
||||
|
||||
import ErrorBoundary from './src/common/ErrorBoundary';
|
||||
|
||||
@@ -20,6 +20,8 @@ import { COLORS } from './RN-UI-LIB/src/styles/colors';
|
||||
import codePush from 'react-native-code-push';
|
||||
import { ENV } from './src/constants/config';
|
||||
import { mockApiServer } from './src/mock-api/server';
|
||||
import Text from './RN-UI-LIB/src/components/Text';
|
||||
import { PermissionStatusEnum } from './src/services/geolocation.service';
|
||||
Sentry.init({ dsn: SENTRY_DSN });
|
||||
|
||||
if (ENV !== 'prod') {
|
||||
@@ -28,8 +30,38 @@ if (ENV !== 'prod') {
|
||||
|
||||
LogBox.ignoreAllLogs();
|
||||
|
||||
|
||||
const askForPermissions = (setPermissions:React.Dispatch<React.SetStateAction<boolean>> ) => {
|
||||
if (Platform.OS === 'android') {
|
||||
PermissionsAndroid.requestMultiple(
|
||||
[PermissionsAndroid.PERMISSIONS.CAMERA,
|
||||
PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
|
||||
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
|
||||
PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
|
||||
PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
|
||||
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE]
|
||||
).then((result) => {
|
||||
if (result['android.permission.ACCESS_COARSE_LOCATION']
|
||||
&& result['android.permission.CAMERA']
|
||||
&& result['android.permission.READ_CONTACTS']
|
||||
&& result['android.permission.ACCESS_FINE_LOCATION']
|
||||
&& result['android.permission.READ_EXTERNAL_STORAGE']
|
||||
&& result['android.permission.WRITE_EXTERNAL_STORAGE'] === PermissionStatusEnum.GRANTED) {
|
||||
setPermissions(true)
|
||||
} else {
|
||||
toast({type:'info', text1:'Please Go into Settings -> Applications -> Field App -> Permissions and Allow permissions to continue'});
|
||||
setPermissions(false)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const App = () => {
|
||||
useNativeButtons();
|
||||
const [permissions, setPermissions] = React.useState(true);
|
||||
React.useEffect(()=>{
|
||||
askForPermissions(setPermissions);
|
||||
}, [])
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<PersistGate
|
||||
@@ -38,7 +70,8 @@ const App = () => {
|
||||
<NavigationContainer ref={navigationRef}>
|
||||
<StatusBar backgroundColor={COLORS.BACKGROUND.INDIGO_DARK} />
|
||||
<ErrorBoundary>
|
||||
<ProtectedRouter />
|
||||
{/* TODO: ASK Adhya for designs its been more than 1 month */}
|
||||
{permissions ? <ProtectedRouter /> : <Text>Please grant Permisisons</Text>}
|
||||
</ErrorBoundary>
|
||||
</NavigationContainer>
|
||||
{
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"react-native": "0.70.6",
|
||||
"react-native-code-push": "7.1.0",
|
||||
"react-native-device-info": "10.3.0",
|
||||
"react-native-geolocation-service": "5.3.1",
|
||||
"react-native-image-picker": "4.10.2",
|
||||
"react-native-pager-view": "6.1.2",
|
||||
"react-native-permissions": "3.6.1",
|
||||
|
||||
@@ -4,11 +4,10 @@ import {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
TouchableHighlight,
|
||||
View,
|
||||
View
|
||||
} from 'react-native';
|
||||
import Geolocation from 'react-native-geolocation-service';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { useNavigationState } from '@react-navigation/native';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import Button from '../../../RN-UI-LIB/src/components/Button';
|
||||
import Heading from '../../../RN-UI-LIB/src/components/Heading';
|
||||
import Text from '../../../RN-UI-LIB/src/components/Text';
|
||||
@@ -16,22 +15,24 @@ import ArrowSolidIcon from '../../../RN-UI-LIB/src/Icons/ArrowSolidIcon';
|
||||
import CloseIcon from '../../../RN-UI-LIB/src/Icons/CloseIcon';
|
||||
import { GenericStyles, getShadowStyle } from '../../../RN-UI-LIB/src/styles';
|
||||
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
|
||||
import { useAppDispatch, useAppSelector } from '../../hooks';
|
||||
import { getUpdatedAVCaseDetail, getUpdatedCollectionCaseDetail, updateCaseDetail } from '../../reducer/allCasesSlice';
|
||||
import { deleteInteraction, deleteJourney, updateInteraction, } from '../../reducer/caseReducer';
|
||||
import { getTemplateRoute, getWidgetNameFromRoute, goBack, navigateToScreen, } from '../utlis/navigationUtlis';
|
||||
import RenderQuestion from './RenderQuestion';
|
||||
import Submit from './Submit';
|
||||
import { addClickstreamEvent } from '../../services/clickstreamEventService';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from '../../common/Constants';
|
||||
import Layout from '../../screens/layout/Layout';
|
||||
import { getNextJourneyActions, getNextWidget } from "./services/forms.service";
|
||||
import { FormTemplateV1 } from "../../types/template.types";
|
||||
import { CaseAllocationType } from "../../screens/allCases/interface";
|
||||
import useIsOnline from '../../hooks/useIsOnline';
|
||||
import { getUnSyncedCase } from '../../screens/caseDetails/interactionsHandler';
|
||||
import { getTransformedAvCase, getTransformedCollectionCaseItem } from '../../services/casePayload.transformer';
|
||||
import { syncCaseDetail } from '../../action/dataActions';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from '../../common/Constants';
|
||||
import { useAppDispatch, useAppSelector } from '../../hooks';
|
||||
import useIsOnline from '../../hooks/useIsOnline';
|
||||
import { getUpdatedAVCaseDetail, getUpdatedCollectionCaseDetail, updateCaseDetail } from '../../reducer/allCasesSlice';
|
||||
import { deleteInteraction, deleteJourney, updateInteraction } from '../../reducer/caseReducer';
|
||||
import { CaseAllocationType } from "../../screens/allCases/interface";
|
||||
import { getUnSyncedCase } from '../../screens/caseDetails/interactionsHandler';
|
||||
import Layout from '../../screens/layout/Layout';
|
||||
import { getTransformedAvCase, getTransformedCollectionCaseItem } from '../../services/casePayload.transformer';
|
||||
import { addClickstreamEvent } from '../../services/clickstreamEventService';
|
||||
import { FormTemplateV1 } from "../../types/template.types";
|
||||
import { logError } from '../utlis/errorUtils';
|
||||
import { getTemplateRoute, getWidgetNameFromRoute, goBack, navigateToScreen } from '../utlis/navigationUtlis';
|
||||
import RenderQuestion from './RenderQuestion';
|
||||
import { getNextJourneyActions, getNextWidget } from "./services/forms.service";
|
||||
import { requestLocationPermission } from './services/geoLocation.service';
|
||||
import Submit from './Submit';
|
||||
import { toast } from '../../../RN-UI-LIB/src/components/toast';
|
||||
|
||||
interface IWidget {
|
||||
@@ -134,11 +135,27 @@ const Widget: React.FC<IWidget> = props => {
|
||||
);
|
||||
}
|
||||
|
||||
const handleSubmitJourney = async(data: any) => {
|
||||
const submitJourneyWithGeoLocation = (data: any) => {
|
||||
addClickstreamEvent(
|
||||
CLICKSTREAM_EVENT_NAMES.AV_FORM_SUBMIT_BUTTON_CLICKED,
|
||||
{ caseId, journeyId: journey, widgetId: name },
|
||||
);
|
||||
const isLocationOn = requestLocationPermission();
|
||||
if(!isLocationOn) return;
|
||||
Geolocation.getCurrentPosition(
|
||||
position => {
|
||||
return handleSubmitJourney(data, position.coords);
|
||||
},
|
||||
error => {
|
||||
logError((error as any), "Unable to get location")
|
||||
return;
|
||||
},
|
||||
{ enableHighAccuracy: true, timeout: 15e3, maximumAge: 1e4 },
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
const handleSubmitJourney = async(data: any, coords: Geolocation.GeoCoordinates) => {
|
||||
dispatch(
|
||||
updateInteraction({
|
||||
caseId,
|
||||
@@ -146,9 +163,9 @@ const Widget: React.FC<IWidget> = props => {
|
||||
widgetId: name,
|
||||
answer: data,
|
||||
}),
|
||||
);
|
||||
);
|
||||
if (caseType === CaseAllocationType.COLLECTION_CASE) {
|
||||
const updatedCase = getUpdatedCollectionCaseDetail({caseData, answer: data});
|
||||
const updatedCase = getUpdatedCollectionCaseDetail({caseData, answer: data, coords});
|
||||
if(isOnline) {
|
||||
setShowSubmitLoader(true);
|
||||
const unsyncedCase = getUnSyncedCase(updatedCase);
|
||||
@@ -196,6 +213,7 @@ const Widget: React.FC<IWidget> = props => {
|
||||
caseData,
|
||||
nextActions,
|
||||
templateId,
|
||||
coords
|
||||
});
|
||||
|
||||
if(isOnline) {
|
||||
@@ -373,7 +391,7 @@ const Widget: React.FC<IWidget> = props => {
|
||||
showLoader={isLeaf && showSubmitLoader}
|
||||
onPress={
|
||||
isLeaf
|
||||
? handleSubmit(handleSubmitJourney, onError)
|
||||
? handleSubmit(submitJourneyWithGeoLocation, onError)
|
||||
: handleSubmit(onSubmit, onError)
|
||||
}
|
||||
rightIcon={
|
||||
|
||||
19
src/components/form/services/geoLocation.service.ts
Normal file
19
src/components/form/services/geoLocation.service.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { PermissionsAndroid } from "react-native";
|
||||
|
||||
export const requestLocationPermission = async () => {
|
||||
try {
|
||||
const granted = await PermissionsAndroid.request(
|
||||
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
|
||||
{
|
||||
title: 'Geolocation Permission',
|
||||
message: 'Can we access your location?',
|
||||
buttonNeutral: 'Ask Me Later',
|
||||
buttonNegative: 'Cancel',
|
||||
buttonPositive: 'OK',
|
||||
},
|
||||
);
|
||||
return granted === 'granted';
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -66,7 +66,24 @@ const initialState: IAllCasesSlice = {
|
||||
visitPlansUpdating: false,
|
||||
};
|
||||
|
||||
export const getUpdatedCollectionCaseDetail = ({caseData, answer}: any) => {
|
||||
const getPinnedListDetails = (casesList: ICaseItem[]) => {
|
||||
let maxPinnedRank = 0;
|
||||
const pinnedList: ICaseItem[] = [];
|
||||
casesList.forEach(caseItem => {
|
||||
const { pinRank } = caseItem;
|
||||
if (pinRank === null || pinRank === undefined) {
|
||||
return;
|
||||
}
|
||||
pinnedList.push(caseItem);
|
||||
if (pinRank > maxPinnedRank) {
|
||||
maxPinnedRank = pinRank;
|
||||
}
|
||||
});
|
||||
return { pinnedList, maxPinnedRank };
|
||||
};
|
||||
|
||||
export const getUpdatedCollectionCaseDetail = ({caseData, answer, coords}: any) => {
|
||||
|
||||
const updatedValue = { ...caseData };
|
||||
updatedValue.isSynced = false;
|
||||
updatedValue.isApiCalled = false;
|
||||
@@ -83,10 +100,11 @@ export const getUpdatedCollectionCaseDetail = ({caseData, answer}: any) => {
|
||||
allocationReferenceId: answer.allocationReferenceId,
|
||||
};
|
||||
updatedValue.answer = newAnswer;
|
||||
updatedValue.coords = coords;
|
||||
return updatedValue;
|
||||
};
|
||||
|
||||
export const getUpdatedAVCaseDetail = ({journeyId, answer, caseData, nextActions, templateId}: any) => {
|
||||
export const getUpdatedAVCaseDetail = ({journeyId, answer, caseData, nextActions, templateId, coords}: any) => {
|
||||
const updatedValue = { ...caseData };
|
||||
updatedValue.isSynced = false;
|
||||
updatedValue.isApiCalled = false;
|
||||
@@ -170,6 +188,7 @@ export const getUpdatedAVCaseDetail = ({journeyId, answer, caseData, nextActions
|
||||
updatedValue.caseStatus = CaseStatuses.CLOSED;
|
||||
updatedValue.caseVerdict = caseVerdict.EXHAUSTED;
|
||||
}
|
||||
updatedValue.coords = coords;
|
||||
return updatedValue;
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { CaseDetail } from './../screens/caseDetails/interface';
|
||||
import { AnswerType } from '../components/form/interface';
|
||||
import OfflineImageDAO from '../wmDB/dao/OfflineImageDAO';
|
||||
import { CaseAllocationType } from '../screens/allCases/interface';
|
||||
import Geolocation from 'react-native-geolocation-service';
|
||||
|
||||
interface QuestionContext {
|
||||
answer: string;
|
||||
@@ -129,10 +130,10 @@ export const getImageFromOfflineDb = async (imageId: string) => {
|
||||
export interface IGetTransformedCaseItem extends CaseDetail {
|
||||
answer: any;
|
||||
caseId: string;
|
||||
coords: Geolocation.GeoCoordinates
|
||||
}
|
||||
export const getTransformedCollectionCaseItem = async (
|
||||
caseItem: IGetTransformedCaseItem,
|
||||
) => {
|
||||
caseItem: IGetTransformedCaseItem) => {
|
||||
let cloneCaseItem = { ...caseItem };
|
||||
let answerContextArray = await extractQuestionContext(
|
||||
cloneCaseItem?.answer,
|
||||
@@ -140,13 +141,13 @@ export const getTransformedCollectionCaseItem = async (
|
||||
let data = {
|
||||
caseReferenceId: caseItem.caseReferenceId,
|
||||
answers: answerContextArray,
|
||||
location: undefined,
|
||||
location: cloneCaseItem?.coords,
|
||||
};
|
||||
return { caseType: caseItem.caseType, data };
|
||||
};
|
||||
|
||||
export const getTransformedAvCase = async(caseItem: IGetTransformedCaseItem, templateId: string) => {
|
||||
const { caseType, allocationReferenceId, caseId } = caseItem;
|
||||
const { caseType, allocationReferenceId, caseId, coords } = caseItem;
|
||||
const transformedAvCase: any = {
|
||||
caseType: caseType || CaseAllocationType.ADDRESS_VERIFICATION_CASE,
|
||||
data: {
|
||||
@@ -155,6 +156,7 @@ export const getTransformedAvCase = async(caseItem: IGetTransformedCaseItem, tem
|
||||
caseReferenceId: caseId,
|
||||
taskStatuses: {},
|
||||
answers: [],
|
||||
location: coords,
|
||||
}
|
||||
}
|
||||
const taskContext = caseItem?.context?.taskContext;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { logError } from '../components/utlis/errorUtils';
|
||||
|
||||
const { RNFusedLocation } = NativeModules;
|
||||
|
||||
enum PermissionStatusEnum {
|
||||
export enum PermissionStatusEnum {
|
||||
GRANTED = 'granted',
|
||||
DENIED = 'denied',
|
||||
NEVER_ASK = 'never_ask_again'
|
||||
|
||||
@@ -7255,6 +7255,11 @@ react-native-device-info@10.3.0:
|
||||
resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-10.3.0.tgz#6bab64d84d3415dd00cc446c73ec5e2e61fddbe7"
|
||||
integrity sha512-/ziZN1sA1REbJTv5mQZ4tXggcTvSbct+u5kCaze8BmN//lbxcTvWsU6NQd4IihLt89VkbX+14IGc9sVApSxd/w==
|
||||
|
||||
react-native-geolocation-service@5.3.1:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-native-geolocation-service/-/react-native-geolocation-service-5.3.1.tgz#4ce1017789da6fdfcf7576eb6f59435622af4289"
|
||||
integrity sha512-LTXPtPNmrdhx+yeWG47sAaCgQc3nG1z+HLLHlhK/5YfOgfLcAb9HAkhREPjQKPZOUx8pKZMIpdGFUGfJYtimXQ==
|
||||
|
||||
react-native-gradle-plugin@^0.70.3:
|
||||
version "0.70.3"
|
||||
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.70.3.tgz#cbcf0619cbfbddaa9128701aa2d7b4145f9c4fc8"
|
||||
|
||||
Reference in New Issue
Block a user