import AsyncStorage from '@react-native-async-storage/async-storage'; import { NavigationContainer } from '@react-navigation/native'; import React, { useEffect } from 'react'; import { AppState, LogBox, PermissionsAndroid, Platform, StatusBar, type Permission, } from 'react-native'; import { Provider } from 'react-redux'; import { PersistGate } from 'redux-persist/integration/react'; import store, { persistor } from './src/store/store'; import { navigationRef } from '@utils/navigationUtlis'; import FullScreenLoader from './RN-UI-LIB/src/components/FullScreenLoader'; import { toastConfigs, ToastContainer } from './RN-UI-LIB/src/components/toast'; import { hydrateGlobalImageMap } from '@common/CachedImage'; import { CLICKSTREAM_EVENT_NAMES, LocalStorageKeys } from '@common/Constants'; import { getAppVersion, sendDeviceDetailsToClickstream } from '@components/utlis/commonFunctions'; import { linkingConf } from '@components/utlis/deeplinkingUtils'; import { fetchSimDetails, getBuildFlavour, restartApp } from '@components/utlis/DeviceUtils'; import { initSentry } from '@components/utlis/sentry'; import { GLOBAL, setGlobalBuildFlavour } from '@constants/Global'; import { AppStates } from '@interfaces/appStates'; import analytics from '@react-native-firebase/analytics'; import { COLORS } from '@rn-ui-lib/colors'; import { type TDocumentObj } from '@screens/caseDetails/interface'; import { addClickstreamEvent } from '@services/clickstreamEventService'; import { setJsErrorHandler } from '@services/exception-handler.service'; import syncSelfCallData from '@services/syncSelfCallData'; import { getPermissionsToRequest } from '@utils/PermissionUtils'; import dayJs from 'dayjs'; import CodePushLoadingModal, { CodePushLoadingModalRef } from './CodePushModal'; import ErrorBoundary from './src/common/ErrorBoundary'; import ScreenshotBlocker from './src/components/utlis/ScreenshotBlocker'; import { setItem } from './src/components/utlis/storageHelper'; import { BASE_AV_APP_URL, ENV } from './src/constants/config'; import AuthRouter from './src/screens/auth/AuthRouter'; import Permissions from './src/screens/permissions/Permissions'; import fetchUpdatedRemoteConfig from './src/services/firebaseFetchAndUpdate.service'; import { StorageKeys } from './src/types/storageKeys'; import { CodePushStorageKeys, useCheckVersion } from '@hooks/useCheckVersion'; if (!__DEV__) { initSentry(); } if (ENV !== 'prod') { // mockApiServer(); } setJsErrorHandler(); LogBox.ignoreAllLogs(); export let GlobalDocumentMap: Record = {}; function App() { const [permissions, setPermissions] = React.useState(true); const modalRef = React.useRef(null); const { checkForUpdates, applyUpdate } = useCheckVersion({ apiConfig: { baseUrl: BASE_AV_APP_URL, appVersionParam: getAppVersion(), }, onUpdateAvailable: async (result) => { const updateCheck = (await AsyncStorage.getItem(CodePushStorageKeys.CodePushVersionTag)) ?? 0; if (+result.versionTag === +updateCheck) { addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_CODEPUSH_INFINITE_INSTALL_ERROR, {}); return; } if (result.isAvailable) { addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_INSTALLING_CODEPUSH, {}); modalRef.current?.show(); applyUpdate(result.url, result.versionTag); } }, onDownloadProgress: (received, total) => { modalRef.current?.updateProgress({ totalBytes: +total, receivedBytes: +received, }); }, onUpdateSuccess: () => { setTimeout(() => { restartApp(); }, 4000); }, onUpdateFail: (message?: string) => { addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_CODEPUSH_UNKNOWN_ERROR, { message }); modalRef.current?.hide(); }, }); const askForPermissions = async () => { const permissionsToRequest = await getPermissionsToRequest(); if (Platform.OS === 'android') { PermissionsAndroid.requestMultiple(permissionsToRequest) .then(async (result) => { let isAllPermissionsGranted = true; for (const permission in result) { if (result?.[permission as Permission] !== PermissionsAndroid.RESULTS.GRANTED) { isAllPermissionsGranted = false; break; } } setPermissions(isAllPermissionsGranted); }) .catch((err) => { setPermissions(false); }); } }; const getActiveRouteName = (state) => { if (!state || typeof state.index !== 'number') { return 'Unknown'; } const route = state.routes[state.index]; if (route.state) { return getActiveRouteName(route.state); } return route?.name || ''; }; async function setForegroundTimeStampAndClickstream() { const now = dayJs().toString(); await setItem(StorageKeys.APP_FOREGROUND_TIMESTAMP, now); addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_APP_FOREGROUND, { now }, true); } useEffect(() => { ScreenshotBlocker.unblockScreenshots(); getBuildFlavour().then((flavour) => { setGlobalBuildFlavour(flavour); }); // Device Details sendDeviceDetailsToClickstream(); fetchSimDetails(); }, []); React.useEffect(() => { fetchUpdatedRemoteConfig(); askForPermissions(); const appStateChange = AppState.addEventListener('change', async (change) => { if (change === AppStates.ACTIVE) { askForPermissions(); if (GLOBAL.AGENT_ID) { syncSelfCallData(GLOBAL.AGENT_ID); } checkForUpdates(); } hydrateGlobalImageMap(); }); (async () => { const data = await AsyncStorage.getItem(LocalStorageKeys.GLOBAL_DOCUMENT_MAP); if (data) { const parsedData = JSON.parse(data); GlobalDocumentMap = parsedData; } })(); setForegroundTimeStampAndClickstream(); return () => { appStateChange.remove(); }; }, []); return ( } persistor={persistor} > { const currentRouteName = getActiveRouteName(state); await analytics().logScreenView({ screen_name: currentRouteName, screen_class: currentRouteName, }); }} > {permissions ? : } ); } export default App;