Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(wallet-mobile): display native kb for device pin #3653

Draft
wants to merge 12 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import {defineMessages, useIntl} from 'react-intl'

import {showErrorDialog} from '../../../kernel/dialogs'
Expand All @@ -25,6 +25,16 @@ export const CreatePinInput = ({onDone}: Props) => {
const [pin, setPin] = React.useState('')
const [step, setStep] = React.useState<'pin' | 'pinConfirmation'>('pin')

React.useEffect(() => {
if (step === 'pin') {
pinInputRef.current?.clear()
pinInputRef.current?.focus()
} else if (step === 'pinConfirmation') {
pinConfirmationInputRef.current?.clear()
pinConfirmationInputRef.current?.focus()
}
}, [step])

const onPinInput = (pin: string) => {
setPin(pin)
setStep('pinConfirmation')
Expand Down
68 changes: 51 additions & 17 deletions apps/wallet-mobile/src/features/Auth/PinInput/PinInput.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {useTheme} from '@yoroi/theme'
import _ from 'lodash'
import React from 'react'
import {StyleSheet, View} from 'react-native'
import * as React from 'react'
import {StyleSheet, TextInput, View} from 'react-native'
import {InteractionManager} from 'react-native'

import {BACKSPACE, NumericKeyboard} from '../../../components/NumericKeyboard'
import {Spacer} from '../../../components/Spacer/Spacer'
import {Text} from '../../../components/Text'

Expand All @@ -18,35 +18,52 @@ type Props = {

export type PinInputRef = {
clear: () => void
focus: () => void
}

export const PinInput = React.forwardRef<PinInputRef, Props>((props, ref) => {
const {enabled = true, pinMaxLength, title, subtitles = [], onDone, onGoBack} = props
const {enabled = true, pinMaxLength, title, subtitles = [], onDone} = props
const styles = useStyles()

const [pin, setPin] = React.useState('')
const inputRef = React.useRef<TextInput>(null)
const {isDark} = useTheme()

React.useEffect(() => {
if (enabled) {
const interaction = InteractionManager.runAfterInteractions(() => {
const timer = setTimeout(() => {
inputRef.current?.focus()
}, 300)
return () => clearTimeout(timer)
})
return () => interaction.cancel()
}
}, [enabled])

React.useImperativeHandle(ref, () => ({
clear: () => {
setPin('')
inputRef.current?.clear()
inputRef.current?.focus()
},
focus: () => {
inputRef.current?.focus()
},
}))

const onKeyDown = (value: string) => {
const handleTextChange = (value: string) => {
if (!enabled) return
if (value === BACKSPACE) {
if (pin.length === 0) onGoBack?.()
setPin(pin.substring(0, pin.length - 1))
return
}

if (pin.length === pinMaxLength) {
return
if (value.length > pinMaxLength) {
value = value.substring(0, pinMaxLength)
}

const newPin = pin.concat(value)
setPin(newPin)
if (newPin.length === pinMaxLength) onDone(newPin)
setPin(value)

if (value.length === pinMaxLength) {
onDone(value)
}
}

return (
Expand All @@ -71,7 +88,18 @@ export const PinInput = React.forwardRef<PinInputRef, Props>((props, ref) => {
</View>
</View>

<NumericKeyboard onKeyDown={onKeyDown} />
<TextInput
ref={inputRef}
style={styles.hiddenInput}
keyboardType="numeric"
value={pin}
onChangeText={handleTextChange}
maxLength={pinMaxLength}
autoFocus={true}
caretHidden={true}
importantForAccessibility="no"
keyboardAppearance={isDark ? 'dark' : 'light'}
/>
</View>
)
})
Expand All @@ -90,7 +118,7 @@ const PinPlaceholder = ({isActive}: PinPlaceholderProps) => {
}

const useStyles = () => {
const {color} = useTheme()
const {color, atoms} = useTheme()

const styles = StyleSheet.create({
pinInput: {
Expand Down Expand Up @@ -136,6 +164,12 @@ const useStyles = () => {
pinCircleActive: {
backgroundColor: color.primary_600,
},
hiddenInput: {
...atoms.absolute,
opacity: 0,
height: 0,
width: 0,
},
})
return styles
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,59 @@
"defaultMessage": "!!!Enter PIN",
"file": "src/features/Auth/CreatePinInput/CreatePinInput.tsx",
"start": {
"line": 78,
"line": 88,
"column": 17,
"index": 2443
"index": 2729
},
"end": {
"line": 81,
"line": 91,
"column": 3,
"index": 2551
"index": 2837
}
},
{
"id": "components.initialization.custompinscreen.pinInputSubtitle",
"defaultMessage": "!!!Choose a new PIN to quickly access your wallet",
"file": "src/features/Auth/CreatePinInput/CreatePinInput.tsx",
"start": {
"line": 82,
"line": 92,
"column": 20,
"index": 2573
"index": 2859
},
"end": {
"line": 85,
"line": 95,
"column": 3,
"index": 2721
"index": 3007
}
},
{
"id": "components.initialization.custompinscreen.pinConfirmationTitle",
"defaultMessage": "!!!Repeat PIN",
"file": "src/features/Auth/CreatePinInput/CreatePinInput.tsx",
"start": {
"line": 86,
"line": 96,
"column": 29,
"index": 2752
"index": 3038
},
"end": {
"line": 89,
"line": 99,
"column": 3,
"index": 2868
"index": 3154
}
},
{
"id": "components.firstrun.custompinscreen.pinInputConfirmationSubTitle",
"defaultMessage": "!!!Repeat a new PIN to quickly access your wallet",
"file": "src/features/Auth/CreatePinInput/CreatePinInput.tsx",
"start": {
"line": 90,
"line": 100,
"column": 32,
"index": 2902
"index": 3188
},
"end": {
"line": 93,
"line": 103,
"column": 3,
"index": 3056
"index": 3342
}
}
]
Loading