added insert pin

This commit is contained in:
Ksenia Lebedeva 2024-09-13 12:19:38 +02:00
parent 660960db1a
commit 5855b788ec
11 changed files with 217 additions and 14 deletions

View File

@ -1,6 +1,11 @@
apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"
apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")
project.ext.vectoricons = [
iconFontNames: [ 'Feather.ttf' ]
]
/**
* This is the configuration block to customize your React Native Android app.

53
package-lock.json generated
View File

@ -11,7 +11,8 @@
"react": "18.3.1",
"react-native": "0.75.2",
"react-native-modal": "^13.0.1",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.5.39"
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.5.39",
"react-native-vector-icons": "^10.1.0"
},
"devDependencies": {
"@babel/core": "^7.20.0",
@ -12043,6 +12044,56 @@
"resolved": "git+ssh://git@github.com/status-im/react-native-status-keycard.git#93dd64754e676172310e6ea7187cc49f2dc013c6",
"license": "MPL 2.0"
},
"node_modules/react-native-vector-icons": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-10.1.0.tgz",
"integrity": "sha512-fdQjCHIdoXmRoTZ5gvN1FmT4sGLQ2wmQiNZHKJQUYnE2tkIwjGnxNch+6Nd4lHAACvMWO7LOzBNot2u/zlOmkw==",
"dependencies": {
"prop-types": "^15.7.2",
"yargs": "^16.1.1"
},
"bin": {
"fa-upgrade.sh": "bin/fa-upgrade.sh",
"fa5-upgrade": "bin/fa5-upgrade.sh",
"fa6-upgrade": "bin/fa6-upgrade.sh",
"generate-icon": "bin/generate-icon.js"
}
},
"node_modules/react-native-vector-icons/node_modules/cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^7.0.0"
}
},
"node_modules/react-native-vector-icons/node_modules/yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"dependencies": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.0",
"y18n": "^5.0.5",
"yargs-parser": "^20.2.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/react-native-vector-icons/node_modules/yargs-parser": {
"version": "20.2.9",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
"engines": {
"node": ">=10"
}
},
"node_modules/react-native/node_modules/@jest/types": {
"version": "26.6.2",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",

View File

@ -13,7 +13,8 @@
"react": "18.3.1",
"react-native": "0.75.2",
"react-native-modal": "^13.0.1",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.5.39"
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.5.39",
"react-native-vector-icons": "^10.1.0"
},
"devDependencies": {
"@babel/core": "^7.20.0",

View File

@ -111,12 +111,16 @@ const Main = () => {
return connectCard();
}
const cancel = () => {
setStep(Step.Discovery);
}
return (
<SafeAreaView style={[backgroundStyle, styles.container]}>
{step == Step.Discovery && <DiscoveryScreen onPressFunc={connectCard}></DiscoveryScreen>}
{step == Step.Initialization && <InitializationScreen onPressFunc={initPin} ></InitializationScreen>}
{step == Step.Loading && <MnemonicScreen onPressFunc={loadMnemonic} pinRequired={pinRef.current ? false : true}></MnemonicScreen>}
{step == Step.Authentication && <AuthenticationScreen onPressFunc={() => {}}></AuthenticationScreen>}
{step == Step.Initialization && <InitializationScreen onPressFunc={initPin} onCancelFunc={cancel}></InitializationScreen>}
{step == Step.Loading && <MnemonicScreen onPressFunc={loadMnemonic} pinRequired={pinRef.current ? false : true} onCancelFunc={cancel}></MnemonicScreen>}
{step == Step.Authentication && <AuthenticationScreen onPressFunc={() => {} } onCancelFunc={cancel}></AuthenticationScreen>}
<NFCModal isVisible={isModalVisible} onChangeFunc={setIsModalVisible}></NFCModal>
</SafeAreaView>
);
@ -124,10 +128,8 @@ const Main = () => {
const styles = StyleSheet.create({
container: {
paddingTop: '30%',
width: '100%',
height: '100%',
paddingLeft: '6%',
paddingRight: '6%'
},
});

View File

@ -27,10 +27,9 @@ const buttonStyle = StyleSheet.create({
textAlign: 'center',
paddingTop: 25,
paddingBottom: 15,
justifyContent: 'flex-start'
justifyContent: 'flex-start',
},
button: {
},
title: {
fontSize: 15,

View File

@ -0,0 +1,73 @@
import { SafeAreaView, StyleSheet, Text, View, Dimensions } from "react-native";
import React, {FC, useState } from "react";
import DialpadKeypad from "./DialpadKeypad";
import Button from "./Button";
const { width, height } = Dimensions.get("window");
type CustomDialpadProps = {
onCancelFunc: () => void;
onNextFunc: (p?: string) => void;
};
const CustomDialpad: FC<CustomDialpadProps> = props => {
const {onNextFunc, onCancelFunc} = props;
const dialPadContent = [1, 2, 3, 4, 5, 6, 7, 8, 9, "", 0, "X"];
const dialPadSize = width * 0.2;
const dialPadTextSize = dialPadSize * 0.36;
const [code, setCode] = useState([]);
const pinLength = 6;
const updateCode = (item: never) => {
if (item === "X") {
setCode((prev) => prev.slice(0, -1));
} else {
setCode((prev) => [...prev, item]);
}
}
return (
<SafeAreaView style={styles.container}>
<View style={styles.textContainer}>
<Text style={styles.pinText}>Create PIN</Text>
<Text style={styles.pinSubText}>Enter your secure six-digit code</Text>
<DialpadKeypad dialPadContent={dialPadContent} pinLength={pinLength} dialPadSize={dialPadSize} dialPadTextSize={dialPadTextSize} setCode={updateCode} code={code}/>
</View>
<View style={styles.btnContainer}>
<Button label="Cancel" disabled={false} btnColor="#4A646C" btnWidth="50%" onChangeFunc={onCancelFunc} btnJustifyContent='center'></Button>
<Button label="Next" disabled={false} btnColor="#4A646C" btnWidth="50%" onChangeFunc={onNextFunc} btnJustifyContent='center'></Button>
</View>
</SafeAreaView>
)};
const styles = StyleSheet.create({
container: {
backgroundColor: "#4A646C55",
height: '100%'
},
textContainer: {
justifyContent: "center",
alignItems: "center",
marginTop: 40,
position: "relative",
},
pinText: {
fontSize: 30,
fontWeight: "medium",
color: "white",
},
pinSubText: {
fontSize: 18,
fontWeight: "medium",
color: "white",
marginVertical: 30,
},
btnContainer: {
flexDirection: 'row',
width: '100%',
alignItems: 'center'
}
});
export default CustomDialpad;

View File

@ -0,0 +1,60 @@
import {FC } from "react";
import { StyleSheet, Text, View, FlatList, TouchableOpacity } from "react-native";
import Icon from 'react-native-vector-icons/Feather';
type DialpadKeypadProps = {
dialPadContent: any[];
pinLength: number;
dialPadSize: number;
dialPadTextSize: number;
code: number[];
setCode: (item: never) => void;
};
const DialpadKeypad: FC<DialpadKeypadProps> = props => {
const {dialPadContent, pinLength, dialPadSize, dialPadTextSize} = props;
return (
<FlatList data={dialPadContent} numColumns={3} keyExtractor={(_, index) => index.toString()} renderItem={({ item }) => {
return (
<TouchableOpacity disabled={item === ""}>
<View style={[
{
backgroundColor: item === "" ? "transparent" : "#fff",
width: dialPadSize,
height: dialPadSize,
},
styles.dialPadContainer,
]}
>
{item === "X" ? (
<Icon name="delete" size={24} color="#3F1D38" />
) : (
<Text
style={[{ fontSize: dialPadTextSize }, styles.dialPadText]}
>
{item}
</Text>
)}
</View>
</TouchableOpacity>
);
}}
/>
)};
const styles = StyleSheet.create({
dialPadContainer: {
justifyContent: "center",
alignItems: "center",
margin: 15,
borderRadius: 45,
padding: 0,
borderColor: "transparent",
},
dialPadText: {
color: "#3F1D38",
}
});
export default DialpadKeypad;

View File

View File

@ -1,17 +1,20 @@
import {FC } from "react";
import { StyleSheet, Text, View } from "react-native";
import Button from "../Button";
type AuthenticationScreenProps = {
onPressFunc: () => void;
onCancelFunc: () => void;
};
const AuthenticationScreen: FC<AuthenticationScreenProps> = props => {
const {onPressFunc} = props;
const {onPressFunc, onCancelFunc} = props;
return (
<View>
<View>
<Text style={styles.heading}> Success</Text>
<Button label="Cancel" disabled={false} btnColor="#4A646C" btnWidth="100%" onChangeFunc={onCancelFunc} btnJustifyContent='center'></Button>
</View>
</View>
)};

View File

@ -1,21 +1,24 @@
import {FC, useState } from "react";
import { StyleSheet, Text, TextInput, View } from "react-native";
import Button from "../Button";
import CustomDialpad from "../CustomDialpad";
enum PinSteps {
NumPad,
InsertPin,
RepeatPin
}
type InitializationScreenProps = {
onPressFunc: (pin: string) => void;
onCancelFunc: () => void;
};
const InitializationScreen: FC<InitializationScreenProps> = props => {
const {onPressFunc} = props;
const {onPressFunc, onCancelFunc} = props;
const [pin, onChangePin] = useState('');
const [btnDisabled, setBtnDisabled] = useState(true);
const [step, setStep] = useState(PinSteps.InsertPin);
const [step, setStep] = useState(PinSteps.NumPad);
const checkPin = (p: string) => {
pin === p ? setBtnDisabled(false) : setBtnDisabled(true);
@ -23,11 +26,13 @@ const InitializationScreen: FC<InitializationScreenProps> = props => {
return (
<View>
<CustomDialpad onCancelFunc={() => {}} onNextFunc={() => {}}></CustomDialpad>
{ step == PinSteps.InsertPin &&
<View>
<Text style={styles.heading}> Insert pin</Text>
<TextInput onChangeText={onChangePin} value={pin} keyboardType="number-pad" maxLength={6}/>
<Button label="Next" disabled={false} btnColor="#4A646C" btnWidth="100%" onChangeFunc={() => setStep(PinSteps.RepeatPin)} btnJustifyContent='center'></Button>
<Button label="Cancel" disabled={false} btnColor="#4A646C" btnWidth="100%" onChangeFunc={onCancelFunc} btnJustifyContent='center'></Button>
</View>
}
@ -36,6 +41,7 @@ const InitializationScreen: FC<InitializationScreenProps> = props => {
<Text style={styles.heading}> Repeat pin</Text>
<TextInput onChangeText={(val) => {checkPin(val)}} keyboardType="number-pad" maxLength={6}/>
<Button label="Next" disabled={btnDisabled} btnColor="#4A646C" btnWidth="100%" onChangeFunc={() => {onPressFunc(pin)}} btnJustifyContent='center'></Button>
<Button label="Back" disabled={false} btnColor="#4A646C" btnWidth="100%" onChangeFunc={() => setStep(PinSteps.InsertPin)} btnJustifyContent='center'></Button>
</View>
}
</View>

View File

@ -11,10 +11,11 @@ enum LoadMnemonicSteps {
type MnemonicScreenProps = {
pinRequired: boolean;
onPressFunc: (mn: string, pin?: string) => void;
onCancelFunc: () => void;
};
const MnemonicScreen: FC<MnemonicScreenProps> = props => {
const {pinRequired, onPressFunc} = props;
const {pinRequired, onPressFunc, onCancelFunc} = props;
const [mnemonic, setMnemonic] = useState('');
const [pin, setPin] = useState('');
const [errMessage, setErrMessage] = useState('');
@ -49,6 +50,7 @@ const MnemonicScreen: FC<MnemonicScreenProps> = props => {
<Text style={styles.heading}> Load mnemonic</Text>
<TextInput editable multiline numberOfLines={6} onChangeText={(val) => setMnemonic(val)} value={mnemonic} style={{backgroundColor: '#4A646C'}} />
<Button label="Next" disabled={false} btnColor="#4A646C" btnWidth="100%" onChangeFunc={() => updateMnemonic(mnemonic)} btnJustifyContent='center'></Button>
<Button label="Cancel" disabled={false} btnColor="#4A646C" btnWidth="100%" onChangeFunc={onCancelFunc} btnJustifyContent='center'></Button>
<Text>{errMessage}</Text>
</View>
}
@ -57,6 +59,7 @@ const MnemonicScreen: FC<MnemonicScreenProps> = props => {
<Text style={styles.heading}> Insert pin</Text>
<TextInput onChangeText={setPin} value={pin} keyboardType="number-pad" maxLength={6}/>
<Button label="Next" disabled={false} btnColor="#4A646C" btnWidth="100%" onChangeFunc={() => {onPressFunc(mnemonic, pin)}} btnJustifyContent='center'></Button>
<Button label="Back" disabled={false} btnColor="#4A646C" btnWidth="100%" onChangeFunc={() => setStep(LoadMnemonicSteps.InsertMnemonic)} btnJustifyContent='center'></Button>
</View>
}
</View>