diff --git a/src/assets/svgs/hive-signer-icon.tsx b/src/assets/svgs/hive-signer-icon.tsx
new file mode 100644
index 000000000..ad78b01a3
--- /dev/null
+++ b/src/assets/svgs/hive-signer-icon.tsx
@@ -0,0 +1,50 @@
+import React from 'react';
+import { SvgXml } from 'react-native-svg';
+
+const xml = `
+
+`;
+export default () => ;
diff --git a/src/assets/svgs/index.ts b/src/assets/svgs/index.ts
new file mode 100644
index 000000000..d16aae933
--- /dev/null
+++ b/src/assets/svgs/index.ts
@@ -0,0 +1 @@
+export { default as HiveSignerIcon } from './hive-signer-icon';
diff --git a/src/components/formInput/view/formInputView.tsx b/src/components/formInput/view/formInputView.tsx
index 0e40399bf..43aba58dd 100644
--- a/src/components/formInput/view/formInputView.tsx
+++ b/src/components/formInput/view/formInputView.tsx
@@ -201,7 +201,7 @@ const FormInputView = ({
) : value && value.length > 0 ? (
setValue('')}
+ onPress={() => _handleOnChange('')}
name={leftIconName}
style={styles.icon}
/>
diff --git a/src/components/index.tsx b/src/components/index.tsx
index 05eb5b790..629c65d8c 100644
--- a/src/components/index.tsx
+++ b/src/components/index.tsx
@@ -103,6 +103,7 @@ import TransferAccountSelector from './transferAccountSelector/transferAccountSe
import TransferAmountInputSection from './transferAmountInputSection/transferAmountInputSection';
import TextBoxWithCopy from './textBoxWithCopy/textBoxWithCopy';
import WebViewModal from './webViewModal/webViewModal';
+import OrDivider from './orDivider/orDividerView';
// Basic UI Elements
import {
@@ -253,4 +254,5 @@ export {
TransferAmountInputSection,
TextBoxWithCopy,
WebViewModal,
+ OrDivider,
};
diff --git a/src/components/loginHeader/view/loginHeaderStyles.js b/src/components/loginHeader/view/loginHeaderStyles.js
index caf6b1fa4..c673a1822 100644
--- a/src/components/loginHeader/view/loginHeaderStyles.js
+++ b/src/components/loginHeader/view/loginHeaderStyles.js
@@ -4,7 +4,6 @@ export default EStyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
- height: '$deviceHeight / 3',
backgroundColor: '$primaryBackgroundColor',
},
safeArea: {
@@ -15,7 +14,7 @@ export default EStyleSheet.create({
maxHeight: '$deviceHeight / 3',
overflow: 'hidden',
backgroundColor: '$primaryBackgroundColor',
- height: '$deviceHeight / 3.9',
+ height: 120,
justifyContent: 'space-between',
alignItems: 'center',
},
@@ -37,12 +36,10 @@ export default EStyleSheet.create({
alignItems: 'center',
},
mascot: {
- width: '70%',
- height: '70%',
+ width: '60%',
},
titleText: {
alignSelf: 'center',
- marginTop: 20,
marginLeft: 32,
marginRight: 12,
flex: 1,
@@ -54,9 +51,15 @@ export default EStyleSheet.create({
backgroundColor: '$primaryBackgroundColor',
paddingVertical: 8,
},
+ backIconContainer: {
+ marginLeft: 20,
+ },
+ backIcon: {
+ fontSize: 24,
+ color: '$iconColor',
+ },
logoContainer: {
- paddingLeft: 32,
- paddingRight: 8,
+ paddingRight: 32,
alignItems: 'center',
justifyContent: 'center',
},
diff --git a/src/components/loginHeader/view/loginHeaderView.js b/src/components/loginHeader/view/loginHeaderView.js
index 7c3ca23d3..050ef45e0 100644
--- a/src/components/loginHeader/view/loginHeaderView.js
+++ b/src/components/loginHeader/view/loginHeaderView.js
@@ -4,11 +4,11 @@ import * as Animatable from 'react-native-animatable';
// Constants
// Components
-import { TextButton } from '../../buttons';
import { LineBreak } from '../../basicUIElements';
// Styles
import styles from './loginHeaderStyles';
import getWindowDimensions from '../../../utils/getWindowDimensions';
+import { IconButton } from '../..';
class LoginHeaderView extends PureComponent {
/* Props
@@ -27,24 +27,18 @@ class LoginHeaderView extends PureComponent {
// Component Functions
render() {
- const { description, isKeyboardOpen, onPress, rightButtonText, title } = this.props;
+ const { description, isKeyboardOpen, title, onBackPress } = this.props;
return (
-
-
-
-
-
+
@@ -61,7 +55,7 @@ class LoginHeaderView extends PureComponent {
@@ -76,7 +70,7 @@ class LoginHeaderView extends PureComponent {
export default LoginHeaderView;
const { height } = getWindowDimensions();
-const bodyHeight = height / 3.9;
+const bodyHeight = 120;
const showAnimation = {
from: {
opacity: 0,
diff --git a/src/components/mainButton/view/mainButtonView.js b/src/components/mainButton/view/mainButtonView.js
index 8d2122144..dbdd0006e 100644
--- a/src/components/mainButton/view/mainButtonView.js
+++ b/src/components/mainButton/view/mainButtonView.js
@@ -47,24 +47,28 @@ class MainButton extends Component {
iconType,
textStyle,
iconPosition,
+ iconStyle,
+ renderIcon,
} = this.props;
if (isLoading) {
this._getIndicator();
}
- const iconComponent = source ? (
-
- ) : (
- iconName && (
-
- )
- );
+ const iconComponent =
+ renderIcon ||
+ (source ? (
+
+ ) : (
+ iconName && (
+
+ )
+ ));
if (text) {
return (
@@ -108,7 +112,7 @@ class MainButton extends Component {
}
render() {
- const { wrapperStyle, children, height, style, isLoading } = this.props;
+ const { wrapperStyle, children, height, style, isLoading, bodyWrapperStyle } = this.props;
const { isDisable } = this.state;
return (
@@ -123,7 +127,7 @@ class MainButton extends Component {
style && style,
]}
>
-
+
{isLoading ? this._getIndicator() : children || this._getBody()}
diff --git a/src/components/orDivider/orDividerStyles.ts b/src/components/orDivider/orDividerStyles.ts
new file mode 100644
index 000000000..7adc23992
--- /dev/null
+++ b/src/components/orDivider/orDividerStyles.ts
@@ -0,0 +1,25 @@
+import EStyleSheet from 'react-native-extended-stylesheet';
+
+export default EStyleSheet.create({
+ dividerContainer: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ },
+ divider: {
+ borderWidth: 0.5,
+ flex: 1,
+ borderColor: '$primaryDarkGray',
+ },
+ leftDivider: {
+ marginLeft: 20,
+ },
+ rightDivider: {
+ marginRight: 20,
+ },
+ orText: {
+ fontSize: 16,
+ color: '$primaryDarkGray',
+ marginHorizontal: 8,
+ },
+});
diff --git a/src/components/orDivider/orDividerView.tsx b/src/components/orDivider/orDividerView.tsx
new file mode 100644
index 000000000..7b9ed5ede
--- /dev/null
+++ b/src/components/orDivider/orDividerView.tsx
@@ -0,0 +1,24 @@
+import React from 'react';
+import { View, Text, ViewStyle } from 'react-native';
+import { useIntl } from 'react-intl';
+import styles from './orDividerStyles';
+
+interface OrDividerProps {
+ containerStyle?: ViewStyle;
+}
+const OrDivider = ({ containerStyle }: OrDividerProps) => {
+ const intl = useIntl();
+ return (
+
+
+
+ {intl.formatMessage({
+ id: 'login.or',
+ })}
+
+
+
+ );
+};
+
+export default OrDivider;
diff --git a/src/config/locales/en-US.json b/src/config/locales/en-US.json
index 63d73cdf2..157fd6295 100644
--- a/src/config/locales/en-US.json
+++ b/src/config/locales/en-US.json
@@ -377,12 +377,13 @@
"no_user": "User is not found."
},
"login": {
- "signin": "Sign in",
+ "signin": "Login",
+ "login_with_hs": "Login with hivesigner",
"signup": "JOIN NOW",
"signin_title": "To get all the benefits of using Ecency",
- "username": "Username",
- "password": "Password or WIF",
- "description": "By signing in, you agree to our Terms of Services and Privacy Policies.",
+ "username": "username",
+ "password": "password / private key",
+ "description": "By logging in, you agree to our Terms of Services and Privacy Policies.",
"cancel": "cancel",
"login": "LOGIN",
"steemconnect_description": "If you don't want to keep your password encrypted and saved on your device, you can use Hivesigner.",
@@ -394,7 +395,10 @@
"deep_login_alert_title": "Easy Login @{username}",
"deep_login_alert_body":"Verify direct login using access code",
"deep_login_url_expired":"Login url expired, please use private key or password to login",
- "deep_login_malformed_url":"Malformed login url, please use private key or password to login"
+ "deep_login_malformed_url":"Malformed login url, please use private key or password to login",
+ "no_account_text": "Don't have an account?",
+ "signup_now": "Sign up now!",
+ "or": "OR"
},
"register": {
"modal_title":"Get Hive Account",
diff --git a/src/screens/editor/container/editorContainer.tsx b/src/screens/editor/container/editorContainer.tsx
index c5223ba8c..95d74d14f 100644
--- a/src/screens/editor/container/editorContainer.tsx
+++ b/src/screens/editor/container/editorContainer.tsx
@@ -55,6 +55,7 @@ import { useUserActivityMutation } from '../../../providers/queries/pointQueries
import { PointActivityIds } from '../../../providers/ecency/ecency.types';
import { usePostsCachePrimer } from '../../../providers/queries/postQueries/postQueries';
import { PostTypes } from '../../../constants/postTypes';
+
import { speakQueries } from '../../../providers/queries';
import {
BENEFICIARY_SRC_ENCODER,
diff --git a/src/screens/login/screen/loginScreen.js b/src/screens/login/screen/loginScreen.js
index 93bcbcdcd..9ff06dff2 100644
--- a/src/screens/login/screen/loginScreen.js
+++ b/src/screens/login/screen/loginScreen.js
@@ -1,8 +1,7 @@
-import React, { PureComponent } from 'react';
-import { View, Platform, Keyboard } from 'react-native';
+import React, { useEffect, useState } from 'react';
+import { View, Platform, Keyboard, Text } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
-import ScrollableTabView from 'react-native-scrollable-tab-view';
-import { injectIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { debounce } from 'lodash';
// Actions
@@ -15,213 +14,219 @@ import {
LoginHeader,
MainButton,
Modal,
- TabBar,
- TextButton,
+ OrDivider,
} from '../../../components';
// Constants
import { default as ROUTES } from '../../../constants/routeNames';
+import { ECENCY_TERMS_URL } from '../../../config/ecencyApi';
// Styles
import styles from './loginStyles';
-import globalStyles from '../../../globalStyles';
+import { HiveSignerIcon } from '../../../assets/svgs';
-import STEEM_CONNECT_LOGO from '../../../assets/steem_connect.png';
-import { ECENCY_TERMS_URL } from '../../../config/ecencyApi';
+const LoginScreen = ({
+ initialUsername,
+ getAccountsWithUsername,
+ navigation,
+ handleOnPressLogin,
+ handleSignUp,
+ isLoading,
+}) => {
+ const intl = useIntl();
+ const [username, setUsername] = useState(initialUsername || '');
+ const [password, setPassword] = useState('');
+ const [isUsernameValid, setIsUsernameValid] = useState(true);
+ const [keyboardIsOpen, setKeyboardIsOpen] = useState(false);
+ const [isModalOpen, setIsModalOpen] = useState(false);
-class LoginScreen extends PureComponent {
- constructor(props) {
- super(props);
-
- this.state = {
- username: props.initialUsername || '',
- password: '',
- isUsernameValid: true,
- keyboardIsOpen: false,
- isModalOpen: false,
- };
- }
-
- componentDidMount() {
- if (this.props.initialUsername) {
- this._handleUsernameChange(this.props.initialUsername);
+ useEffect(() => {
+ if (initialUsername) {
+ _handleUsernameChange(initialUsername);
}
- }
+ }, []);
- componentWillUnmount() {
- this.keyboardDidShowListener.remove();
- this.keyboardDidHideListener.remove();
- }
+ useEffect(() => {
+ const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', _keyboardDidShow);
+ const keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', _keyboardDidHide);
- _handleOnPasswordChange = (value) => {
- this.setState({ password: value });
+ return () => {
+ keyboardDidShowListener.remove();
+ keyboardDidHideListener.remove();
+ };
+ }, []);
+
+ const debouncedCheckValidity = debounce((uname) => {
+ _checkUsernameIsValid(uname);
+ }, 1000);
+
+ useEffect(() => {
+ if (username) {
+ debouncedCheckValidity(username);
+
+ return () => debouncedCheckValidity.cancel();
+ }
+ }, [username]);
+
+ const _keyboardDidShow = () => {
+ setKeyboardIsOpen(true);
};
- _handleUsernameChange = (username) => {
- const { getAccountsWithUsername } = this.props;
+ const _keyboardDidHide = () => {
+ setKeyboardIsOpen(false);
+ };
- this.setState({ username });
+ const _handleOnPasswordChange = (value) => {
+ setPassword(value);
+ };
- getAccountsWithUsername(username).then((res) => {
- const isValid = res.includes(username);
+ const _handleUsernameChange = (username) => {
+ const formattedUsername = username.trim().toLowerCase();
+ setUsername(formattedUsername);
+ };
- this.setState({ isUsernameValid: isValid });
+ const _checkUsernameIsValid = (uname) => {
+ getAccountsWithUsername(uname).then((res) => {
+ const isValid = res.includes(uname);
+ setIsUsernameValid(isValid);
});
};
- _handleOnModalToggle = () => {
- const { isModalOpen } = this.state;
- this.setState({ isModalOpen: !isModalOpen });
+ const _handleOnModalToggle = () => {
+ setIsModalOpen(!isModalOpen);
};
- UNSAFE_componentWillMount() {
- this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () =>
- this.setState({ keyboardIsOpen: true }),
- );
- this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () =>
- this.setState({ keyboardIsOpen: false }),
- );
- }
+ const _renderHiveicon = () => (
+
+
+
+ );
- render() {
- const { navigation, intl, handleOnPressLogin, handleSignUp, isLoading } = this.props;
- const { username, isUsernameValid, keyboardIsOpen, password, isModalOpen } = this.state;
+ return (
+
+ handleSignUp()}
+ rightButtonText={intl.formatMessage({
+ id: 'login.signup',
+ })}
+ onBackPress={() => {
+ navigation.navigate({
+ name: ROUTES.DRAWER.MAIN,
+ });
+ }}
+ />
- console.log('keyboardIsOpen : ', keyboardIsOpen);
- return (
-
- handleSignUp()}
- rightButtonText={intl.formatMessage({
- id: 'login.signup',
- })}
- />
- (
-
- )}
+
+
-
-
-
- this._handleOnPasswordChange(value)}
- placeholder={intl.formatMessage({
- id: 'login.password',
- })}
- isEditable
- secureTextEntry
- type="password"
- numberOfLines={1}
- value={password}
- inputStyle={styles.input}
- />
-
-
-
-
-
- navigation.navigate({
- name: ROUTES.DRAWER.MAIN,
- })
- }
- text={intl.formatMessage({
- id: 'login.cancel',
- })}
- />
- handleOnPressLogin(username, password)}
- iconName="person"
- iconColor="white"
- text={intl.formatMessage({
- id: 'login.login',
- })}
- textStyle={styles.mainBtnText}
- isDisable={!isUsernameValid || password.length < 2 || username.length < 2}
- isLoading={isLoading}
- />
-
-
-
-
- this._handleOnModalToggle()}
- source={STEEM_CONNECT_LOGO}
- text="hive"
- secondText="signer"
- />
-
-
-
-
-
+ isEditable
+ type="username"
+ isFirstImage
+ value={username}
+ inputStyle={styles.input}
+ onBlur={() => _checkUsernameIsValid(username)}
+ />
+
+
+ handleOnPressLogin(username, password)}
+ iconName="person"
+ iconColor="white"
+ text={intl.formatMessage({
+ id: 'login.login',
+ })}
+ textStyle={styles.mainBtnText}
+ isDisable={!isUsernameValid || password.length < 2 || username.length < 2}
+ isLoading={isLoading}
+ wrapperStyle={styles.loginBtnWrapper}
+ bodyWrapperStyle={styles.loginBtnBodyWrapper}
+ height={50}
+ iconStyle={styles.loginBtnIconStyle}
+ />
+
+ _handleOnModalToggle()}
+ renderIcon={_renderHiveicon()}
+ text={intl.formatMessage({
+ id: 'login.login_with_hs',
+ })}
+ textStyle={styles.hsLoginBtnText}
+ wrapperStyle={styles.loginBtnWrapper}
+ bodyWrapperStyle={styles.loginBtnBodyWrapper}
+ height={48}
+ style={styles.hsLoginBtnStyle}
+ />
+
+
+
+ {intl.formatMessage({
+ id: 'login.no_account_text',
+ })}
+
+ handleSignUp()}>
+ {intl.formatMessage({
+ id: 'login.signup_now',
+ })}
+
+
- );
- }
-}
+
+
+
+
+ );
+};
-export default injectIntl(LoginScreen);
+export default LoginScreen;
diff --git a/src/screens/login/screen/loginStyles.js b/src/screens/login/screen/loginStyles.js
index 4a83a154a..f39532355 100644
--- a/src/screens/login/screen/loginStyles.js
+++ b/src/screens/login/screen/loginStyles.js
@@ -3,7 +3,7 @@ import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
container: {
flex: 1,
- backgroundColor: '$primaryLightBackground',
+ backgroundColor: '$primaryBackgroundColor',
},
tabbar: {
alignSelf: 'center',
@@ -11,10 +11,9 @@ export default EStyleSheet.create({
backgroundColor: '$primaryBackgroundColor',
},
tabbarItem: {
- flex: 1,
+ // flex: 1,
backgroundColor: '$primaryBackgroundColor',
minWidth: '$deviceWidth',
- height: '$deviceHeight / 1.95',
},
mainButtonWrapper: {
position: 'absolute',
@@ -22,20 +21,13 @@ export default EStyleSheet.create({
bottom: 24,
flexDirection: 'row',
},
- footerButtons: {
- flexDirection: 'row',
- justifyContent: 'center',
- alignItems: 'center',
- alignSelf: 'flex-end',
- paddingRight: 24,
- paddingBottom: 24,
- backgroundColor: '$primaryBackgroundColor',
- },
+
cancelButton: {
marginRight: 10,
+ justifyContent: 'center',
+ alignItems: 'center',
},
formWrapper: {
- flexGrow: 1,
marginHorizontal: 30,
marginVertical: 10,
},
@@ -44,6 +36,44 @@ export default EStyleSheet.create({
flexGrow: 1,
},
mainBtnText: {
- marginRight: 12,
+ flexGrow: 1,
+ },
+ loginBtnWrapper: {
+ marginVertical: 12,
+ },
+ loginBtnBodyWrapper: {
+ flex: 1,
+ },
+ loginBtnIconStyle: {
+ position: 'absolute',
+ left: 0,
+ },
+ hsLoginBtnStyle: {
+ backgroundColor: 'transparent',
+ borderWidth: 1,
+ borderColor: '$primaryBlue',
+ },
+ hsLoginBtnText: {
+ flexGrow: 1,
+ color: '$primaryBlue',
+ },
+ hsLoginBtnIconStyle: {
+ marginLeft: 20,
+ },
+ footerButtons: {
+ flexDirection: 'row',
+ justifyContent: 'center',
+ alignItems: 'center',
+ paddingHorizontal: 24,
+ backgroundColor: '$primaryBackgroundColor',
+ },
+ noAccountText: {
+ color: '$primaryDarkGray',
+ fontSize: 16,
+ },
+ signUpNowText: {
+ color: '$primaryBlue',
+ marginLeft: 4,
+ fontSize: 16,
},
});