2016-07-26 12:09:09 +02:00
var publishNumberStyle = {
2016-07-15 14:04:47 +02:00
width : '50px' ,
2016-07-20 08:25:22 +02:00
} , publishFieldLabelStyle = {
display : 'inline-block' ,
width : '118px' ,
textAlign : 'right' ,
verticalAlign : 'top' ,
} , publishFieldStyle = {
width : '330px' ,
2016-07-15 14:04:47 +02:00
} ;
2016-05-23 17:14:21 +02:00
var PublishPage = React . createClass ( {
2016-08-08 11:53:41 +02:00
_requiredFields : [ 'name' , 'bid' , 'meta_title' , 'meta_author' , 'meta_license' , 'meta_description' ] ,
2016-07-26 12:09:09 +02:00
handleSubmit : function ( ) {
2016-07-21 08:58:06 +02:00
this . setState ( {
submitting : true ,
} ) ;
2016-08-08 11:53:41 +02:00
var checkFields = this . _requiredFields . slice ( ) ;
if ( ! this . state . nameIsMine ) {
checkFields . push ( 'file' ) ;
}
2016-07-26 12:09:09 +02:00
var missingFieldFound = false ;
2016-08-08 11:53:41 +02:00
for ( let fieldName of checkFields ) {
2016-07-26 12:09:09 +02:00
var field = this . refs [ fieldName ] ;
2016-07-27 17:57:18 +02:00
if ( field . getValue ( ) === '' ) {
2016-07-26 12:09:09 +02:00
field . warnRequired ( ) ;
if ( ! missingFieldFound ) {
field . focus ( ) ;
missingFieldFound = true ;
}
}
}
if ( missingFieldFound ) {
this . setState ( {
submitting : false ,
} ) ;
2016-07-27 13:46:48 +02:00
return ;
2016-07-26 12:09:09 +02:00
}
2016-07-20 08:25:22 +02:00
2016-08-23 07:03:03 +02:00
if ( this . state . nameIsMine ) {
// Pre-populate with existing metadata
var metadata = Object . assign ( { } , this . state . claimMetadata ) ;
if ( this . refs . file . getValue ( ) !== '' ) {
delete metadata . sources ;
}
} else {
var metadata = { } ;
}
2016-08-27 08:18:19 +02:00
2016-07-27 17:57:18 +02:00
for ( let metaField of [ 'title' , 'author' , 'description' , 'thumbnail' , 'license' , 'license_url' , 'language' , 'nsfw' ] ) {
var value = this . refs [ 'meta_' + metaField ] . getValue ( ) ;
2016-07-27 19:54:25 +02:00
if ( value !== '' ) {
2016-07-26 12:09:09 +02:00
metadata [ metaField ] = value ;
}
}
2016-07-27 17:57:18 +02:00
/ *
2016-07-26 12:09:09 +02:00
metadata . license = { } ;
metadata . license . name = this . refs . meta _license . getValue ( ) ;
var licenseUrl = this . refs . meta _license _url . getValue ( ) ;
if ( licenseUrl != '' ) {
2016-07-26 14:30:46 +02:00
metadata . license . url = licenseUrl ;
2016-07-20 08:25:22 +02:00
}
2016-07-27 17:57:18 +02:00
* /
var licenseUrl = this . refs . meta _license _url . getValue ( ) ;
if ( licenseUrl ) {
metadata . license _url = licenseUrl ;
}
2016-07-20 08:25:22 +02:00
2016-07-21 08:58:06 +02:00
var doPublish = ( ) => {
2016-08-08 11:53:41 +02:00
var publishArgs = {
name : this . state . name ,
2016-07-21 08:58:06 +02:00
bid : parseFloat ( this . state . bid ) ,
metadata : metadata ,
2016-08-08 11:53:41 +02:00
} ;
2016-08-23 07:03:03 +02:00
if ( this . refs . file . getValue ( ) !== '' ) {
2016-08-08 11:53:41 +02:00
publishArgs . file _path = this . _tempFilePath ;
}
console . log ( publishArgs ) ;
lbry . publish ( publishArgs , ( message ) => {
2016-09-16 17:23:39 +02:00
this . handlePublishStarted ( ) ;
2016-07-21 08:58:06 +02:00
this . setState ( {
submitting : false ,
} ) ;
2016-09-16 17:23:39 +02:00
} , null , ( error ) => {
2016-07-21 08:58:06 +02:00
this . handlePublishError ( error ) ;
this . setState ( {
submitting : false ,
} ) ;
} ) ;
} ;
2016-07-20 08:25:22 +02:00
if ( this . state . isFee ) {
2016-07-21 08:58:06 +02:00
lbry . getNewAddress ( ( address ) => {
2016-07-30 07:47:37 +02:00
metadata . fee = { } ;
metadata . fee [ this . state . feeCurrency ] = {
amount : parseFloat ( this . state . feeAmount ) ,
address : address ,
2016-07-21 08:58:06 +02:00
} ;
2016-07-20 08:25:22 +02:00
2016-07-21 08:58:06 +02:00
doPublish ( ) ;
} ) ;
} else {
doPublish ( ) ;
}
2016-05-23 17:14:21 +02:00
} ,
2016-07-15 14:04:47 +02:00
getInitialState : function ( ) {
2016-07-20 08:25:22 +02:00
this . _tempFilePath = null ;
2016-07-15 14:04:47 +02:00
return {
name : '' ,
bid : '' ,
2016-07-30 07:47:37 +02:00
feeAmount : '' ,
2016-08-08 11:47:20 +02:00
feeCurrency : 'USD' ,
2016-07-20 08:25:22 +02:00
nameResolved : false ,
2016-08-08 11:53:41 +02:00
nameIsMine : false ,
2016-07-20 08:25:22 +02:00
claimValue : 0.0 ,
2016-08-09 08:41:57 +02:00
claimMetadata : null ,
2016-07-20 08:25:22 +02:00
fileInfo : null ,
uploadProgress : 0.0 ,
uploaded : false ,
tempFileReady : false ,
2016-07-21 08:58:06 +02:00
submitting : false ,
2016-07-15 14:04:47 +02:00
} ;
} ,
2016-09-16 17:23:39 +02:00
handlePublishStarted : function ( ) {
2016-07-27 21:26:49 +02:00
alert ( ` Your file ${ this . refs . meta _title . getValue ( ) } has been published to LBRY at the address lbry:// ${ this . state . name } ! \n \n ` +
2016-08-03 12:08:37 +02:00
` You will now be taken to your My Files page, where your newly published file will be listed. Your file will take a few minutes to appear for other LBRY users; until then it will be listed as "pending." ` ) ;
2016-09-23 11:19:39 +02:00
window . location = "?published" ;
2016-07-21 08:58:06 +02:00
} ,
handlePublishError : function ( error ) {
alert ( ` The following error occurred when attempting to publish your file: \n \n ` +
error . message ) ;
} ,
2016-07-15 14:04:47 +02:00
handleNameChange : function ( event ) {
2016-09-01 09:30:12 +02:00
var rawName = event . target . value ;
2016-07-15 14:04:47 +02:00
2016-09-01 09:30:12 +02:00
if ( ! rawName ) {
2016-07-15 14:04:47 +02:00
this . setState ( {
name : '' ,
nameResolved : false ,
2016-07-20 08:25:22 +02:00
} ) ;
2016-07-15 14:04:47 +02:00
return ;
}
2016-09-01 09:30:12 +02:00
var name = lbry . formatName ( rawName ) ;
2016-07-15 14:04:47 +02:00
lbry . resolveName ( name , ( info ) => {
2016-09-01 09:30:12 +02:00
if ( name != lbry . formatName ( this . refs . name . getValue ( ) ) ) {
// A new name has been typed already, so bail
2016-08-10 09:05:17 +02:00
return ;
}
2016-07-15 14:04:47 +02:00
if ( ! info ) {
this . setState ( {
name : name ,
2016-07-20 08:25:22 +02:00
nameResolved : false ,
2016-07-15 14:04:47 +02:00
} ) ;
} else {
2016-07-29 00:04:55 +02:00
lbry . getClaimInfo ( name , ( claimInfo ) => {
2016-08-10 09:05:17 +02:00
if ( name != this . refs . name . getValue ( ) ) {
return ;
}
2016-08-08 11:53:41 +02:00
var newState = {
2016-07-15 14:04:47 +02:00
name : name ,
nameResolved : true ,
2016-08-10 09:05:17 +02:00
nameIsMine : claimInfo . is _mine ,
2016-07-29 00:04:55 +02:00
claimValue : parseFloat ( claimInfo . amount ) ,
2016-08-09 08:41:57 +02:00
claimMetadata : claimInfo . value ,
2016-08-08 11:53:41 +02:00
} ;
if ( claimInfo . is _mine ) {
newState . bid = claimInfo . amount ;
} else if ( this . state . nameIsMine && ! claimInfo . name _is _mine ) {
// Just changed away from a name we control, so clear pre-fill
newState . bid = '' ;
}
this . setState ( newState ) ;
2016-07-15 14:04:47 +02:00
} ) ;
}
} ) ;
} ,
2016-07-20 08:25:22 +02:00
handleBidChange : function ( event ) {
2016-07-15 14:04:47 +02:00
this . setState ( {
2016-07-20 08:25:22 +02:00
bid : event . target . value ,
2016-07-15 14:04:47 +02:00
} ) ;
} ,
2016-07-30 07:47:37 +02:00
handleFeeAmountChange : function ( event ) {
2016-07-15 14:04:47 +02:00
this . setState ( {
2016-07-30 07:47:37 +02:00
feeAmount : event . target . value ,
} ) ;
} ,
handleFeeCurrencyChange : function ( event ) {
this . setState ( {
feeCurrency : event . target . value ,
2016-07-20 08:25:22 +02:00
} ) ;
} ,
handleFileChange : function ( event ) {
event . preventDefault ( ) ;
var fileInput = event . target ;
this . _tempFilePath = null ;
if ( fileInput . files . length == 0 ) {
// File was removed
this . setState ( {
fileInfo : null ,
uploadProgress : 0.0 ,
uploaded : false ,
tempFileReady : false ,
} ) ;
} else {
var file = fileInput . files [ 0 ] ;
this . setState ( {
fileInfo : {
name : file . name ,
size : file . size ,
} ,
uploadProgress : 0.0 ,
uploaded : false ,
tempFileReady : false ,
} ) ;
var xhr = new XMLHttpRequest ( ) ;
xhr . upload . addEventListener ( 'progress' , ( event ) => {
this . setState ( {
uploadProgress : ( event . loaded / event . total ) ,
} ) ;
} ) ;
xhr . upload . addEventListener ( 'load' , ( event ) => {
this . setState ( {
uploaded : true ,
} ) ;
} ) ;
xhr . addEventListener ( 'load' , ( event ) => {
this . _tempFilePath = JSON . parse ( xhr . responseText ) ;
this . setState ( {
tempFileReady : true ,
} ) ;
} )
xhr . open ( 'POST' , '/upload' , true ) ;
xhr . send ( new FormData ( fileInput . form ) ) ;
}
} ,
handleFeePrefChange : function ( feeEnabled ) {
this . setState ( {
isFee : feeEnabled
2016-07-15 14:04:47 +02:00
} ) ;
} ,
2016-08-08 00:13:17 +02:00
componentDidMount : function ( ) {
document . title = "Publish" ;
} ,
2016-07-27 17:57:18 +02:00
componentDidUpdate : function ( ) {
2016-07-20 08:25:22 +02:00
if ( this . state . fileInfo && ! this . state . tempFileReady ) {
// A file was chosen but the daemon hasn't finished processing it yet, i.e. it's loading, so
2016-07-27 17:57:18 +02:00
// we're displaying a progress bar and need a value for it.
// React can't unset the "value" prop (to show an "indeterminate" bar) after it's already
// been set, so we have to manage it manually.
2016-07-20 08:25:22 +02:00
if ( ! this . state . uploaded ) {
// Still uploading
2016-07-27 17:57:18 +02:00
this . refs . progress . setAttribute ( 'value' , this . state . uploadProgress ) ;
2016-07-20 08:25:22 +02:00
} else {
// Fully uploaded and waiting for server to finish processing, so set progress bar to "indeterminite"
2016-07-27 17:57:18 +02:00
this . refs . progress . removeAttribute ( 'value' ) ;
2016-07-20 08:25:22 +02:00
}
}
2016-07-27 17:57:18 +02:00
} ,
render : function ( ) {
2016-05-23 17:14:21 +02:00
return (
2016-08-08 05:31:21 +02:00
< main ref = "page" >
< section className = "card" >
2016-07-22 17:29:43 +02:00
< h4 > LBRY Name < / h 4 >
2016-08-08 05:31:21 +02:00
< div className = "form-row" >
lbry : //<FormField type="text" ref="name" onChange={this.handleNameChange} />
{
( ! this . state . name ? '' :
2016-09-01 09:30:12 +02:00
( ! this . state . nameResolved ? < em > The name < strong > { this . state . name } < / s t r o n g > i s a v a i l a b l e . < / e m >
: ( this . state . nameIsMine ? < em > You already control the name < strong > { this . state . name } < / s t r o n g > . Y o u c a n u s e t h i s p a g e t o u p d a t e y o u r c l a i m . < / e m >
: < em > The name { this . state . name } is currently claimed for < strong > { lbry . formatCredits ( this . state . claimValue ) } < / s t r o n g > c r e d i t s . < / e m > ) ) )
2016-08-08 05:31:21 +02:00
}
< div className = "help" > What LBRY name would you like to claim for this file ? < / d i v >
< / d i v >
2016-05-23 17:14:21 +02:00
< / s e c t i o n >
2016-08-08 05:31:21 +02:00
< section className = "card" >
2016-07-22 17:29:43 +02:00
< h4 > Choose File < / h 4 >
2016-07-20 08:25:22 +02:00
< form >
2016-07-26 12:09:09 +02:00
< FormField name = "file" ref = "file" type = "file" onChange = { this . handleFileChange } / >
2016-07-20 08:25:22 +02:00
{ ! this . state . fileInfo ? '' :
( ! this . state . tempFileReady ? < div >
2016-07-27 17:57:18 +02:00
< progress ref = 'progress' > < / p r o g r e s s >
2016-07-20 08:25:22 +02:00
{ ! this . state . uploaded ? < span > Importing file into LBRY ... < / s p a n > : < s p a n > P r o c e s s i n g f i l e . . . < / s p a n > }
< / d i v >
: < div > File ready for publishing ! < / d i v > ) }
< / f o r m >
2016-08-08 11:53:41 +02:00
{ this . state . nameIsMine ? < div className = "help" > If you don ' t choose a file , the file from your existing claim will be used . < / d i v > : n u l l }
2016-05-23 17:14:21 +02:00
< / s e c t i o n >
2016-08-08 05:31:21 +02:00
< section className = "card" >
2016-07-22 17:29:43 +02:00
< h4 > Bid Amount < / h 4 >
2016-08-08 05:31:21 +02:00
< div className = "form-row" >
Credits < FormField ref = "bid" style = { publishNumberStyle } type = "text" onChange = { this . handleBidChange } value = { this . state . bid } placeholder = { this . state . nameResolved ? lbry . formatCredits ( this . state . claimValue + 10 ) : 100 } / >
< div className = "help" > How much would you like to bid for this name ?
{ ! this . state . nameResolved ? < span > Since this name is not currently resolved , you may bid as low as you want , but higher bids help prevent others from claiming your name . < / s p a n >
: ( this . state . nameIsMine ? < span > Your current bid is < strong > { lbry . formatCredits ( this . state . claimValue ) } < / s t r o n g > c r e d i t s . < / s p a n >
: < span > You must bid over < strong > { lbry . formatCredits ( this . state . claimValue ) } < / s t r o n g > c r e d i t s t o c l a i m t h i s n a m e . < / s p a n > ) }
< / d i v >
2016-07-22 17:29:43 +02:00
< / d i v >
2016-07-20 08:25:22 +02:00
< / s e c t i o n >
2016-08-08 05:31:21 +02:00
< section className = "card" >
2016-07-20 08:25:22 +02:00
< h4 > Fee < / h 4 >
2016-08-08 05:31:21 +02:00
< div className = "form-row" >
2016-07-22 17:29:43 +02:00
< label >
2016-07-26 12:09:09 +02:00
< FormField type = "radio" onChange = { ( ) => { this . handleFeePrefChange ( false ) } } checked = { ! this . state . isFee } / > No fee
2016-07-22 17:29:43 +02:00
< / l a b e l >
< label >
2016-07-30 07:47:37 +02:00
< FormField type = "radio" onChange = { ( ) => { this . handleFeePrefChange ( true ) } } checked = { this . state . isFee } / > { ! this . state . isFee ? 'Choose fee...' : 'Fee ' }
< span className = { ! this . state . isFee ? 'hidden' : '' } >
< FormField type = "text" onChange = { this . handleFeeAmountChange } style = { publishNumberStyle } / > < FormField type = "select" onChange = { this . handleFeeCurrencyChange } >
2016-08-08 11:47:20 +02:00
< option value = "USD" > US Dollars < / o p t i o n >
2016-07-30 07:47:37 +02:00
< option value = "LBC" > LBRY credits < / o p t i o n >
< / F o r m F i e l d >
< / s p a n >
2016-07-22 17:29:43 +02:00
< / l a b e l >
2016-08-08 05:31:21 +02:00
< div className = "help" >
< p > How much would you like to charge for this file ? < / p >
If you choose to price this content in dollars , the number of credits charged will be adjusted based on the value of LBRY credits at the time of purchase .
< / d i v >
2016-07-30 07:47:37 +02:00
< / d i v >
2016-05-23 17:14:21 +02:00
< / s e c t i o n >
2016-07-20 08:25:22 +02:00
2016-08-08 05:31:21 +02:00
< section className = "card" >
2016-07-22 17:29:43 +02:00
< h4 > Your Content < / h 4 >
2016-07-20 08:25:22 +02:00
2016-08-08 05:31:21 +02:00
< div className = "form-row" >
< label htmlFor = "title" > Title < /label><FormField type="text" ref="meta_title" name="title" placeholder="My Show, Episode 1" style={publishFieldStyle} / >
< / d i v >
< div className = "form-row" >
< label htmlFor = "author" > Author < /label><FormField type="text" ref="meta_author" name="author" placeholder="My Company, Inc." style={publishFieldStyle} / >
< / d i v >
< div className = "form-row" >
2016-07-26 12:09:09 +02:00
< label htmlFor = "license" > License info < /label><FormField type="text" ref="meta_license" name="license" defaultValue="Creative Commons Attribution 3.0 United States" style={publishFieldStyle} / >
2016-08-08 05:31:21 +02:00
< / d i v >
< div className = "form-row" >
2016-08-07 17:27:00 +02:00
< label htmlFor = "language" > Language < / l a b e l > < F o r m F i e l d t y p e = " s e l e c t " d e f a u l t V a l u e = " e n " r e f = " m e t a _ l a n g u a g e " n a m e = " l a n g u a g e " >
< option value = "en" > English < / o p t i o n >
2016-07-20 08:25:22 +02:00
< option value = "zh" > Chinese < / o p t i o n >
< option value = "fr" > French < / o p t i o n >
< option value = "de" > German < / o p t i o n >
< option value = "jp" > Japanese < / o p t i o n >
< option value = "ru" > Russian < / o p t i o n >
< option value = "es" > Spanish < / o p t i o n >
2016-07-26 12:09:09 +02:00
< / F o r m F i e l d >
2016-08-08 05:31:21 +02:00
< / d i v >
< div className = "form-row" >
< label htmlFor = "description" > Description < /label> <FormField type="textarea" ref="meta_description" name="description" placeholder="Description of your content" style={publishFieldStyle} / >
< / d i v >
< div className = "form-row" >
< label > < FormField type = "checkbox" ref = "meta_nsfw" name = "nsfw" placeholder = "Description of your content" / > Not Safe For Work < / l a b e l >
< / d i v >
2016-07-20 08:25:22 +02:00
< / s e c t i o n >
2016-08-07 17:27:00 +02:00
2016-07-20 08:25:22 +02:00
2016-08-08 05:31:21 +02:00
< section className = "card" >
2016-07-26 12:09:09 +02:00
< h4 > Additional Content Information ( Optional ) < / h 4 >
2016-08-08 05:31:21 +02:00
< div className = "form-row" >
< label htmlFor = "meta_thumbnail" > Thumbnail URL < /label> <FormField type="text" ref="meta_thumbnail" name="thumbnail" placeholder="http:/ / mycompany . com / images / ep _1 . jpg " style = { publishFieldStyle } / >
< / d i v >
< div className = "form-row" >
< label htmlFor = "meta_license_url" > License URL < /label> <FormField type="text" ref="meta_license_url" name="license_url" defaultValue="https:/ / creativecommons . org / licenses / by / 3.0 / us / legalcode " style = { publishFieldStyle } / >
< / d i v >
2016-07-26 12:09:09 +02:00
< / s e c t i o n >
2016-05-23 17:14:21 +02:00
2016-08-08 05:31:21 +02:00
< div className = "card-series-submit" >
2016-07-27 17:57:18 +02:00
< Link button = "primary" label = { ! this . state . submitting ? 'Publish' : 'Publishing...' } onClick = { this . handleSubmit } disabled = { this . state . submitting } / >
2016-08-08 05:31:21 +02:00
< Link button = "cancel" href = "/" label = "Cancel" / >
2016-07-22 17:29:43 +02:00
< / d i v >
2016-05-23 17:14:21 +02:00
< / m a i n >
) ;
}
2016-08-08 11:53:41 +02:00
} ) ;