TP-35981|device utils and routes and different flavors|Aman Singh
This commit is contained in:
9
App.tsx
9
App.tsx
@@ -32,8 +32,9 @@ import CodePush from 'react-native-code-push';
|
||||
import { TDocumentObj } from './src/screens/caseDetails/interface';
|
||||
import AuthRouter from './src/screens/auth/AuthRouter';
|
||||
import { initSentry } from './src/components/utlis/sentry';
|
||||
import { setGlobalBuildFlavour } from './src/constants/Global';
|
||||
import { getBuildFlavour } from './src/components/utlis/DeviceUtils';
|
||||
import { GLOBAL, setGlobalBuildConfig, setGlobalBuildFlavour } from './src/constants/Global';
|
||||
import { getBuildFlavour, getBuildInfo } from './src/components/utlis/DeviceUtils';
|
||||
import { get } from 'react-hook-form';
|
||||
|
||||
initSentry();
|
||||
|
||||
@@ -107,12 +108,14 @@ const App = () => {
|
||||
getBuildFlavour().then((flavour) => {
|
||||
setGlobalBuildFlavour(flavour);
|
||||
});
|
||||
getBuildInfo().then((buildInfo) => {
|
||||
setGlobalBuildConfig(JSON.parse(buildInfo));
|
||||
});
|
||||
checkCodePushAndSync();
|
||||
return () => {
|
||||
appStateChange.remove();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<PersistGate loading={<FullScreenLoader loading />} persistor={persistor}>
|
||||
|
||||
@@ -89,4 +89,16 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule implements Act
|
||||
promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getBuildInfo(Promise promise) {
|
||||
try {
|
||||
JSONObject mainObject = new JSONObject();
|
||||
mainObject.put("versionCode", BuildConfig.VERSION_CODE);
|
||||
mainObject.put("versionName", BuildConfig.VERSION_NAME);
|
||||
promise.resolve(mainObject.toString());
|
||||
} catch (Exception err) {
|
||||
promise.reject(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import { BLOCKER_SCREEN_DATA } from './Constants';
|
||||
import { useAppDispatch, useAppSelector } from '../hooks';
|
||||
import { setIsDeviceLocationEnabled } from '../reducer/foregroundServiceSlice';
|
||||
import { toast } from '../../RN-UI-LIB/src/components/toast';
|
||||
import { locationEnabled } from '../components/utlis/DeviceUtils';
|
||||
import { buildFlavour, locationEnabled } from '../components/utlis/DeviceUtils';
|
||||
import { GLOBAL } from '../constants/Global';
|
||||
|
||||
interface IBlockerScreen {
|
||||
children?: ReactNode;
|
||||
@@ -20,6 +21,7 @@ const RETRY_GEOLOCATION_STEPS =
|
||||
|
||||
const BlockerScreen = (props: IBlockerScreen) => {
|
||||
const [forceReinstallData, setForceReinstallData] = useState<UninstallInformation>();
|
||||
const [shouldUpdate, setShouldUpdate] = useState<boolean>();
|
||||
const { isTimeSynced, isDeviceLocationEnabled } = useAppSelector(
|
||||
(state) => state.foregroundService
|
||||
);
|
||||
@@ -32,6 +34,10 @@ const BlockerScreen = (props: IBlockerScreen) => {
|
||||
return state.metadata?.forceUninstall;
|
||||
});
|
||||
|
||||
const appUpdate = useSelector((state: RootState) => {
|
||||
return state.metadata?.appUpdate;
|
||||
});
|
||||
|
||||
function compareSemverVersions(a: string, b: string) {
|
||||
return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' });
|
||||
}
|
||||
@@ -54,12 +60,33 @@ const BlockerScreen = (props: IBlockerScreen) => {
|
||||
setForceReinstallData(undefined);
|
||||
}, [JSON.stringify(forceUninstallData || {})]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!appUpdate) return;
|
||||
const buildToCompare = GLOBAL.BUILD_FLAVOUR;
|
||||
if (!buildToCompare) return;
|
||||
const flavorToUpdate = appUpdate[buildToCompare];
|
||||
if (!flavorToUpdate) return;
|
||||
const currentBuildNumber = GLOBAL.BUILD_CONFIG?.versionCode;
|
||||
if (currentBuildNumber && currentBuildNumber < flavorToUpdate.buildNumber) {
|
||||
setShouldUpdate(true);
|
||||
} else {
|
||||
setShouldUpdate(false);
|
||||
}
|
||||
}, [JSON.stringify(appUpdate || {})]);
|
||||
|
||||
const handleDownloadNewApp = () => {
|
||||
if (forceReinstallData?.reinstall_endpoint) {
|
||||
openApkDownloadLink(forceReinstallData?.reinstall_endpoint);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAppUpdate = () => {
|
||||
const appUpdateUrl = appUpdate?.[GLOBAL.BUILD_FLAVOUR as buildFlavour]?.currentProdAPK;
|
||||
if (appUpdateUrl) {
|
||||
openApkDownloadLink(appUpdateUrl);
|
||||
}
|
||||
};
|
||||
|
||||
const handleOpenSettings = useCallback(async () => {
|
||||
await Linking.openSettings();
|
||||
}, []);
|
||||
@@ -86,17 +113,28 @@ const BlockerScreen = (props: IBlockerScreen) => {
|
||||
);
|
||||
}
|
||||
|
||||
if (!isTimeSynced) {
|
||||
const { heading, instructions } = BLOCKER_SCREEN_DATA.TIME_UNSYNC;
|
||||
if (shouldUpdate) {
|
||||
const { heading, instructions } = BLOCKER_SCREEN_DATA.UNINSTALL_APP;
|
||||
return (
|
||||
<BlockerInstructions
|
||||
heading={heading}
|
||||
instructions={instructions}
|
||||
actionBtn={{ title: 'Go to settings', action: handleOpenSettings }}
|
||||
actionBtn={{ title: 'Download New App', action: handleAppUpdate }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// if (!isTimeSynced) {
|
||||
// const { heading, instructions } = BLOCKER_SCREEN_DATA.TIME_UNSYNC;
|
||||
// return (
|
||||
// <BlockerInstructions
|
||||
// heading={heading}
|
||||
// instructions={instructions}
|
||||
// actionBtn={{ title: 'Go to settings', action: handleOpenSettings }}
|
||||
// />
|
||||
// );
|
||||
// }
|
||||
|
||||
if (!isDeviceLocationEnabled) {
|
||||
const { heading, instructions } = BLOCKER_SCREEN_DATA.DEVICE_LOCATION_OFF;
|
||||
return (
|
||||
|
||||
@@ -27,6 +27,8 @@ import { syncCasesByFallback } from '../reducer/allCasesSlice';
|
||||
import { MILLISECONDS_IN_A_MINUTE } from '../../RN-UI-LIB/src/utlis/common';
|
||||
import { setLockData } from '../reducer/userSlice';
|
||||
import { getConfigData } from '../action/configActions';
|
||||
import { GLOBAL } from '../constants/Global';
|
||||
import { getBuildFlavour } from '../components/utlis/DeviceUtils';
|
||||
|
||||
export enum FOREGROUND_TASKS {
|
||||
GEOLOCATION = 'GEOLOCATION',
|
||||
@@ -146,7 +148,10 @@ const TrackingComponent: React.FC<ITrackingComponent> = ({ children }) => {
|
||||
tasks.push({
|
||||
taskId: FOREGROUND_TASKS.DATA_SYNC,
|
||||
task: dataSyncService,
|
||||
delay: DATA_SYNC_TIME_INTERVAL,
|
||||
delay:
|
||||
GLOBAL?.BUILD_FLAVOUR === 'callingAgents'
|
||||
? DATA_SYNC_TIME_INTERVAL
|
||||
: 5 * MILLISECONDS_IN_A_MINUTE,
|
||||
onLoop: true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,3 +12,10 @@ export const getAllInstalledApp = (): Promise<string> => DeviceUtilsModule.getAl
|
||||
export type buildFlavour = 'fieldAgents' | 'callingAgents';
|
||||
|
||||
export const getBuildFlavour = (): Promise<buildFlavour> => DeviceUtilsModule.getBuildFlavour();
|
||||
|
||||
export type buildConfig = {
|
||||
versionCode: number;
|
||||
versionName: string;
|
||||
};
|
||||
|
||||
export const getBuildInfo = (): Promise<string> => DeviceUtilsModule.getBuildInfo();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { buildFlavour, getBuildFlavour } from '../components/utlis/DeviceUtils';
|
||||
import { buildConfig, buildFlavour, getBuildFlavour } from '../components/utlis/DeviceUtils';
|
||||
import { isNullOrUndefined } from '../components/utlis/commonFunctions';
|
||||
|
||||
export enum DEVICE_TYPE_ENUM {
|
||||
@@ -12,8 +12,9 @@ export const GLOBAL = {
|
||||
AGENT_ID: '',
|
||||
DEVICE_TYPE: DEVICE_TYPE_ENUM.MOBILE,
|
||||
IS_IMPERSONATED: false,
|
||||
BUILD_FLAVOUR: '',
|
||||
};
|
||||
BUILD_FLAVOUR: null,
|
||||
BUILD_CONFIG: null,
|
||||
} as unknown as IGlobalUserData;
|
||||
|
||||
interface IGlobalUserData {
|
||||
token?: string;
|
||||
@@ -22,6 +23,12 @@ interface IGlobalUserData {
|
||||
deviceType?: DEVICE_TYPE_ENUM;
|
||||
isImpersonated?: boolean;
|
||||
BUILD_FLAVOUR?: buildFlavour;
|
||||
BUILD_CONFIG?: buildConfig;
|
||||
SESSION_TOKEN: string;
|
||||
DEVICE_ID: string;
|
||||
AGENT_ID: string;
|
||||
IS_IMPERSONATED: boolean;
|
||||
DEVICE_TYPE: DEVICE_TYPE_ENUM;
|
||||
}
|
||||
|
||||
export const setGlobalUserData = (userData: IGlobalUserData) => {
|
||||
@@ -34,5 +41,9 @@ export const setGlobalUserData = (userData: IGlobalUserData) => {
|
||||
};
|
||||
|
||||
export const setGlobalBuildFlavour = (buildFlavour: buildFlavour) => {
|
||||
if (GLOBAL.BUILD_FLAVOUR) GLOBAL.BUILD_FLAVOUR = buildFlavour;
|
||||
if (buildFlavour) GLOBAL.BUILD_FLAVOUR = buildFlavour;
|
||||
};
|
||||
|
||||
export const setGlobalBuildConfig = (buildConfig: buildConfig) => {
|
||||
if (buildConfig) GLOBAL.BUILD_CONFIG = buildConfig;
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@ import { ILockData, setLockData, VisitPlanStatus } from '../reducer/userSlice';
|
||||
import { setFilters } from '../reducer/filtersSlice';
|
||||
import { FormTemplateV1 } from '../types/template.types';
|
||||
import { ToastMessages } from '../screens/allCases/constants';
|
||||
import { setForceUninstallData } from '../reducer/metadataSlice';
|
||||
import { setCurrentProdAPK, setForceUninstallData } from '../reducer/metadataSlice';
|
||||
import { logError } from '../components/utlis/errorUtils';
|
||||
import { GenericFunctionArgs } from '../common/GenericTypes';
|
||||
|
||||
@@ -52,6 +52,7 @@ const useFirestoreUpdates = () => {
|
||||
let filterUnsubscribe: GenericFunctionArgs;
|
||||
let forceUninstallUnsubscribe: GenericFunctionArgs;
|
||||
let lockUnsubscribe: GenericFunctionArgs;
|
||||
let appUpdateUnsubscribe: GenericFunctionArgs;
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
@@ -139,6 +140,13 @@ const useFirestoreUpdates = () => {
|
||||
dispatch(setForceUninstallData(configData));
|
||||
};
|
||||
|
||||
const handleAppUpdate = (
|
||||
snapshot: FirebaseFirestoreTypes.DocumentSnapshot<FirebaseFirestoreTypes.DocumentData>
|
||||
) => {
|
||||
const configData = snapshot.data();
|
||||
dispatch(setCurrentProdAPK(configData));
|
||||
};
|
||||
|
||||
const handleFilterUpdate = (
|
||||
snapshot: FirebaseFirestoreTypes.DocumentSnapshot<FirebaseFirestoreTypes.DocumentData>
|
||||
) => {
|
||||
@@ -211,6 +219,16 @@ const useFirestoreUpdates = () => {
|
||||
return subscribeToDoc(handleForceUninstallUpdate, collectionPath);
|
||||
};
|
||||
|
||||
const subscribeToAppUpdate = () => {
|
||||
const collectionPath = 'app-state/app-update';
|
||||
console.log(
|
||||
'subscribeToAppUpdate',
|
||||
collectionPath,
|
||||
subscribeToDoc(handleAppUpdate, collectionPath)
|
||||
);
|
||||
return subscribeToDoc(handleAppUpdate, collectionPath);
|
||||
};
|
||||
|
||||
const subscribeToFilters = () => {
|
||||
const collectionPath = `filters/${user?.referenceId}`;
|
||||
return subscribeToDoc(handleFilterUpdate, collectionPath);
|
||||
@@ -237,6 +255,7 @@ const useFirestoreUpdates = () => {
|
||||
avTemplateUnSubscriber = subscribeToAvTemplate();
|
||||
collectionTemplateUnsubscribe = subscribeToCollectionTemplate();
|
||||
lockUnsubscribe = subscribeToLocks();
|
||||
appUpdateUnsubscribe = subscribeToAppUpdate();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
@@ -265,6 +284,7 @@ const useFirestoreUpdates = () => {
|
||||
|
||||
useEffect(() => {
|
||||
forceUninstallUnsubscribe = subscribeToForceUninstall();
|
||||
subscribeToAppUpdate();
|
||||
}, []);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import { buildFlavour } from '../components/utlis/DeviceUtils';
|
||||
export interface UninstallInformation {
|
||||
last_operational_time: any;
|
||||
reinstall_endpoint: string;
|
||||
@@ -8,12 +9,20 @@ interface IMetadata {
|
||||
isOnline: boolean;
|
||||
forceUninstall: Record<string, UninstallInformation>;
|
||||
isWifiOrCellularOn: boolean;
|
||||
appUpdate: Record<buildFlavour, typeAppUpdate>;
|
||||
}
|
||||
|
||||
type typeAppUpdate = {
|
||||
buildVersion: string;
|
||||
buildNumber: number;
|
||||
currentProdAPK: string;
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
isOnline: true,
|
||||
forceUninstall: {},
|
||||
isWifiOrCellularOn: true,
|
||||
appUpdate: {},
|
||||
} as IMetadata;
|
||||
|
||||
const MetadataSlice = createSlice({
|
||||
@@ -29,9 +38,13 @@ const MetadataSlice = createSlice({
|
||||
setIsWifiOrCellularOn: (state, action) => {
|
||||
state.isWifiOrCellularOn = action.payload;
|
||||
},
|
||||
setCurrentProdAPK: (state, action) => {
|
||||
state.appUpdate = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const { setIsOnline, setForceUninstallData, setIsWifiOrCellularOn } = MetadataSlice.actions;
|
||||
export const { setIsOnline, setForceUninstallData, setIsWifiOrCellularOn, setCurrentProdAPK } =
|
||||
MetadataSlice.actions;
|
||||
|
||||
export default MetadataSlice.reducer;
|
||||
|
||||
Reference in New Issue
Block a user