not enough progress
This commit is contained in:
parent
b6881c829c
commit
4f65957287
19 changed files with 414 additions and 826 deletions
|
@ -18,6 +18,9 @@ import {
|
||||||
import {
|
import {
|
||||||
doAuthenticate
|
doAuthenticate
|
||||||
} from 'actions/user'
|
} from 'actions/user'
|
||||||
|
import {
|
||||||
|
doRewardList
|
||||||
|
} from 'actions/rewards'
|
||||||
import {
|
import {
|
||||||
doFileList
|
doFileList
|
||||||
} from 'actions/file_info'
|
} from 'actions/file_info'
|
||||||
|
|
|
@ -3,7 +3,7 @@ import lbry from "lbry";
|
||||||
import lbryio from "lbryio";
|
import lbryio from "lbryio";
|
||||||
import rewards from "rewards";
|
import rewards from "rewards";
|
||||||
|
|
||||||
export function doFetchRewards() {
|
export function doRewardList() {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
|
||||||
|
@ -11,11 +11,16 @@ export function doFetchRewards() {
|
||||||
type: types.FETCH_REWARDS_STARTED,
|
type: types.FETCH_REWARDS_STARTED,
|
||||||
});
|
});
|
||||||
|
|
||||||
lbryio.call("reward", "list", {}).then(function(userRewards) {
|
lbryio.call('reward', 'list', {}).then((userRewards) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.FETCH_REWARDS_COMPLETED,
|
type: types.FETCH_REWARDS_COMPLETED,
|
||||||
data: { userRewards },
|
data: { userRewards }
|
||||||
});
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
dispatch({
|
||||||
|
type: types.FETCH_REWARDS_COMPLETED,
|
||||||
|
data: { userRewards: [] }
|
||||||
|
})
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {
|
||||||
setLocal
|
setLocal
|
||||||
} from 'utils'
|
} from 'utils'
|
||||||
import {
|
import {
|
||||||
doFetchRewards
|
doRewardList
|
||||||
} from 'actions/rewards'
|
} from 'actions/rewards'
|
||||||
|
|
||||||
export function doAuthenticate() {
|
export function doAuthenticate() {
|
||||||
|
@ -17,7 +17,12 @@ export function doAuthenticate() {
|
||||||
type: types.AUTHENTICATION_SUCCESS,
|
type: types.AUTHENTICATION_SUCCESS,
|
||||||
data: { user }
|
data: { user }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
dispatch(doRewardList()) //FIXME - where should this happen?
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
|
console.log('auth error')
|
||||||
|
console.log(error)
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.AUTHENTICATION_FAILURE,
|
type: types.AUTHENTICATION_FAILURE,
|
||||||
data: { error }
|
data: { error }
|
||||||
|
@ -30,6 +35,7 @@ export function doUserEmailNew(email) {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.USER_EMAIL_NEW_STARTED,
|
type: types.USER_EMAIL_NEW_STARTED,
|
||||||
|
email: email
|
||||||
})
|
})
|
||||||
lbryio.call('user_email', 'new', { email }, 'post').then(() => {
|
lbryio.call('user_email', 'new', { email }, 'post').then(() => {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -59,4 +65,31 @@ export function doUserEmailDecline() {
|
||||||
type: types.USER_EMAIL_DECLINE,
|
type: types.USER_EMAIL_DECLINE,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doUserEmailVerify(email, verificationToken) {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
dispatch({
|
||||||
|
type: types.USER_EMAIL_VERIFY_STARTED,
|
||||||
|
code: code
|
||||||
|
})
|
||||||
|
|
||||||
|
const failure = (error) => {
|
||||||
|
dispatch({
|
||||||
|
type: types.USER_EMAIL_VERIFY_FAILURE,
|
||||||
|
data: { error: error.message }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
lbryio.call('user_email', 'confirm', {verification_token: verificationToken, email: email }, 'post').then((userEmail) => {
|
||||||
|
if (userEmail.is_verified) {
|
||||||
|
dispatch({
|
||||||
|
type: types.USER_EMAIL_VERIFY_SUCCESS,
|
||||||
|
data: { email }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
failure(new Error("Your email is still not verified.")) //shouldn't happen?
|
||||||
|
}
|
||||||
|
}, failure);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,27 +1,22 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {
|
import {
|
||||||
connect,
|
connect
|
||||||
} from 'react-redux'
|
} from 'react-redux'
|
||||||
import {
|
import {
|
||||||
selectFetchingRewards,
|
doUserEmailDecline
|
||||||
selectClaimedRewardsByType,
|
} from 'actions/user'
|
||||||
makeSelectRewardByType,
|
import {
|
||||||
} from 'selectors/rewards'
|
selectAuthenticationIsPending,
|
||||||
import AuthOverlay from './view'
|
selectEmailNewDeclined,
|
||||||
|
selectEmailNewExistingEmail,
|
||||||
|
selectUser,
|
||||||
|
} from 'selectors/user'
|
||||||
|
import Auth from './view'
|
||||||
|
|
||||||
const makeSelect = () => {
|
const select = (state) => ({
|
||||||
const selectRewardByType = makeSelectRewardByType()
|
isPending: selectAuthenticationIsPending(state),
|
||||||
|
existingEmail: selectEmailNewExistingEmail(state),
|
||||||
const select = (state) => ({
|
user: selectUser(state),
|
||||||
fetchingRewards: selectFetchingRewards(state),
|
|
||||||
claimedRewardsByType: selectClaimedRewardsByType(state),
|
|
||||||
newUserReward: selectRewardByType(state, { reward_type: 'new_user' }),
|
|
||||||
})
|
|
||||||
|
|
||||||
return select
|
|
||||||
}
|
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export default connect(makeSelect, perform)(AuthOverlay)
|
export default connect(select, null)(Auth)
|
||||||
|
|
|
@ -1,517 +1,29 @@
|
||||||
import React from "react";
|
import React from 'react'
|
||||||
import lbry from "../lbry.js";
|
import {BusyMessage} from 'component/common'
|
||||||
import lbryio from "../lbryio.js";
|
import UserEmailNew from 'component/userEmailNew'
|
||||||
import Modal from "./modal.js";
|
import UserEmailVerify from 'component/userEmailVerify'
|
||||||
import ModalPage from "./modal-page.js";
|
|
||||||
import Link from "component/link";
|
|
||||||
import { RewardLink } from "component/reward-link";
|
|
||||||
import { FormRow } from "../component/form.js";
|
|
||||||
import { CreditAmount, Address } from "../component/common.js";
|
|
||||||
import { getLocal, setLocal } from "../utils.js";
|
|
||||||
|
|
||||||
class SubmitEmailStage extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
rewardType: null,
|
|
||||||
email: '',
|
|
||||||
showNoEmailConfirm: false,
|
|
||||||
submitting: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
handleEmailChanged(event) {
|
|
||||||
this.setState({
|
|
||||||
email: event.target.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onEmailSaved(email) {
|
|
||||||
this.props.setStage("confirm", { email: email });
|
|
||||||
}
|
|
||||||
|
|
||||||
onEmailSkipClick() {
|
|
||||||
this.setState({ showNoEmailConfirm: true })
|
|
||||||
}
|
|
||||||
|
|
||||||
onEmailSkipConfirm() {
|
|
||||||
setLocal('auth_bypassed', true);
|
|
||||||
this.props.setStage(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSubmit(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
submitting: true,
|
|
||||||
});
|
|
||||||
lbryio.call("user_email", "new", { email: this.state.email }, "post").then(
|
|
||||||
() => {
|
|
||||||
this.onEmailSaved(this.state.email);
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
if (
|
|
||||||
error.xhr &&
|
|
||||||
(error.xhr.status == 409 ||
|
|
||||||
error.message == __("This email is already in use"))
|
|
||||||
) {
|
|
||||||
this.onEmailSaved(this.state.email);
|
|
||||||
return;
|
|
||||||
} else if (this._emailRow) {
|
|
||||||
this._emailRow.showError(error.message);
|
|
||||||
}
|
|
||||||
this.setState({ submitting: false });
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<section>
|
|
||||||
<form onSubmit={(event) => { this.handleSubmit(event) }}>
|
|
||||||
<FormRow ref={(ref) => { this._emailRow = ref }} type="text" label={__("Email")} placeholder="scrwvwls@lbry.io"
|
|
||||||
name="email" value={this.state.email}
|
|
||||||
onChange={(event) => { this.handleEmailChanged(event) }} />
|
|
||||||
<div className="form-row-submit form-row-submit--with-footer">
|
|
||||||
<Link button="primary" label={__("Next")} disabled={this.state.submitting} onClick={(event) => { this.handleSubmit(event) }} />
|
|
||||||
</div>
|
|
||||||
{ this.state.showNoEmailConfirm ?
|
|
||||||
<div>
|
|
||||||
<p className="help form-input-width">If you continue without an email, you will be ineligible to earn free LBC rewards, as well as unable to receive security related communications.</p>
|
|
||||||
<Link className="button-text-help" onClick={ () => { this.onEmailSkipConfirm() }} label="Continue without email" />
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<Link className="button-text-help" onClick={ () => { this.onEmailSkipClick() }} label="Do I have to?" />
|
|
||||||
}
|
|
||||||
</form>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConfirmEmailStage extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
rewardType: null,
|
|
||||||
code: "",
|
|
||||||
submitting: false,
|
|
||||||
errorMessage: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCodeChanged(event) {
|
|
||||||
this.setState({
|
|
||||||
code: event.target.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSubmit(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
this.setState({
|
|
||||||
submitting: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmitError = error => {
|
|
||||||
if (this._codeRow) {
|
|
||||||
this._codeRow.showError(error.message);
|
|
||||||
}
|
|
||||||
this.setState({ submitting: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
lbryio
|
|
||||||
.call(
|
|
||||||
"user_email",
|
|
||||||
"confirm",
|
|
||||||
{ verification_token: this.state.code, email: this.props.email },
|
|
||||||
"post"
|
|
||||||
)
|
|
||||||
.then(userEmail => {
|
|
||||||
if (userEmail.is_verified) {
|
|
||||||
this.props.setStage("welcome");
|
|
||||||
} else {
|
|
||||||
onSubmitError(new Error(__("Your email is still not verified."))); //shouldn't happen?
|
|
||||||
}
|
|
||||||
}, onSubmitError);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<section>
|
|
||||||
<form
|
|
||||||
onSubmit={event => {
|
|
||||||
this.handleSubmit(event);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FormRow
|
|
||||||
label={__("Verification Code")}
|
|
||||||
ref={ref => {
|
|
||||||
this._codeRow = ref;
|
|
||||||
}}
|
|
||||||
type="text"
|
|
||||||
name="code"
|
|
||||||
placeholder="a94bXXXXXXXXXXXXXX"
|
|
||||||
value={this.state.code}
|
|
||||||
onChange={event => {
|
|
||||||
this.handleCodeChanged(event);
|
|
||||||
}}
|
|
||||||
helper={__(
|
|
||||||
"A verification code is required to access this version."
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<div className="form-row-submit form-row-submit--with-footer">
|
|
||||||
<Link
|
|
||||||
button="primary"
|
|
||||||
label={__("Verify")}
|
|
||||||
disabled={this.state.submitting}
|
|
||||||
onClick={event => {
|
|
||||||
this.handleSubmit(event);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="form-field__helper">
|
|
||||||
{__("No code?")}
|
|
||||||
{" "}
|
|
||||||
<Link
|
|
||||||
onClick={() => {
|
|
||||||
this.props.setStage("nocode");
|
|
||||||
}}
|
|
||||||
label={__("Click here")}
|
|
||||||
/>.
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WelcomeStage extends React.Component {
|
|
||||||
static propTypes = {
|
|
||||||
endAuth: React.PropTypes.func,
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
hasReward: true,
|
|
||||||
rewardAmount: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onRewardClaim(reward) {
|
|
||||||
this.setState({
|
|
||||||
hasReward: true,
|
|
||||||
rewardAmount: reward.amount,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
export class Auth extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
claimedRewardsByType,
|
isPending,
|
||||||
fetchingRewards,
|
existingEmail,
|
||||||
newUserReward,
|
user,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const hasReward = claimedRewardsByType.length > 0
|
console.log('auth render')
|
||||||
|
console.log(this.props)
|
||||||
|
|
||||||
if (fetchingRewards) return null
|
if (isPending) {
|
||||||
if (!newUserReward) return null
|
return <BusyMessage message="Authenticating" />
|
||||||
|
} else if (!existingEmail && !user.has_email) {
|
||||||
return !hasReward
|
return <UserEmailNew />
|
||||||
? <Modal
|
} else if (!user.has_verified_email) {
|
||||||
type="custom"
|
return <UserEmailVerify />
|
||||||
isOpen={true}
|
} else {
|
||||||
contentLabel={__("Welcome to LBRY")}
|
return <span className="empty">Auth is done fix this yo</span>
|
||||||
{...this.props}
|
}
|
||||||
>
|
|
||||||
<section>
|
|
||||||
<h3 className="modal__header">{__("Welcome to LBRY.")}</h3>
|
|
||||||
<p>
|
|
||||||
{__(
|
|
||||||
"Using LBRY is like dating a centaur. Totally normal up top, and way different underneath."
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>{__("Up top, LBRY is similar to popular media sites.")}</p>
|
|
||||||
<p>
|
|
||||||
{__(
|
|
||||||
"Below, LBRY is controlled by users -- you -- via blockchain and decentralization."
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{__(
|
|
||||||
"Thank you for making content freedom possible! Here's a nickel, kid."
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<div style={{ textAlign: "center", marginBottom: "12px" }}>
|
|
||||||
<RewardLink
|
|
||||||
type="new_user"
|
|
||||||
button="primary"
|
|
||||||
onRewardClaim={event => {
|
|
||||||
this.onRewardClaim(event);
|
|
||||||
}}
|
|
||||||
onRewardFailure={() => this.props.setStage(null)}
|
|
||||||
onConfirmed={() => {
|
|
||||||
this.props.setStage(null);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</Modal>
|
|
||||||
: <Modal
|
|
||||||
type="alert"
|
|
||||||
overlayClassName="modal-overlay modal-overlay--clear"
|
|
||||||
isOpen={true}
|
|
||||||
contentLabel={__("Welcome to LBRY")}
|
|
||||||
{...this.props}
|
|
||||||
onConfirmed={() => {
|
|
||||||
this.props.setStage(null);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<section>
|
|
||||||
<h3 className="modal__header">{__("About Your Reward")}</h3>
|
|
||||||
<p>
|
|
||||||
{__("You earned a reward of ")}
|
|
||||||
{" "}
|
|
||||||
<CreditAmount amount={this.state.rewardAmount} label={false} />
|
|
||||||
{" "}{__('LBRY credits, or "LBC".')}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{__(
|
|
||||||
"This reward will show in your Wallet momentarily, probably while you are reading this message."
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{__(
|
|
||||||
"LBC is used to compensate creators, to publish, and to have say in how the network works."
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{__(
|
|
||||||
"No need to understand it all just yet! Try watching or downloading something next."
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{__(
|
|
||||||
"Finally, know that LBRY is an early beta and that it earns the name."
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
</Modal>;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ErrorStage = props => {
|
export default Auth
|
||||||
return (
|
|
||||||
<section>
|
|
||||||
<p>{__("An error was encountered that we cannot continue from.")}</p>
|
|
||||||
<p>{__("At least we're earning the name beta.")}</p>
|
|
||||||
{props.errorText ? <p>{__("Message:")} {props.errorText}</p> : ""}
|
|
||||||
<Link
|
|
||||||
button="alt"
|
|
||||||
label={__("Try Reload")}
|
|
||||||
onClick={() => {
|
|
||||||
window.location.reload();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const PendingStage = props => {
|
|
||||||
return (
|
|
||||||
<section>
|
|
||||||
<p>
|
|
||||||
{__("Preparing for first access")} <span className="busy-indicator" />
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
class CodeRequiredStage extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this._balanceSubscribeId = null;
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
balance: 0,
|
|
||||||
address: getLocal("wallet_address"),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillMount() {
|
|
||||||
this._balanceSubscribeId = lbry.balanceSubscribe(balance => {
|
|
||||||
this.setState({
|
|
||||||
balance: balance,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!this.state.address) {
|
|
||||||
lbry.wallet_unused_address().then(address => {
|
|
||||||
setLocal("wallet_address", address);
|
|
||||||
this.setState({ address: address });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
if (this._balanceSubscribeId) {
|
|
||||||
lbry.balanceUnsubscribe(this._balanceSubscribeId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const disabled = this.state.balance < 1;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<section className="section-spaced">
|
|
||||||
<p>
|
|
||||||
{__(
|
|
||||||
"Early access to LBRY is restricted as we build and scale the network."
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>{__("There are two ways in:")}</p>
|
|
||||||
<h3>{__("Own LBRY Credits")}</h3>
|
|
||||||
<p>{__("If you own at least 1 LBC, you can get in right now.")}</p>
|
|
||||||
<p style={{ textAlign: "center" }}>
|
|
||||||
<Link
|
|
||||||
onClick={() => {
|
|
||||||
setLocal("auth_bypassed", true);
|
|
||||||
this.props.setStage(null);
|
|
||||||
}}
|
|
||||||
disabled={disabled}
|
|
||||||
label={__("Let Me In")}
|
|
||||||
button={disabled ? "alt" : "primary"}
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{__("Your balance is ")}<CreditAmount
|
|
||||||
amount={this.state.balance}
|
|
||||||
/>. {__("To increase your balance, send credits to this address:")}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<Address
|
|
||||||
address={
|
|
||||||
this.state.address
|
|
||||||
? this.state.address
|
|
||||||
: __("Generating Address...")
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
<p>{__("If you don't understand how to send credits, then...")}</p>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h3>{__("Wait For A Code")}</h3>
|
|
||||||
<p>
|
|
||||||
{__(
|
|
||||||
"If you provide your email, you'll automatically receive a notification when the system is open."
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<Link
|
|
||||||
onClick={() => {
|
|
||||||
this.props.setStage("email");
|
|
||||||
}}
|
|
||||||
label={__("Return")}
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AuthOverlay extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this._stages = {
|
|
||||||
pending: PendingStage,
|
|
||||||
error: ErrorStage,
|
|
||||||
nocode: CodeRequiredStage,
|
|
||||||
email: SubmitEmailStage,
|
|
||||||
confirm: ConfirmEmailStage,
|
|
||||||
welcome: WelcomeStage,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
stage: "pending",
|
|
||||||
stageProps: {},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
setStage(stage, stageProps = {}) {
|
|
||||||
this.setState({
|
|
||||||
stage: stage,
|
|
||||||
stageProps: stageProps,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillMount() {
|
|
||||||
lbryio
|
|
||||||
.authenticate()
|
|
||||||
.then(user => {
|
|
||||||
if (!user.has_verified_email) {
|
|
||||||
if (getLocal("auth_bypassed")) {
|
|
||||||
this.setStage(null);
|
|
||||||
} else {
|
|
||||||
this.setStage("email", {});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const {
|
|
||||||
claimedRewardsByType,
|
|
||||||
} = this.props
|
|
||||||
claimedRewardsByType[rewards.TYPE_NEW_USER] ? this.setStage(null) : this.setStage("welcome")
|
|
||||||
}})
|
|
||||||
.catch(err => {
|
|
||||||
this.setStage("error", { errorText: err.message });
|
|
||||||
document.dispatchEvent(
|
|
||||||
new CustomEvent("unhandledError", {
|
|
||||||
detail: {
|
|
||||||
message: err.message,
|
|
||||||
data: err.stack,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (!this.state.stage) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const StageContent = this._stages[this.state.stage];
|
|
||||||
|
|
||||||
if (!StageContent) {
|
|
||||||
return (
|
|
||||||
<span className="empty">{__("Unknown authentication step.")}</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.state.stage != "welcome"
|
|
||||||
? <ModalPage
|
|
||||||
className="modal-page--full"
|
|
||||||
isOpen={true}
|
|
||||||
contentLabel={__("Authentication")}
|
|
||||||
>
|
|
||||||
<h1>{__("LBRY Early Access")}</h1>
|
|
||||||
<StageContent
|
|
||||||
{...this.state.stageProps}
|
|
||||||
setStage={(stage, stageProps) => {
|
|
||||||
this.setStage(stage, stageProps);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ModalPage>
|
|
||||||
: <StageContent
|
|
||||||
setStage={(stage, stageProps) => {
|
|
||||||
this.setStage(stage, stageProps);
|
|
||||||
}}
|
|
||||||
{...this.state.stageProps}
|
|
||||||
/>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AuthOverlay
|
|
||||||
|
|
|
@ -1,17 +1,10 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import lbry from "lbry.js";
|
|
||||||
import lbryio from "lbryio.js";
|
|
||||||
import Modal from "component/modal.js";
|
|
||||||
import ModalPage from "component/modal-page.js";
|
import ModalPage from "component/modal-page.js";
|
||||||
|
import {BusyMessage} from 'component/common'
|
||||||
|
import Auth from 'component/auth'
|
||||||
import Link from "component/link"
|
import Link from "component/link"
|
||||||
import {BusyMessage} from "component/common"
|
|
||||||
import {RewardLink} from 'component/rewardLink';
|
|
||||||
import UserEmailNew from 'component/userEmailNew';
|
|
||||||
import {FormRow} from "component/form.js";
|
|
||||||
import {CreditAmount, Address} from "component/common.js";
|
|
||||||
import {getLocal, setLocal} from 'utils.js';
|
|
||||||
|
|
||||||
class EmailStage extends React.Component {
|
export class AuthOverlay extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
@ -29,9 +22,19 @@ class EmailStage extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
const {
|
||||||
<section>
|
isPending,
|
||||||
<UserEmailNew />
|
isEmailDeclined,
|
||||||
|
user,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
if (!isEmailDeclined && (isPending || (user && !user.has_email))) {
|
||||||
|
return <ModalPage className="modal-page--full" isOpen={true} contentLabel="Authentication">
|
||||||
|
<h1>LBRY Early Access</h1>
|
||||||
|
{ isPending ?
|
||||||
|
<BusyMessage message="Preparing for early access" /> :
|
||||||
|
<Auth /> }
|
||||||
|
{ isPending ? '' :
|
||||||
<div className="form-row-submit">
|
<div className="form-row-submit">
|
||||||
{ this.state.showNoEmailConfirm ?
|
{ this.state.showNoEmailConfirm ?
|
||||||
<div>
|
<div>
|
||||||
|
@ -41,282 +44,136 @@ class EmailStage extends React.Component {
|
||||||
:
|
:
|
||||||
<Link className="button-text-help" onClick={ () => { this.onEmailSkipClick() }} label="Do I have to?" />
|
<Link className="button-text-help" onClick={ () => { this.onEmailSkipClick() }} label="Do I have to?" />
|
||||||
}
|
}
|
||||||
</div>
|
</div> }
|
||||||
</section>
|
</ModalPage>
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConfirmEmailStage extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
code: '',
|
|
||||||
submitting: false,
|
|
||||||
errorMessage: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCodeChanged(event) {
|
|
||||||
this.setState({
|
|
||||||
code: event.target.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSubmit(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
this.setState({
|
|
||||||
submitting: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmitError = (error) => {
|
|
||||||
if (this._codeRow) {
|
|
||||||
this._codeRow.showError(error.message)
|
|
||||||
}
|
|
||||||
this.setState({ submitting: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
lbryio.call('user_email', 'confirm', {verification_token: this.state.code, email: this.props.email}, 'post').then((userEmail) => {
|
|
||||||
if (userEmail.is_verified) {
|
|
||||||
this.props.setStage("welcome")
|
|
||||||
} else {
|
|
||||||
onSubmitError(new Error("Your email is still not verified.")) //shouldn't happen?
|
|
||||||
}
|
|
||||||
}, onSubmitError);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<section>
|
|
||||||
<form onSubmit={(event) => { this.handleSubmit(event) }}>
|
|
||||||
<FormRow label="Verification Code" ref={(ref) => { this._codeRow = ref }} type="text"
|
|
||||||
name="code" placeholder="a94bXXXXXXXXXXXXXX" value={this.state.code} onChange={(event) => { this.handleCodeChanged(event) }}
|
|
||||||
helper="A verification code is required to access this version."/>
|
|
||||||
<div className="form-row-submit form-row-submit--with-footer">
|
|
||||||
<Link button="primary" label="Verify" disabled={this.state.submitting} onClick={(event) => { this.handleSubmit(event)}} />
|
|
||||||
</div>
|
|
||||||
<div className="form-field__helper">
|
|
||||||
No code? <Link onClick={() => { this.props.setStage("nocode")}} label="Click here" />.
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WelcomeStage extends React.Component {
|
|
||||||
static propTypes = {
|
|
||||||
endAuth: React.PropTypes.func,
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
hasReward: false,
|
|
||||||
rewardAmount: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onRewardClaim(reward) {
|
|
||||||
this.setState({
|
|
||||||
hasReward: true,
|
|
||||||
rewardAmount: reward.amount
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
!this.state.hasReward ?
|
|
||||||
<Modal type="custom" isOpen={true} contentLabel="Welcome to LBRY" {...this.props}>
|
|
||||||
<section>
|
|
||||||
<h3 className="modal__header">Welcome to LBRY.</h3>
|
|
||||||
<p>Using LBRY is like dating a centaur. Totally normal up top, and <em>way different</em> underneath.</p>
|
|
||||||
<p>Up top, LBRY is similar to popular media sites.</p>
|
|
||||||
<p>Below, LBRY is controlled by users -- you -- via blockchain and decentralization.</p>
|
|
||||||
<p>Thank you for making content freedom possible! Here's a nickel, kid.</p>
|
|
||||||
<div style={{textAlign: "center", marginBottom: "12px"}}>
|
|
||||||
<RewardLink type="new_user" button="primary" onRewardClaim={(event) => { this.onRewardClaim(event) }} onRewardFailure={() => this.props.setStage(null)} onConfirmed={() => { this.props.setStage(null) }} />
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</Modal> :
|
|
||||||
<Modal type="alert" overlayClassName="modal-overlay modal-overlay--clear" isOpen={true} contentLabel="Welcome to LBRY" {...this.props} onConfirmed={() => { this.props.setStage(null) }}>
|
|
||||||
<section>
|
|
||||||
<h3 className="modal__header">About Your Reward</h3>
|
|
||||||
<p>You earned a reward of <CreditAmount amount={this.state.rewardAmount} label={false} /> LBRY credits, or <em>LBC</em>.</p>
|
|
||||||
<p>This reward will show in your Wallet momentarily, probably while you are reading this message.</p>
|
|
||||||
<p>LBC is used to compensate creators, to publish, and to have say in how the network works.</p>
|
|
||||||
<p>No need to understand it all just yet! Try watching or downloading something next.</p>
|
|
||||||
<p>Finally, know that LBRY is an early beta and that it earns the name.</p>
|
|
||||||
</section>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const ErrorStage = (props) => {
|
|
||||||
return <section>
|
|
||||||
<p>An error was encountered that we cannot continue from.</p>
|
|
||||||
<p>At least we're earning the name beta.</p>
|
|
||||||
{ props.errorText ? <p>Message: {props.errorText}</p> : '' }
|
|
||||||
<Link button="alt" label="Try Reload" onClick={() => { window.location.reload() } } />
|
|
||||||
</section>
|
|
||||||
}
|
|
||||||
|
|
||||||
const PendingStage = (props) => {
|
|
||||||
return <section>
|
|
||||||
<BusyMessage message="Authenticating" />
|
|
||||||
</section>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class CodeRequiredStage extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this._balanceSubscribeId = null
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
balance: 0,
|
|
||||||
address: getLocal('wallet_address')
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillMount() {
|
|
||||||
this._balanceSubscribeId = lbry.balanceSubscribe((balance) => {
|
|
||||||
this.setState({
|
|
||||||
balance: balance
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!this.state.address) {
|
|
||||||
lbry.wallet_unused_address().then((address) => {
|
|
||||||
setLocal('wallet_address', address);
|
|
||||||
this.setState({ address: address });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
if (this._balanceSubscribeId) {
|
|
||||||
lbry.balanceUnsubscribe(this._balanceSubscribeId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const disabled = this.state.balance < 1;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<section className="section-spaced">
|
|
||||||
<p>Early access to LBRY is restricted as we build and scale the network.</p>
|
|
||||||
<p>There are two ways in.</p>
|
|
||||||
<h3>Own LBRY Credits</h3>
|
|
||||||
<p>If you own at least 1 LBC, you can get in right now.</p>
|
|
||||||
<p style={{ textAlign: "center"}}><Link onClick={() => { setLocal('auth_bypassed', true); this.props.setStage(null); }}
|
|
||||||
disabled={disabled} label="Let Me In" button={ disabled ? "alt" : "primary" } /></p>
|
|
||||||
<p>Your balance is <CreditAmount amount={this.state.balance} />. To increase your balance, send credits to this address:</p>
|
|
||||||
<p><Address address={ this.state.address ? this.state.address : "Generating Address..." } /></p>
|
|
||||||
<p>If you don't understand how to send credits, then...</p>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h3>Wait For A Code</h3>
|
|
||||||
<p>If you provide your email, you'll automatically receive a notification when the system is open.</p>
|
|
||||||
<p><Link onClick={() => { this.props.setStage("email"); }} label="Return" /></p>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class AuthOverlay extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this._stages = {
|
|
||||||
error: ErrorStage,
|
|
||||||
nocode: CodeRequiredStage,
|
|
||||||
confirm: ConfirmEmailStage,
|
|
||||||
welcome: WelcomeStage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setStage(stage, stageProps = {}) {
|
|
||||||
this.setState({
|
|
||||||
stage: stage,
|
|
||||||
stageProps: stageProps
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillMount() {
|
|
||||||
// lbryio.authenticate().then((user) => {
|
|
||||||
// if (!user.has_verified_email) {
|
|
||||||
// if (getLocal('auth_bypassed')) {
|
|
||||||
// this.setStage(null)
|
|
||||||
// } else {
|
|
||||||
// this.setStage("email", {})
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// lbryio.call('reward', 'list', {}).then((userRewards) => {
|
|
||||||
// userRewards.filter(function(reward) {
|
|
||||||
// return reward.reward_type == rewards.TYPE_NEW_USER && reward.transaction_id;
|
|
||||||
// }).length ?
|
|
||||||
// this.setStage(null) :
|
|
||||||
// this.setStage("welcome")
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }).catch((err) => {
|
|
||||||
// this.setStage("error", { errorText: err.message })
|
|
||||||
// document.dispatchEvent(new CustomEvent('unhandledError', {
|
|
||||||
// detail: {
|
|
||||||
// message: err.message,
|
|
||||||
// data: err.stack
|
|
||||||
// }
|
|
||||||
// }));
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let stageContent
|
|
||||||
|
|
||||||
const {
|
|
||||||
isPending,
|
|
||||||
isEmailDeclined,
|
|
||||||
user,
|
|
||||||
userEmailDecline
|
|
||||||
} = this.props
|
|
||||||
|
|
||||||
console.log('auth overlay render')
|
|
||||||
console.log(user)
|
|
||||||
|
|
||||||
if (isEmailDeclined) {
|
|
||||||
return null
|
|
||||||
} else if (isPending) {
|
|
||||||
stageContent = <PendingStage />;
|
|
||||||
} else if (!user.has_email) {
|
|
||||||
stageContent = <EmailStage userEmailDecline={userEmailDecline} />;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null
|
|
||||||
//StageContent = this._stages[this.state.stage];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return <ModalPage className="modal-page--full" isOpen={true} contentLabel="Authentication">
|
return null
|
||||||
<h1>LBRY Early Access</h1>
|
|
||||||
{stageContent}
|
|
||||||
</ModalPage>;
|
|
||||||
|
|
||||||
//setStage={(stage, stageProps) => { this.setStage(stage, stageProps) }} {...this.state.stageProps}
|
|
||||||
return (
|
|
||||||
true || this.state.stage != "welcome" ?
|
|
||||||
<ModalPage className="modal-page--full" isOpen={true} contentLabel="Authentication">
|
|
||||||
<h1>LBRY Early Access</h1>
|
|
||||||
<StageContent />
|
|
||||||
</ModalPage> :
|
|
||||||
<StageContent />
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AuthOverlay
|
export default AuthOverlay
|
||||||
|
|
||||||
|
// class WelcomeStage extends React.Component {
|
||||||
|
// static propTypes = {
|
||||||
|
// endAuth: React.PropTypes.func,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// constructor(props) {
|
||||||
|
// super(props);
|
||||||
|
//
|
||||||
|
// this.state = {
|
||||||
|
// hasReward: false,
|
||||||
|
// rewardAmount: null,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// onRewardClaim(reward) {
|
||||||
|
// this.setState({
|
||||||
|
// hasReward: true,
|
||||||
|
// rewardAmount: reward.amount
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// render() {
|
||||||
|
// return (
|
||||||
|
// !this.state.hasReward ?
|
||||||
|
// <Modal type="custom" isOpen={true} contentLabel="Welcome to LBRY" {...this.props}>
|
||||||
|
// <section>
|
||||||
|
// <h3 className="modal__header">Welcome to LBRY.</h3>
|
||||||
|
// <p>Using LBRY is like dating a centaur. Totally normal up top, and <em>way different</em> underneath.</p>
|
||||||
|
// <p>Up top, LBRY is similar to popular media sites.</p>
|
||||||
|
// <p>Below, LBRY is controlled by users -- you -- via blockchain and decentralization.</p>
|
||||||
|
// <p>Thank you for making content freedom possible! Here's a nickel, kid.</p>
|
||||||
|
// <div style={{textAlign: "center", marginBottom: "12px"}}>
|
||||||
|
// <RewardLink type="new_user" button="primary" onRewardClaim={(event) => { this.onRewardClaim(event) }} onRewardFailure={() => this.props.setStage(null)} onConfirmed={() => { this.props.setStage(null) }} />
|
||||||
|
// </div>
|
||||||
|
// </section>
|
||||||
|
// </Modal> :
|
||||||
|
// <Modal type="alert" overlayClassName="modal-overlay modal-overlay--clear" isOpen={true} contentLabel="Welcome to LBRY" {...this.props} onConfirmed={() => { this.props.setStage(null) }}>
|
||||||
|
// <section>
|
||||||
|
// <h3 className="modal__header">About Your Reward</h3>
|
||||||
|
// <p>You earned a reward of <CreditAmount amount={this.state.rewardAmount} label={false} /> LBRY credits, or <em>LBC</em>.</p>
|
||||||
|
// <p>This reward will show in your Wallet momentarily, probably while you are reading this message.</p>
|
||||||
|
// <p>LBC is used to compensate creators, to publish, and to have say in how the network works.</p>
|
||||||
|
// <p>No need to understand it all just yet! Try watching or downloading something next.</p>
|
||||||
|
// <p>Finally, know that LBRY is an early beta and that it earns the name.</p>
|
||||||
|
// </section>
|
||||||
|
// </Modal>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// // }
|
||||||
|
// //
|
||||||
|
// // const ErrorStage = (props) => {
|
||||||
|
// // return <section>
|
||||||
|
// // <p>An error was encountered that we cannot continue from.</p>
|
||||||
|
// // <p>At least we're earning the name beta.</p>
|
||||||
|
// // { props.errorText ? <p>Message: {props.errorText}</p> : '' }
|
||||||
|
// // <Link button="alt" label="Try Reload" onClick={() => { window.location.reload() } } />
|
||||||
|
// // </section>
|
||||||
|
// // }
|
||||||
|
// // //
|
||||||
|
// // // const PendingStage = (props) => {
|
||||||
|
// // // return <section>
|
||||||
|
// // // <BusyMessage message="Authenticating" />
|
||||||
|
// // // </section>
|
||||||
|
// // // }
|
||||||
|
// // // //
|
||||||
|
// // // //
|
||||||
|
// // // // class CodeRequiredStage extends React.Component {
|
||||||
|
// // // // constructor(props) {
|
||||||
|
// // // // super(props);
|
||||||
|
// // // //
|
||||||
|
// // // // this._balanceSubscribeId = null
|
||||||
|
// // // //
|
||||||
|
// // // // this.state = {
|
||||||
|
// // // // balance: 0,
|
||||||
|
// // // // address: getLocal('wallet_address')
|
||||||
|
// // // // };
|
||||||
|
// // // // }
|
||||||
|
// // // //
|
||||||
|
// // // // componentWillMount() {
|
||||||
|
// // // // this._balanceSubscribeId = lbry.balanceSubscribe((balance) => {
|
||||||
|
// // // // this.setState({
|
||||||
|
// // // // balance: balance
|
||||||
|
// // // // });
|
||||||
|
// // // // })
|
||||||
|
// // // //
|
||||||
|
// // // // if (!this.state.address) {
|
||||||
|
// // // // lbry.wallet_unused_address().then((address) => {
|
||||||
|
// // // // setLocal('wallet_address', address);
|
||||||
|
// // // // this.setState({ address: address });
|
||||||
|
// // // // });
|
||||||
|
// // // // }
|
||||||
|
// // // // }
|
||||||
|
// // // //
|
||||||
|
// // // // componentWillUnmount() {
|
||||||
|
// // // // if (this._balanceSubscribeId) {
|
||||||
|
// // // // lbry.balanceUnsubscribe(this._balanceSubscribeId)
|
||||||
|
// // // // }
|
||||||
|
// // // // }
|
||||||
|
// // // //
|
||||||
|
// // // // render() {
|
||||||
|
// // // // const disabled = this.state.balance < 1;
|
||||||
|
// // // // return (
|
||||||
|
// // // // <div>
|
||||||
|
// // // // <section className="section-spaced">
|
||||||
|
// // // // <p>Early access to LBRY is restricted as we build and scale the network.</p>
|
||||||
|
// // // // <p>There are two ways in.</p>
|
||||||
|
// // // // <h3>Own LBRY Credits</h3>
|
||||||
|
// // // // <p>If you own at least 1 LBC, you can get in right now.</p>
|
||||||
|
// // // // <p style={{ textAlign: "center"}}><Link onClick={() => { setLocal('auth_bypassed', true); this.props.setStage(null); }}
|
||||||
|
// // // // disabled={disabled} label="Let Me In" button={ disabled ? "alt" : "primary" } /></p>
|
||||||
|
// // // // <p>Your balance is <CreditAmount amount={this.state.balance} />. To increase your balance, send credits to this address:</p>
|
||||||
|
// // // // <p><Address address={ this.state.address ? this.state.address : "Generating Address..." } /></p>
|
||||||
|
// // // // <p>If you don't understand how to send credits, then...</p>
|
||||||
|
// // // // </section>
|
||||||
|
// // // // <section>
|
||||||
|
// // // // <h3>Wait For A Code</h3>
|
||||||
|
// // // // <p>If you provide your email, you'll automatically receive a notification when the system is open.</p>
|
||||||
|
// // // // <p><Link onClick={() => { this.props.setStage("email"); }} label="Return" /></p>
|
||||||
|
// // // // </section>
|
||||||
|
// // // // </div>
|
||||||
|
// // // // );
|
||||||
|
// // // // }
|
||||||
|
// // // // }
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import AuthPage from 'page/auth';
|
||||||
import SettingsPage from "page/settings";
|
import SettingsPage from "page/settings";
|
||||||
import HelpPage from "page/help";
|
import HelpPage from "page/help";
|
||||||
import ReportPage from "page/report.js";
|
import ReportPage from "page/report.js";
|
||||||
|
@ -41,6 +42,7 @@ const Router = props => {
|
||||||
discover: <DiscoverPage {...params} />,
|
discover: <DiscoverPage {...params} />,
|
||||||
rewards: <RewardsPage {...params} />,
|
rewards: <RewardsPage {...params} />,
|
||||||
search: <SearchPage {...params} />,
|
search: <SearchPage {...params} />,
|
||||||
|
"account-verification": <AuthPage {...params} />
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
25
ui/js/component/userEmailVerify/index.jsx
Normal file
25
ui/js/component/userEmailVerify/index.jsx
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {
|
||||||
|
connect
|
||||||
|
} from 'react-redux'
|
||||||
|
import {
|
||||||
|
doUserEmailVerify
|
||||||
|
} from 'actions/user'
|
||||||
|
import {
|
||||||
|
selectEmailVerifyIsPending,
|
||||||
|
selectEmailNewExistingEmail,
|
||||||
|
selectEmailVerifyErrorMessage,
|
||||||
|
} from 'selectors/user'
|
||||||
|
import UserEmailVerify from './view'
|
||||||
|
|
||||||
|
const select = (state) => ({
|
||||||
|
isPending: selectEmailVerifyIsPending(state),
|
||||||
|
email: selectEmailNewExistingEmail,
|
||||||
|
errorMessage: selectEmailVerifyErrorMessage(state),
|
||||||
|
})
|
||||||
|
|
||||||
|
const perform = (dispatch) => ({
|
||||||
|
verifyUserEmail: (email, code) => dispatch(doUserEmailVerify(email, code))
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(select, perform)(UserEmailVerify)
|
47
ui/js/component/userEmailVerify/view.jsx
Normal file
47
ui/js/component/userEmailVerify/view.jsx
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import React from 'react';
|
||||||
|
import Link from 'component/link';
|
||||||
|
import {FormRow} from 'component/form.js';
|
||||||
|
|
||||||
|
class UserEmailVerify extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
code: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCodeChanged(event) {
|
||||||
|
this.setState({
|
||||||
|
code: event.target.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSubmit(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.props.verifyUserEmail(this.state.code)
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// <div className="form-field__helper">
|
||||||
|
// No code? <Link onClick={() => { this.props.setStage("nocode")}} label="Click here" />.
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
errorMessage,
|
||||||
|
isPending
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
return <form onSubmit={(event) => { this.handleSubmit(event) }}>
|
||||||
|
<FormRow type="text" label="Verification Code" placeholder="a94bXXXXXXXXXXXXXX"
|
||||||
|
name="code" value={this.state.code} onChange={(event) => { this.handleCodeChanged(event) }}
|
||||||
|
errorMessage={errorMessage}
|
||||||
|
helper="A verification code is required to access this version."/>
|
||||||
|
<div className="form-row-submit form-row-submit--with-footer">
|
||||||
|
<Link button="primary" label="Verify" disabled={this.state.submitting} onClick={(event) => { this.handleSubmit(event)}} />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UserEmailVerify
|
|
@ -79,6 +79,9 @@ export const USER_EMAIL_NEW_STARTED = 'USER_EMAIL_NEW_STARTED'
|
||||||
export const USER_EMAIL_NEW_SUCCESS = 'USER_EMAIL_NEW_SUCCESS'
|
export const USER_EMAIL_NEW_SUCCESS = 'USER_EMAIL_NEW_SUCCESS'
|
||||||
export const USER_EMAIL_NEW_EXISTS = 'USER_EMAIL_NEW_EXISTS'
|
export const USER_EMAIL_NEW_EXISTS = 'USER_EMAIL_NEW_EXISTS'
|
||||||
export const USER_EMAIL_NEW_FAILURE = 'USER_EMAIL_NEW_FAILURE'
|
export const USER_EMAIL_NEW_FAILURE = 'USER_EMAIL_NEW_FAILURE'
|
||||||
|
export const USER_EMAIL_VERIFY_STARTED = 'USER_EMAIL_VERIFY_STARTED'
|
||||||
|
export const USER_EMAIL_VERIFY_SUCCESS = 'USER_EMAIL_VERIFY_SUCCESS'
|
||||||
|
export const USER_EMAIL_VERIFY_FAILURE = 'USER_EMAIL_VERIFY_FAILURE'
|
||||||
|
|
||||||
// Rewards
|
// Rewards
|
||||||
export const FETCH_REWARDS_STARTED = 'FETCH_REWARDS_STARTED'
|
export const FETCH_REWARDS_STARTED = 'FETCH_REWARDS_STARTED'
|
||||||
|
|
|
@ -144,7 +144,7 @@ lbryio.authenticate = function() {
|
||||||
lbryio._authenticationPromise = new Promise((resolve, reject) => {
|
lbryio._authenticationPromise = new Promise((resolve, reject) => {
|
||||||
lbry.status().then((response) => {
|
lbry.status().then((response) => {
|
||||||
|
|
||||||
let installation_id = response.installation_id.substring(0, response.installation_id.length - 2) + "D";
|
let installation_id = response.installation_id.substring(0, response.installation_id.length - 2) + "E";
|
||||||
|
|
||||||
function setCurrentUser() {
|
function setCurrentUser() {
|
||||||
lbryio.call('user', 'me').then((data) => {
|
lbryio.call('user', 'me').then((data) => {
|
||||||
|
|
25
ui/js/page/auth/index.jsx
Normal file
25
ui/js/page/auth/index.jsx
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {
|
||||||
|
connect
|
||||||
|
} from 'react-redux'
|
||||||
|
import {
|
||||||
|
doUserEmailDecline
|
||||||
|
} from 'actions/user'
|
||||||
|
import {
|
||||||
|
selectAuthenticationIsPending,
|
||||||
|
selectEmailNewDeclined,
|
||||||
|
selectUser,
|
||||||
|
} from 'selectors/user'
|
||||||
|
import AuthPage from './view'
|
||||||
|
|
||||||
|
const select = (state) => ({
|
||||||
|
isPending: selectAuthenticationIsPending(state),
|
||||||
|
isEmailDeclined: selectEmailNewDeclined(state),
|
||||||
|
user: selectUser(state),
|
||||||
|
})
|
||||||
|
|
||||||
|
const perform = (dispatch) => ({
|
||||||
|
userEmailDecline: () => dispatch(doUserEmailDecline())
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(select, perform)(AuthPage)
|
19
ui/js/page/auth/view.jsx
Normal file
19
ui/js/page/auth/view.jsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import React from 'react'
|
||||||
|
import Auth from 'component/auth'
|
||||||
|
|
||||||
|
export class AuthPage extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <main className="main--single-column">
|
||||||
|
<section className="card">
|
||||||
|
<div className="card__inner">
|
||||||
|
<div className="card__title-identity"><h1>Early Access Verification</h1></div>
|
||||||
|
</div>
|
||||||
|
<div className="card__content">
|
||||||
|
<Auth />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AuthPage
|
|
@ -2,19 +2,27 @@ import React from 'react'
|
||||||
import {
|
import {
|
||||||
connect,
|
connect,
|
||||||
} from 'react-redux'
|
} from 'react-redux'
|
||||||
|
import {
|
||||||
|
doNavigate
|
||||||
|
} from 'actions/app'
|
||||||
import {
|
import {
|
||||||
selectFetchingRewards,
|
selectFetchingRewards,
|
||||||
selectIsRewardEligible,
|
selectIsRewardEligible,
|
||||||
selectRewards,
|
selectRewards,
|
||||||
} from 'selectors/rewards'
|
} from 'selectors/rewards'
|
||||||
|
import {
|
||||||
|
selectUserIsRewardEligible
|
||||||
|
} from 'selectors/user'
|
||||||
import RewardsPage from './view'
|
import RewardsPage from './view'
|
||||||
|
|
||||||
const select = (state) => ({
|
const select = (state) => ({
|
||||||
fetching: selectFetchingRewards(state),
|
fetching: selectFetchingRewards(state),
|
||||||
rewards: selectRewards(state),
|
rewards: selectRewards(state),
|
||||||
|
isEligible: selectUserIsRewardEligible(state)
|
||||||
})
|
})
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
|
navigateToAuth: () => dispatch(doNavigate('/account-verification'))
|
||||||
})
|
})
|
||||||
|
|
||||||
export default connect(select, perform)(RewardsPage)
|
export default connect(select, perform)(RewardsPage)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import lbryio from 'lbryio';
|
import lbryio from 'lbryio';
|
||||||
import {CreditAmount, Icon} from 'component/common';
|
import {BusyMessage, CreditAmount, Icon} from 'component/common';
|
||||||
import SubHeader from 'component/subHeader'
|
import SubHeader from 'component/subHeader'
|
||||||
|
import Link from 'component/link'
|
||||||
import RewardLink from 'component/rewardLink';
|
import RewardLink from 'component/rewardLink';
|
||||||
|
|
||||||
const RewardTile = (props) => {
|
const RewardTile = (props) => {
|
||||||
|
@ -32,15 +33,24 @@ const RewardTile = (props) => {
|
||||||
const RewardsPage = (props) => {
|
const RewardsPage = (props) => {
|
||||||
const {
|
const {
|
||||||
fetching,
|
fetching,
|
||||||
|
isEligible,
|
||||||
|
navigateToAuth,
|
||||||
rewards,
|
rewards,
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
let content
|
let content
|
||||||
|
|
||||||
if (fetching) content = <div className="empty">Fetching rewards</div>
|
if (!isEligible) {
|
||||||
if (!fetching && rewards.length == 0) content = <div className="empty">Failed to load rewards.</div>
|
content = <div className="empty">
|
||||||
if (!fetching && rewards.length > 0) {
|
You are not eligible to claim rewards. { ' ' }
|
||||||
|
<Link onClick={navigateToAuth} label="Become eligible" />.
|
||||||
|
</div>
|
||||||
|
} else if (fetching) {
|
||||||
|
content = <BusyMessage message="Fetching rewards" />
|
||||||
|
} else if (rewards.length > 0) {
|
||||||
content = rewards.map(reward => <RewardTile key={reward.reward_type} reward={reward} />)
|
content = rewards.map(reward => <RewardTile key={reward.reward_type} reward={reward} />)
|
||||||
|
} else {
|
||||||
|
content = <div className="empty">Failed to load rewards.</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -54,6 +54,7 @@ reducers[types.USER_EMAIL_NEW_SUCCESS] = function(state, action) {
|
||||||
|
|
||||||
reducers[types.USER_EMAIL_NEW_EXISTS] = function(state, action) {
|
reducers[types.USER_EMAIL_NEW_EXISTS] = function(state, action) {
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
|
emailNewExistingEmail: action.data.email,
|
||||||
emailNewIsPending: false,
|
emailNewIsPending: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -65,6 +66,25 @@ reducers[types.USER_EMAIL_NEW_FAILURE] = function(state, action) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reducers[types.USER_EMAIL_VERIFY_STARTED] = function(state, action) {
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
emailVerifyIsPending: true,
|
||||||
|
emailVerifyErrorMessage: ''
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
reducers[types.USER_EMAIL_VERIFY_SUCCESS] = function(state, action) {
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
emailVerifyIsPending: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
reducers[types.USER_EMAIL_VERIFY_FAILURE] = function(state, action) {
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
emailVerifyIsPending: false,
|
||||||
|
emailVerifyErrorMessage: action.data.error
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function reducer(state = defaultState, action) {
|
export default function reducer(state = defaultState, action) {
|
||||||
|
|
|
@ -54,6 +54,8 @@ export const selectPageTitle = createSelector(
|
||||||
return __("Publishes");
|
return __("Publishes");
|
||||||
case "discover":
|
case "discover":
|
||||||
return __("Home");
|
return __("Home");
|
||||||
|
case 'account-verification':
|
||||||
|
return __('Early Access Verification')
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,5 +68,7 @@ export const selectWunderBarIcon = createSelector(selectCurrentPage, page => {
|
||||||
return "icon-code";
|
return "icon-code";
|
||||||
case "discover":
|
case "discover":
|
||||||
return "icon-home";
|
return "icon-home";
|
||||||
|
case 'account-verification':
|
||||||
|
return 'icon-lock'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,6 +12,11 @@ export const selectUser = createSelector(
|
||||||
(state) => state.user
|
(state) => state.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const selectUserIsRewardEligible = createSelector(
|
||||||
|
_selectState,
|
||||||
|
(state) => state.user.can_claim_rewards
|
||||||
|
)
|
||||||
|
|
||||||
export const selectEmailNewIsPending = createSelector(
|
export const selectEmailNewIsPending = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
(state) => state.emailNewIsPending
|
(state) => state.emailNewIsPending
|
||||||
|
@ -25,4 +30,19 @@ export const selectEmailNewErrorMessage = createSelector(
|
||||||
export const selectEmailNewDeclined = createSelector(
|
export const selectEmailNewDeclined = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
(state) => state.emailNewDeclined
|
(state) => state.emailNewDeclined
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const selectEmailNewExistingEmail = createSelector(
|
||||||
|
_selectState,
|
||||||
|
(state) => state.emailNewExistingEmail
|
||||||
|
)
|
||||||
|
|
||||||
|
export const selectEmailVerifyIsPending = createSelector(
|
||||||
|
_selectState,
|
||||||
|
(state) => state.emailVerifyIsPending
|
||||||
|
)
|
||||||
|
|
||||||
|
export const selectEmailVerifyErrorMessage = createSelector(
|
||||||
|
_selectState,
|
||||||
|
(state) => state.emailVerifyErrorMessage
|
||||||
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue