2017-04-20 16:45:39 +02:00
import React from "react" ;
2017-05-25 00:25:22 +02:00
import lbry from "../lbry.js" ;
2017-04-20 16:45:39 +02:00
import lbryio from "../lbryio.js" ;
import Modal from "./modal.js" ;
import ModalPage from "./modal-page.js" ;
2017-05-04 05:44:08 +02:00
import Link from "component/link"
import { RewardLink } from 'component/reward-link' ;
2017-04-20 16:45:39 +02:00
import { FormRow } from "../component/form.js" ;
import { CreditAmount , Address } from "../component/common.js" ;
2017-05-11 19:46:41 +02:00
import { getLocal , setLocal } from '../utils.js' ;
2017-05-25 19:38:53 +02:00
import rewards from '../rewards'
2017-04-09 17:06:23 +02:00
2017-05-17 10:10:25 +02:00
class SubmitEmailStage extends React . Component {
constructor ( props ) {
super ( props ) ;
this . state = {
2017-04-09 17:06:23 +02:00
rewardType : null ,
email : '' ,
submitting : false
} ;
2017-05-17 10:10:25 +02:00
}
handleEmailChanged ( event ) {
2017-04-09 17:06:23 +02:00
this . setState ( {
email : event . target . value ,
} ) ;
2017-05-17 10:10:25 +02:00
}
onEmailSaved ( email ) {
2017-04-20 16:45:39 +02:00
this . props . setStage ( "confirm" , { email : email } )
2017-05-17 10:10:25 +02:00
}
handleSubmit ( event ) {
2017-04-09 17:06:23 +02:00
event . preventDefault ( ) ;
this . setState ( {
submitting : true ,
} ) ;
lbryio . call ( 'user_email' , 'new' , { email : this . state . email } , 'post' ) . then ( ( ) => {
2017-04-20 16:45:39 +02:00
this . onEmailSaved ( this . state . email ) ;
2017-04-09 17:06:23 +02:00
} , ( error ) => {
2017-06-01 17:49:07 +02:00
if ( error . xhr && ( error . xhr . status == 409 || error . message == _ _ ( "This email is already in use" ) ) ) {
2017-04-20 16:45:39 +02:00
this . onEmailSaved ( this . state . email ) ;
2017-04-18 21:45:15 +02:00
return ;
} else if ( this . _emailRow ) {
2017-04-10 14:32:40 +02:00
this . _emailRow . showError ( error . message )
2017-04-09 17:06:23 +02:00
}
this . setState ( { submitting : false } ) ;
} ) ;
2017-05-17 10:10:25 +02:00
}
render ( ) {
2017-04-09 17:06:23 +02:00
return (
< section >
2017-05-18 03:37:39 +02:00
< form onSubmit = { ( event ) => { this . handleSubmit ( event ) } } >
2017-05-26 02:16:25 +02:00
< FormRow ref = { ( ref ) => { this . _emailRow = ref } } type = "text" label = { _ _ ( "Email" ) } placeholder = "scrwvwls@lbry.io"
2017-04-09 17:06:23 +02:00
name = "email" value = { this . state . email }
2017-05-18 03:37:39 +02:00
onChange = { ( event ) => { this . handleEmailChanged ( event ) } } / >
2017-04-10 14:32:40 +02:00
< div className = "form-row-submit" >
2017-05-26 02:16:25 +02:00
< Link button = "primary" label = { _ _ ( "Next" ) } disabled = { this . state . submitting } onClick = { ( event ) => { this . handleSubmit ( event ) } } / >
2017-04-09 17:06:23 +02:00
< / d i v >
< / f o r m >
< / s e c t i o n >
) ;
}
2017-05-17 10:10:25 +02:00
}
2017-04-09 17:06:23 +02:00
2017-05-17 10:10:25 +02:00
class ConfirmEmailStage extends React . Component {
constructor ( props ) {
super ( props ) ;
this . state = {
2017-04-09 17:06:23 +02:00
rewardType : null ,
code : '' ,
submitting : false ,
errorMessage : null ,
} ;
2017-05-17 10:10:25 +02:00
}
handleCodeChanged ( event ) {
2017-04-09 17:06:23 +02:00
this . setState ( {
code : event . target . value ,
} ) ;
2017-05-17 10:10:25 +02:00
}
handleSubmit ( event ) {
2017-04-09 17:06:23 +02:00
event . preventDefault ( ) ;
this . setState ( {
submitting : true ,
} ) ;
2017-04-30 03:56:55 +02:00
const onSubmitError = ( error ) => {
2017-04-10 14:32:40 +02:00
if ( this . _codeRow ) {
this . _codeRow . showError ( error . message )
2017-04-09 17:06:23 +02:00
}
2017-04-10 14:32:40 +02:00
this . setState ( { submitting : false } ) ;
2017-04-30 03:56:55 +02:00
} ;
2017-04-10 14:32:40 +02:00
2017-04-18 22:51:00 +02:00
lbryio . call ( 'user_email' , 'confirm' , { verification _token : this . state . code , email : this . props . email } , 'post' ) . then ( ( userEmail ) => {
2017-05-11 19:46:41 +02:00
if ( userEmail . is _verified ) {
2017-04-20 16:45:39 +02:00
this . props . setStage ( "welcome" )
2017-04-10 14:32:40 +02:00
} else {
2017-05-26 02:16:25 +02:00
onSubmitError ( new Error ( _ _ ( "Your email is still not verified." ) ) ) //shouldn't happen?
2017-04-10 14:32:40 +02:00
}
} , onSubmitError ) ;
2017-05-17 10:10:25 +02:00
}
render ( ) {
2017-04-09 17:06:23 +02:00
return (
< section >
2017-05-18 03:37:39 +02:00
< form onSubmit = { ( event ) => { this . handleSubmit ( event ) } } >
2017-05-26 02:16:25 +02:00
< FormRow label = { _ _ ( "Verification Code" ) } ref = { ( ref ) => { this . _codeRow = ref } } type = "text"
2017-05-18 03:37:39 +02:00
name = "code" placeholder = "a94bXXXXXXXXXXXXXX" value = { this . state . code } onChange = { ( event ) => { this . handleCodeChanged ( event ) } }
2017-05-26 02:16:25 +02:00
helper = { _ _ ( "A verification code is required to access this version." ) } / >
2017-04-20 16:45:39 +02:00
< div className = "form-row-submit form-row-submit--with-footer" >
2017-05-26 02:16:25 +02:00
< Link button = "primary" label = { _ _ ( "Verify" ) } disabled = { this . state . submitting } onClick = { ( event ) => { this . handleSubmit ( event ) } } / >
2017-04-09 17:06:23 +02:00
< / d i v >
2017-04-20 16:45:39 +02:00
< div className = "form-field__helper" >
2017-05-26 02:16:25 +02:00
{ _ _ ( "No code?" ) } < Link onClick = { ( ) => { this . props . setStage ( "nocode" ) } } label = { _ _ ( "Click here" ) } / > .
2017-04-20 16:45:39 +02:00
< / d i v >
2017-04-09 17:06:23 +02:00
< / f o r m >
< / s e c t i o n >
) ;
}
2017-05-17 10:10:25 +02:00
}
class WelcomeStage extends React . Component {
2017-05-19 18:17:19 +02:00
static propTypes = {
endAuth : React . PropTypes . func ,
}
2017-05-17 10:10:25 +02:00
constructor ( props ) {
super ( props ) ;
this . state = {
2017-04-12 22:23:20 +02:00
hasReward : false ,
rewardAmount : null ,
2017-05-17 10:10:25 +02:00
} ;
}
onRewardClaim ( reward ) {
2017-04-12 22:23:20 +02:00
this . setState ( {
hasReward : true ,
2017-04-15 00:23:42 +02:00
rewardAmount : reward . amount
2017-04-12 22:23:20 +02:00
} )
2017-05-17 10:10:25 +02:00
}
render ( ) {
2017-04-10 14:32:40 +02:00
return (
2017-04-12 22:23:20 +02:00
! this . state . hasReward ?
2017-05-26 02:16:25 +02:00
< Modal type = "custom" isOpen = { true } contentLabel = { _ _ ( "Welcome to LBRY" ) } { ... this . props } >
2017-04-12 22:23:20 +02:00
< section >
2017-05-26 02:16:25 +02:00
< h3 className = "modal__header" > { _ _ ( "Welcome to LBRY." ) } < / h 3 >
< 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 >
2017-04-12 22:23:20 +02:00
< div style = { { textAlign : "center" , marginBottom : "12px" } } >
2017-05-18 03:37:39 +02:00
< RewardLink type = "new_user" button = "primary" onRewardClaim = { ( event ) => { this . onRewardClaim ( event ) } } onRewardFailure = { ( ) => this . props . setStage ( null ) } onConfirmed = { ( ) => { this . props . setStage ( null ) } } / >
2017-04-12 22:23:20 +02:00
< / d i v >
< / s e c t i o n >
< / M o d a l > :
2017-05-26 02:16:25 +02:00
< Modal type = "alert" overlayClassName = "modal-overlay modal-overlay--clear" isOpen = { true } contentLabel = { _ _ ( "Welcome to LBRY" ) } { ... this . props } onConfirmed = { ( ) => { this . props . setStage ( null ) } } >
2017-04-12 22:23:20 +02:00
< section >
2017-05-26 02:16:25 +02:00
< h3 className = "modal__header" > { _ _ ( "About Your Reward" ) } < / h 3 >
< 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 >
2017-04-12 22:23:20 +02:00
< / s e c t i o n >
< / M o d a l >
2017-04-10 14:32:40 +02:00
) ;
}
2017-05-17 10:10:25 +02:00
}
2017-04-10 14:32:40 +02:00
2017-05-19 18:17:19 +02:00
const ErrorStage = ( props ) => {
return < section >
2017-05-26 02:16:25 +02:00
< 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 ( ) } } / >
2017-05-19 18:17:19 +02:00
< / s e c t i o n >
2017-05-17 10:10:25 +02:00
}
2017-04-09 17:06:23 +02:00
2017-05-19 18:17:19 +02:00
const PendingStage = ( props ) => {
return < section >
2017-05-26 02:16:25 +02:00
< p > { _ _ ( "Preparing for first access" ) } < span className = "busy-indicator" > < / s p a n > < / p >
2017-05-19 18:17:19 +02:00
< / s e c t i o n >
2017-05-17 10:10:25 +02:00
}
2017-04-09 17:06:23 +02:00
2017-05-17 10:10:25 +02:00
class CodeRequiredStage extends React . Component {
constructor ( props ) {
super ( props ) ;
2017-04-20 16:45:39 +02:00
2017-05-25 00:25:22 +02:00
this . _balanceSubscribeId = null
2017-05-17 10:10:25 +02:00
this . state = {
2017-04-20 16:45:39 +02:00
balance : 0 ,
address : getLocal ( 'wallet_address' )
2017-05-17 10:10:25 +02:00
} ;
}
2017-04-20 16:45:39 +02:00
2017-05-17 10:10:25 +02:00
componentWillMount ( ) {
2017-04-20 16:45:39 +02:00
this . _balanceSubscribeId = lbry . balanceSubscribe ( ( balance ) => {
this . setState ( {
balance : balance
} ) ;
} )
if ( ! this . state . address ) {
2017-05-18 19:58:28 +02:00
lbry . wallet _unused _address ( ) . then ( ( address ) => {
2017-04-20 16:45:39 +02:00
setLocal ( 'wallet_address' , address ) ;
this . setState ( { address : address } ) ;
} ) ;
}
2017-05-17 10:10:25 +02:00
}
componentWillUnmount ( ) {
2017-04-20 16:45:39 +02:00
if ( this . _balanceSubscribeId ) {
lbry . balanceUnsubscribe ( this . _balanceSubscribeId )
}
2017-05-17 10:10:25 +02:00
}
render ( ) {
2017-04-20 16:45:39 +02:00
const disabled = this . state . balance < 1 ;
return (
< div >
< section className = "section-spaced" >
2017-05-26 02:16:25 +02:00
< 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" ) } < / h 3 >
< p > { _ _ ( "If you own at least 1 LBC, you can get in right now." ) } < / p >
2017-04-20 16:45:39 +02:00
< p style = { { textAlign : "center" } } > < Link onClick = { ( ) => { setLocal ( 'auth_bypassed' , true ) ; this . props . setStage ( null ) ; } }
2017-05-26 02:16:25 +02:00
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 >
2017-04-20 16:45:39 +02:00
< / s e c t i o n >
< section >
2017-05-26 02:16:25 +02:00
< h3 > { _ _ ( "Wait For A Code" ) } < / h 3 >
< 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 >
2017-04-20 16:45:39 +02:00
< / s e c t i o n >
< / d i v >
) ;
}
2017-05-17 10:10:25 +02:00
}
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 = {
2017-04-18 21:45:15 +02:00
stage : "pending" ,
2017-04-09 17:06:23 +02:00
stageProps : { }
} ;
2017-05-17 10:10:25 +02:00
}
setStage ( stage , stageProps = { } ) {
2017-04-10 14:32:40 +02:00
this . setState ( {
2017-04-20 16:45:39 +02:00
stage : stage ,
stageProps : stageProps
} )
2017-05-17 10:10:25 +02:00
}
componentWillMount ( ) {
2017-04-20 16:45:39 +02:00
lbryio . authenticate ( ) . then ( ( user ) => {
2017-05-11 19:46:41 +02:00
if ( ! user . has _verified _email ) {
2017-04-20 16:45:39 +02:00
if ( getLocal ( 'auth_bypassed' ) ) {
this . setStage ( null )
} else {
this . setStage ( "email" , { } )
}
2017-04-10 20:12:07 +02:00
} else {
2017-04-20 16:45:39 +02:00
lbryio . call ( 'reward' , 'list' , { } ) . then ( ( userRewards ) => {
2017-04-12 22:23:20 +02:00
userRewards . filter ( function ( reward ) {
2017-05-25 19:38:53 +02:00
return reward . reward _type == rewards . TYPE _NEW _USER && reward . transaction _id ;
2017-04-12 22:23:20 +02:00
} ) . length ?
2017-04-20 16:45:39 +02:00
this . setStage ( null ) :
this . setStage ( "welcome" )
} ) ;
2017-04-10 20:12:07 +02:00
}
2017-04-20 16:45:39 +02:00
} ) . catch ( ( err ) => {
this . setStage ( "error" , { errorText : err . message } )
2017-04-10 20:12:07 +02:00
document . dispatchEvent ( new CustomEvent ( 'unhandledError' , {
detail : {
message : err . message ,
data : err . stack
}
} ) ) ;
} )
2017-05-17 10:10:25 +02:00
}
render ( ) {
2017-04-12 22:23:20 +02:00
if ( ! this . state . stage ) {
2017-04-12 18:59:43 +02:00
return null ;
2017-04-09 17:06:23 +02:00
}
const StageContent = this . _stages [ this . state . stage ] ;
2017-05-19 18:17:19 +02:00
if ( ! StageContent ) {
2017-05-26 02:16:25 +02:00
return < span className = "empty" > { _ _ ( "Unknown authentication step." ) } < / s p a n >
2017-05-19 18:17:19 +02:00
}
2017-04-09 17:06:23 +02:00
return (
2017-04-10 14:32:40 +02:00
this . state . stage != "welcome" ?
2017-05-26 02:16:25 +02:00
< ModalPage className = "modal-page--full" isOpen = { true } contentLabel = { _ _ ( "Authentication" ) } >
< h1 > { _ _ ( "LBRY Early Access" ) } < / h 1 >
2017-05-18 03:37:39 +02:00
< StageContent { ... this . state . stageProps } setStage = { ( stage , stageProps ) => { this . setStage ( stage , stageProps ) } } / >
2017-04-10 14:32:40 +02:00
< / M o d a l P a g e > :
2017-05-18 03:37:39 +02:00
< StageContent setStage = { ( stage , stageProps ) => { this . setStage ( stage , stageProps ) } } { ... this . state . stageProps } / >
2017-04-09 17:06:23 +02:00
) ;
}
2017-05-26 02:16:25 +02:00
}