2017-04-20 16:45:39 +02:00
import React from "react" ;
import lbryio from "../lbryio.js" ;
import Modal from "./modal.js" ;
import ModalPage from "./modal-page.js" ;
2017-04-23 11:56:50 +02:00
import { Link , RewardLink } from "../component/link" ;
2017-04-20 16:45:39 +02:00
import { FormRow } from "../component/form.js" ;
import { CreditAmount , Address } from "../component/common.js" ;
import { getLocal , getSession , setSession , setLocal } from '../utils.js' ;
2017-04-09 17:06:23 +02:00
const SubmitEmailStage = React . createClass ( {
getInitialState : function ( ) {
return {
rewardType : null ,
email : '' ,
submitting : false
} ;
} ,
handleEmailChanged : function ( event ) {
this . setState ( {
email : event . target . value ,
} ) ;
} ,
2017-04-20 16:45:39 +02:00
onEmailSaved : function ( email ) {
this . props . setStage ( "confirm" , { email : email } )
} ,
2017-04-09 17:06:23 +02:00
handleSubmit : function ( event ) {
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-04-18 21:45:15 +02:00
if ( error . xhr && error . xhr . status == 409 ) {
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 } ) ;
} ) ;
} ,
render : function ( ) {
return (
< section >
< form onSubmit = { this . handleSubmit } >
2017-04-17 22:45:51 +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 }
onChange = { this . handleEmailChanged } / >
2017-04-10 14:32:40 +02:00
< div className = "form-row-submit" >
2017-04-09 17:06:23 +02:00
< Link button = "primary" label = "Next" disabled = { this . state . submitting } onClick = { this . handleSubmit } / >
< / d i v >
< / f o r m >
< / s e c t i o n >
) ;
}
} ) ;
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 ,
} ) ;
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-04-10 14:32:40 +02:00
if ( userEmail . IsVerified ) {
2017-04-20 16:45:39 +02:00
this . props . setStage ( "welcome" )
2017-04-10 14:32:40 +02:00
} else {
onSubmitError ( new Error ( "Your email is still not verified." ) ) //shouldn't happen?
}
} , onSubmitError ) ;
2017-04-09 17:06:23 +02:00
} ,
render : function ( ) {
return (
< section >
< form onSubmit = { this . handleSubmit } >
2017-04-10 14:32:40 +02:00
< FormRow label = "Verification Code" ref = { ( ref ) => { this . _codeRow = ref } } type = "text"
2017-04-09 17:06:23 +02:00
name = "code" placeholder = "a94bXXXXXXXXXXXXXX" value = { this . state . code } onChange = { this . handleCodeChanged }
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-04-09 17:06:23 +02:00
< Link button = "primary" label = "Verify" disabled = { this . state . submitting } onClick = { this . handleSubmit } / >
< / d i v >
2017-04-20 16:45:39 +02:00
< div className = "form-field__helper" >
No code ? < Link onClick = { ( ) => { this . props . setStage ( "nocode" ) } } label = "Click here" / > .
< / d i v >
2017-04-09 17:06:23 +02:00
< / f o r m >
< / s e c t i o n >
) ;
}
} ) ;
2017-04-10 14:32:40 +02:00
const WelcomeStage = React . createClass ( {
2017-04-12 22:23:20 +02:00
propTypes : {
endAuth : React . PropTypes . func ,
} ,
getInitialState : function ( ) {
return {
hasReward : false ,
rewardAmount : null ,
}
} ,
onRewardClaim : function ( reward ) {
this . setState ( {
hasReward : true ,
2017-04-15 00:23:42 +02:00
rewardAmount : reward . amount
2017-04-12 22:23:20 +02:00
} )
} ,
2017-04-10 14:32:40 +02:00
render : function ( ) {
return (
2017-04-12 22:23:20 +02:00
! this . state . hasReward ?
< Modal type = "custom" isOpen = { true } contentLabel = "Welcome to LBRY" { ... this . props } >
< section >
< h3 className = "modal__header" > Welcome to LBRY . < / h 3 >
2017-04-13 20:52:26 +02:00
< p > Using LBRY is like dating a centaur . Totally normal up top , and < em > way different < / e m > u n d e r n e a t h . < / p >
2017-04-17 22:45:51 +02:00
< 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-02 09:26:23 +02:00
< RewardLink type = "new_user" button = "primary" onRewardClaim = { this . onRewardClaim } 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-02 09:26:23 +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 >
< h3 className = "modal__header" > About Your Reward < / h 3 >
2017-04-15 00:23:42 +02:00
< p > You earned a reward of < CreditAmount amount = { this . state . rewardAmount } label = { false } / > LBRY credits , or < em > LBC < / e m > . < / p >
< p > This reward will show in your Wallet momentarily , probably while you are reading this message . < / p >
2017-04-12 22:23:20 +02:00
< 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 >
2017-04-17 22:45:51 +02:00
< p > Finally , know that LBRY is a 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-04-09 17:06:23 +02:00
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 >
2017-04-17 22:45:51 +02:00
{ this . props . errorText ? < p > Message : { this . props . errorText } < / p > : ' ' }
2017-04-09 17:06:23 +02:00
< Link button = "alt" label = "Try Reload" onClick = { ( ) => { window . location . reload ( ) } } / >
< / s e c t i o n >
) ;
}
} ) ;
const PendingStage = React . createClass ( {
render : function ( ) {
return (
< section >
< p > Preparing for first access < span className = "busy-indicator" > < / s p a n > < / p >
< / s e c t i o n >
) ;
}
} ) ;
2017-04-20 16:45:39 +02:00
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 ) {
2017-04-27 20:18:59 +02:00
lbry . getUnusedAddress ( ( address ) => {
2017-04-20 16:45:39 +02:00
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 < / h 3 >
< 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 >
< / s e c t i o n >
< section >
< 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 >
< / s e c t i o n >
< / d i v >
) ;
}
} ) ;
2017-04-09 17:06:23 +02:00
export const AuthOverlay = React . createClass ( {
_stages : {
pending : PendingStage ,
error : ErrorStage ,
2017-04-20 16:45:39 +02:00
nocode : CodeRequiredStage ,
2017-04-09 17:06:23 +02:00
email : SubmitEmailStage ,
confirm : ConfirmEmailStage ,
2017-04-12 22:23:20 +02:00
welcome : WelcomeStage
2017-04-09 17:06:23 +02:00
} ,
getInitialState : function ( ) {
return {
2017-04-18 21:45:15 +02:00
stage : "pending" ,
2017-04-09 17:06:23 +02:00
stageProps : { }
} ;
} ,
2017-04-20 16:45:39 +02:00
setStage : function ( 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-04-10 14:32:40 +02:00
} ,
2017-04-09 17:06:23 +02:00
componentWillMount : function ( ) {
2017-04-20 16:45:39 +02:00
lbryio . authenticate ( ) . then ( ( user ) => {
if ( ! user . HasVerifiedEmail ) {
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 ) {
return reward . RewardType == "new_user" && reward . TransactionID ;
} ) . 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-04-09 17:06:23 +02:00
} ,
render : function ( ) {
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 ] ;
return (
2017-04-10 14:32:40 +02:00
this . state . stage != "welcome" ?
2017-04-12 22:23:20 +02:00
< ModalPage className = "modal-page--full" isOpen = { true } contentLabel = "Authentication" { ... this . props } >
2017-04-10 14:32:40 +02:00
< h1 > LBRY Early Access < / h 1 >
2017-04-20 16:45:39 +02:00
< StageContent { ... this . state . stageProps } setStage = { this . setStage } / >
2017-04-10 14:32:40 +02:00
< / M o d a l P a g e > :
2017-04-20 16:45:39 +02:00
< StageContent setStage = { this . setStage } { ... this . state . stageProps } / >
2017-04-09 17:06:23 +02:00
) ;
}
} ) ;