[IMPROVE] - migrating the Passcode container
This commit is contained in:
parent
60f659618d
commit
369b3f2ef6
|
@ -1,47 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { Text } from 'react-native';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import styles from './styles';
|
|
||||||
import { themes } from '../../../constants/colors';
|
|
||||||
import Touch from '../../../utils/touch';
|
|
||||||
import { CustomIcon } from '../../../lib/Icons';
|
|
||||||
|
|
||||||
const Button = React.memo(({
|
|
||||||
text, disabled, theme, onPress, icon
|
|
||||||
}) => {
|
|
||||||
const press = () => onPress && onPress(text);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Touch
|
|
||||||
style={[styles.buttonView, { backgroundColor: 'transparent' }]}
|
|
||||||
underlayColor={themes[theme].passcodeButtonActive}
|
|
||||||
rippleColor={themes[theme].passcodeButtonActive}
|
|
||||||
enabled={!disabled}
|
|
||||||
theme={theme}
|
|
||||||
onPress={press}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
icon
|
|
||||||
? (
|
|
||||||
<CustomIcon name={icon} size={36} color={themes[theme].passcodePrimary} />
|
|
||||||
)
|
|
||||||
: (
|
|
||||||
<Text style={[styles.buttonText, { color: themes[theme].passcodePrimary }]}>
|
|
||||||
{text}
|
|
||||||
</Text>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</Touch>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
Button.propTypes = {
|
|
||||||
text: PropTypes.string,
|
|
||||||
icon: PropTypes.string,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
disabled: PropTypes.bool,
|
|
||||||
onPress: PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Button;
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Text } from 'react-native';
|
||||||
|
|
||||||
|
import styles from './styles';
|
||||||
|
import { themes } from '../../../constants/colors';
|
||||||
|
import Touch from '../../../utils/touch';
|
||||||
|
import { CustomIcon } from '../../../lib/Icons';
|
||||||
|
|
||||||
|
interface IPasscodeButton {
|
||||||
|
text: string;
|
||||||
|
icon: string;
|
||||||
|
theme: string;
|
||||||
|
disabled: boolean;
|
||||||
|
onPress({}?): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Button = React.memo(({ text, disabled, theme, onPress, icon }: Partial<IPasscodeButton>) => {
|
||||||
|
const press = () => onPress && onPress(text!);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Touch
|
||||||
|
style={[styles.buttonView, { backgroundColor: 'transparent' }]}
|
||||||
|
underlayColor={themes[theme!].passcodeButtonActive}
|
||||||
|
rippleColor={themes[theme!].passcodeButtonActive}
|
||||||
|
enabled={!disabled}
|
||||||
|
theme={theme}
|
||||||
|
onPress={press}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
icon
|
||||||
|
? (
|
||||||
|
<CustomIcon name={icon} size={36} color={themes[theme!].passcodePrimary} />
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
<Text style={[styles.buttonText, { color: themes[theme!].passcodePrimary }]}>
|
||||||
|
{text}
|
||||||
|
</Text>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Touch>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Button;
|
|
@ -1,7 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import range from 'lodash/range';
|
import range from 'lodash/range';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { themes } from '../../../constants/colors';
|
import { themes } from '../../../constants/colors';
|
||||||
|
@ -9,7 +8,13 @@ import { themes } from '../../../constants/colors';
|
||||||
const SIZE_EMPTY = 12;
|
const SIZE_EMPTY = 12;
|
||||||
const SIZE_FULL = 16;
|
const SIZE_FULL = 16;
|
||||||
|
|
||||||
const Dots = React.memo(({ passcode, theme, length }) => (
|
interface IPasscodeDots {
|
||||||
|
passcode: string;
|
||||||
|
theme: string;
|
||||||
|
length: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Dots = React.memo(({ passcode, theme, length }: IPasscodeDots) => (
|
||||||
<View style={styles.dotsContainer}>
|
<View style={styles.dotsContainer}>
|
||||||
{range(length).map((val) => {
|
{range(length).map((val) => {
|
||||||
const lengthSup = (passcode.length >= val + 1);
|
const lengthSup = (passcode.length >= val + 1);
|
||||||
|
@ -42,10 +47,4 @@ const Dots = React.memo(({ passcode, theme, length }) => (
|
||||||
</View>
|
</View>
|
||||||
));
|
));
|
||||||
|
|
||||||
Dots.propTypes = {
|
|
||||||
passcode: PropTypes.string,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
length: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Dots;
|
export default Dots;
|
|
@ -1,13 +1,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import { Row } from 'react-native-easy-grid';
|
import { Row } from 'react-native-easy-grid';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
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';
|
||||||
|
|
||||||
const LockIcon = React.memo(({ theme }) => (
|
const LockIcon = React.memo(({ theme }: {theme: string}) => (
|
||||||
<Row style={styles.row}>
|
<Row style={styles.row}>
|
||||||
<View style={styles.iconView}>
|
<View style={styles.iconView}>
|
||||||
<CustomIcon name='auth' size={40} color={themes[theme].passcodeLockIcon} />
|
<CustomIcon name='auth' size={40} color={themes[theme].passcodeLockIcon} />
|
||||||
|
@ -15,8 +14,4 @@ const LockIcon = React.memo(({ theme }) => (
|
||||||
</Row>
|
</Row>
|
||||||
));
|
));
|
||||||
|
|
||||||
LockIcon.propTypes = {
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
export default LockIcon;
|
export default LockIcon;
|
|
@ -1,5 +1,4 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Grid } from 'react-native-easy-grid';
|
import { Grid } from 'react-native-easy-grid';
|
||||||
|
|
||||||
import { themes } from '../../../constants/colors';
|
import { themes } from '../../../constants/colors';
|
||||||
|
@ -12,7 +11,18 @@ import Title from './Title';
|
||||||
import Subtitle from './Subtitle';
|
import Subtitle from './Subtitle';
|
||||||
import LockIcon from './LockIcon';
|
import LockIcon from './LockIcon';
|
||||||
|
|
||||||
const Timer = React.memo(({ time, theme, setStatus }) => {
|
type TPasscodeTimer = {
|
||||||
|
time: string;
|
||||||
|
theme: string;
|
||||||
|
setStatus: Function;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IPasscodeLocked {
|
||||||
|
theme: string;
|
||||||
|
setStatus: Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Timer = React.memo(({ time, theme, setStatus }: TPasscodeTimer) => {
|
||||||
const calcTimeLeft = () => {
|
const calcTimeLeft = () => {
|
||||||
const diff = getDiff(time);
|
const diff = getDiff(time);
|
||||||
if (diff > 0) {
|
if (diff > 0) {
|
||||||
|
@ -20,7 +30,7 @@ const Timer = React.memo(({ time, theme, setStatus }) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const [timeLeft, setTimeLeft] = useState(calcTimeLeft());
|
const [timeLeft, setTimeLeft] = useState<any>(calcTimeLeft());
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -39,8 +49,8 @@ const Timer = React.memo(({ time, theme, setStatus }) => {
|
||||||
return <Subtitle text={I18n.t('Passcode_app_locked_subtitle', { timeLeft })} theme={theme} />;
|
return <Subtitle text={I18n.t('Passcode_app_locked_subtitle', { timeLeft })} theme={theme} />;
|
||||||
});
|
});
|
||||||
|
|
||||||
const Locked = React.memo(({ theme, setStatus }) => {
|
const Locked = React.memo(({ theme, setStatus }: IPasscodeLocked) => {
|
||||||
const [lockedUntil, setLockedUntil] = useState(null);
|
const [lockedUntil, setLockedUntil] = useState<any>(null);
|
||||||
|
|
||||||
const readItemFromStorage = async() => {
|
const readItemFromStorage = async() => {
|
||||||
const l = await getLockedUntil();
|
const l = await getLockedUntil();
|
||||||
|
@ -60,15 +70,4 @@ const Locked = React.memo(({ theme, setStatus }) => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Locked.propTypes = {
|
|
||||||
theme: PropTypes.string,
|
|
||||||
setStatus: PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
Timer.propTypes = {
|
|
||||||
time: PropTypes.string,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
setStatus: PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Locked;
|
export default Locked;
|
|
@ -1,12 +1,16 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { View, Text } from 'react-native';
|
import { View, Text } from 'react-native';
|
||||||
import { Row } from 'react-native-easy-grid';
|
import { Row } from 'react-native-easy-grid';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { themes } from '../../../constants/colors';
|
import { themes } from '../../../constants/colors';
|
||||||
|
|
||||||
const Subtitle = React.memo(({ text, theme }) => (
|
interface IPasscodeSubtitle {
|
||||||
|
text: string;
|
||||||
|
theme: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Subtitle = React.memo(({ text, theme }: IPasscodeSubtitle) => (
|
||||||
<Row style={styles.row}>
|
<Row style={styles.row}>
|
||||||
<View style={styles.subtitleView}>
|
<View style={styles.subtitleView}>
|
||||||
<Text style={[styles.textSubtitle, { color: themes[theme].passcodeSecondary }]}>{text}</Text>
|
<Text style={[styles.textSubtitle, { color: themes[theme].passcodeSecondary }]}>{text}</Text>
|
||||||
|
@ -14,9 +18,4 @@ const Subtitle = React.memo(({ text, theme }) => (
|
||||||
</Row>
|
</Row>
|
||||||
));
|
));
|
||||||
|
|
||||||
Subtitle.propTypes = {
|
|
||||||
text: PropTypes.string,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Subtitle;
|
export default Subtitle;
|
|
@ -1,12 +1,16 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { View, Text } from 'react-native';
|
import { View, Text } from 'react-native';
|
||||||
import { Row } from 'react-native-easy-grid';
|
import { Row } from 'react-native-easy-grid';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { themes } from '../../../constants/colors';
|
import { themes } from '../../../constants/colors';
|
||||||
|
|
||||||
const Title = React.memo(({ text, theme }) => (
|
interface IPasscodeTitle {
|
||||||
|
text: string;
|
||||||
|
theme: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Title = React.memo(({ text, theme }: IPasscodeTitle) => (
|
||||||
<Row style={styles.row}>
|
<Row style={styles.row}>
|
||||||
<View style={styles.titleView}>
|
<View style={styles.titleView}>
|
||||||
<Text style={[styles.textTitle, { color: themes[theme].passcodePrimary }]}>{text}</Text>
|
<Text style={[styles.textTitle, { color: themes[theme].passcodePrimary }]}>{text}</Text>
|
||||||
|
@ -14,9 +18,4 @@ const Title = React.memo(({ text, theme }) => (
|
||||||
</Row>
|
</Row>
|
||||||
));
|
));
|
||||||
|
|
||||||
Title.propTypes = {
|
|
||||||
text: PropTypes.string,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Title;
|
export default Title;
|
|
@ -1,9 +1,6 @@
|
||||||
import React, {
|
import React, { useState, forwardRef, useImperativeHandle, useRef } from 'react';
|
||||||
useState, forwardRef, useImperativeHandle, useRef
|
|
||||||
} from 'react';
|
|
||||||
import { Col, Row, Grid } from 'react-native-easy-grid';
|
import { Col, Row, Grid } from 'react-native-easy-grid';
|
||||||
import range from 'lodash/range';
|
import range from 'lodash/range';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
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';
|
||||||
|
|
||||||
|
@ -17,11 +14,23 @@ import LockIcon from './LockIcon';
|
||||||
import Title from './Title';
|
import Title from './Title';
|
||||||
import Subtitle from './Subtitle';
|
import Subtitle from './Subtitle';
|
||||||
|
|
||||||
|
interface IPasscodeBase {
|
||||||
|
theme: string;
|
||||||
|
type: string;
|
||||||
|
previousPasscode: string;
|
||||||
|
title: string;
|
||||||
|
subtitle: string;
|
||||||
|
showBiometry: string;
|
||||||
|
onEndProcess: Function;
|
||||||
|
onError: Function;
|
||||||
|
onBiometryPress(): void;
|
||||||
|
}
|
||||||
|
|
||||||
const Base = forwardRef(({
|
const Base = forwardRef(({
|
||||||
theme, type, onEndProcess, previousPasscode, title, subtitle, onError, showBiometry, onBiometryPress
|
theme, type, onEndProcess, previousPasscode, title, subtitle, onError, showBiometry, onBiometryPress
|
||||||
}, ref) => {
|
}: IPasscodeBase, ref) => {
|
||||||
const rootRef = useRef();
|
const rootRef = useRef<any>();
|
||||||
const dotsRef = useRef();
|
const dotsRef = useRef<any>();
|
||||||
const [passcode, setPasscode] = useState('');
|
const [passcode, setPasscode] = useState('');
|
||||||
|
|
||||||
const clearPasscode = () => setPasscode('');
|
const clearPasscode = () => setPasscode('');
|
||||||
|
@ -32,11 +41,11 @@ const Base = forwardRef(({
|
||||||
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
|
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
|
||||||
};
|
};
|
||||||
|
|
||||||
const animate = (animation, duration = 500) => {
|
const animate = (animation: string, duration = 500) => {
|
||||||
rootRef?.current?.[animation](duration);
|
rootRef?.current?.[animation](duration);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPressNumber = text => setPasscode((p) => {
|
const onPressNumber = (text: string) => setPasscode((p) => {
|
||||||
const currentPasscode = p + text;
|
const currentPasscode = p + text;
|
||||||
if (currentPasscode?.length === PASSCODE_LENGTH) {
|
if (currentPasscode?.length === PASSCODE_LENGTH) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -77,28 +86,28 @@ const Base = forwardRef(({
|
||||||
<Grid style={[styles.grid, { backgroundColor: themes[theme].passcodeBackground }]}>
|
<Grid style={[styles.grid, { backgroundColor: themes[theme].passcodeBackground }]}>
|
||||||
<LockIcon theme={theme} />
|
<LockIcon theme={theme} />
|
||||||
<Title text={title} theme={theme} />
|
<Title text={title} theme={theme} />
|
||||||
<Subtitle text={subtitle} theme={theme} />
|
<Subtitle text={subtitle!} theme={theme} />
|
||||||
<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} theme={theme} 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 => (
|
{range(1, 4).map((i: any) => (
|
||||||
<Col key={i} style={styles.colButton}>
|
<Col key={i} style={styles.colButton}>
|
||||||
<Button text={i} theme={theme} onPress={onPressNumber} />
|
<Button text={i} theme={theme} onPress={onPressNumber} />
|
||||||
</Col>
|
</Col>
|
||||||
))}
|
))}
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={[styles.row, styles.buttonRow]}>
|
<Row style={[styles.row, styles.buttonRow]}>
|
||||||
{range(4, 7).map(i => (
|
{range(4, 7).map((i: any) => (
|
||||||
<Col key={i} style={styles.colButton}>
|
<Col key={i} style={styles.colButton}>
|
||||||
<Button text={i} theme={theme} onPress={onPressNumber} />
|
<Button text={i} theme={theme} onPress={onPressNumber} />
|
||||||
</Col>
|
</Col>
|
||||||
))}
|
))}
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={[styles.row, styles.buttonRow]}>
|
<Row style={[styles.row, styles.buttonRow]}>
|
||||||
{range(7, 10).map(i => (
|
{range(7, 10).map((i: any) => (
|
||||||
<Col key={i} style={styles.colButton}>
|
<Col key={i} style={styles.colButton}>
|
||||||
<Button text={i} theme={theme} onPress={onPressNumber} />
|
<Button text={i} theme={theme} onPress={onPressNumber} />
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -124,16 +133,4 @@ const Base = forwardRef(({
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Base.propTypes = {
|
|
||||||
theme: PropTypes.string,
|
|
||||||
type: PropTypes.string,
|
|
||||||
previousPasscode: PropTypes.string,
|
|
||||||
title: PropTypes.string,
|
|
||||||
subtitle: PropTypes.string,
|
|
||||||
showBiometry: PropTypes.string,
|
|
||||||
onEndProcess: PropTypes.func,
|
|
||||||
onError: PropTypes.func,
|
|
||||||
onBiometryPress: PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Base;
|
export default Base;
|
|
@ -1,5 +1,4 @@
|
||||||
import React, { useState, useRef } from 'react';
|
import React, { useState, useRef } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
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';
|
||||||
|
|
||||||
|
@ -7,14 +6,20 @@ import Base from './Base';
|
||||||
import { TYPE } from './constants';
|
import { TYPE } from './constants';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
|
|
||||||
const PasscodeChoose = ({ theme, finishProcess, force = false }) => {
|
interface IPasscodeChoose {
|
||||||
const chooseRef = useRef(null);
|
theme: string;
|
||||||
const confirmRef = useRef(null);
|
force: boolean;
|
||||||
|
finishProcess: Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PasscodeChoose = ({ theme, finishProcess, force = false }: IPasscodeChoose) => {
|
||||||
|
const chooseRef = useRef<any>(null);
|
||||||
|
const confirmRef = useRef<any>(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(null);
|
const [previousPasscode, setPreviouPasscode] = useState<any>(null);
|
||||||
|
|
||||||
const firstStep = (p) => {
|
const firstStep = (p: any) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setStatus(TYPE.CONFIRM);
|
setStatus(TYPE.CONFIRM);
|
||||||
setPreviouPasscode(p);
|
setPreviouPasscode(p);
|
||||||
|
@ -22,7 +27,7 @@ const PasscodeChoose = ({ theme, finishProcess, force = false }) => {
|
||||||
}, 200);
|
}, 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
const changePasscode = p => finishProcess && finishProcess(p);
|
const changePasscode = (p: string) => finishProcess && finishProcess(p);
|
||||||
|
|
||||||
const onError = () => {
|
const onError = () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -36,6 +41,7 @@ const PasscodeChoose = ({ theme, finishProcess, force = false }) => {
|
||||||
|
|
||||||
if (status === TYPE.CONFIRM) {
|
if (status === TYPE.CONFIRM) {
|
||||||
return (
|
return (
|
||||||
|
// @ts-ignore
|
||||||
<Base
|
<Base
|
||||||
ref={confirmRef}
|
ref={confirmRef}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
|
@ -49,6 +55,7 @@ const PasscodeChoose = ({ theme, finishProcess, force = false }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
// @ts-ignore
|
||||||
<Base
|
<Base
|
||||||
ref={chooseRef}
|
ref={chooseRef}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
|
@ -60,10 +67,4 @@ const PasscodeChoose = ({ theme, finishProcess, force = false }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
PasscodeChoose.propTypes = {
|
|
||||||
theme: PropTypes.string,
|
|
||||||
force: PropTypes.bool,
|
|
||||||
finishProcess: PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
export default gestureHandlerRootHOC(PasscodeChoose);
|
export default gestureHandlerRootHOC(PasscodeChoose);
|
|
@ -1,6 +1,5 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { useAsyncStorage } from '@react-native-community/async-storage';
|
import { useAsyncStorage } from '@react-native-community/async-storage';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';
|
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';
|
||||||
|
@ -16,17 +15,24 @@ import { getLockedUntil, getDiff } from './utils';
|
||||||
import UserPreferences from '../../lib/userPreferences';
|
import UserPreferences from '../../lib/userPreferences';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
|
|
||||||
const PasscodeEnter = ({ theme, hasBiometry, finishProcess }) => {
|
|
||||||
|
interface IPasscodePasscodeEnter {
|
||||||
|
theme: string;
|
||||||
|
hasBiometry: string;
|
||||||
|
finishProcess: Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PasscodeEnter = ({ theme, hasBiometry, finishProcess }: IPasscodePasscodeEnter) => {
|
||||||
const ref = useRef(null);
|
const ref = useRef(null);
|
||||||
let attempts = 0;
|
let attempts: any = 0;
|
||||||
let lockedUntil = false;
|
let lockedUntil: any = false;
|
||||||
const [passcode, setPasscode] = useState(null);
|
const [passcode, setPasscode] = useState(null);
|
||||||
const [status, setStatus] = useState(null);
|
const [status, setStatus] = useState(null);
|
||||||
const { getItem: getAttempts, setItem: setAttempts } = useAsyncStorage(ATTEMPTS_KEY);
|
const { getItem: getAttempts, setItem: setAttempts } = useAsyncStorage(ATTEMPTS_KEY);
|
||||||
const { setItem: setLockedUntil } = useAsyncStorage(LOCKED_OUT_TIMER_KEY);
|
const { setItem: setLockedUntil } = useAsyncStorage(LOCKED_OUT_TIMER_KEY);
|
||||||
|
|
||||||
const fetchPasscode = async() => {
|
const fetchPasscode = async() => {
|
||||||
const p = await UserPreferences.getStringAsync(PASSCODE_KEY);
|
const p: any = await UserPreferences.getStringAsync(PASSCODE_KEY);
|
||||||
setPasscode(p);
|
setPasscode(p);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,7 +67,7 @@ const PasscodeEnter = ({ theme, hasBiometry, finishProcess }) => {
|
||||||
readStorage();
|
readStorage();
|
||||||
}, [status]);
|
}, [status]);
|
||||||
|
|
||||||
const onEndProcess = (p) => {
|
const onEndProcess = (p: any) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (sha256(p) === passcode) {
|
if (sha256(p) === passcode) {
|
||||||
finishProcess();
|
finishProcess();
|
||||||
|
@ -72,6 +78,7 @@ const PasscodeEnter = ({ theme, hasBiometry, finishProcess }) => {
|
||||||
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);
|
||||||
|
@ -97,10 +104,4 @@ const PasscodeEnter = ({ theme, hasBiometry, finishProcess }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
PasscodeEnter.propTypes = {
|
|
||||||
theme: PropTypes.string,
|
|
||||||
hasBiometry: PropTypes.string,
|
|
||||||
finishProcess: PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
export default gestureHandlerRootHOC(PasscodeEnter);
|
export default gestureHandlerRootHOC(PasscodeEnter);
|
|
@ -1,4 +1,4 @@
|
||||||
export const TYPE = {
|
export const TYPE: any = {
|
||||||
CHOOSE: 'choose',
|
CHOOSE: 'choose',
|
||||||
CONFIRM: 'confirm',
|
CONFIRM: 'confirm',
|
||||||
ENTER: 'enter',
|
ENTER: 'enter',
|
|
@ -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 = await AsyncStorage.getItem(LOCKED_OUT_TIMER_KEY);
|
const t: any = 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);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
// @ts-ignore
|
||||||
export const getDiff = t => new Date(t) - new Date();
|
export const getDiff = t => new Date(t) - new Date();
|
Loading…
Reference in New Issue