diff --git a/app/containers/Passcode/Button.js b/app/containers/Passcode/Base/Button.js similarity index 87% rename from app/containers/Passcode/Button.js rename to app/containers/Passcode/Base/Button.js index ae76fc850..8f8f30362 100644 --- a/app/containers/Passcode/Button.js +++ b/app/containers/Passcode/Base/Button.js @@ -3,8 +3,8 @@ 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 { themes } from '../../../constants/colors'; +import Touch from '../../../utils/touch'; const Button = ({ text, disabled, theme, onPress diff --git a/app/containers/Passcode/Dots.js b/app/containers/Passcode/Base/Dots.js similarity index 96% rename from app/containers/Passcode/Dots.js rename to app/containers/Passcode/Base/Dots.js index 2fcb994a4..4d1974cd8 100644 --- a/app/containers/Passcode/Dots.js +++ b/app/containers/Passcode/Base/Dots.js @@ -3,7 +3,7 @@ import { View } from 'react-native'; import _ from 'lodash'; import styles from './styles'; -import { themes } from '../../constants/colors'; +import { themes } from '../../../constants/colors'; const SIZE_EMPTY = 8; const SIZE_FULL = 12; diff --git a/app/containers/Passcode/grid.js b/app/containers/Passcode/Base/grid.js similarity index 100% rename from app/containers/Passcode/grid.js rename to app/containers/Passcode/Base/grid.js diff --git a/app/containers/Passcode/Base.js b/app/containers/Passcode/Base/index.js similarity index 86% rename from app/containers/Passcode/Base.js rename to app/containers/Passcode/Base/index.js index 070ed73eb..face8ae2a 100644 --- a/app/containers/Passcode/Base.js +++ b/app/containers/Passcode/Base/index.js @@ -1,5 +1,5 @@ import React, { useState, forwardRef, useImperativeHandle } from 'react'; -import { View } from 'react-native'; +import { View, Text } from 'react-native'; import { Col, Row, Grid } from 'react-native-easy-grid'; import _ from 'lodash'; import PropTypes from 'prop-types'; @@ -7,14 +7,13 @@ import PropTypes from 'prop-types'; import styles from './styles'; import Button from './Button'; import Dots from './Dots'; -import Title from './Title'; -import Subtitle from './Subtitle'; -import { TYPE } from './constants'; +import { TYPE } from '../constants'; +import { themes } from '../../../constants/colors'; const PASSCODE_LENGTH = 6; const Base = forwardRef(({ - theme, type, onEndProcess, previousPasscode + theme, type, onEndProcess, previousPasscode, title, subtitle }, ref) => { const [passcode, setPasscode] = useState(''); @@ -36,6 +35,7 @@ const Base = forwardRef(({ // } break; case TYPE.CONFIRM: + console.log('currentPasscode', currentPasscode, previousPasscode); if (currentPasscode !== previousPasscode) { // this.showError(); alert('SHOW ERROR'); @@ -73,8 +73,8 @@ const Base = forwardRef(({ - - <Subtitle theme={theme} /> + <Text style={[styles.textTitle, { color: themes[theme].titleText }]}>{title}</Text> + {subtitle ? <Text style={[styles.textSubtitle, { color: themes[theme].bodyText }]}>{subtitle}</Text> : null} </View> <View style={styles.flexCirclePasscode}> <Dots passcode={passcode} theme={theme} length={PASSCODE_LENGTH} /> diff --git a/app/containers/Passcode/styles.js b/app/containers/Passcode/Base/styles.js similarity index 100% rename from app/containers/Passcode/styles.js rename to app/containers/Passcode/Base/styles.js diff --git a/app/containers/Passcode/PasscodeChoose.js b/app/containers/Passcode/PasscodeChoose.js new file mode 100644 index 000000000..df7068b85 --- /dev/null +++ b/app/containers/Passcode/PasscodeChoose.js @@ -0,0 +1,34 @@ +import React, { useRef, useState } from 'react'; +import PropTypes from 'prop-types'; + +import Base from './Base'; +import { TYPE } from './constants'; + +const PasscodeEnter = ({ + theme, type, finishProcess +}) => { + const ref = useRef(null); + const [status, setStatus] = useState(type); + const [previousPasscode, setPreviouPasscode] = useState(null); + + const firstStep = (p) => { + setStatus(TYPE.CONFIRM); + setPreviouPasscode(p); + }; + + const changePasscode = p => finishProcess && finishProcess(p); + + if (status === TYPE.CONFIRM) { + return <Base ref={ref} theme={theme} type={TYPE.CONFIRM} onEndProcess={changePasscode} previousPasscode={previousPasscode} title='Confirm your new passcode' />; + } + + return <Base ref={ref} theme={theme} type={TYPE.CHOOSE} onEndProcess={firstStep} title='Choose your new passcode' />; +}; + +PasscodeEnter.propTypes = { + theme: PropTypes.string, + type: PropTypes.string, + finishProcess: PropTypes.func +}; + +export default PasscodeEnter; diff --git a/app/containers/Passcode/PasscodeEnter.js b/app/containers/Passcode/PasscodeEnter.js new file mode 100644 index 000000000..a4945ba45 --- /dev/null +++ b/app/containers/Passcode/PasscodeEnter.js @@ -0,0 +1,76 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { useAsyncStorage } from '@react-native-community/async-storage'; +import RNUserDefaults from 'rn-user-defaults'; +import PropTypes from 'prop-types'; + +import Base from './Base'; +import Locked from './Locked'; +import { TYPE } from './constants'; +import { + ATTEMPTS_KEY, LOCKED_OUT_TIMER_KEY, PASSCODE_KEY, MAX_ATTEMPTS +} from '../../constants/localAuthentication'; +import { resetAttempts } from '../../utils/localAuthentication'; +import { getLockedUntil, getDiff } from './utils'; + +const PasscodeEnter = ({ + theme, type, finishProcess +}) => { + const ref = useRef(null); + let attempts = 0; + let lockedUntil = false; + let passcode = null; + const [status, setStatus] = useState(type); + const { getItem: getAttempts, setItem: setAttempts } = useAsyncStorage(ATTEMPTS_KEY); + const { setItem: setLockedUntil } = useAsyncStorage(LOCKED_OUT_TIMER_KEY); + + const fetchPasscode = async() => { + passcode = await RNUserDefaults.get(PASSCODE_KEY); + }; + + const readStorage = async() => { + lockedUntil = await getLockedUntil(); + if (lockedUntil) { + const diff = getDiff(lockedUntil); + if (diff <= 1) { + resetAttempts(); + } else { + attempts = await getAttempts(); + setStatus(TYPE.LOCKED); + } + } + fetchPasscode(); + }; + + useEffect(() => { + readStorage(); + }, []); + + const onEndProcess = (p) => { + if (p === passcode) { + finishProcess(); + } else { + attempts += 1; + if (attempts >= MAX_ATTEMPTS) { + setStatus(TYPE.LOCKED); + setLockedUntil(new Date().toISOString()); + } else { + ref.current.wrongPasscode(); + setAttempts(attempts?.toString()); + } + } + }; + + if (status === TYPE.LOCKED) { + return <Locked theme={theme} setStatus={setStatus} />; + } + + return <Base ref={ref} theme={theme} type={TYPE.ENTER} onEndProcess={onEndProcess} title='Enter your passcode' />; +}; + +PasscodeEnter.propTypes = { + theme: PropTypes.string, + type: PropTypes.string, + finishProcess: PropTypes.func +}; + +export default PasscodeEnter; diff --git a/app/containers/Passcode/Subtitle.js b/app/containers/Passcode/Subtitle.js deleted file mode 100644 index b5586bec1..000000000 --- a/app/containers/Passcode/Subtitle.js +++ /dev/null @@ -1,25 +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'; - -const Subtitle = ({ theme }) => ( - <Text - style={[ - styles.textSubtitle, - { - color: themes[theme].bodyText - } - ]} - > - Subtitle - </Text> -); - -Subtitle.propTypes = { - theme: PropTypes.string -}; - -export default Subtitle; diff --git a/app/containers/Passcode/Title.js b/app/containers/Passcode/Title.js deleted file mode 100644 index 7a203d80c..000000000 --- a/app/containers/Passcode/Title.js +++ /dev/null @@ -1,25 +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'; - -const Title = ({ theme }) => ( - <Text - style={[ - styles.textTitle, - { - color: themes[theme].titleText, - } - ]} - > - Title - </Text> -); - -Title.propTypes = { - theme: PropTypes.string -}; - -export default Title; diff --git a/app/containers/Passcode/index.js b/app/containers/Passcode/index.js index bba7bac24..489003058 100644 --- a/app/containers/Passcode/index.js +++ b/app/containers/Passcode/index.js @@ -1,76 +1,4 @@ -import React, { useEffect, useRef, useState } from 'react'; -import { useAsyncStorage } from '@react-native-community/async-storage'; -import RNUserDefaults from 'rn-user-defaults'; -import PropTypes from 'prop-types'; +import PasscodeEnter from './PasscodeEnter'; +import PasscodeChoose from './PasscodeChoose'; -import Base from './Base'; -import Locked from './Locked'; -import { TYPE } from './constants'; -import { - ATTEMPTS_KEY, LOCKED_OUT_TIMER_KEY, PASSCODE_KEY, MAX_ATTEMPTS -} from '../../constants/localAuthentication'; -import { resetAttempts } from '../../utils/localAuthentication'; -import { getLockedUntil, getDiff } from './utils'; - -const PasscodeEnter = ({ - theme, type, finishProcess -}) => { - const ref = useRef(null); - let attempts = 0; - let lockedUntil = false; - let passcode = null; - const [status, setStatus] = useState(type); - const { getItem: getAttempts, setItem: setAttempts } = useAsyncStorage(ATTEMPTS_KEY); - const { setItem: setLockedUntil } = useAsyncStorage(LOCKED_OUT_TIMER_KEY); - - const fetchPasscode = async() => { - passcode = await RNUserDefaults.get(PASSCODE_KEY); - }; - - const readStorage = async() => { - lockedUntil = await getLockedUntil(); - if (lockedUntil) { - const diff = getDiff(lockedUntil); - if (diff <= 1) { - resetAttempts(); - } else { - attempts = await getAttempts(); - setStatus(TYPE.LOCKED); - } - } - fetchPasscode(); - }; - - useEffect(() => { - readStorage(); - }, []); - - const onEndProcess = (p) => { - if (p === passcode) { - finishProcess(); - } else { - attempts += 1; - if (attempts >= MAX_ATTEMPTS) { - setStatus(TYPE.LOCKED); - setLockedUntil(new Date().toISOString()); - } else { - ref.current.wrongPasscode(); - setAttempts(attempts?.toString()); - } - } - }; - - if (status === TYPE.LOCKED) { - return <Locked theme={theme} setStatus={setStatus} />; - } - - return <Base ref={ref} theme={theme} type={TYPE.ENTER} onEndProcess={onEndProcess} />; -}; - -PasscodeEnter.propTypes = { - theme: PropTypes.string, - type: PropTypes.string, - finishProcess: PropTypes.func -}; - -export default PasscodeEnter; +export { PasscodeEnter, PasscodeChoose }; diff --git a/app/views/ChangePasscodeView.js b/app/views/ChangePasscodeView.js index dca3dbefb..3833e09ce 100644 --- a/app/views/ChangePasscodeView.js +++ b/app/views/ChangePasscodeView.js @@ -12,6 +12,8 @@ import { themes } from '../constants/colors'; import sharedStyles from './Styles'; import { PASSCODE_KEY, PASSCODE_LENGTH } from '../constants/localAuthentication'; import { isTablet } from '../utils/deviceInfo'; +import { TYPE } from '../containers/Passcode/constants'; +import { PasscodeChoose } from '../containers/Passcode'; const ScreenLockConfigView = React.memo(({ navigation, theme }) => { const savePasscode = async(passcode) => { @@ -34,7 +36,7 @@ const ScreenLockConfigView = React.memo(({ navigation, theme }) => { <SafeAreaView style={[sharedStyles.container, { backgroundColor: themes[theme].auxiliaryBackground }]} > - <PINCode + {/* <PINCode status={PinStatus.choose} passwordLength={PASSCODE_LENGTH} customBackSpaceIcon={() => null} @@ -59,7 +61,8 @@ const ScreenLockConfigView = React.memo(({ navigation, theme }) => { titleChoose='Enter your new passcode' titleConfirm='Confirm your passcode' subtitleChoose='' - /> + /> */} + <PasscodeChoose theme={theme} type={TYPE.choose} finishProcess={savePasscode} /> </SafeAreaView> ); }); diff --git a/app/views/ScreenLockConfigView.js b/app/views/ScreenLockConfigView.js index 551866000..2eabec07c 100644 --- a/app/views/ScreenLockConfigView.js +++ b/app/views/ScreenLockConfigView.js @@ -21,8 +21,6 @@ import { supportedBiometryLabel } from '../utils/localAuthentication'; import { DisclosureImage } from '../containers/DisclosureIndicator'; import { PASSCODE_KEY } from '../constants/localAuthentication'; -// RNUserDefaults.set(PASSCODE_KEY, '') - const DEFAULT_AUTO_LOCK = [ { title: 'After 1 minute', diff --git a/app/views/ScreenLockedView.js b/app/views/ScreenLockedView.js index 9865790eb..e37b9d3a3 100644 --- a/app/views/ScreenLockedView.js +++ b/app/views/ScreenLockedView.js @@ -17,7 +17,7 @@ import EventEmitter from '../utils/events'; import { withSplit } from '../split'; import { LOCAL_AUTHENTICATE_EMITTER } from '../constants/localAuthentication'; import { isTablet } from '../utils/deviceInfo'; -import Passcode from '../containers/Passcode'; +import { PasscodeEnter } from '../containers/Passcode'; import { TYPE } from '../containers/Passcode/constants'; const styles = StyleSheet.create({ @@ -99,7 +99,7 @@ const ScreenLockedView = ({ theme }) => { pinAttemptsAsyncStorageName={ATTEMPTS_KEY} lockedPage={<AppLocked />} /> */} - <Passcode theme={theme} type={TYPE.ENTER} finishProcess={onSubmit} /> + <PasscodeEnter theme={theme} type={TYPE.ENTER} finishProcess={onSubmit} /> </View> </Modal> );