TP-35796 | replaced redux with async storage
This commit is contained in:
@@ -2,6 +2,7 @@ import { type ReactNode, useEffect, useRef } from 'react';
|
||||
import { type NativeEventSubscription, AppState, type AppStateStatus } from 'react-native';
|
||||
import dayJs from 'dayjs';
|
||||
import dayjs from 'dayjs';
|
||||
import { setItem, getItem } from '../components/utlis/storageHelper';
|
||||
import UnstoppableService, {
|
||||
type IForegroundTask,
|
||||
} from '../services/foregroundServices/foreground.service';
|
||||
@@ -15,7 +16,6 @@ import { useAppDispatch, useAppSelector } from '../hooks';
|
||||
import { dataSyncService } from '../services/dataSync.service';
|
||||
import { DATA_SYNC_TIME_INTERVAL, IS_DATA_SYNC_REQUIRED } from '../constants/config';
|
||||
import useIsLocationEnabled from '../hooks/useIsLocationEnabled';
|
||||
import { setAppForegroundTimestamp, setAppBackgroundTimestamp } from '../reducer/metadataSlice';
|
||||
import {
|
||||
type ISyncCaseIdPayload,
|
||||
type ISyncedCases,
|
||||
@@ -27,9 +27,10 @@ import {
|
||||
import { getSyncCaseIds } from '../components/utlis/firebaseFallbackUtils';
|
||||
import { syncCasesByFallback } from '../reducer/allCasesSlice';
|
||||
import { MILLISECONDS_IN_A_MINUTE } from '../../RN-UI-LIB/src/utlis/common';
|
||||
import { setIsActiveUser, setLockData } from '../reducer/userSlice';
|
||||
import { setLockData } from '../reducer/userSlice';
|
||||
import { getConfigData } from '../action/configActions';
|
||||
import { AppStates } from '../types/appStates';
|
||||
import { StorageKeys } from '../types/storageKeys';
|
||||
|
||||
export enum FOREGROUND_TASKS {
|
||||
GEOLOCATION = 'GEOLOCATION',
|
||||
@@ -44,15 +45,15 @@ interface ITrackingComponent {
|
||||
}
|
||||
|
||||
let LAST_SYNC_STATUS = 'SKIP';
|
||||
const ACTIVITY_TIME_ON_APP = 5; // 5 seconds
|
||||
const ACTIVITY_TIME_WINDOW = 10; // 10 minutes
|
||||
|
||||
const TrackingComponent: React.FC<ITrackingComponent> = ({ children }) => {
|
||||
const isOnline = useIsOnline();
|
||||
const dispatch = useAppDispatch();
|
||||
const appState = useRef(AppState.currentState);
|
||||
const user = useAppSelector((state) => state.user);
|
||||
const foregroundTimestamp = useAppSelector((state) => state.metadata.appForegroundTimestamp);
|
||||
const backgroundTimestamp = useAppSelector((state) => state.metadata.appBackgroundTimestamp);
|
||||
const isActive = useAppSelector((state) => state.user.user.isActive);
|
||||
const isActive = useAppSelector((state) => state?.user?.user?.isActive);
|
||||
|
||||
const {
|
||||
referenceId,
|
||||
@@ -88,7 +89,9 @@ const TrackingComponent: React.FC<ITrackingComponent> = ({ children }) => {
|
||||
})
|
||||
);
|
||||
if (user.isLoggedIn) {
|
||||
await sendLocationAndActivenessToServer(location, isActive);
|
||||
const isUserActive: string | boolean =
|
||||
(await getItem(StorageKeys.IS_USER_ACTIVE)) || false;
|
||||
await sendLocationAndActivenessToServer(location, Boolean(isUserActive));
|
||||
}
|
||||
}
|
||||
} catch (e: any) {
|
||||
@@ -129,12 +132,38 @@ const TrackingComponent: React.FC<ITrackingComponent> = ({ children }) => {
|
||||
};
|
||||
|
||||
const handleUpdateActiveness = async () => {
|
||||
const foregroundTime = foregroundTimestamp;
|
||||
const backgroundTime = backgroundTimestamp;
|
||||
const diff = dayjs(foregroundTime).diff(dayjs(backgroundTime), 'minute');
|
||||
if (diff <= 10) {
|
||||
setIsActiveUser(true);
|
||||
const foregroundTimestamp = await getItem(StorageKeys.APP_FOREGROUND_TIMESTAMP);
|
||||
const backgroundTimestamp = await getItem(StorageKeys.APP_BACKGROUND_TIMESTAMP);
|
||||
const foregroundTime = dayjs(foregroundTimestamp);
|
||||
const backgroundTime = dayjs(backgroundTimestamp);
|
||||
const diffBetweenBackgroundAndForegroundTime = dayJs(backgroundTime).diff(
|
||||
foregroundTime,
|
||||
'seconds'
|
||||
);
|
||||
const diffBetweenCurrentTimeAndForegroundTime =
|
||||
dayjs().diff(foregroundTime, 'minutes') < 0 ? 0 : dayjs().diff(foregroundTime, 'minutes');
|
||||
const isForegroundTimeWithInRange =
|
||||
diffBetweenCurrentTimeAndForegroundTime <= ACTIVITY_TIME_WINDOW;
|
||||
const isForegroundTimeAfterBackground = dayjs(foregroundTimestamp).isAfter(backgroundTimestamp);
|
||||
console.log({
|
||||
diffBetweenBackgroundAndForegroundTime,
|
||||
diffBetweenCurrentTimeAndForegroundTime,
|
||||
isForegroundTimeWithInRange,
|
||||
isForegroundTimeAfterBackground,
|
||||
dayjs: dayjs().toString(),
|
||||
});
|
||||
if (isForegroundTimeWithInRange) {
|
||||
if (
|
||||
isForegroundTimeAfterBackground ||
|
||||
diffBetweenBackgroundAndForegroundTime >= ACTIVITY_TIME_ON_APP
|
||||
) {
|
||||
await setItem(StorageKeys.IS_USER_ACTIVE, 'true');
|
||||
return;
|
||||
}
|
||||
await setItem(StorageKeys.IS_USER_ACTIVE, 'false');
|
||||
}
|
||||
await setItem(StorageKeys.IS_USER_ACTIVE, 'false');
|
||||
return;
|
||||
};
|
||||
|
||||
const tasks: IForegroundTask[] = [
|
||||
@@ -165,7 +194,7 @@ const TrackingComponent: React.FC<ITrackingComponent> = ({ children }) => {
|
||||
{
|
||||
taskId: FOREGROUND_TASKS.UPDATE_AGENT_ACTIVENESS,
|
||||
task: handleUpdateActiveness,
|
||||
delay: 10 * MILLISECONDS_IN_A_MINUTE, // 10 minutes
|
||||
delay: ACTIVITY_TIME_WINDOW * MILLISECONDS_IN_A_MINUTE, // 10 minutes
|
||||
onLoop: true,
|
||||
},
|
||||
];
|
||||
@@ -181,15 +210,15 @@ const TrackingComponent: React.FC<ITrackingComponent> = ({ children }) => {
|
||||
|
||||
const handleAppStateChange = async (nextAppState: AppStateStatus) => {
|
||||
// App comes to foreground from background
|
||||
console.log('next app state', nextAppState);
|
||||
const now = dayjs().toString();
|
||||
if (nextAppState === AppStates.ACTIVE) {
|
||||
setAppForegroundTimestamp(dayjs());
|
||||
await setItem(StorageKeys.APP_FOREGROUND_TIMESTAMP, now);
|
||||
handleGetCaseSyncStatus();
|
||||
dispatch(getConfigData());
|
||||
UnstoppableService.start(tasks);
|
||||
}
|
||||
if (nextAppState === 'background') {
|
||||
setAppBackgroundTimestamp(dayjs());
|
||||
if (nextAppState === AppStates.BACKGROUND) {
|
||||
await setItem(StorageKeys.APP_BACKGROUND_TIMESTAMP, now);
|
||||
}
|
||||
appState.current = nextAppState;
|
||||
};
|
||||
|
||||
6
src/components/utlis/storageHelper.ts
Normal file
6
src/components/utlis/storageHelper.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
export const setItem = async (key: string, value: string): Promise<void> => {
|
||||
await AsyncStorage.setItem(key, value);
|
||||
};
|
||||
export const getItem = async (key: string): Promise<any> => await AsyncStorage.getItem(key);
|
||||
@@ -1,4 +1,4 @@
|
||||
import { GeoCoordinates } from 'react-native-geolocation-service';
|
||||
import { type GeoCoordinates } from 'react-native-geolocation-service';
|
||||
import axiosInstance, { ApiKeys, getApiUrl } from '../components/utlis/apiHelper';
|
||||
|
||||
export const sendLocationAndActivenessToServer = async (
|
||||
@@ -14,6 +14,7 @@ export const sendLocationAndActivenessToServer = async (
|
||||
longitude: location?.longitude,
|
||||
accuracy: location?.accuracy,
|
||||
timestamp: new Date().getTime(),
|
||||
isUserActive: isActive,
|
||||
},
|
||||
],
|
||||
{
|
||||
|
||||
@@ -9,16 +9,12 @@ interface IMetadata {
|
||||
isOnline: boolean;
|
||||
forceUninstall: Record<string, UninstallInformation>;
|
||||
isWifiOrCellularOn: boolean;
|
||||
appForegroundTimestamp: string;
|
||||
appBackgroundTimestamp: string;
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
isOnline: true,
|
||||
forceUninstall: {},
|
||||
isWifiOrCellularOn: true,
|
||||
appForegroundTimestamp: '',
|
||||
appBackgroundTimestamp: '',
|
||||
} as IMetadata;
|
||||
|
||||
const MetadataSlice = createSlice({
|
||||
@@ -34,21 +30,9 @@ const MetadataSlice = createSlice({
|
||||
setIsWifiOrCellularOn: (state, action) => {
|
||||
state.isWifiOrCellularOn = action.payload;
|
||||
},
|
||||
setAppForegroundTimestamp: (state, action) => {
|
||||
state.appForegroundTimestamp = action.payload;
|
||||
},
|
||||
setAppBackgroundTimestamp: (state, action) => {
|
||||
state.appBackgroundTimestamp = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
setIsOnline,
|
||||
setForceUninstallData,
|
||||
setIsWifiOrCellularOn,
|
||||
setAppForegroundTimestamp,
|
||||
setAppBackgroundTimestamp,
|
||||
} = MetadataSlice.actions;
|
||||
export const { setIsOnline, setForceUninstallData, setIsWifiOrCellularOn } = MetadataSlice.actions;
|
||||
|
||||
export default MetadataSlice.reducer;
|
||||
|
||||
@@ -21,8 +21,6 @@ interface IUserDetails {
|
||||
name: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
// check weather user is recently active on app or not
|
||||
isActive: boolean;
|
||||
}
|
||||
|
||||
export interface IUser {
|
||||
@@ -88,12 +86,9 @@ export const userSlice = createSlice({
|
||||
state.lock = action.payload;
|
||||
}
|
||||
},
|
||||
setIsActiveUser: (state, action) => {
|
||||
state.user.isActive = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const { setAuthData, setDeviceId, setLockData, setIsActiveUser } = userSlice.actions;
|
||||
export const { setAuthData, setDeviceId, setLockData } = userSlice.actions;
|
||||
|
||||
export default userSlice.reducer;
|
||||
|
||||
5
src/types/storageKeys.ts
Normal file
5
src/types/storageKeys.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export enum StorageKeys {
|
||||
APP_FOREGROUND_TIMESTAMP = 'appForegroundTimestamp',
|
||||
APP_BACKGROUND_TIMESTAMP = 'appBackgroundTimestamp',
|
||||
IS_USER_ACTIVE = 'isUserActive',
|
||||
}
|
||||
Reference in New Issue
Block a user