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