Merge pull request #29 from esteemapp/redesign/login

Redesign/login
This commit is contained in:
Feruz M 2018-09-28 16:38:58 +03:00 committed by GitHub
commit 3641726fa0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 394 additions and 360 deletions

25
package-lock.json generated
View File

@ -7710,6 +7710,15 @@
"graceful-fs": "^4.1.2", "graceful-fs": "^4.1.2",
"jsonfile": "^2.1.0" "jsonfile": "^2.1.0"
} }
},
"react-native-keyboard-aware-scroll-view": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/react-native-keyboard-aware-scroll-view/-/react-native-keyboard-aware-scroll-view-0.5.0.tgz",
"integrity": "sha512-nGXsACZBCiWuwRrZy+UjiSJqb4tZ/6ePHUSY8M+09g4VfNm/ogvvWpwBa6B999NZ6DwhZTKBjVWeZxX9XG8bbQ==",
"requires": {
"prop-types": "^15.6.0",
"react-native-iphone-x-helper": "^1.0.1"
}
} }
} }
}, },
@ -8867,17 +8876,17 @@
} }
}, },
"react-native-iphone-x-helper": { "react-native-iphone-x-helper": {
"version": "1.0.3", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.0.3.tgz", "resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.0.tgz",
"integrity": "sha512-QHzpx4fv9u30VVU1DMgotiZsUB+m4BRjypca2rOczyj3cZBny5I+QDplrpFIBhzsa1iADNkziWa7kInzmKs00Q==" "integrity": "sha512-xIeTo4s77wwKgBZLVRIZC9tM9/PkXS46Ul76NXmvmixEb3ZwqGdQesR3zRiLMOoIdfOURB6N9bba9po7+x9Bag=="
}, },
"react-native-keyboard-aware-scroll-view": { "react-native-keyboard-aware-scroll-view": {
"version": "0.5.0", "version": "0.7.2",
"resolved": "https://registry.npmjs.org/react-native-keyboard-aware-scroll-view/-/react-native-keyboard-aware-scroll-view-0.5.0.tgz", "resolved": "https://registry.npmjs.org/react-native-keyboard-aware-scroll-view/-/react-native-keyboard-aware-scroll-view-0.7.2.tgz",
"integrity": "sha512-nGXsACZBCiWuwRrZy+UjiSJqb4tZ/6ePHUSY8M+09g4VfNm/ogvvWpwBa6B999NZ6DwhZTKBjVWeZxX9XG8bbQ==", "integrity": "sha512-FCVKAmM5jHwbWZFW/zUOhid18OoSGcbyx2jGk+q6eVjjtj+RPomeqX0aAHf2ALXYJ1BuC5+OtXhFA/hp8ombcQ==",
"requires": { "requires": {
"prop-types": "^15.6.0", "prop-types": "^15.6.2",
"react-native-iphone-x-helper": "^1.0.1" "react-native-iphone-x-helper": "^1.0.3"
} }
}, },
"react-native-lightbox": { "react-native-lightbox": {

View File

@ -25,6 +25,7 @@
"react-native-extended-stylesheet": "^0.10.0", "react-native-extended-stylesheet": "^0.10.0",
"react-native-fast-image": "^4.0.14", "react-native-fast-image": "^4.0.14",
"react-native-html-renderer": "^1.0.0", "react-native-html-renderer": "^1.0.0",
"react-native-keyboard-aware-scroll-view": "^0.7.2",
"react-native-markdown-editor": "^1.0.1", "react-native-markdown-editor": "^1.0.1",
"react-native-modal": "^6.5.0", "react-native-modal": "^6.5.0",
"react-native-modal-popover": "0.0.10", "react-native-modal-popover": "0.0.10",

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,5 +1,5 @@
import React, { Fragment } from "react"; import React, { Fragment } from "react";
import { TouchableWithoutFeedback, Text } from "react-native"; import { TouchableWithoutFeedback, Text, View } from "react-native";
import styles from "./greetingHeaderButtonStyles"; import styles from "./greetingHeaderButtonStyles";
@ -9,7 +9,9 @@ const GreetingHeaderButtonView = ({ text, onPress, style }) => (
style={[styles.button, style]} style={[styles.button, style]}
onPress={() => onPress && onPress()} onPress={() => onPress && onPress()}
> >
<View>
<Text style={styles.buttonText}>{text}</Text> <Text style={styles.buttonText}>{text}</Text>
</View>
</TouchableWithoutFeedback> </TouchableWithoutFeedback>
</Fragment> </Fragment>
); );

View File

@ -5,7 +5,7 @@ export default EStyleSheet.create({
borderTopLeftRadius: 8, borderTopLeftRadius: 8,
borderTopRightRadius: 8, borderTopRightRadius: 8,
marginHorizontal: 30, marginHorizontal: 30,
marginVertical: 20, marginVertical: 10,
flexDirection: "row", flexDirection: "row",
backgroundColor: "#f5f5f5", backgroundColor: "#f5f5f5",
height: 60, height: 60,

View File

@ -5,7 +5,7 @@ export default EStyleSheet.create({
flexDirection: "row", flexDirection: "row",
paddingLeft: 50, paddingLeft: 50,
paddingRight: 32, paddingRight: 32,
marginTop: 10, marginTop: 20,
}, },
infoIcon: { infoIcon: {
flex: 0.125, flex: 0.125,

View File

@ -26,7 +26,7 @@ class LoginHeaderView extends Component {
// Component Functions // Component Functions
render() { render() {
const { description, title } = this.props; const { description, title, onPress, isKeyboardOpen } = this.props;
return ( return (
<View styles={styles.container}> <View styles={styles.container}>
@ -36,9 +36,10 @@ class LoginHeaderView extends Component {
source={require("../../../assets/esteem.png")} source={require("../../../assets/esteem.png")}
/> />
<View style={styles.headerButton}> <View style={styles.headerButton}>
<GreetingHeaderButton text="Sign up" /> <GreetingHeaderButton onPress={onPress} text="Sign up" />
</View> </View>
</View> </View>
{!isKeyboardOpen && (
<View style={styles.body}> <View style={styles.body}>
<View style={styles.titleText}> <View style={styles.titleText}>
<Text style={styles.title}>{title}</Text> <Text style={styles.title}>{title}</Text>
@ -51,6 +52,7 @@ class LoginHeaderView extends Component {
/> />
</View> </View>
</View> </View>
)}
<LineBreak /> <LineBreak />
</View> </View>
); );

View File

@ -0,0 +1,3 @@
import MainButton from "./view/mainButtonView";
export { MainButton };

View File

@ -0,0 +1,48 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
wrapper: {},
touchable: {
maxWidth: 200,
minWidth: 56,
height: 56,
borderRadius: 30,
backgroundColor: "#357ce6",
flexDirection: "row",
margin: 5,
shadowOffset: {
height: 5,
},
shadowColor: "#5f5f5fbf",
shadowOpacity: 0.3,
},
icon: {
alignSelf: "center",
fontSize: 25,
marginLeft: 20,
},
text: {
color: "white",
fontWeight: "400",
alignSelf: "center",
fontSize: 14,
paddingLeft: 10,
paddingRight: 20,
},
secondText: {
fontWeight: "bold",
},
activityIndicator: {
minWidth: 56,
height: 56,
},
body: {
flexDirection: "row",
},
image: {
marginLeft: 20,
alignSelf: "center",
width: 20,
height: 20,
},
});

View File

@ -0,0 +1,93 @@
import React, { Component, Fragment } from "react";
import {
ActivityIndicator,
Image,
Text,
TouchableOpacity,
View,
} from "react-native";
import Ionicons from "react-native-vector-icons/Ionicons";
// Constants
// Components
// Styles
import styles from "./mainButtonStyles";
class MainButton extends Component {
/* Props
* ------------------------------------------------
* @prop { string } isLoading - TODO:
* @prop { string } text - TODO:
* @prop { boolean } secondText - TODO:
* @prop { boolean } iconColor - TODO:
* @prop { boolean } iconName - TODO:
* @prop { boolean } isDisable - TODO:
*
*
*/
constructor(props) {
super(props);
this.state = {};
}
// Component Life Cycles
// Component Functions
_handleOnPress = () => {
const { onPress, isDisable, source } = this.props;
onPress && !isDisable && onPress();
};
_getBody = () => {
const {
isLoading,
text,
secondText,
iconColor,
iconName,
source,
} = this.props;
if (isLoading) {
return (
<ActivityIndicator color="white" style={styles.activityIndicator} />
);
} else if (text) {
return (
<Fragment>
{source ? (
<Image source={source} style={styles.image} resizeMode="contain" />
) : (
<Ionicons color={iconColor} name={iconName} style={styles.icon} />
)}
<Text style={styles.text}>
{text}
{secondText && <Text style={styles.secondText}>{secondText}</Text>}
</Text>
</Fragment>
);
}
return <Ionicons color={iconColor} name={iconName} style={styles.icon} />;
};
render() {
const { wrapperStyle, isDisable } = this.props;
return (
<View style={wrapperStyle}>
<TouchableOpacity
onPress={() => this._handleOnPress()}
style={styles.touchable}
>
<View style={styles.body}>{this._getBody()}</View>
</TouchableOpacity>
</View>
);
}
}
export default MainButton;

View File

@ -43,9 +43,7 @@ export default class TabBar extends Component {
onPress={() => onPressHandler(page)} onPress={() => onPressHandler(page)}
> >
<View style={styles.tab}> <View style={styles.tab}>
<Text style={[{ color: textColor, fontWeight }]}> <Text style={[{ color: textColor, fontWeight }]}>{name}</Text>
{name}
</Text>
</View> </View>
</Button> </Button>
); );
@ -119,13 +117,7 @@ export default class TabBar extends Component {
const { activeTab, backgroundColor, goToPage, style } = this.props; const { activeTab, backgroundColor, goToPage, style } = this.props;
return ( return (
<View <View style={[styles.tabs, { backgroundColor: backgroundColor }, style]}>
style={[
styles.tabs,
{ backgroundColor: backgroundColor },
style,
]}
>
{this.props.tabs.map((name, page) => { {this.props.tabs.map((name, page) => {
const isTabActive = activeTab === page; const isTabActive = activeTab === page;
return this._renderTab(name, page, isTabActive, goToPage); return this._renderTab(name, page, isTabActive, goToPage);

View File

@ -1,68 +1,26 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { import { View, BackHandler, Linking, StatusBar } from "react-native";
View, import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
ActivityIndicator,
Text,
Image,
TouchableOpacity,
TextInput,
BackHandler,
Linking,
StatusBar,
} from "react-native";
import { Navigation } from "react-native-navigation";
import Ionicons from "react-native-vector-icons/Ionicons";
import FastImage from "react-native-fast-image";
import { TabBar } from "../../../components/tabBar";
import { LoginHeader } from "../../../components/loginHeader";
import { FormInput } from "../../../components/formInput";
import { InformationArea } from "../../../components/informationArea";
import ScrollableTabView from "@esteemapp/react-native-scrollable-tab-view"; import ScrollableTabView from "@esteemapp/react-native-scrollable-tab-view";
// Internal Components
import { FormInput } from "../../../components/formInput";
import { GreetingHeaderButton } from "../../../components/buttons";
import { InformationArea } from "../../../components/informationArea";
import { Login } from "../../../providers/steem/auth"; import { Login } from "../../../providers/steem/auth";
import { LoginHeader } from "../../../components/loginHeader";
import { MainButton } from "../../../components/mainButton";
import { Navigation } from "react-native-navigation";
import { TabBar } from "../../../components/tabBar";
import { addNewAccount } from "../../../redux/actions/accountAction"; import { addNewAccount } from "../../../redux/actions/accountAction";
import { lookupAccounts } from "../../../providers/steem/dsteem";
import { goToAuthScreens } from "../../../navigation"; import { goToAuthScreens } from "../../../navigation";
import { lookupAccounts } from "../../../providers/steem/dsteem";
import STEEM_CONNECT_LOGO from "../../../assets/steem_connect.png";
// Styles // Styles
import styles from "./loginStyles"; import styles from "./loginStyles";
class LoginScreen extends Component { class LoginScreen extends Component {
static get options() {
return {
_statusBar: {
visible: true,
drawBehind: false,
},
topBar: {
animate: true,
hideOnScroll: false,
drawBehind: false,
noBorder: true,
visible: true,
elevation: 0,
leftButtons: {},
rightButtons: [
{
id: "signup",
text: "Sign Up",
color: "#a7adaf",
marginRight: 50,
},
],
},
layout: {
backgroundColor: "#f5fcff",
},
bottomTabs: {
visible: false,
drawBehind: true,
},
};
}
constructor(props) { constructor(props) {
super(props); super(props);
Navigation.events().bindComponent(this); Navigation.events().bindComponent(this);
@ -72,6 +30,7 @@ class LoginScreen extends Component {
password: "", password: "",
isLoading: false, isLoading: false,
isUsernameValid: true, isUsernameValid: true,
keyboardIsOpen: false,
}; };
} }
@ -127,15 +86,13 @@ class LoginScreen extends Component {
this.setState({ password: value }); this.setState({ password: value });
}; };
navigationButtonPressed({ buttonId }) { _handleSignUp = () => {
if (buttonId === "signup") {
Linking.openURL("https://signup.steemit.com/?ref=esteem").catch(err => Linking.openURL("https://signup.steemit.com/?ref=esteem").catch(err =>
console.error("An error occurred", err) console.error("An error occurred", err)
); );
} };
}
loginwithSc2 = () => { _loginwithSc2 = () => {
Navigation.push(this.props.componentId, { Navigation.push(this.props.componentId, {
component: { component: {
name: "navigation.eSteem.SteemConnect", name: "navigation.eSteem.SteemConnect",
@ -152,14 +109,22 @@ class LoginScreen extends Component {
}; };
render() { render() {
const { isLoading, username, isUsernameValid, keyboardIsOpen } = this.state;
return ( return (
<View style={{ flex: 1 }}> <View style={{ flex: 1 }}>
<StatusBar hidden translucent /> <StatusBar hidden translucent />
<LoginHeader <LoginHeader
isKeyboardOpen={keyboardIsOpen}
title="Sign in" title="Sign in"
description="To get all the benefits using eSteem" description="To get all the benefits using eSteem"
onPress={() => this._handleSignUp()}
/> />
<KeyboardAwareScrollView
onKeyboardWillShow={() => this.setState({ keyboardIsOpen: true })}
onKeyboardWillHide={() => this.setState({ keyboardIsOpen: false })}
>
<ScrollableTabView <ScrollableTabView
locked={isLoading}
style={styles.tabView} style={styles.tabView}
renderTabBar={() => ( renderTabBar={() => (
<TabBar <TabBar
@ -175,147 +140,57 @@ class LoginScreen extends Component {
<FormInput <FormInput
rightIconName="md-at" rightIconName="md-at"
leftIconName="md-close-circle" leftIconName="md-close-circle"
isValid={this.state.isUsernameValid} isValid={isUsernameValid}
onChange={value => this.handleUsername(value)} onChange={value => this.handleUsername(value)}
placeholder="Username" placeholder="Username"
isEditable isEditable
type="username" type="username"
isFirstImage isFirstImage
value={this.state.username} value={username}
/> />
<FormInput <FormInput
rightIconName="md-lock" rightIconName="md-lock"
leftIconName="md-close-circle" leftIconName="md-close-circle"
isValid={this.state.isUsernameValid} isValid={isUsernameValid}
onChange={value => this._handleOnPasswordChange(value)} onChange={value => this._handleOnPasswordChange(value)}
placeholder="Password or WIF" placeholder="Password or WIF"
isEditable isEditable
secureTextEntry secureTextEntry
type="password" type="password"
/> />
<InformationArea <InformationArea
description="User credentials are kept locally on the device. Credentials are description="User credentials are kept locally on the device. Credentials are
removed upon logout!" removed upon logout!"
iconName="ios-information-circle-outline" iconName="ios-information-circle-outline"
/> />
<View style={{ flexDirection: "row", margin: 30 }}> {/* It will remove */}
<View style={{ flex: 0.6 }}> <GreetingHeaderButton onPress={goToAuthScreens} text="cancel" />
<TouchableOpacity <MainButton
onPress={goToAuthScreens} wrapperStyle={styles.mainButtonWrapper}
style={{
alignContent: "center",
padding: "9%",
}}
>
<Text
style={{
color: "#788187",
alignSelf: "center",
fontWeight: "bold",
}}
>
Cancel
</Text>
</TouchableOpacity>
</View>
<TouchableOpacity
onPress={this._handleOnPressLogin} onPress={this._handleOnPressLogin}
style={{ iconName="md-person"
flex: 0.4, iconColor="white"
width: 100, text="LOGIN"
height: 50, isLoading={isLoading}
borderRadius: 30,
backgroundColor: "#357ce6",
flexDirection: "row",
}}
>
{!this.state.isLoading ? (
<View
style={{
flex: 1,
flexDirection: "row",
}}
>
<Ionicons
color="white"
name="md-person"
style={{
alignSelf: "center",
fontSize: 25,
flex: 0.4,
left: 15,
}}
/> />
<Text
style={{
color: "white",
fontWeight: "600",
alignSelf: "center",
fontSize: 16,
flex: 0.6,
}}
>
LOGIN
</Text>
</View>
) : (
<ActivityIndicator
color="white"
style={{ alignSelf: "center", flex: 1 }}
/>
)}
</TouchableOpacity>
</View>
</View> </View>
<View tabLabel="SteemConnect" style={styles.steemConnectTab}> <View tabLabel="SteemConnect" style={styles.steemConnectTab}>
<InformationArea <InformationArea
description="If you don't want to keep your password encrypted and saved on your device, you can use Steemconnect." description="If you don't want to keep your password encrypted and saved on your device, you can use Steemconnect."
iconName="ios-information-circle-outline" iconName="ios-information-circle-outline"
/> />
<View
style={{ <MainButton
alignItems: "flex-end", wrapperStyle={styles.mainButtonWrapper}
backgroundColor: "#ffffff", onPress={this._loginwithSc2}
}} iconName="md-person"
> source={STEEM_CONNECT_LOGO}
<TouchableOpacity text="steem"
onPress={this.loginwithSc2} secondText="connect"
style={{
width: 200,
height: 50,
borderRadius: 30,
backgroundColor: "#357ce6",
flexDirection: "row",
margin: 20,
}}
>
<View style={{ flex: 1, flexDirection: "row" }}>
<Ionicons
color="white"
name="md-person"
style={{
alignSelf: "center",
fontSize: 25,
marginHorizontal: 20,
}}
/> />
<Text
style={{
color: "white",
fontWeight: "400",
alignSelf: "center",
fontSize: 16,
}}
>
steem
<Text style={{ fontWeight: "800" }}>connect</Text>
</Text>
</View>
</TouchableOpacity>
</View>
</View> </View>
</ScrollableTabView> </ScrollableTabView>
</KeyboardAwareScrollView>
</View> </View>
); );
} }

View File

@ -36,9 +36,18 @@ export default EStyleSheet.create({
flex: 1, flex: 1,
backgroundColor: "#ffffff", backgroundColor: "#ffffff",
minWidth: "$deviceWidth", minWidth: "$deviceWidth",
height: "$deviceHeight / 1.95",
}, },
steemConnectTab: { steemConnectTab: {
backgroundColor: "#fff", backgroundColor: "#fff",
minWidth: "$deviceWidth", minWidth: "$deviceWidth",
flex: 1,
height: "$deviceHeight / 1.95",
},
mainButtonWrapper: {
position: "absolute",
right: 24,
bottom: 24,
flexDirection: "row",
}, },
}); });