Merge pull request #37 from esteemapp/pin-code-two

Pin code two
This commit is contained in:
Feruz M 2018-10-04 09:12:31 +03:00 committed by GitHub
commit 88891438b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 10409 additions and 2727 deletions

View File

@ -14,7 +14,7 @@ module.exports = {
},
plugins: ["react"],
rules: {
indent: ["error", "space"],
indent: ["error", 2],
"linebreak-style": ["error", "unix"],
quotes: ["error", "double"],
semi: ["error", "always"],

View File

@ -95,7 +95,7 @@ def enableProguardInReleaseBuilds = false
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
buildToolsVersion '28.0.2'
defaultConfig {
applicationId "com.esteem"

View File

@ -8,7 +8,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.android.tools.build:gradle:3.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

View File

@ -1,5 +1,6 @@
#Wed Sep 26 23:32:58 EET 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

4497
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,49 @@
import React, { Component } from "react";
import { connect } from "react-redux";
// Services and Actions
// Middleware
// Constants
// Utilities
// Component
import { ExampleView } from "../..";
/*
* Props Name Description Value
*@props --> props name here description here Value Type Here
*
*/
class ExampleContainer extends Component {
constructor(props) {
super(props);
this.state = {};
}
// Component Life Cycle Functions
// Component Functions
render() {
const {} = this.props;
return <ExampleView />;
}
}
const mapStateToProps = state => ({
user: state.user.user,
});
const mapDispatchToProps = (dispatch, ownProps) => ({
// onClick: () => dispatch(setVisibilityFilter(ownProps.filter))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(ExampleContainer);

View File

@ -1,3 +1,5 @@
import CircularButton from "./views/circularButtonView";
import IconButton from "./views/iconButtomView";
import TextButton from "./views/textButtonView";
export { TextButton };
export { CircularButton, IconButton, TextButton };

View File

@ -0,0 +1,18 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
button: {
width: 60,
height: 60,
borderRadius: 60 / 2,
borderColor: "#357ce6",
borderWidth: 1,
backgroundColor: "transparent",
alignItems: "center",
justifyContent: "center",
},
buttonText: {
color: "#357ce6",
fontSize: 16,
},
});

View File

@ -0,0 +1,22 @@
import React from "react";
import { TouchableOpacity, Text } from "react-native";
import styles from "./circularButtonStyles";
/* Props
*
* @prop { string } text - Text inside of button.
* @prop { func } onPress - When button clicked, this function will call.
* @prop { array } style - It is addionatly syle for button.
* @prop { any } value - When button clicked, this value will push with on press func.
*/
const CircularButtonView = ({ text, onPress, style, value }) => (
<TouchableOpacity
style={[styles.button, style]}
onPress={() => onPress && onPress(value)}
>
<Text style={styles.buttonText}>{text}</Text>
</TouchableOpacity>
);
export default CircularButtonView;

View File

@ -0,0 +1,83 @@
import React, { Component } from "react";
import { TouchableOpacity, Platform } from "react-native";
import Ionicons from "react-native-vector-icons/Ionicons";
// Styles
import styles from "./iconButtonStyles";
/*
* Props Name Description Value
*@props --> defaultToggled it can be start with disable icon bolean
*@props --> handleToggle description here function
*@props --> isToggle declaration toggle or normal icon button boolean
*@props --> name icon name string
*@props --> size icon size numeric
*@props --> toggledName disable toggled name string
*@props --> handleOnPress handle for press string
*@props --> isCircle button gona be circle bolean
*
*/
class IconButtonView extends Component {
constructor(props) {
super(props);
this.state = {};
}
// Component Functions
_handleOnPress = () => {
const { handleOnPress } = this.props;
if (handleOnPress) {
handleOnPress();
}
};
_getIconName = () => {
const { name, androidName } = this.props;
if (name) {
const isIos = Platform.OS === "ios";
let iconName;
if (isIos) {
iconName = `ios-${name}`;
} else {
iconName = androidName || `md-${name}`;
}
return iconName;
}
return null;
};
render() {
const {
buttonStyle,
size,
style,
isCircle,
color,
buttonColor,
} = this.props;
return (
<TouchableOpacity
style={[
buttonStyle,
isCircle && styles.circleButton,
buttonColor && { backgroundColor: buttonColor },
]}
onPress={() => this._handleOnPress()}
>
<Ionicons
style={[styles.icon, style]}
color={color}
name={this._getIconName()}
size={size}
/>
</TouchableOpacity>
);
}
}
export default IconButtonView;

View File

@ -0,0 +1,14 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
circleButton: {
alignItems: "center",
backgroundColor: "$white",
height: 60,
width: 60,
borderRadius: 60 / 2,
justifyContent: "center",
borderColor: "$primaryBlue",
borderWidth: 1,
},
});

View File

@ -4,5 +4,20 @@ import PostCard from "./postCard";
import Reply from "./reply/reply";
import Search from "./search/search";
import { FormInput } from "./formInput";
import { CircularButton, GreetingHeaderButton, IconButton } from "./buttons";
import { NumericKeyboard } from "./numericKeyboard";
import { PinAnimatedInput } from "./pinAnimatedInput";
export { Logo, Comment, PostCard, Reply, Search, FormInput };
export {
Logo,
Comment,
PostCard,
Reply,
Search,
FormInput,
CircularButton,
GreetingHeaderButton,
IconButton,
NumericKeyboard,
PinAnimatedInput,
};

View File

@ -8,13 +8,13 @@ import styles from "../../styles/logo.styles";
import globalStyles from "../../globalStyles";
const Logo = props => (
<View style={globalStyles.container}>
<Image
source={props.source ? props.source : LOGO}
style={[styles.logo, props.style]}
resizeMode="contain"
/>
</View>
<View style={globalStyles.container}>
<Image
source={props.source ? props.source : LOGO}
style={[styles.logo, props.style]}
resizeMode="contain"
/>
</View>
);
export default Logo;

View File

@ -0,0 +1,3 @@
import NumericKeyboard from "./views/numericKeyboardView";
export { NumericKeyboard };

View File

@ -0,0 +1,28 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
container: {
flex: 1,
flexDirection: "column",
alignItems: "center",
justifyContent: "space-between",
width: "$deviceWidth / 1.8",
},
buttonGroup: {
width: "100%",
flex: 1,
flexDirection: "row",
justifyContent: "space-between",
},
lastButtonGroup: {
width: "63%",
flex: 1,
flexDirection: "row",
justifyContent: "space-between",
alignSelf: "flex-end",
},
iconButton: {
fontSize: 20,
color: "$primaryBlue",
},
});

View File

@ -0,0 +1,112 @@
import React, { Fragment, Component } from "react";
import { View } from "react-native";
import { CircularButton, IconButton } from "../../";
import styles from "./numericKeyboardStyles";
class NumericKeyboard extends Component {
/* Props
*
* @prop { func } onPress - Function will trigger when any button clicked.
*
*/
constructor(props) {
super(props);
this.state = {};
}
// Component Life Cycles
// Component Functions
_handleOnPress = value => {
alert(value);
};
render() {
const { onPress } = this.props;
return (
<View style={styles.container}>
<View style={styles.buttonGroup}>
<CircularButton
style={styles.button}
text={1}
value={1}
onPress={value => onPress && onPress(value)}
/>
<CircularButton
style={styles.button}
text={2}
value={2}
onPress={value => onPress && onPress(value)}
/>
<CircularButton
style={styles.button}
text={3}
value={3}
onPress={value => onPress && onPress(value)}
/>
</View>
<View style={styles.buttonGroup}>
<CircularButton
style={styles.button}
text={4}
value={4}
onPress={value => onPress && onPress(value)}
/>
<CircularButton
style={styles.button}
text={5}
value={5}
onPress={value => onPress && onPress(value)}
/>
<CircularButton
style={styles.button}
text={6}
value={6}
onPress={value => onPress && onPress(value)}
/>
</View>
<View style={styles.buttonGroup}>
<CircularButton
style={styles.button}
text={7}
value={7}
onPress={value => onPress && onPress(value)}
/>
<CircularButton
style={styles.button}
text={8}
value={8}
onPress={value => onPress && onPress(value)}
/>
<CircularButton
style={styles.button}
text={9}
value={9}
onPress={value => onPress && onPress(value)}
/>
</View>
<View style={styles.lastButtonGroup}>
<CircularButton
style={styles.button}
text={0}
value={0}
onPress={value => onPress && onPress(value)}
/>
<IconButton
handleOnPress={() => onPress && onPress("clear")}
isCircle
style={styles.iconButton}
name="close"
/>
</View>
</View>
);
}
}
export default NumericKeyboard;

View File

@ -0,0 +1,3 @@
import PinAnimatedInput from "./views/pinAnimatedInputView";
export { PinAnimatedInput };

View File

@ -0,0 +1,22 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
container: {
flexDirection: "row",
alignSelf: "center",
},
activeInput: {
backgroundColor: "$primaryBlue",
},
input: {
alignItems: "center",
justifyContent: "center",
height: 20,
margin: 5,
width: 20,
borderRadius: 20 / 2,
borderWidth: 1,
borderColor: "$primaryBlue",
backgroundColor: "#fff",
},
});

View File

@ -0,0 +1,56 @@
import React, { Component } from "react";
import { Animated } from "react-native";
// Styles
import styles from "./pinAnimatedInputStyles";
class PinAnimatedInput extends Component {
/* Props
*
* @prop { string } pin - Description.
*
*/
constructor(props) {
super(props);
this.state = {};
}
render() {
const { pin } = this.props;
const test = new Animated.Value(0);
const tilt = test.interpolate({
inputRange: [0, 0.3, 0.6, 0.9],
outputRange: [0, -50, 50, 0],
});
return (
<Animated.View
style={[
{
transform: [{ translateX: tilt }],
},
styles.container,
]}
>
{[...Array(4)].map((val, index) => {
if (pin.length > index) {
return (
<Animated.View
key={"passwordItem-" + index}
style={[styles.input, styles.activeInput]}
/>
);
} else {
return (
<Animated.View
key={"passwordItem-" + index}
style={styles.input}
/>
);
}
})}
</Animated.View>
);
}
}
export default PinAnimatedInput;

View File

@ -1,47 +1,47 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
title: {},
text: {
fontFamily: "$primaryFont",
letterSpacing: "$primaryLatterSpacing",
},
subTitle: {
fontFamily: "$primaryFont",
letterSpacing: "$primaryLatterSpacing",
},
subText: {
fontFamily: "$primaryFont",
letterSpacing: "$primaryLatterSpacing",
},
shadow: {
shadowOpacity: 0.8,
shadowColor: "$shadowColor",
shadowOffset: {
width: 0,
height: 6,
},
},
errorText: {
fontFamily: "$primaryFont",
letterSpacing: "$primaryLatterSpacing",
width: "$deviceWidth / 1.4",
fontSize: 10,
padding: 5,
height: 50,
flex: 1,
color: "#ff1954",
paddingTop: 10,
textAlign: "center",
},
label: {
fontFamily: "$primaryFont",
letterSpacing: "$primaryLatterSpacing",
fontSize: 12,
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
title: {},
text: {
fontFamily: "$primaryFont",
letterSpacing: "$primaryLatterSpacing",
},
subTitle: {
fontFamily: "$primaryFont",
letterSpacing: "$primaryLatterSpacing",
},
subText: {
fontFamily: "$primaryFont",
letterSpacing: "$primaryLatterSpacing",
},
shadow: {
shadowOpacity: 0.8,
shadowColor: "$shadowColor",
shadowOffset: {
width: 0,
height: 6,
},
},
errorText: {
fontFamily: "$primaryFont",
letterSpacing: "$primaryLatterSpacing",
width: "$deviceWidth / 1.4",
fontSize: 10,
padding: 5,
height: 50,
flex: 1,
color: "#ff1954",
paddingTop: 10,
textAlign: "center",
},
label: {
fontFamily: "$primaryFont",
letterSpacing: "$primaryLatterSpacing",
fontSize: 12,
},
});

View File

@ -1,197 +1,182 @@
import * as dsteem from "dsteem";
import { getAccount } from "./dsteem";
import {
setUserData,
setAuthStatus,
getUserDataWithUsername,
updateUserData,
setUserData,
setAuthStatus,
getUserDataWithUsername,
updateUserData,
} from "../../realm/realm";
import { encryptKey, decryptKey } from "../../utils/crypto";
import steemConnect from "./steemConnectAPI";
export const Login = (username, password) => {
let publicKeys;
let privateKeys;
let resultKeys = { active: null, memo: null, owner: null, posting: null };
let loginFlag = false;
let publicKeys;
let privateKeys;
let resultKeys = { active: null, memo: null, owner: null, posting: null };
let loginFlag = false;
return new Promise((resolve, reject) => {
// Get user account data from STEEM Blockchain
getAccount(username)
.then(result => {
if (result.length < 1) {
reject(
new Error(
"Invalid credentails, please check and try again"
)
);
}
return new Promise((resolve, reject) => {
// Get user account data from STEEM Blockchain
getAccount(username)
.then(result => {
if (result.length < 1) {
reject(new Error("Invalid credentails, please check and try again"));
}
const account = result[0];
const account = result[0];
// Public keys of user
publicKeys = {
active: account["active"].key_auths.map(x => x[0]),
memo: account["memo_key"],
owner: account["owner"].key_auths.map(x => x[0]),
posting: account["posting"].key_auths.map(x => x[0]),
};
// Public keys of user
publicKeys = {
active: account["active"].key_auths.map(x => x[0]),
memo: account["memo_key"],
owner: account["owner"].key_auths.map(x => x[0]),
posting: account["posting"].key_auths.map(x => x[0]),
};
// Set private keys of user
privateKeys = getPrivateKeys(username, password);
// Set private keys of user
privateKeys = getPrivateKeys(username, password);
// Check all keys
Object.keys(publicKeys).map(pubKey => {
if (
publicKeys[pubKey] ===
privateKeys[pubKey].createPublic().toString()
) {
loginFlag = true;
resultKeys[pubKey] = publicKeys[pubKey];
}
});
// Check all keys
Object.keys(publicKeys).map(pubKey => {
if (
publicKeys[pubKey] === privateKeys[pubKey].createPublic().toString()
) {
loginFlag = true;
resultKeys[pubKey] = publicKeys[pubKey];
}
});
if (loginFlag) {
let userData = {
username: username,
authType: "masterKey",
masterKey: "",
postingKey: "",
activeKey: "",
memoKey: "",
accessToken: "",
};
if (loginFlag) {
let userData = {
username: username,
authType: "masterKey",
masterKey: "",
postingKey: "",
activeKey: "",
memoKey: "",
accessToken: "",
};
// Save user data to Realm DB
setUserData(userData)
.then(() => {
resolve({ ...account, password });
})
.catch(() => {
reject(
new Error(
"Invalid credentails, please check and try again"
)
);
});
} else {
reject(
new Error(
"Invalid credentails, please check and try again"
)
);
}
// Save user data to Realm DB
setUserData(userData)
.then(() => {
resolve({ ...account, password });
})
.catch(() => {
reject(
new Error("Invalid credentails, please check and try again")
);
reject(
new Error("Invalid credentails, please check and try again")
);
});
});
} else {
reject(new Error("Invalid credentails, please check and try again"));
}
})
.catch(() => {
reject(new Error("Invalid credentails, please check and try again"));
});
});
};
export const setUserDataWithPinCode = data =>
new Promise((resolve, reject) => {
const result = getUserDataWithUsername(data.username);
const userData = result[0];
new Promise((resolve, reject) => {
const result = getUserDataWithUsername(data.username);
const userData = result[0];
const privateKeys = getPrivateKeys(userData.username, data.password);
const privateKeys = getPrivateKeys(userData.username, data.password);
const updatedUserData = {
username: userData.username,
authType: "masterKey",
masterKey: encryptKey(data.password, data.pinCode),
postingKey: encryptKey(
privateKeys.posting.toString(),
data.pinCode
),
activeKey: encryptKey(privateKeys.active.toString(), data.pinCode),
memoKey: encryptKey(privateKeys.memo.toString(), data.pinCode),
};
updateUserData(updatedUserData)
.then(() => {
let authData = {
isLoggedIn: true,
};
setAuthStatus(authData)
.then(() => {
resolve();
})
.catch(error => {
reject(error);
});
})
.catch(err => {
reject(err);
});
resolve();
});
export const verifyPinCode = data =>
new Promise((resolve, reject) => {
const result = getUserDataWithUsername(data.username);
const userData = result[0];
const masterKey = decryptKey(userData.masterKey, data.pinCode);
if (masterKey === data.password) {
let authData = {
isLoggedIn: true,
};
setAuthStatus(authData)
.then(() => {
resolve();
})
.catch(error => {
reject(error);
});
} else {
reject();
}
});
const getPrivateKeys = (username, password) => {
return {
active: dsteem.PrivateKey.fromLogin(username, password, "active"),
memo: dsteem.PrivateKey.fromLogin(username, password, "memo"),
owner: dsteem.PrivateKey.fromLogin(username, password, "owner"),
posting: dsteem.PrivateKey.fromLogin(username, password, "posting"),
const updatedUserData = {
username: userData.username,
authType: "masterKey",
masterKey: encryptKey(data.password, data.pinCode),
postingKey: encryptKey(privateKeys.posting.toString(), data.pinCode),
activeKey: encryptKey(privateKeys.active.toString(), data.pinCode),
memoKey: encryptKey(privateKeys.memo.toString(), data.pinCode),
};
};
export const loginWithSC2 = async (access_token, pinCode) => {
let account;
await steemConnect.setAccessToken(access_token);
account = await steemConnect.me();
return new Promise((resolve, reject) => {
let userData = {
username: account.name,
authType: "steemConnect",
accessToken: encryptKey(access_token, pinCode),
postingKey: "",
masterKey: "",
activeKey: "",
memoKey: "",
};
updateUserData(updatedUserData)
.then(() => {
let authData = {
isLoggedIn: true,
isLoggedIn: true,
};
setAuthStatus(authData)
.then(() => {
setUserData(userData)
.then(() => {
resolve(true);
})
.catch(error => {
reject(error);
});
})
.catch(error => {
reject(error);
});
});
.then(() => {
resolve();
})
.catch(error => {
reject(error);
});
})
.catch(err => {
reject(err);
});
resolve();
});
export const verifyPinCode = data =>
new Promise((resolve, reject) => {
const result = getUserDataWithUsername(data.username);
const userData = result[0];
const masterKey = decryptKey(userData.masterKey, data.pinCode);
if (masterKey === data.password) {
let authData = {
isLoggedIn: true,
};
setAuthStatus(authData)
.then(() => {
resolve();
})
.catch(error => {
reject(new Error("Invalid pin code, please check and try again"));
});
} else {
reject(new Error("Invalid pin code, please check and try again"));
reject();
}
});
const getPrivateKeys = (username, password) => {
return {
active: dsteem.PrivateKey.fromLogin(username, password, "active"),
memo: dsteem.PrivateKey.fromLogin(username, password, "memo"),
owner: dsteem.PrivateKey.fromLogin(username, password, "owner"),
posting: dsteem.PrivateKey.fromLogin(username, password, "posting"),
};
};
export const loginWithSC2 = async (access_token, pinCode) => {
let account;
await steemConnect.setAccessToken(access_token);
account = await steemConnect.me();
return new Promise((resolve, reject) => {
let userData = {
username: account.name,
authType: "steemConnect",
accessToken: encryptKey(access_token, pinCode),
postingKey: "",
masterKey: "",
activeKey: "",
memoKey: "",
};
let authData = {
isLoggedIn: true,
};
setAuthStatus(authData)
.then(() => {
setUserData(userData)
.then(() => {
resolve(true);
})
.catch(error => {
reject(error);
});
})
.catch(error => {
reject(error);
});
});
};

View File

@ -1,5 +1,5 @@
import React from "react";
import { FlatList, View, ActivityIndicator } from "react-native";
import { FlatList, View, ActivityIndicator, AppState } from "react-native";
import {
Container,
Header,
@ -39,9 +39,28 @@ class FeedPage extends React.Component {
start_permlink: "",
refreshing: false,
loading: false,
appState: AppState.currentState,
};
}
componentDidMount() {
AppState.addEventListener("change", this._handleAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener("change", this._handleAppStateChange);
}
_handleAppStateChange = nextAppState => {
if (
this.state.appState.match(/inactive|background/) &&
nextAppState === "active"
) {
alert("App has come to the foreground!");
}
this.setState({ appState: nextAppState });
};
componentWillMount() {
this.getFeed();
}

View File

@ -0,0 +1,145 @@
import React from "react";
import { AsyncStorage } from "react-native";
import { connect } from "react-redux";
import { Navigation } from "react-native-navigation";
import {
setUserDataWithPinCode,
verifyPinCode,
} from "../../../providers/steem/auth";
import { default as INITIAL } from "../../../constants/initial";
import { PinCodeScreen } from "../";
class PinCodeContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
isExistUser: null,
informationText: "",
pinCode: null,
};
}
// TODO: if check for decide to set to pin or verify to pin page
componentDidMount() {
this._getDataFromStorage().then(() => {
const { isExistUser } = this.state;
if (isExistUser) {
this.setState({
informationText: "Enter pin to unlock",
});
} else {
this.setState({
informationText: "Set new pin",
});
}
});
}
_getDataFromStorage = () =>
new Promise(resolve => {
AsyncStorage.getItem(INITIAL.IS_EXIST_USER, (err, result) => {
this.setState(
{
isExistUser: JSON.parse(result),
},
resolve
);
});
});
_setPinCode = pin =>
new Promise((resolve, reject) => {
const {
currentAccount: { password, name },
componentId,
} = this.props;
const { isExistUser, pinCode } = this.state;
if (isExistUser) {
// If the user is exist, we are just checking to pin and navigating to home screen
const pinData = {
pinCode: pin,
password,
username: name,
};
verifyPinCode(pinData)
.then(() => {
Navigation.setStackRoot(componentId, {
component: {
name: "navigation.eSteem.Home",
},
});
resolve();
})
.catch(err => {
alert(err);
reject(err);
});
} else {
// If the user is logging in for the first time, the user should set to pin
if (!pinCode) {
this.setState({
informationText: "Write again",
pinCode: pin,
});
resolve();
} else {
if (pinCode === pin) {
const pinData = {
pinCode: pin,
password,
username: name,
};
setUserDataWithPinCode(pinData).then(() => {
AsyncStorage.setItem(
INITIAL.IS_EXIST_USER,
JSON.stringify(true),
() => {
Navigation.setStackRoot(componentId, {
component: {
name: "navigation.eSteem.Home",
},
});
resolve();
}
);
});
} else {
this.setState({
informationText: "wrongggg!!!",
});
setTimeout(() => {
this.setState({
informationText: "setup screen",
pinCode: null,
});
resolve();
}, 1000);
}
}
}
});
render() {
const { currentAccount } = this.props;
const { informationText, isExistUser } = this.state;
return (
<PinCodeScreen
informationText={informationText}
setPinCode={this._setPinCode}
showForgotButton={isExistUser}
username={currentAccount ? currentAccount.name : "unknow"}
/>
);
}
}
const mapStateToProps = state => ({
currentAccount: state.account.data.accounts.find(
item => item.id === state.account.data.currentAccountId
),
});
export default connect(mapStateToProps)(PinCodeContainer);

View File

@ -0,0 +1,5 @@
import PinCodeScreen from "./screen/pinCodeScreen";
import PinCode from "./container/pinCodeContainer";
export { PinCodeScreen, PinCode };
export default PinCode;

View File

@ -1,137 +0,0 @@
import React from "react";
import { AsyncStorage } from "react-native";
import { connect } from "react-redux";
import { Navigation } from "react-native-navigation";
import {
setUserDataWithPinCode,
verifyPinCode,
} from "../../providers/steem/auth";
import { default as INITIAL } from "../../constants/initial";
import PinCodeScreen from "./pinCodeScreen";
class PinCodeContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
isExistUser: null,
informationText: "",
pinCode: null,
};
}
// TODO: if check for decide to set to pin or verify to pin page
componentDidMount() {
this._getDataFromStorage().then(() => {
const { isExistUser } = this.state;
if (isExistUser) {
this.setState({
informationText: "verify screen",
});
} else {
this.setState({
informationText: "setup screen",
});
}
});
}
_getDataFromStorage = () =>
new Promise(resolve => {
AsyncStorage.getItem(INITIAL.IS_EXIST_USER, (err, result) => {
this.setState(
{
isExistUser: JSON.parse(result),
},
resolve
);
});
});
_setPinCode = pin => {
const {
currentAccount: { password, name },
componentId,
} = this.props;
const { isExistUser, pinCode } = this.state;
console.log(password, name);
if (isExistUser) {
// If the user is exist, we are just checking to pin and navigating to home screen
const pinData = {
pinCode: pin,
password,
username: name,
};
verifyPinCode(pinData)
.then(() => {
Navigation.setStackRoot(componentId, {
component: {
name: "navigation.eSteem.Home",
},
});
})
.catch(err => {
alert(err);
});
} else {
// If the user is logging in for the first time, the user should set to pin
if (!pinCode) {
this.setState({
informationText: "write again",
pinCode: pin,
});
} else {
if (pinCode === pin) {
const pinData = {
pinCode: pin,
password,
username: name,
};
setUserDataWithPinCode(pinData).then(() => {
AsyncStorage.setItem(
INITIAL.IS_EXIST_USER,
JSON.stringify(true),
() => {
Navigation.setStackRoot(componentId, {
component: {
name: "navigation.eSteem.Home",
},
});
}
);
});
} else {
this.setState({
informationText: "wrongggg!!!",
});
setTimeout(() => {
this.setState({
informationText: "setup screen",
pinCode: null,
});
}, 1000);
}
}
}
};
render() {
const { informationText } = this.state;
return (
<PinCodeScreen
informationText={informationText}
setPinCode={this._setPinCode}
/>
);
}
}
const mapStateToProps = state => ({
currentAccount: state.account.data.accounts.find(
item => item.id === state.account.data.currentAccountId
),
});
export default connect(mapStateToProps)(PinCodeContainer);

View File

@ -1,74 +0,0 @@
import React from "react";
import { Text, TouchableOpacity } from "react-native";
import { Container, Content, Icon, Item, Input } from "native-base";
import { Logo, FormInput } from "../../components";
import styles from "../../styles/pinCode.styles";
import globalStyles from "../../globalStyles";
class PinCodeScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
showPassword: false,
pin: "",
};
}
_handleOnChangeInput = text => {
const { setPinCode } = this.props;
if (text.length === 4) {
setPinCode(text);
this.setState({ pin: "" });
} else {
this.setState({ pin: text });
}
};
render() {
return (
<Container style={globalStyles.container}>
<Content>
<Logo style={styles.logo} />
<Text style={styles.title}>Enter Pin Code</Text>
<Item style={styles.input}>
<Input
secureTextEntry={!this.state.showPassword}
keyboardType="numeric"
maxLength={4}
onChangeText={e => this._handleOnChangeInput(e)}
value={this.state.pin}
/>
<TouchableOpacity
onPress={() =>
this.setState({
showPassword: !this.state.showPassword,
})
}
>
<Icon
style={styles.icon}
active
name="lock"
type="EvilIcons"
backgroundColor={"#fff"}
/>
</TouchableOpacity>
</Item>
<TouchableOpacity>
<Text style={styles.forgotButtonText}>
Oh, I forgot it
</Text>
</TouchableOpacity>
<Text style={styles.forgotButtonText}>
{this.props.informationText}
</Text>
</Content>
</Container>
);
}
}
export default PinCodeScreen;

View File

@ -0,0 +1,81 @@
import React from "react";
import { Text, TouchableOpacity, Animated, View } from "react-native";
import { Container } from "native-base";
import { Logo, NumericKeyboard, PinAnimatedInput } from "../../../components";
import styles from "./pinCodeStyles";
class PinCodeScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
showPassword: false,
pin: "",
};
}
// Component Life Cycles
// Component Functions
_handleKeyboardOnPress = value => {
const { setPinCode } = this.props;
const { pin } = this.state;
if (value === "clear") {
this.setState({ pin: "" });
return;
}
const newPin = `${pin}${value}`;
if (pin.length < 3) {
this.setState({ pin: newPin });
} else if (pin.length === 3) {
this.setState({ pin: newPin });
setPinCode(`${pin}${value}`)
.then(() => {
this.setState({ pin: "" });
})
.catch(() => {
this.setState({ pin: "" });
});
} else if (pin.length > 3) {
this.setState({ pin: `${value}` });
}
};
render() {
const { informationText, showForgotButton, username } = this.props;
const { pin } = this.state;
return (
<Container style={styles.container}>
<View style={styles.logoView}>
<Logo />
</View>
<View style={styles.titleView}>
<Text style={styles.title}>{`@${username}`}</Text>
</View>
<View style={styles.informationView}>
<Text>{informationText}</Text>
</View>
<View style={styles.animatedView}>
<PinAnimatedInput pin={pin} />
</View>
<View style={styles.numericKeyboardView}>
<NumericKeyboard onPress={this._handleKeyboardOnPress} />
</View>
{showForgotButton ? (
<TouchableOpacity style={styles.forgotButtonView}>
<Text style={styles.forgotButtonText}>Oh, I forgot it</Text>
</TouchableOpacity>
) : (
<View style={styles.forgotButtonView} />
)}
</Container>
);
}
}
export default PinCodeScreen;

View File

@ -0,0 +1,47 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
container: {
flex: 1,
paddingTop: "$deviceHeight / 15",
},
logoView: {
flex: 2,
},
titleView: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
title: {
color: "#357ce6",
fontSize: 20,
fontWeight: "bold",
},
informationView: {
flex: 1,
alignItems: "center",
},
animatedView: {
flex: 1,
alignItems: "center",
},
numericKeyboardView: {
flex: 6,
justifyContent: "center",
alignItems: "center",
alignSelf: "center",
},
forgotButtonView: {
flex: 2,
justifyContent: "center",
alignItems: "center",
},
forgotButtonText: {
color: "#788187",
fontSize: 14,
marginTop: 25,
alignSelf: "center",
marginBottom: 25,
},
});

View File

@ -18,7 +18,7 @@ import Editor from "./editor/editor";
import Discover from "./discover/discover";
import Settings from "./settings/settings";
import { Notification } from "./notification";
import PinCode from "./pinCode/pinCodeContainer";
import PinCode from "./pinCode";
// COMPONENTS
import SteemConnect from "./steem-connect/steemConnect";

View File

@ -20,8 +20,7 @@ class SplashContainer extends React.Component {
goToNoAuthScreens();
}
})
.catch(error => {
console.log(error);
.catch(() => {
goToAuthScreens();
});
}

View File

@ -1,14 +1,14 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
logo: {
width: "$deviceWidth / 3",
height: "$deviceHeight / 6",
backgroundColor: "transparent",
},
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
logo: {
width: "100%",
height: "100%",
backgroundColor: "transparent",
},
});

View File

@ -1,32 +0,0 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
title: {
color: "$primaryBlue",
fontSize: 20,
fontWeight: "bold",
marginTop: 25,
alignSelf: "center",
marginBottom: 25,
},
logo: {
marginTop: "$deviceHeight / 8",
},
forgotButtonText: {
color: "$primaryGray",
fontSize: 14,
marginTop: 25,
alignSelf: "center",
marginBottom: 25,
},
input: {
backgroundColor: "#f5f5f5",
borderColor: "#fff",
borderRadius: 5,
paddingLeft: 15,
minWidth: "$deviceWidth / 2",
},
icon: {
color: "$primaryBlue",
},
});

7215
yarn.lock Normal file

File diff suppressed because it is too large Load Diff