diff --git a/packages/mobile/src/screens/signon/SignOn.tsx b/packages/mobile/src/screens/signon/SignOn.tsx index 0198745958a..26c362d9e25 100644 --- a/packages/mobile/src/screens/signon/SignOn.tsx +++ b/packages/mobile/src/screens/signon/SignOn.tsx @@ -1,5 +1,6 @@ import { useState, useRef, useEffect, useCallback } from 'react' +import { formatOtp } from '@audius/common/schemas' import { accountSelectors } from '@audius/common/store' import Clipboard from '@react-native-clipboard/clipboard' import type { NativeStackScreenProps } from '@react-navigation/native-stack' @@ -580,7 +581,12 @@ const SignOn = ({ navigation }: SignOnProps) => { return <> } - const otpInputField = () => { + const OtpInputField = ({ show }: { show: boolean }) => { + const [value, setValue] = useState('') + + if (!show) { + return null + } return ( { autoCorrect={false} autoCapitalize='characters' enablesReturnKeyAutomatically={true} - maxLength={6} + keyboardType='number-pad' inputMode='numeric' textContentType='oneTimeCode' - onChangeText={(newText) => { - dispatch(signOnActions.setValueField('otp', newText)) + value={value} + onChangeText={(text) => { + const formatted = formatOtp(text) + setValue(formatted) + const sanitized = formatted.replace(/\s/g, '') + dispatch(signOnActions.setValueField('otp', sanitized)) }} onFocus={() => { setOtpBorderColor('#7E1BCC') @@ -774,7 +784,9 @@ const SignOn = ({ navigation }: SignOnProps) => { /> {passwordInputField()} {errorView()} - {requiresOtp ? otpInputField() : null} + {OtpInputField({ + show: requiresOtp || (!!otpField.value && isWorking) + })}