import React, {useEffect, useState} from 'react'; import {Linking, BackHandler} from 'react-native'; import VersionCheck from 'react-native-version-check'; import * as Sentry from '@sentry/react-native'; import {Severity} from '@sentry/types'; import AsyncStorage from '@react-native-async-storage/async-storage'; import {QueryClient, QueryClientProvider} from 'react-query'; import SplashScreen from 'react-native-splash-screen'; import {SafeAreaProvider} from 'react-native-safe-area-context'; import {NavigationContainer} from '@react-navigation/native'; import Config from 'react-native-config'; import Loader from '@components/Loader'; import Navigation from '@navigation/index'; import {TncProvider} from '@contexts/tnc'; import AppUpdateModal from '@components/AppUpdateModal'; import useUser, {UserProvider, ACCESS_TOKEN} from '@contexts/user'; import { issuanceServiceInstance, cloudWalletServiceInstance, } from '@services/Axios'; import {LoaderProvider} from '@contexts/loader'; import {SENTRY_DSN, ENV} from '@constants/api'; const queryClient = new QueryClient(); type getDescriptionTypes = { optional: string; mandatory: string; }; const getDescription: getDescriptionTypes = { optional: 'Asli wallet recommends that you update to the latest version.', mandatory: 'An update to Asli wallet is required to continue.', }; const getUpdateTitle = { optional: 'Update Asli?', mandatory: 'Update required', }; const Wrapper = () => { const {getAccessToken, user, logout, isTokenExpired, getPhoneNumber} = useUser(); useEffect(() => SplashScreen.hide(), []); useEffect(() => { (async () => { if (!user?.accessToken) { await getAccessToken(); } else { const tokenExpired = await isTokenExpired(); const phoneNumber = await getPhoneNumber(); if (!!user?.accessToken && tokenExpired) { Sentry.captureMessage( `Logout fn called, Mobile Number : ${phoneNumber} / Access Token : ${user?.accessToken} / tokenExpired : ${tokenExpired} `, Severity.Log, ); await logout(); return; } // Add a Issuance request interceptor issuanceServiceInstance.interceptors.request.use( async config => { const value = await AsyncStorage.getItem(ACCESS_TOKEN); if (config?.headers && !!value) { config.headers.Authorization = value; } return config; }, error => Promise.reject(error), ); // Add a Issuance response interceptor issuanceServiceInstance.interceptors.response.use( response => response, async error => { if (error?.response?.status === 401) { Sentry.captureMessage( `Logout fn called, Mobile Number : ${phoneNumber} / Access Token : ${ user?.accessToken } / tokenExpired : ${tokenExpired} / Error : ${JSON.stringify( error?.response, )}`, Severity.Error, ); await logout(); return; } return Promise.reject(error); }, ); // Add a Cloud Service request interceptor cloudWalletServiceInstance.interceptors.request.use( async config => { const value = await AsyncStorage.getItem(ACCESS_TOKEN); if (config?.headers && !!value) { config.headers.Authorization = `Bearer ${value}`; } return config; }, error => Promise.reject(error), ); // Add a response interceptor cloudWalletServiceInstance.interceptors.response.use( response => response, async error => { if (error?.response?.status === 401) { Sentry.captureMessage( `Cloud Wallet API 401,Logout fn called, Mobile Number : ${phoneNumber} / Access Token : ${ user?.accessToken } / tokenExpired : ${tokenExpired} / Error : ${JSON.stringify( error?.response, )}`, Severity.Error, ); await logout(); return; } return Promise.reject(error); }, ); } })(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [user?.accessToken]); return ( ); }; const App = () => { const [showUpdateModal, setshowUpdateModal] = useState(false); const updateType: string = Config.APP_STORE_UPDATE_TYPE; useEffect(() => { Sentry.init({ dsn: SENTRY_DSN, tracesSampleRate: 1.0, environment: ENV, }); }, []); useEffect(() => { const checkLatestVersion = async () => { const isUpdateRequired = await VersionCheck.needUpdate({ forceUpdate: true, }); if (isUpdateRequired.isNeeded) { setshowUpdateModal(true); } }; checkLatestVersion(); }, []); const updateApp = async () => { const isUpdateRequired = await VersionCheck.needUpdate(); Linking.openURL(isUpdateRequired.storeUrl); }; const hideUpdateModal = async () => { //Exit, if update is mandatory if (updateType !== 'optional') { BackHandler.exitApp(); } setshowUpdateModal(false); }; return ( ); }; export default Sentry.wrap(App);