import React from "react"; import lbryio from "../lbryio.js"; import Modal from "./modal.js"; import ModalPage from "./modal-page.js"; import {Link, RewardLink} from "../component/link.js"; import {FormRow} from "../component/form.js"; import {CreditAmount, Address} from "../component/common.js"; import {getLocal, getSession, setSession, setLocal} from '../utils.js'; const SubmitEmailStage = React.createClass({ getInitialState: function() { return { rewardType: null, email: '', submitting: false }; }, handleEmailChanged: function(event) { this.setState({ email: event.target.value, }); }, onEmailSaved: function(email) { this.props.setStage("confirm", { email: email }) }, handleSubmit: function(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) { this.onEmailSaved(this.state.email); return; } else if (this._emailRow) { this._emailRow.showError(error.message) } this.setState({ submitting: false }); }); }, render: function() { return ( <section> <form onSubmit={this.handleSubmit}> <FormRow ref={(ref) => { this._emailRow = ref }} type="text" label="Email" placeholder="scrwvwls@lbry.io" name="email" value={this.state.email} onChange={this.handleEmailChanged} /> <div className="form-row-submit"> <Link button="primary" label="Next" disabled={this.state.submitting} onClick={this.handleSubmit} /> </div> </form> </section> ); } }); const ConfirmEmailStage = React.createClass({ getInitialState: function() { return { rewardType: null, code: '', submitting: false, errorMessage: null, }; }, handleCodeChanged: function(event) { this.setState({ code: event.target.value, }); }, handleSubmit: function(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.IsVerified) { this.props.setStage("welcome") } else { onSubmitError(new Error("Your email is still not verified.")) //shouldn't happen? } }, onSubmitError); }, render: function() { return ( <section> <form onSubmit={this.handleSubmit}> <FormRow label="Verification Code" ref={(ref) => { this._codeRow = ref }} type="text" name="code" placeholder="a94bXXXXXXXXXXXXXX" value={this.state.code} onChange={this.handleCodeChanged} 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={this.handleSubmit} /> </div> <div className="form-field__helper"> No code? <Link onClick={() => { this.props.setStage("nocode")}} label="Click here" />. </div> </form> </section> ); } }); const WelcomeStage = React.createClass({ propTypes: { endAuth: React.PropTypes.func, }, getInitialState: function() { return { hasReward: false, rewardAmount: null, } }, onRewardClaim: function(reward) { this.setState({ hasReward: true, rewardAmount: reward.amount }) }, render: function() { 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={this.onRewardClaim} 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 a beta and that it earns the name.</p> </section> </Modal> ); } }); const ErrorStage = React.createClass({ render: function() { return ( <section> <p>An error was encountered that we cannot continue from.</p> <p>At least we're earning the name beta.</p> { this.props.errorText ? <p>Message: {this.props.errorText}</p> : '' } <Link button="alt" label="Try Reload" onClick={() => { window.location.reload() } } /> </section> ); } }); const PendingStage = React.createClass({ render: function() { return ( <section> <p>Preparing for first access <span className="busy-indicator"></span></p> </section> ); } }); const CodeRequiredStage = React.createClass({ _balanceSubscribeId: null, getInitialState: function() { return { balance: 0, address: getLocal('wallet_address') } }, componentWillMount: function() { this._balanceSubscribeId = lbry.balanceSubscribe((balance) => { this.setState({ balance: balance }); }) if (!this.state.address) { lbry.getUnusedAddress((address) => { setLocal('wallet_address', address); this.setState({ address: address }); }); } }, componentWillUnmount: function() { if (this._balanceSubscribeId) { lbry.balanceUnsubscribe(this._balanceSubscribeId) } }, render: function() { const disabled = this.state.balance < 1; return ( <div> <section className="section-spaced"> <p>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 const AuthOverlay = React.createClass({ _stages: { pending: PendingStage, error: ErrorStage, nocode: CodeRequiredStage, email: SubmitEmailStage, confirm: ConfirmEmailStage, welcome: WelcomeStage }, getInitialState: function() { return { stage: "pending", stageProps: {} }; }, setStage: function(stage, stageProps = {}) { this.setState({ stage: stage, stageProps: stageProps }) }, componentWillMount: function() { lbryio.authenticate().then((user) => { if (!user.HasVerifiedEmail) { if (getLocal('auth_bypassed')) { this.setStage(null) } else { this.setStage("email", {}) } } else { lbryio.call('reward', 'list', {}).then((userRewards) => { userRewards.filter(function(reward) { return reward.RewardType == "new_user" && reward.TransactionID; }).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: function() { if (!this.state.stage) { return null; } const StageContent = this._stages[this.state.stage]; return ( this.state.stage != "welcome" ? <ModalPage className="modal-page--full" isOpen={true} contentLabel="Authentication" {...this.props}> <h1>LBRY Early Access</h1> <StageContent {...this.state.stageProps} setStage={this.setStage} /> </ModalPage> : <StageContent setStage={this.setStage} {...this.state.stageProps} /> ); } });