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:
parent
97f1b530b2
commit
5a737ce38d
21 changed files with 333 additions and 82 deletions
21
app/package-lock.json
generated
21
app/package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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",
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
50
app/src/page/firstRun/internal/email-verify-page.js
Normal file
50
app/src/page/firstRun/internal/email-verify-page.js
Normal 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;
|
|
@ -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}>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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}>
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
|
@ -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 |
Loading…
Reference in a new issue