Chore: Evaluate Passcode - TypeScript (#3931)

* Chore: Migrate containers: Passcode to Typescript

* minor tweak

* minor tweak
This commit is contained in:
Reinaldo Neto 2022-03-22 21:43:59 -03:00 committed by GitHub
parent cbe2b23e27
commit 4d3c440892
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 147 additions and 132 deletions

View File

@ -5,16 +5,18 @@ import styles from './styles';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import Touch from '../../../utils/touch'; import Touch from '../../../utils/touch';
import { CustomIcon } from '../../../lib/Icons'; import { CustomIcon } from '../../../lib/Icons';
import { useTheme } from '../../../theme';
interface IPasscodeButton { interface IPasscodeButton {
text?: string; text?: string;
icon?: string; icon?: string;
theme: string;
disabled?: boolean; disabled?: boolean;
onPress?: Function; onPress?: Function;
} }
const Button = React.memo(({ text, disabled, theme, onPress, icon }: IPasscodeButton) => { const Button = React.memo(({ text, disabled, onPress, icon }: IPasscodeButton) => {
const { theme } = useTheme();
const press = () => onPress && onPress(text); const press = () => onPress && onPress(text);
return ( return (

View File

@ -4,47 +4,51 @@ import range from 'lodash/range';
import styles from './styles'; import styles from './styles';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import { useTheme } from '../../../theme';
const SIZE_EMPTY = 12; const SIZE_EMPTY = 12;
const SIZE_FULL = 16; const SIZE_FULL = 16;
interface IPasscodeDots { interface IPasscodeDots {
passcode: string; passcode: string;
theme: string;
length: number; length: number;
} }
const Dots = React.memo(({ passcode, theme, length }: IPasscodeDots) => ( const Dots = React.memo(({ passcode, length }: IPasscodeDots) => {
<View style={styles.dotsContainer}> const { theme } = useTheme();
{range(length).map(val => {
const lengthSup = passcode.length >= val + 1; return (
const height = lengthSup ? SIZE_FULL : SIZE_EMPTY; <View style={styles.dotsContainer}>
const width = lengthSup ? SIZE_FULL : SIZE_EMPTY; {range(length).map(val => {
let backgroundColor = ''; const lengthSup = passcode.length >= val + 1;
if (lengthSup && passcode.length > 0) { const height = lengthSup ? SIZE_FULL : SIZE_EMPTY;
backgroundColor = themes[theme].passcodeDotFull; const width = lengthSup ? SIZE_FULL : SIZE_EMPTY;
} else { let backgroundColor = '';
backgroundColor = themes[theme].passcodeDotEmpty; if (lengthSup && passcode.length > 0) {
} backgroundColor = themes[theme].passcodeDotFull;
const borderRadius = lengthSup ? SIZE_FULL / 2 : SIZE_EMPTY / 2; } else {
const marginRight = lengthSup ? 10 - (SIZE_FULL - SIZE_EMPTY) / 2 : 10; backgroundColor = themes[theme].passcodeDotEmpty;
const marginLeft = lengthSup ? 10 - (SIZE_FULL - SIZE_EMPTY) / 2 : 10; }
return ( const borderRadius = lengthSup ? SIZE_FULL / 2 : SIZE_EMPTY / 2;
<View style={styles.dotsView}> const marginRight = lengthSup ? 10 - (SIZE_FULL - SIZE_EMPTY) / 2 : 10;
<View const marginLeft = lengthSup ? 10 - (SIZE_FULL - SIZE_EMPTY) / 2 : 10;
style={{ return (
height, <View style={styles.dotsView}>
width, <View
borderRadius, style={{
backgroundColor, height,
marginRight, width,
marginLeft borderRadius,
}} backgroundColor,
/> marginRight,
</View> marginLeft
); }}
})} />
</View> </View>
)); );
})}
</View>
);
});
export default Dots; export default Dots;

View File

@ -5,13 +5,18 @@ import { Row } from 'react-native-easy-grid';
import styles from './styles'; import styles from './styles';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import { CustomIcon } from '../../../lib/Icons'; import { CustomIcon } from '../../../lib/Icons';
import { useTheme } from '../../../theme';
const LockIcon = React.memo(({ theme }: { theme: string }) => ( const LockIcon = React.memo(() => {
<Row style={styles.row}> const { theme } = useTheme();
<View style={styles.iconView}>
<CustomIcon name='auth' size={40} color={themes[theme].passcodeLockIcon} /> return (
</View> <Row style={styles.row}>
</Row> <View style={styles.iconView}>
)); <CustomIcon name='auth' size={40} color={themes[theme].passcodeLockIcon} />
</View>
</Row>
);
});
export default LockIcon; export default LockIcon;

View File

@ -6,36 +6,35 @@ import { resetAttempts } from '../../../utils/localAuthentication';
import { TYPE } from '../constants'; import { TYPE } from '../constants';
import { getDiff, getLockedUntil } from '../utils'; import { getDiff, getLockedUntil } from '../utils';
import I18n from '../../../i18n'; import I18n from '../../../i18n';
import { useTheme } from '../../../theme';
import styles from './styles'; import styles from './styles';
import Title from './Title'; import Title from './Title';
import Subtitle from './Subtitle'; import Subtitle from './Subtitle';
import LockIcon from './LockIcon'; import LockIcon from './LockIcon';
interface IPasscodeTimer { interface IPasscodeTimer {
time: string; time: Date | null;
theme: string;
setStatus: Function; setStatus: Function;
} }
interface IPasscodeLocked { interface IPasscodeLocked {
theme: string;
setStatus: Function; setStatus: Function;
} }
const Timer = React.memo(({ time, theme, setStatus }: IPasscodeTimer) => { const Timer = React.memo(({ time, setStatus }: IPasscodeTimer) => {
const calcTimeLeft = () => { const calcTimeLeft = () => {
const diff = getDiff(time); const diff = getDiff(time || 0);
if (diff > 0) { if (diff > 0) {
return Math.floor((diff / 1000) % 60); return Math.floor((diff / 1000) % 60);
} }
}; };
const [timeLeft, setTimeLeft] = useState<any>(calcTimeLeft()); const [timeLeft, setTimeLeft] = useState(calcTimeLeft());
useEffect(() => { useEffect(() => {
setTimeout(() => { setTimeout(() => {
setTimeLeft(calcTimeLeft()); setTimeLeft(calcTimeLeft());
if (timeLeft <= 1) { if (timeLeft && timeLeft <= 1) {
resetAttempts(); resetAttempts();
setStatus(TYPE.ENTER); setStatus(TYPE.ENTER);
} }
@ -46,11 +45,12 @@ const Timer = React.memo(({ time, theme, setStatus }: IPasscodeTimer) => {
return null; return null;
} }
return <Subtitle text={I18n.t('Passcode_app_locked_subtitle', { timeLeft })} theme={theme} />; return <Subtitle text={I18n.t('Passcode_app_locked_subtitle', { timeLeft })} />;
}); });
const Locked = React.memo(({ theme, setStatus }: IPasscodeLocked) => { const Locked = React.memo(({ setStatus }: IPasscodeLocked) => {
const [lockedUntil, setLockedUntil] = useState<any>(null); const [lockedUntil, setLockedUntil] = useState<Date | null>(null);
const { theme } = useTheme();
const readItemFromStorage = async () => { const readItemFromStorage = async () => {
const l = await getLockedUntil(); const l = await getLockedUntil();
@ -63,9 +63,9 @@ const Locked = React.memo(({ theme, setStatus }: IPasscodeLocked) => {
return ( return (
<Grid style={[styles.grid, { backgroundColor: themes[theme].passcodeBackground }]}> <Grid style={[styles.grid, { backgroundColor: themes[theme].passcodeBackground }]}>
<LockIcon theme={theme} /> <LockIcon />
<Title text={I18n.t('Passcode_app_locked_title')} theme={theme} /> <Title text={I18n.t('Passcode_app_locked_title')} />
<Timer theme={theme} time={lockedUntil} setStatus={setStatus} /> <Timer time={lockedUntil} setStatus={setStatus} />
</Grid> </Grid>
); );
}); });

View File

@ -4,18 +4,22 @@ import { Row } from 'react-native-easy-grid';
import styles from './styles'; import styles from './styles';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import { useTheme } from '../../../theme';
interface IPasscodeSubtitle { interface IPasscodeSubtitle {
text: string; text: string;
theme: string;
} }
const Subtitle = React.memo(({ text, theme }: IPasscodeSubtitle) => ( const Subtitle = React.memo(({ text }: IPasscodeSubtitle) => {
<Row style={styles.row}> const { theme } = useTheme();
<View style={styles.subtitleView}>
<Text style={[styles.textSubtitle, { color: themes[theme].passcodeSecondary }]}>{text}</Text> return (
</View> <Row style={styles.row}>
</Row> <View style={styles.subtitleView}>
)); <Text style={[styles.textSubtitle, { color: themes[theme].passcodeSecondary }]}>{text}</Text>
</View>
</Row>
);
});
export default Subtitle; export default Subtitle;

View File

@ -4,18 +4,22 @@ import { Row } from 'react-native-easy-grid';
import styles from './styles'; import styles from './styles';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import { useTheme } from '../../../theme';
interface IPasscodeTitle { interface IPasscodeTitle {
text: string; text: string;
theme: string;
} }
const Title = React.memo(({ text, theme }: IPasscodeTitle) => ( const Title = React.memo(({ text }: IPasscodeTitle) => {
<Row style={styles.row}> const { theme } = useTheme();
<View style={styles.titleView}>
<Text style={[styles.textTitle, { color: themes[theme].passcodePrimary }]}>{text}</Text> return (
</View> <Row style={styles.row}>
</Row> <View style={styles.titleView}>
)); <Text style={[styles.textTitle, { color: themes[theme].passcodePrimary }]}>{text}</Text>
</View>
</Row>
);
});
export default Title; export default Title;

View File

@ -1,6 +1,7 @@
import React, { forwardRef, useImperativeHandle, useRef, useState } from 'react'; import React, { forwardRef, useImperativeHandle, useRef, useState } from 'react';
import { Col, Grid, Row } from 'react-native-easy-grid'; import { Col, Grid, Row } from 'react-native-easy-grid';
import range from 'lodash/range'; import range from 'lodash/range';
import { View } from 'react-native';
import * as Animatable from 'react-native-animatable'; import * as Animatable from 'react-native-animatable';
import * as Haptics from 'expo-haptics'; import * as Haptics from 'expo-haptics';
@ -10,12 +11,12 @@ import Dots from './Dots';
import { TYPE } from '../constants'; import { TYPE } from '../constants';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import { PASSCODE_LENGTH } from '../../../constants/localAuthentication'; import { PASSCODE_LENGTH } from '../../../constants/localAuthentication';
import { useTheme } from '../../../theme';
import LockIcon from './LockIcon'; import LockIcon from './LockIcon';
import Title from './Title'; import Title from './Title';
import Subtitle from './Subtitle'; import Subtitle from './Subtitle';
interface IPasscodeBase { interface IPasscodeBase {
theme: string;
type: string; type: string;
previousPasscode?: string; previousPasscode?: string;
title: string; title: string;
@ -26,25 +27,30 @@ interface IPasscodeBase {
onBiometryPress?(): void; onBiometryPress?(): void;
} }
const Base = forwardRef( export interface IBase {
( clearPasscode: () => void;
{ theme, type, onEndProcess, previousPasscode, title, subtitle, onError, showBiometry, onBiometryPress }: IPasscodeBase, wrongPasscode: () => void;
ref animate: (animation: Animatable.Animation, duration?: number) => void;
) => { }
const rootRef = useRef<any>();
const dotsRef = useRef<any>(); const Base = forwardRef<IBase, IPasscodeBase>(
({ type, onEndProcess, previousPasscode, title, subtitle, onError, showBiometry, onBiometryPress }, ref) => {
const { theme } = useTheme();
const rootRef = useRef<Animatable.View & View>(null);
const dotsRef = useRef<Animatable.View & View>(null);
const [passcode, setPasscode] = useState(''); const [passcode, setPasscode] = useState('');
const clearPasscode = () => setPasscode(''); const clearPasscode = () => setPasscode('');
const wrongPasscode = () => { const wrongPasscode = () => {
clearPasscode(); clearPasscode();
dotsRef?.current?.shake(500); dotsRef?.current?.shake?.(500);
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error); Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
}; };
const animate = (animation: string, duration = 500) => { const animate = (animation: Animatable.Animation, duration = 500) => {
rootRef?.current?.[animation](duration); rootRef?.current?.[animation]?.(duration);
}; };
const onPressNumber = (text: string) => const onPressNumber = (text: string) =>
@ -90,48 +96,48 @@ const Base = forwardRef(
return ( return (
<Animatable.View ref={rootRef} style={styles.container}> <Animatable.View ref={rootRef} style={styles.container}>
<Grid style={[styles.grid, { backgroundColor: themes[theme].passcodeBackground }]}> <Grid style={[styles.grid, { backgroundColor: themes[theme].passcodeBackground }]}>
<LockIcon theme={theme} /> <LockIcon />
<Title text={title} theme={theme} /> <Title text={title} />
<Subtitle text={subtitle!} theme={theme} /> {subtitle ? <Subtitle text={subtitle} /> : null}
<Row style={styles.row}> <Row style={styles.row}>
<Animatable.View ref={dotsRef}> <Animatable.View ref={dotsRef}>
<Dots passcode={passcode} theme={theme} length={PASSCODE_LENGTH} /> <Dots passcode={passcode} length={PASSCODE_LENGTH} />
</Animatable.View> </Animatable.View>
</Row> </Row>
<Row style={[styles.row, styles.buttonRow]}> <Row style={[styles.row, styles.buttonRow]}>
{range(1, 4).map((i: any) => ( {range(1, 4).map(i => (
<Col key={i} style={styles.colButton}> <Col key={i} style={styles.colButton}>
<Button text={i} theme={theme} onPress={onPressNumber} /> <Button text={i.toString()} onPress={onPressNumber} />
</Col> </Col>
))} ))}
</Row> </Row>
<Row style={[styles.row, styles.buttonRow]}> <Row style={[styles.row, styles.buttonRow]}>
{range(4, 7).map((i: any) => ( {range(4, 7).map(i => (
<Col key={i} style={styles.colButton}> <Col key={i} style={styles.colButton}>
<Button text={i} theme={theme} onPress={onPressNumber} /> <Button text={i.toString()} onPress={onPressNumber} />
</Col> </Col>
))} ))}
</Row> </Row>
<Row style={[styles.row, styles.buttonRow]}> <Row style={[styles.row, styles.buttonRow]}>
{range(7, 10).map((i: any) => ( {range(7, 10).map(i => (
<Col key={i} style={styles.colButton}> <Col key={i} style={styles.colButton}>
<Button text={i} theme={theme} onPress={onPressNumber} /> <Button text={i.toString()} onPress={onPressNumber} />
</Col> </Col>
))} ))}
</Row> </Row>
<Row style={[styles.row, styles.buttonRow]}> <Row style={[styles.row, styles.buttonRow]}>
{showBiometry ? ( {showBiometry ? (
<Col style={styles.colButton}> <Col style={styles.colButton}>
<Button icon='fingerprint' theme={theme} onPress={onBiometryPress} /> <Button icon='fingerprint' onPress={onBiometryPress} />
</Col> </Col>
) : ( ) : (
<Col style={styles.colButton} /> <Col style={styles.colButton} />
)} )}
<Col style={styles.colButton}> <Col style={styles.colButton}>
<Button text='0' theme={theme} onPress={onPressNumber} /> <Button text='0' onPress={onPressNumber} />
</Col> </Col>
<Col style={styles.colButton}> <Col style={styles.colButton}>
<Button icon='backspace' theme={theme} onPress={onPressDelete} /> <Button icon='backspace' onPress={onPressDelete} />
</Col> </Col>
</Row> </Row>
</Grid> </Grid>

View File

@ -2,24 +2,23 @@ import React, { useRef, useState } from 'react';
import * as Haptics from 'expo-haptics'; import * as Haptics from 'expo-haptics';
import { gestureHandlerRootHOC } from 'react-native-gesture-handler'; import { gestureHandlerRootHOC } from 'react-native-gesture-handler';
import Base from './Base'; import Base, { IBase } from './Base';
import { TYPE } from './constants'; import { TYPE } from './constants';
import I18n from '../../i18n'; import I18n from '../../i18n';
interface IPasscodeChoose { interface IPasscodeChoose {
theme: string;
force?: boolean; force?: boolean;
finishProcess: Function; finishProcess: Function;
} }
const PasscodeChoose = ({ theme, finishProcess, force = false }: IPasscodeChoose) => { const PasscodeChoose = ({ finishProcess, force = false }: IPasscodeChoose) => {
const chooseRef = useRef<any>(null); const chooseRef = useRef<IBase>(null);
const confirmRef = useRef<any>(null); const confirmRef = useRef<IBase>(null);
const [subtitle, setSubtitle] = useState(null); const [subtitle, setSubtitle] = useState(null);
const [status, setStatus] = useState(TYPE.CHOOSE); const [status, setStatus] = useState(TYPE.CHOOSE);
const [previousPasscode, setPreviouPasscode] = useState<any>(null); const [previousPasscode, setPreviouPasscode] = useState('');
const firstStep = (p: any) => { const firstStep = (p: string) => {
setTimeout(() => { setTimeout(() => {
setStatus(TYPE.CONFIRM); setStatus(TYPE.CONFIRM);
setPreviouPasscode(p); setPreviouPasscode(p);
@ -43,7 +42,6 @@ const PasscodeChoose = ({ theme, finishProcess, force = false }: IPasscodeChoose
return ( return (
<Base <Base
ref={confirmRef} ref={confirmRef}
theme={theme}
type={TYPE.CONFIRM} type={TYPE.CONFIRM}
onEndProcess={changePasscode} onEndProcess={changePasscode}
previousPasscode={previousPasscode} previousPasscode={previousPasscode}
@ -56,7 +54,6 @@ const PasscodeChoose = ({ theme, finishProcess, force = false }: IPasscodeChoose
return ( return (
<Base <Base
ref={chooseRef} ref={chooseRef}
theme={theme}
type={TYPE.CHOOSE} type={TYPE.CHOOSE}
onEndProcess={firstStep} onEndProcess={firstStep}
title={I18n.t('Passcode_choose_title')} title={I18n.t('Passcode_choose_title')}

View File

@ -4,7 +4,7 @@ import { gestureHandlerRootHOC } from 'react-native-gesture-handler';
import * as Haptics from 'expo-haptics'; import * as Haptics from 'expo-haptics';
import { sha256 } from 'js-sha256'; import { sha256 } from 'js-sha256';
import Base from './Base'; import Base, { IBase } from './Base';
import Locked from './Base/Locked'; import Locked from './Base/Locked';
import { TYPE } from './constants'; import { TYPE } from './constants';
import { ATTEMPTS_KEY, LOCKED_OUT_TIMER_KEY, MAX_ATTEMPTS, PASSCODE_KEY } from '../../constants/localAuthentication'; import { ATTEMPTS_KEY, LOCKED_OUT_TIMER_KEY, MAX_ATTEMPTS, PASSCODE_KEY } from '../../constants/localAuthentication';
@ -14,18 +14,17 @@ import { useUserPreferences } from '../../lib/userPreferences';
import I18n from '../../i18n'; import I18n from '../../i18n';
interface IPasscodePasscodeEnter { interface IPasscodePasscodeEnter {
theme: string;
hasBiometry: boolean; hasBiometry: boolean;
finishProcess: Function; finishProcess: Function;
} }
const PasscodeEnter = ({ theme, hasBiometry, finishProcess }: IPasscodePasscodeEnter) => { const PasscodeEnter = ({ hasBiometry, finishProcess }: IPasscodePasscodeEnter) => {
const ref = useRef(null); const ref = useRef<IBase>(null);
let attempts: any = 0; let attempts = 0;
let lockedUntil: any = false; let lockedUntil: any = false;
const [passcode] = useUserPreferences(PASSCODE_KEY); const [passcode] = useUserPreferences(PASSCODE_KEY);
const [status, setStatus] = useState(null); const [status, setStatus] = useState<TYPE | null>(null);
const { getItem: getAttempts, setItem: setAttempts } = useAsyncStorage(ATTEMPTS_KEY); const { setItem: setAttempts } = useAsyncStorage(ATTEMPTS_KEY);
const { setItem: setLockedUntil } = useAsyncStorage(LOCKED_OUT_TIMER_KEY); const { setItem: setLockedUntil } = useAsyncStorage(LOCKED_OUT_TIMER_KEY);
const biometry = async () => { const biometry = async () => {
@ -45,7 +44,6 @@ const PasscodeEnter = ({ theme, hasBiometry, finishProcess }: IPasscodePasscodeE
await resetAttempts(); await resetAttempts();
setStatus(TYPE.ENTER); setStatus(TYPE.ENTER);
} else { } else {
attempts = await getAttempts();
setStatus(TYPE.LOCKED); setStatus(TYPE.LOCKED);
} }
} else { } else {
@ -58,7 +56,7 @@ const PasscodeEnter = ({ theme, hasBiometry, finishProcess }: IPasscodePasscodeE
readStorage(); readStorage();
}, [status]); }, [status]);
const onEndProcess = (p: any) => { const onEndProcess = (p: string) => {
setTimeout(() => { setTimeout(() => {
if (sha256(p) === passcode) { if (sha256(p) === passcode) {
finishProcess(); finishProcess();
@ -69,8 +67,7 @@ const PasscodeEnter = ({ theme, hasBiometry, finishProcess }: IPasscodePasscodeE
setLockedUntil(new Date().toISOString()); setLockedUntil(new Date().toISOString());
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error); Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
} else { } else {
// @ts-ignore ref?.current?.wrongPasscode();
ref.current.wrongPasscode();
setAttempts(attempts?.toString()); setAttempts(attempts?.toString());
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning); Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning);
} }
@ -79,13 +76,12 @@ const PasscodeEnter = ({ theme, hasBiometry, finishProcess }: IPasscodePasscodeE
}; };
if (status === TYPE.LOCKED) { if (status === TYPE.LOCKED) {
return <Locked theme={theme} setStatus={setStatus} />; return <Locked setStatus={setStatus} />;
} }
return ( return (
<Base <Base
ref={ref} ref={ref}
theme={theme}
type={TYPE.ENTER} type={TYPE.ENTER}
title={I18n.t('Passcode_enter_title')} title={I18n.t('Passcode_enter_title')}
showBiometry={hasBiometry} showBiometry={hasBiometry}

View File

@ -1,6 +1,6 @@
export const TYPE: any = { export enum TYPE {
CHOOSE: 'choose', CHOOSE = 'choose',
CONFIRM: 'confirm', CONFIRM = 'confirm',
ENTER: 'enter', ENTER = 'enter',
LOCKED: 'locked' LOCKED = 'locked'
}; }

View File

@ -4,11 +4,11 @@ import moment from 'moment';
import { LOCKED_OUT_TIMER_KEY, TIME_TO_LOCK } from '../../constants/localAuthentication'; import { LOCKED_OUT_TIMER_KEY, TIME_TO_LOCK } from '../../constants/localAuthentication';
export const getLockedUntil = async () => { export const getLockedUntil = async () => {
const t: any = await AsyncStorage.getItem(LOCKED_OUT_TIMER_KEY); const t = await AsyncStorage.getItem(LOCKED_OUT_TIMER_KEY);
if (t) { if (t) {
return moment(t).add(TIME_TO_LOCK); return moment(t).add(TIME_TO_LOCK).toDate();
} }
return null; return null;
}; };
// @ts-ignore
export const getDiff = t => new Date(t) - new Date(); export const getDiff = (t: string | number | Date) => new Date(t).getTime() - new Date().getTime();

View File

@ -80,7 +80,7 @@ const ChangePasscodeView = React.memo(() => {
return ( return (
<Modal useNativeDriver isVisible={visible} hideModalContentWhileAnimating style={styles.modal}> <Modal useNativeDriver isVisible={visible} hideModalContentWhileAnimating style={styles.modal}>
<PasscodeChoose theme={theme} finishProcess={onSubmit} force={data?.force} /> <PasscodeChoose finishProcess={onSubmit} force={data?.force} />
{!data?.force ? ( {!data?.force ? (
<Touchable onPress={onCancel} style={styles.close}> <Touchable onPress={onCancel} style={styles.close}>
<CustomIcon name='close' color={themes[theme].passcodePrimary} size={30} /> <CustomIcon name='close' color={themes[theme].passcodePrimary} size={30} />

View File

@ -4,7 +4,6 @@ import useDeepCompareEffect from 'use-deep-compare-effect';
import isEmpty from 'lodash/isEmpty'; import isEmpty from 'lodash/isEmpty';
import Orientation from 'react-native-orientation-locker'; import Orientation from 'react-native-orientation-locker';
import { useTheme } from '../theme';
import EventEmitter from '../utils/events'; import EventEmitter from '../utils/events';
import { LOCAL_AUTHENTICATE_EMITTER } from '../constants/localAuthentication'; import { LOCAL_AUTHENTICATE_EMITTER } from '../constants/localAuthentication';
import { isTablet } from '../utils/deviceInfo'; import { isTablet } from '../utils/deviceInfo';
@ -19,8 +18,6 @@ const ScreenLockedView = (): JSX.Element => {
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const [data, setData] = useState<IData>({}); const [data, setData] = useState<IData>({});
const { theme } = useTheme();
useDeepCompareEffect(() => { useDeepCompareEffect(() => {
if (!isEmpty(data)) { if (!isEmpty(data)) {
setVisible(true); setVisible(true);
@ -62,7 +59,7 @@ const ScreenLockedView = (): JSX.Element => {
style={{ margin: 0 }} style={{ margin: 0 }}
animationIn='fadeIn' animationIn='fadeIn'
animationOut='fadeOut'> animationOut='fadeOut'>
<PasscodeEnter theme={theme} hasBiometry={!!data?.hasBiometry} finishProcess={onSubmit} /> <PasscodeEnter hasBiometry={!!data?.hasBiometry} finishProcess={onSubmit} />
</Modal> </Modal>
); );
}; };