forked from mosip/inji-wallet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
App.tsx
115 lines (107 loc) · 3.46 KB
/
App.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import React, {useContext, useEffect} from 'react';
import AppLoading from 'expo-app-loading';
import {AppLayout} from './screens/AppLayout';
import {useFont} from './shared/hooks/useFont';
import {GlobalContextProvider} from './components/GlobalContextProvider';
import {GlobalContext} from './shared/GlobalContext';
import {useSelector} from '@xstate/react';
import {useTranslation} from 'react-i18next';
import {
selectIsDecryptError,
selectIsKeyInvalidateError,
selectIsReadError,
selectIsReady,
} from './machines/app';
import {DualMessageOverlay} from './components/DualMessageOverlay';
import {useApp} from './screens/AppController';
import {Alert} from 'react-native';
import {configureTelemetry} from './shared/telemetry/TelemetryUtils';
import {MessageOverlay} from './components/MessageOverlay';
import SecureKeystore from 'react-native-secure-keystore';
import {isHardwareKeystoreExists} from './shared/cryptoutil/cryptoUtil';
import i18n from './i18n';
import './shared/flipperConfig';
// kludge: this is a bad practice but has been done temporarily to surface
// an occurance of a bug with minimal residual code changes, this should
// be removed once the bug cause is determined & fixed, ref: INJI-222
const DecryptErrorAlert = (controller, t) => {
const heading = t('errors.decryptionFailed');
const desc = t('errors.decryptionFailed');
const ignoreBtnTxt = t('ignore');
Alert.alert(heading, desc, [
{
text: ignoreBtnTxt,
onPress: () => controller.ignoreDecrypt(),
style: 'cancel',
},
]);
};
const AppLayoutWrapper: React.FC = () => {
const {appService} = useContext(GlobalContext);
const isDecryptError = useSelector(appService, selectIsDecryptError);
const controller = useApp();
const {t} = useTranslation('WelcomeScreen');
if (isDecryptError) {
DecryptErrorAlert(controller, t);
}
configureTelemetry();
return <AppLayout />;
};
const AppLoadingWrapper: React.FC = () => {
const {appService} = useContext(GlobalContext);
const isReadError = useSelector(appService, selectIsReadError);
const isKeyInvalidateError = useSelector(
appService,
selectIsKeyInvalidateError,
);
const controller = useApp();
const {t} = useTranslation('WelcomeScreen');
return (
<>
<AppLoading />
<MessageOverlay
isVisible={isKeyInvalidateError}
title={t('errors.invalidateKeyError.title')}
message={t('errors.invalidateKeyError.message')}
onButtonPress={controller.RESET}
buttonText={t('common:ok')}
customHeight={'auto'}
/>
{isReadError ? (
<DualMessageOverlay
isVisible={isReadError}
title={t('failedToReadKeys')}
message={t('retryRead')}
onTryAgain={controller.TRY_AGAIN}
onIgnore={controller.IGNORE}
/>
) : null}
</>
);
};
const AppInitialization: React.FC = () => {
const {appService} = useContext(GlobalContext);
const isReady = useSelector(appService, selectIsReady);
const hasFontsLoaded = useFont();
const {t} = useTranslation('common');
useEffect(() => {
if (isHardwareKeystoreExists) {
SecureKeystore.updatePopup(
t('biometricPopup.title'),
t('biometricPopup.description'),
);
}
}, [i18n.language]);
return isReady && hasFontsLoaded ? (
<AppLayoutWrapper />
) : (
<AppLoadingWrapper />
);
};
export default function App() {
return (
<GlobalContextProvider>
<AppInitialization />
</GlobalContextProvider>
);
}