Skip to content

Commit

Permalink
refactor: lockout modal (#1205)
Browse files Browse the repository at this point in the history
Signed-off-by: Bryce McMath <[email protected]>
  • Loading branch information
bryce-mcmath authored Jul 23, 2024
1 parent 430dfbd commit c0c4ffa
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 274 deletions.
4 changes: 2 additions & 2 deletions packages/legacy/core/App/localization/en/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ const translation = {
"BiometricsNotProvided": "Biometrics not provided, you may use PIN to load the wallet.",
"BiometricsError": "Biometrics were not successful.",
"BiometricsErrorEnterPIN": "Please enter your wallet PIN.",
"LoggedOut": "You're logged out",
"LoggedOutDescription": "To protect your information, you're logged out of your wallet if you have not used it for 5 minutes.",
"LockedOut": "You locked out after 5 minutes of inactivity.",
"ReEnterPIN": "Re-enter your wallet PIN",
"BiometricsChanged": "Biometrics unlock has been disabled because your device biometrics changed.",
"BiometricsChangedEnterPIN": "Please enter your wallet PIN.",
"AttemptLockoutWarning": "Note: for your security, entering another incorrect PIN will temporarily lock the wallet."
Expand Down
4 changes: 2 additions & 2 deletions packages/legacy/core/App/localization/fr/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,8 @@ const translation = {
"BiometricsNotProvided": "Biométrie non fournie, vous pouvez utiliser le NIP pour vous connecter au portefeuille.",
"BiometricsError": "La biométrie n'a pas réussi.",
"BiometricsErrorEnterPIN": "Veuillez saisir le code NIP de votre portefeuille.",
"LoggedOut": "Vous avez été déconnecté du portefeuille.",
"LoggedOutDescription": "Pour protéger vos informations, vous êtes déconnecté de votre portefeuille si vous ne l'avez pas utilisé pendant 5 minutes.",
"LockedOut": "You locked out after 5 minutes of inactivity. (FR)",
"ReEnterPIN": "Re-enter your wallet PIN (FR)",
"BiometricsChanged": "Le déverrouillage avec la biométrie a été désactivé, car les données biométriques de votre appareil ont changé.",
"BiometricsChangedEnterPIN": "Veuillez saisir le code NIP de votre portefeuille.",
"AttemptLockoutWarning": "Note: pour votre sécurité, la saisie d'un autre NIP incorrect verrouillera temporairement le portefeuille."
Expand Down
2 changes: 2 additions & 0 deletions packages/legacy/core/App/localization/pt-br/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ const translation = {
"Or": "Ou",
"BiometricsUnlock": "Destravar com Biometria",
"IncorrectPIN": "PIN incorreto",
"LockedOut": "You locked out after 5 minutes of inactivity. (PT-BR)",
"ReEnterPIN": "Re-enter your wallet PIN (PT-BR)",
"EnableBiometrics": "Você deve habilitar a biometria para poder carregar a carteira.",
"BiometricsNotProvided": "Biometria não informada, você deve usar o PIN para carregar a carteira.",
"BiometricsError": "Biometrics were not successful.",
Expand Down
83 changes: 35 additions & 48 deletions packages/legacy/core/App/screens/PINEnter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ const PINEnter: React.FC<PINEnterProps> = ({ setAuthenticated, usage = PINEntryU
const [displayLockoutWarning, setDisplayLockoutWarning] = useState(false)
const [biometricsErr, setBiometricsErr] = useState(false)
const navigation = useNavigation()
// 'You're logged out' popup modal
const [displayNotification, setDisplayNotification] = useState(false)
const [alertModalVisible, setAlertModalVisible] = useState<boolean>(false)
const [biometricsEnrollmentChange, setBiometricsEnrollmentChange] = useState<boolean>(false)
const { ColorPallet, TextTheme, Assets, PINEnterTheme } = useTheme()
Expand All @@ -64,6 +62,12 @@ const PINEnter: React.FC<PINEnterProps> = ({ setAuthenticated, usage = PINEntryU
...TextTheme.normal,
marginVertical: 5,
},
helpText: {
...TextTheme.normal,
alignSelf: 'center',
textAlign: 'center',
marginBottom: 16,
},
modalText: {
...TextTheme.popupModalText,
marginVertical: 5,
Expand Down Expand Up @@ -292,42 +296,43 @@ const PINEnter: React.FC<PINEnterProps> = ({ setAuthenticated, usage = PINEntryU
}
}

// NOTE: Using local state here is to prevent modal issues caused by other modals being left open when the device sleeps.
// When two modals are attempted to be mounted at once it causes issues on iOS - in this case it causes the second modal
// to be invisible and prevent interaction with other elements on the screen. Using this approach ensures that the previous
// screen (and modal) is fully unmounted before this one is mounted. A similar approach would be to use a setTimeout.
useEffect(() => {
const displayHelpText = () => {
if (store.lockout.displayNotification) {
setDisplayNotification(true)
} else {
setDisplayNotification(false)
return (
<>
<Text style={style.helpText}>{t('PINEnter.LockedOut')}</Text>
<Text style={style.helpText}>{t('PINEnter.ReEnterPIN')}</Text>
</>
)
}

if (biometricsEnrollmentChange) {
return (
<>
<Text style={style.helpText}>{t('PINEnter.BiometricsChanged')}</Text>
<Text style={style.helpText}>{t('PINEnter.BiometricsChangedEnterPIN')}</Text>
</>
)
}
}, [store.lockout.displayNotification])

if (biometricsErr) {
return (
<>
<Text style={style.helpText}>{t('PINEnter.BiometricsError')}</Text>
<Text style={style.helpText}>{t('PINEnter.BiometricsErrorEnterPIN')}</Text>
</>
)
}

return <Text style={style.helpText}>{t('PINEnter.EnterPIN')}</Text>
}

return (
<KeyboardView>
<View style={style.screenContainer}>
<View style={style.contentContainer}>
<Image source={Assets.img.logoSecondary.src} style={style.image} />
{biometricsEnrollmentChange ? (
<>
<Text style={[TextTheme.normal, { alignSelf: 'center', textAlign: 'center' }]}>
{t('PINEnter.BiometricsChanged')}
</Text>
<Text style={[TextTheme.normal, { alignSelf: 'center', marginBottom: 16 }]}>
{t('PINEnter.BiometricsChangedEnterPIN')}
</Text>
</>
) : biometricsErr ? (
<>
<Text style={[TextTheme.normal, { alignSelf: 'center' }]}>{t('PINEnter.BiometricsError')}</Text>
<Text style={[TextTheme.normal, { alignSelf: 'center', marginBottom: 16 }]}>
{t('PINEnter.BiometricsErrorEnterPIN')}
</Text>
</>
) : (
<Text style={[TextTheme.normal, { alignSelf: 'center', marginBottom: 16 }]}>{t('PINEnter.EnterPIN')}</Text>
)}
{displayHelpText()}
<PINInput
onPINChanged={(p: string) => {
setPIN(p)
Expand All @@ -340,24 +345,6 @@ const PINEnter: React.FC<PINEnterProps> = ({ setAuthenticated, usage = PINEntryU
autoFocus={true}
/>
</View>
{displayNotification && (
<PopupModal
notificationType={InfoBoxType.Info}
title={t('PINEnter.LoggedOut')}
bodyContent={
<View>
<Text style={style.modalText}>{t('PINEnter.LoggedOutDescription')}</Text>
</View>
}
onCallToActionLabel={t('Global.Okay')}
onCallToActionPressed={() => {
dispatch({
type: DispatchAction.LOCKOUT_UPDATED,
payload: [{ displayNotification: false }],
})
}}
/>
)}
<View style={style.controlsContainer}>
<View style={style.buttonContainer}>
<Button
Expand Down
6 changes: 3 additions & 3 deletions packages/legacy/core/__tests__/screens/PINEnter.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { render } from '@testing-library/react-native'
import React from 'react'

import { AuthContext } from '../../App/contexts/auth'
import { useConfiguration } from '../../App/contexts/configuration'
import { StoreProvider, defaultState } from '../../App/contexts/store'
import PINEnter from '../../App/screens/PINEnter'
import { testIdWithKey } from '../../App/utils/testable'
import authContext from '../contexts/auth'
import { useConfiguration } from '../../App/contexts/configuration'

jest.mock('react-native-fs', () => ({}))
jest.mock('@hyperledger/anoncreds-react-native', () => ({}))
Expand Down Expand Up @@ -48,8 +48,8 @@ describe('displays a PIN Enter screen', () => {
</AuthContext.Provider>
</StoreProvider>
)
const ModalHeader = await tree.getByTestId(testIdWithKey('HeaderText'))
expect(ModalHeader).not.toBeNull()
const textNotice = await tree.findByText('PINEnter.LockedOut')
expect(textNotice).not.toBeNull()
expect(tree).toMatchSnapshot()
})

Expand Down
Loading

0 comments on commit c0c4ffa

Please sign in to comment.