wait for user to complete email verification (#548)

* wait for user to complete email verification on first run
* add password strength meter. fix auth bugs in first run.
This commit is contained in:
Akinwale Ariwodola 2019-05-23 22:11:52 +01:00 committed by GitHub
parent 97f1b530b2
commit 5a737ce38d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 333 additions and 82 deletions

21
app/package-lock.json generated
View file

@ -4832,8 +4832,8 @@
}
},
"lbryinc": {
"version": "github:lbryio/lbryinc#a8fd592c46abb65410785fd0242e91904c158fd7",
"from": "github:lbryio/lbryinc",
"version": "github:lbryio/lbryinc#54ef55d430db13ecd77699d23974cf871445ebd7",
"from": "github:lbryio/lbryinc#check-sync",
"requires": {
"reselect": "^3.0.0"
}
@ -6316,6 +6316,15 @@
"react-native-image-pan-zoom": "^2.1.9"
}
},
"react-native-password-strength-meter": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/react-native-password-strength-meter/-/react-native-password-strength-meter-0.0.2.tgz",
"integrity": "sha512-jONkwnbznl2xJnJK3/eGa/EL87darI6n+/FtVFXRdyGqypWy6lFJALn/C6m9FyodVArrrpXJ60Ke8nWaGmPALw==",
"requires": {
"prop-types": "^15.6.2",
"react-native-speedometer": "^1.0.0"
}
},
"react-native-phone-input": {
"version": "github:lbryio/react-native-phone-input#60fdef484e8bf27328c7fb6a203baab9eb9cd4a1",
"from": "github:lbryio/react-native-phone-input",
@ -6338,6 +6347,14 @@
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-1.0.0-alpha.22.tgz",
"integrity": "sha512-kSyAt0AeVU6N7ZonfV6dP6iZF8B7Bce+tk3eujXhzBGsLg0VSLnU7uE9VqJF0xdQrHR91ZjGgVMieo/8df9KTA=="
},
"react-native-speedometer": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/react-native-speedometer/-/react-native-speedometer-1.0.3.tgz",
"integrity": "sha512-34Ne/ptaWv97jbSOq87b+gKHvGKeZ4AjYXZvovbEnQMnYNzCBWZbQNJqWWzOxyFZXbzeDsfiQ6d4xpq2pc1Tfw==",
"requires": {
"prop-types": "^15.6.2"
}
},
"react-native-tab-view": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-1.3.4.tgz",

View file

@ -9,7 +9,7 @@
"base-64": "^0.1.0",
"@expo/vector-icons": "^8.1.0",
"lbry-redux": "lbryio/lbry-redux",
"lbryinc": "lbryio/lbryinc",
"lbryinc": "lbryio/lbryinc#check-sync",
"lodash": ">=4.17.11",
"merge": ">=1.2.1",
"moment": "^2.22.1",
@ -21,6 +21,7 @@
"react-native-fast-image": "^5.0.3",
"react-native-gesture-handler": "^1.1.0",
"react-native-image-zoom-viewer": "^2.2.5",
"react-native-password-strength-meter": "^0.0.2",
"react-native-phone-input": "lbryio/react-native-phone-input",
"react-native-vector-icons": "^6.4.2",
"react-native-video": "lbryio/react-native-video#exoplayer-lbry-android",

View file

@ -72,7 +72,16 @@ class RewardCard extends React.PureComponent<Props> {
}
}}>
<View style={rewardStyle.leftCol}>
{!isPending && <TouchableOpacity onPress={() => {
if (!claimed) {
this.onClaimPress();
}
}}>
{claimed && <Icon name={claimed ? "check-circle" : "circle"}
style={claimed ? rewardStyle.claimed : (canClaim ? rewardStyle.unclaimed : rewardStyle.disabled)}
size={20} />}
</TouchableOpacity>}
{isPending && <ActivityIndicator size="small" color={Colors.LbryGreen} />}
</View>
<View style={rewardStyle.midCol}>
<Text style={rewardStyle.rewardTitle}>{reward.reward_title}</Text>
@ -83,16 +92,6 @@ class RewardCard extends React.PureComponent<Props> {
error={'The transaction URL could not be opened'} />}
</View>
<View style={rewardStyle.rightCol}>
{!isPending && <TouchableOpacity onPress={() => {
if (!claimed) {
this.onClaimPress();
}
}}>
<Icon name={claimed ? "check-circle" : "circle"}
style={claimed ? rewardStyle.claimed : (canClaim ? rewardStyle.unclaimed : rewardStyle.disabled)}
size={20} />
</TouchableOpacity>}
{isPending && <ActivityIndicator size="small" color={Colors.LbryGreen} />}
<Text style={rewardStyle.rewardAmount}>{reward.reward_amount}</Text>
<Text style={rewardStyle.rewardCurrency}>LBC</Text>
</View>

View file

@ -1,6 +1,7 @@
const Constants = {
FIRST_RUN_PAGE_WELCOME: "welcome",
FIRST_RUN_PAGE_EMAIL_COLLECT: "email-collect",
FIRST_RUN_PAGE_EMAIL_VERIFY:"email-verify",
FIRST_RUN_PAGE_WALLET: "wallet",
FIRST_RUN_PAGE_SKIP_ACCOUNT: "skip-account",

View file

@ -44,6 +44,7 @@ import thunk from 'redux-thunk';
const globalExceptionHandler = (error, isFatal) => {
if (error && NativeModules.Firebase) {
console.log(error);
NativeModules.Firebase.logException(isFatal, error.message ? error.message : "No message", error);
}
};

View file

@ -2,12 +2,17 @@ import { connect } from 'react-redux';
import { doToast } from 'lbry-redux';
import {
doAuthenticate,
doCheckSync,
doUserEmailNew,
doUserResendVerificationEmail,
selectAuthToken,
selectEmailNewErrorMessage,
selectEmailNewIsPending,
selectEmailToVerify,
selectAuthenticationIsPending
selectAuthenticationIsPending,
selectHasSyncedWallet,
selectIsRetrievingSync,
selectUser,
} from 'lbryinc';
import FirstRun from './view';
@ -17,12 +22,17 @@ const select = (state) => ({
emailToVerify: selectEmailToVerify(state),
emailNewErrorMessage: selectEmailNewErrorMessage(state),
emailNewPending: selectEmailNewIsPending(state),
hasSyncedWallet: selectHasSyncedWallet(state),
isRetrievingSync: selectIsRetrievingSync(state),
user: selectUser(state),
});
const perform = dispatch => ({
addUserEmail: email => dispatch(doUserEmailNew(email)),
authenticate: (appVersion, os) => dispatch(doAuthenticate(appVersion, os)),
notify: data => dispatch(doToast(data))
checkSync: () => dispatch(doCheckSync()),
notify: data => dispatch(doToast(data)),
resendVerificationEmail: email => dispatch(doUserResendVerificationEmail(email))
});
export default connect(select, perform)(FirstRun);

View file

@ -22,29 +22,35 @@ class EmailCollectPage extends React.PureComponent {
authenticationStarted: false,
authenticationFailed: false,
placeholder: 'you@example.com',
statusTries: 0
statusTries: 0,
verifying: true
};
componentWillReceiveProps(nextProps) {
const { authenticating, authToken } = this.props;
const { authenticating, authToken, showNextPage } = this.props;
const { user } = nextProps;
if (this.state.authenticationStarted && !authenticating && authToken === null) {
this.setState({ authenticationFailed: true, authenticationStarted: false });
}
if (this.state.verifying) {
if (user && user.primary_email && user.has_verified_email) {
if (showNextPage) {
showNextPage();
}
} else {
this.setState({ verifying: false });
}
}
}
componentDidMount() {
// call user/new
const { generateAuthToken, authenticating, authToken } = this.props;
if (!authToken && !authenticating) {
if (!authenticating) {
this.startAuthenticating();
}
AsyncStorage.getItem('firstRunEmail').then(email => {
if (email) {
this.setState({ email });
}
});
}
startAuthenticating = () => {
@ -88,7 +94,7 @@ class EmailCollectPage extends React.PureComponent {
<Text style={firstRunStyle.paragraph}>The LBRY servers were unreachable at this time. Please check your Internet connection and then restart the app to try again.</Text>
</View>
);
} else if (!authToken || authenticating) {
} else if (!authToken || authenticating || this.state.verifying) {
content = (
<View>
<ActivityIndicator size="large" color={Colors.White} style={firstRunStyle.waiting} />
@ -115,7 +121,7 @@ class EmailCollectPage extends React.PureComponent {
}
}}
/>
<Text style={firstRunStyle.paragraph}>An account will allow you to earn rewards and keep your content and settings synced.</Text>
<Text style={firstRunStyle.paragraph}>An account will allow you to earn rewards and keep your account and settings synced.</Text>
<Text style={firstRunStyle.infoParagraph}>This information is disclosed only to LBRY, Inc. and not to the LBRY network.</Text>
</View>
);

View file

@ -0,0 +1,50 @@
import React from 'react';
import { Lbry } from 'lbry-redux';
import {
ActivityIndicator,
Linking,
NativeModules,
Platform,
Switch,
Text,
TextInput,
View
} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import Button from 'component/button';
import Colors from 'styles/colors';
import Constants from 'constants';
import Icon from 'react-native-vector-icons/FontAwesome5';
import firstRunStyle from 'styles/firstRun';
class EmailVerifyPage extends React.PureComponent {
onResendPressed = () => {
const { email, notify, resendVerificationEmail } = this.props;
resendVerificationEmail(email);
AsyncStorage.setItem(Constants.KEY_EMAIL_VERIFY_PENDING, 'true');
notify({ message: 'Please follow the instructions in the email sent to your address to continue.' });
}
render() {
const { onEmailViewLayout, email } = this.props;
const content = (
<View onLayout={onEmailViewLayout}>
<Text style={firstRunStyle.title}>Verify Email</Text>
<Text style={firstRunStyle.paragraph}>An email has been sent to <Text style={firstRunStyle.nowrap} numberOfLines={1}>{email}</Text>. Please follow the instructions in the message to verify your email address.</Text>
<View style={firstRunStyle.buttonContainer}>
<Button style={firstRunStyle.verificationButton} theme={"light"} text={"Resend"} onPress={this.onResendPressed} />
</View>
</View>
);
return (
<View style={firstRunStyle.container}>
{content}
</View>
);
}
}
export default EmailVerifyPage;

View file

@ -2,6 +2,7 @@ import React from 'react';
import { Lbry } from 'lbry-redux';
import {
ActivityIndicator,
Dimensions,
Linking,
NativeModules,
Platform,
@ -9,6 +10,7 @@ import {
TextInput,
View
} from 'react-native';
import { BarPasswordStrengthDisplay } from 'react-native-password-strength-meter';
import AsyncStorage from '@react-native-community/async-storage';
import Colors from 'styles/colors';
import Constants from 'constants';
@ -18,9 +20,31 @@ class WalletPage extends React.PureComponent {
state = {
password: null,
placeholder: 'password',
statusTries: 0
statusTries: 0,
walletReady: false,
hasCheckedSync: false
};
componentDidMount() {
this.checkWalletReady();
this.props.checkSync();
setTimeout(() => this.setState({ hasCheckedSync: true}), 1000);
}
checkWalletReady = () => {
// make sure the sdk wallet component is ready
Lbry.status().then(status => {
if (status.startup_status && status.startup_status.wallet) {
this.setState({ walletReady: true });
return;
}
setTimeout(this.checkWalletReady, 1000);
}).catch((e) => {
console.log(e);
setTimeout(this.checkWalletReady, 1000);
});
}
handleChangeText = (text) => {
// save the value to the state email
const { onPasswordChanged } = this.props;
@ -37,32 +61,52 @@ class WalletPage extends React.PureComponent {
}
render() {
const { onPasswordChanged, onWalletViewLayout } = this.props;
const { onPasswordChanged, onWalletViewLayout, isRetrievingSync, hasSyncedWallet } = this.props;
const content = (
<View onLayout={onWalletViewLayout}>
<Text style={firstRunStyle.title}>Password</Text>
<Text style={firstRunStyle.paragraph}>Please enter a password to secure your account and wallet.</Text>
<TextInput style={firstRunStyle.passwordInput}
placeholder={this.state.placeholder}
underlineColorAndroid="transparent"
secureTextEntry={true}
value={this.state.password}
onChangeText={text => this.handleChangeText(text)}
onFocus={() => {
if (!this.state.password || this.state.password.length === 0) {
this.setState({ placeholder: '' });
}
}}
onBlur={() => {
if (!this.state.password || this.state.password.length === 0) {
this.setState({ placeholder: 'password' });
}
}}
/>
<Text style={firstRunStyle.infoParagraph}>Note: for wallet security purposes, LBRY is unable to reset your password.</Text>
</View>
);
let content;
if (!this.state.walletReady || !this.state.hasCheckedSync || isRetrievingSync) {
content = (
<View>
<ActivityIndicator size="large" color={Colors.White} style={firstRunStyle.waiting} />
<Text style={firstRunStyle.paragraph}>Retrieving your account information...</Text>
</View>
);
} else {
content = (
<View onLayout={onWalletViewLayout}>
<Text style={firstRunStyle.title}>Password</Text>
<Text style={firstRunStyle.paragraph}>
{hasSyncedWallet ? "Please enter the password you used to secure your wallet." :
"Please enter a password to secure your account and wallet."}
</Text>
<TextInput style={firstRunStyle.passwordInput}
placeholder={this.state.placeholder}
underlineColorAndroid="transparent"
secureTextEntry={true}
value={this.state.password}
onChangeText={text => this.handleChangeText(text)}
onFocus={() => {
if (!this.state.password || this.state.password.length === 0) {
this.setState({ placeholder: '' });
}
}}
onBlur={() => {
if (!this.state.password || this.state.password.length === 0) {
this.setState({ placeholder: 'password' });
}
}}
/>
{(this.state.password && this.state.password.trim().length) > 0 &&
<View style={firstRunStyle.passwordStrength}>
<BarPasswordStrengthDisplay
width={Dimensions.get('window').width - 80}
minLength={1}
password={this.state.password} />
</View>}
<Text style={firstRunStyle.infoParagraph}>Note: for wallet security purposes, LBRY is unable to reset your password.</Text>
</View>
);
}
return (
<View style={firstRunStyle.container}>

View file

@ -15,6 +15,7 @@ import Constants from 'constants';
import WalletPage from './internal/wallet-page';
import WelcomePage from './internal/welcome-page';
import EmailCollectPage from './internal/email-collect-page';
import EmailVerifyPage from './internal/email-verify-page';
import SkipAccountPage from './internal/skip-account-page';
import firstRunStyle from 'styles/firstRun';
@ -22,16 +23,19 @@ class FirstRunScreen extends React.PureComponent {
static pages = [
Constants.FIRST_RUN_PAGE_WELCOME,
Constants.FIRST_RUN_PAGE_EMAIL_COLLECT,
Constants.FIRST_RUN_PAGE_EMAIL_VERIFY,
Constants.FIRST_RUN_PAGE_WALLET,
Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT,
];
state = {
currentPage: null,
email: null,
emailSubmitted: false,
isFirstRun: false,
launchUrl: null,
showSkip: false,
isEmailVerified: false,
skipAccountConfirmed: false,
showBottomContainer: true,
walletPassword: null
@ -61,7 +65,7 @@ class FirstRunScreen extends React.PureComponent {
}
componentWillReceiveProps(nextProps) {
const { emailNewErrorMessage, emailNewPending } = nextProps;
const { emailNewErrorMessage, emailNewPending, user } = nextProps;
const { notify } = this.props;
if (this.state.emailSubmitted && !emailNewPending) {
@ -69,10 +73,24 @@ class FirstRunScreen extends React.PureComponent {
if (emailNewErrorMessage) {
notify ({ message: String(emailNewErrorMessage), isError: true });
} else {
// Request successful. Navigate to next page (wallet).
this.showNextPage();
// Request successful. Navigate to email verify page.
this.showPage(Constants.FIRST_RUN_PAGE_EMAIL_VERIFY)
}
}
this.checkVerificationStatus(user);
}
checkVerificationStatus = (user) => {
const { navigation } = this.props;
this.setState({
isEmailVerified: (user && user.primary_email && user.has_verified_email),
}, () => {
if (this.state.isEmailVerified) {
this.showPage(Constants.FIRST_RUN_PAGE_WALLET);
}
});
}
launchSplashScreen() {
@ -96,14 +114,19 @@ class FirstRunScreen extends React.PureComponent {
if (Constants.FIRST_RUN_PAGE_EMAIL_COLLECT === this.state.currentPage) {
this.showPage(Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT);
}
// Go to email collection page if user cancels from email verification
if (Constants.FIRST_RUN_PAGE_EMAIL_VERIFY === this.state.currentPage) {
this.showPage(Constants.FIRST_RUN_PAGE_EMAIL_COLLECT);
}
}
handleContinuePressed = () => {
const { notify } = this.props;
const { notify, user } = this.props;
const pageIndex = FirstRunScreen.pages.indexOf(this.state.currentPage);
if (Constants.FIRST_RUN_PAGE_WALLET === this.state.currentPage) {
if (!this.state.walletPassword || this.state.walletPassword.trim().length < 6) {
return notify({ message: 'Your wallet password should be at least 6 characters long' });
if (!this.state.walletPassword || this.state.walletPassword.trim().length === 0) {
return notify({ message: 'Please enter a wallet password' });
}
this.closeFinalPage();
@ -144,11 +167,11 @@ class FirstRunScreen extends React.PureComponent {
});
}
showNextPage() {
showNextPage = () => {
const pageIndex = FirstRunScreen.pages.indexOf(this.state.currentPage);
const nextPage = FirstRunScreen.pages[pageIndex + 1];
this.setState({ currentPage: nextPage });
if (nextPage === 'email-collect') {
if (nextPage === Constants.FIRST_RUN_PAGE_EMAIL_COLLECT) {
// do not show the buttons (because we're waiting to get things ready)
this.setState({ showBottomContainer: false });
}
@ -172,6 +195,7 @@ class FirstRunScreen extends React.PureComponent {
}
onEmailChanged = (email) => {
this.setState({ email });
if (Constants.FIRST_RUN_PAGE_EMAIL_COLLECT == this.state.currentPage) {
this.setState({ showSkip: (!email || email.trim().length === 0) });
} else {
@ -203,19 +227,27 @@ class FirstRunScreen extends React.PureComponent {
authenticate,
authenticating,
authToken,
checkSync,
emailNewErrorMessage,
emailNewPending,
emailToVerify
emailToVerify,
notify,
hasSyncedWallet,
isRetrievingSync,
resendVerificationEmail,
user
} = this.props;
let page = null;
switch (this.state.currentPage) {
case 'welcome':
case Constants.FIRST_RUN_PAGE_WELCOME:
page = (<WelcomePage />);
break;
case 'email-collect':
case Constants.FIRST_RUN_PAGE_EMAIL_COLLECT:
page = (<EmailCollectPage
user={user}
showNextPage={this.showNextPage}
authenticating={authenticating}
authToken={authToken}
authenticate={authenticate}
@ -223,13 +255,24 @@ class FirstRunScreen extends React.PureComponent {
onEmailViewLayout={this.onEmailViewLayout} />);
break;
case 'wallet':
page = (<WalletPage
onWalletViewLayout={this.onWalletViewLayout}
onPasswordChanged={this.onWalletPasswordChanged} />);
case Constants.FIRST_RUN_PAGE_EMAIL_VERIFY:
page = (<EmailVerifyPage
onEmailViewLayout={this.onEmailViewLayout}
email={this.state.email}
notify={notify}
resendVerificationEmail={resendVerificationEmail} />);
break;
case 'skip-account':
case Constants.FIRST_RUN_PAGE_WALLET:
page = (<WalletPage
checkSync={checkSync}
hasSyncedWallet={hasSyncedWallet}
isRetrievingSync={isRetrievingSync}
onWalletViewLayout={this.onWalletViewLayout}
onPasswordChanged={this.onWalletPasswordChanged} />);
break;
case Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT:
page = (<SkipAccountPage
onSkipAccountViewLayout={this.onSkipAccountViewLayout}
onSkipSwitchChanged={this.onSkipSwitchChanged} />);
@ -246,9 +289,11 @@ class FirstRunScreen extends React.PureComponent {
<View style={firstRunStyle.buttonRow}>
{([Constants.FIRST_RUN_PAGE_WELCOME, Constants.FIRST_RUN_PAGE_WALLET].indexOf(this.state.currentPage) > -1) && <View />}
{Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT === this.state.currentPage &&
{(Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT === this.state.currentPage ||
Constants.FIRST_RUN_PAGE_EMAIL_VERIFY === this.state.currentPage) &&
<TouchableOpacity style={firstRunStyle.leftButton} onPress={this.handleLeftButtonPressed}>
<Text style={firstRunStyle.buttonText}>« Setup account</Text>
<Text style={firstRunStyle.buttonText}>
« {Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT === this.state.currentPage ? 'Setup account' : 'Change Email'}</Text>
</TouchableOpacity>}
{!emailNewPending && (Constants.FIRST_RUN_PAGE_EMAIL_COLLECT === this.state.currentPage) &&
<TouchableOpacity style={firstRunStyle.leftButton} onPress={this.handleLeftButtonPressed}>
@ -259,7 +304,9 @@ class FirstRunScreen extends React.PureComponent {
<TouchableOpacity style={firstRunStyle.button} onPress={this.handleContinuePressed}>
{Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT === this.state.currentPage &&
<Text style={firstRunStyle.smallButtonText}>Use LBRY »</Text>}
{Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT !== this.state.currentPage &&
Constants.FIRST_RUN_PAGE_EMAIL_VERIFY !== this.state.currentPage &&
<Text style={firstRunStyle.buttonText}>{Constants.FIRST_RUN_PAGE_WALLET === this.state.currentPage ? 'Use LBRY' : 'Continue'} »</Text>}
</TouchableOpacity>}
</View>

View file

@ -18,6 +18,18 @@ class EmailVerifyPage extends React.PureComponent {
previousEmail: null
}
componentDidMount() {
const { setEmailVerificationPhase } = this.props;
if (setEmailVerificationPhase) {
setEmailVerificationPhase(false);
}
}
componentWillUmount() {
AsyncStorage.removeItem(Constants.KEY_EMAIL_VERIFY_PENDING);
AsyncStorage.removeItem(Constants.KEY_FIRST_RUN_EMAIL);
}
handleChangeText = (text) => {
this.setState({ email: text });
AsyncStorage.setItem(Constants.KEY_FIRST_RUN_EMAIL, text);
@ -25,7 +37,7 @@ class EmailVerifyPage extends React.PureComponent {
componentWillReceiveProps(nextProps) {
const { emailNewErrorMessage, emailNewPending, emailToVerify } = nextProps;
const { notify } = this.props;
const { notify, setEmailVerificationPhase } = this.props;
if (this.state.verifyStarted && !emailNewPending) {
if (emailNewErrorMessage) {
@ -33,6 +45,9 @@ class EmailVerifyPage extends React.PureComponent {
this.setState({ verifyStarted: false });
} else {
this.setState({ phase: Constants.PHASE_VERIFICATION });
if (setEmailVerificationPhase) {
setEmailVerificationPhase(true);
}
//notify({ message: 'Please follow the instructions in the email sent to your address to continue.' });
AsyncStorage.setItem(Constants.KEY_EMAIL_VERIFY_PENDING, 'true');
}
@ -40,7 +55,13 @@ class EmailVerifyPage extends React.PureComponent {
}
onSendVerificationPressed = () => {
const { addUserEmail, emailNewPending, notify, resendVerificationEmail } = this.props;
const {
addUserEmail,
emailNewPending,
notify,
resendVerificationEmail,
setEmailVerificationPhase
} = this.props;
if (emailNewPending) {
return;
@ -58,6 +79,9 @@ class EmailVerifyPage extends React.PureComponent {
resendVerificationEmail(this.state.email);
AsyncStorage.setItem(Constants.KEY_EMAIL_VERIFY_PENDING, 'true');
this.setState({ verifyStarted: true, phase: Constants.PHASE_VERIFICATION });
if (setEmailVerificationPhase) {
setEmailVerificationPhase(true);
}
return;
}
@ -74,7 +98,15 @@ class EmailVerifyPage extends React.PureComponent {
}
onEditPressed = () => {
this.setState({ verifyStarted: false, phase: Constants.PHASE_COLLECTION, previousEmail: this.state.email });
const { setEmailVerificationPhase } = this.props;
this.setState({ verifyStarted: false, phase: Constants.PHASE_COLLECTION, previousEmail: this.state.email }, () => {
if (setEmailVerificationPhase) {
setEmailVerificationPhase(false);
}
// clear the previous email
AsyncStorage.removeItem(Constants.KEY_EMAIL_VERIFY_PENDING);
AsyncStorage.removeItem(Constants.KEY_FIRST_RUN_EMAIL);
});
}
render() {

View file

@ -10,6 +10,13 @@ import firstRunStyle from 'styles/firstRun';
import rewardStyle from 'styles/reward';
class ManualVerifyPage extends React.PureComponent {
componentDidMount() {
const { setEmailVerificationPhase } = this.props;
if (setEmailVerificationPhase) {
setEmailVerificationPhase(false);
}
}
render() {
return (
<View style={firstRunStyle.container}>

View file

@ -43,10 +43,13 @@ class PhoneVerifyPage extends React.PureComponent {
}
componentDidMount() {
const { phone } = this.props;
const { phone, setEmailVerificationPhase } = this.props;
if (phone && String(phone).trim().length > 0) {
this.setState({ newPhoneAdded: true, phase: Constants.PHASE_VERIFICATION });
}
if (setEmailVerificationPhase) {
setEmailVerificationPhase(false);
}
}
componentDidUpdate(prevProps) {

View file

@ -27,6 +27,7 @@ class VerificationScreen extends React.PureComponent {
skipAccountConfirmed: false,
showBottomContainer: true,
walletPassword: null,
isEmailVerificationPhase: false,
isEmailVerified: false,
isIdentityVerified: false,
isRewardApproved: false
@ -37,6 +38,10 @@ class VerificationScreen extends React.PureComponent {
this.checkVerificationStatus(user);
}
setEmailVerificationPhase = (value) => {
this.setState({ isEmailVerificationPhase: value });
}
checkVerificationStatus = (user) => {
const { navigation } = this.props;
@ -101,6 +106,7 @@ class VerificationScreen extends React.PureComponent {
emailNewPending={emailNewPending}
emailToVerify={emailToVerify}
notify={notify}
setEmailVerificationPhase={this.setEmailVerificationPhase}
resendVerificationEmail={resendVerificationEmail}
/>
);
@ -114,6 +120,7 @@ class VerificationScreen extends React.PureComponent {
phoneVerifyErrorMessage={phoneVerifyErrorMessage}
phoneNewIsPending={phoneNewIsPending}
phoneNewErrorMessage={phoneNewErrorMessage}
setEmailVerificationPhase={this.setEmailVerificationPhase}
notify={notify}
verifyPhone={verifyPhone}
/>
@ -121,7 +128,7 @@ class VerificationScreen extends React.PureComponent {
break;
case 'manualVerify':
page = (
<ManualVerifyPage />
<ManualVerifyPage setEmailVerificationPhase={this.setEmailVerificationPhase} />
);
}
@ -129,9 +136,10 @@ class VerificationScreen extends React.PureComponent {
<View style={firstRunStyle.screenContainer}>
{page}
<TouchableOpacity style={firstRunStyle.closeButton} onPress={this.onCloseButtonPressed}>
{!this.state.isEmailVerificationPhase &&
(<TouchableOpacity style={firstRunStyle.closeButton} onPress={this.onCloseButtonPressed}>
<Text style={firstRunStyle.closeButtonText}>x</Text>
</TouchableOpacity>
</TouchableOpacity>)}
</View>
);
}

View file

@ -143,6 +143,29 @@ const firstRunStyle = StyleSheet.create({
alignSelf: 'center',
color: Colors.White,
fontSize: 16
},
buttonContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
width: '100%',
paddingLeft: 32,
paddingRight: 32,
marginTop: 16
},
verificationButton: {
backgroundColor: Colors.White,
paddingLeft: 16,
paddingRight: 16
},
passwordStrength: {
marginLeft: 32,
marginRight: 32,
marginBottom: 48
},
nowrap: {
flex: 1,
flexWrap: 'nowrap'
}
});

View file

@ -139,12 +139,12 @@ const rewardStyle = StyleSheet.create({
color: Colors.LbryGreen
},
leftCol: {
width: '5%',
width: '15%',
alignItems: 'center',
paddingLeft: 6
},
midCol: {
width: '75%'
width: '65%'
},
rightCol: {
width: '18%',
@ -278,7 +278,7 @@ const rewardStyle = StyleSheet.create({
width: '100%',
paddingLeft: 32,
paddingRight: 32,
marginTop: 16
marginTop: 8
},
verificationTitle: {
fontSize: 32,

View file

@ -2,9 +2,10 @@
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="colorAccent">#FFFFFF</color>
<color name="red">#FF0000</color>
<color name="green">#00C000</color>
<color name="lbrygreen">#40B89A</color>
<color name="white">#FFFFFF</color>
</resources>

View file

@ -1,5 +1,6 @@
<resources>
<style name="LbryAppTheme" parent="@android:style/Theme.Material.Light">
<item name="android:windowBackground">@color/lbrygreen</item>
<item name="colorControlActivated">@color/white</item>
</style>
</resources>

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB