TP-35796 | replaced redux with async storage

This commit is contained in:
Varnit Goyal
2023-08-02 13:32:18 +05:30
parent 5c0fb462b5
commit d7ce59de3a
6 changed files with 60 additions and 40 deletions

View File

@@ -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;
};

View 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);

View File

@@ -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,
},
],
{

View File

@@ -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;

View File

@@ -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
View File

@@ -0,0 +1,5 @@
export enum StorageKeys {
APP_FOREGROUND_TIMESTAMP = 'appForegroundTimestamp',
APP_BACKGROUND_TIMESTAMP = 'appBackgroundTimestamp',
IS_USER_ACTIVE = 'isUserActive',
}