2017-12-21 22:08:54 +01:00
import React from 'react' ;
import lbry from 'lbry' ;
2018-01-19 16:12:28 +01:00
import { isNameValid , buildURI , regexInvalidURI } from 'lbryURI' ;
2017-12-21 22:08:54 +01:00
import FormField from 'component/formField' ;
import { Form , FormRow , Submit } from 'component/form.js' ;
import Link from 'component/link' ;
import FormFieldPrice from 'component/formFieldPrice' ;
import Modal from 'modal/modal' ;
import { BusyMessage } from 'component/common' ;
import ChannelSection from './internal/channelSection' ;
2017-06-30 10:45:54 +02:00
class PublishForm extends React . PureComponent {
constructor ( props ) {
super ( props ) ;
2017-12-21 22:08:54 +01:00
this . _requiredFields = [ 'name' , 'bid' , 'meta_title' , 'tosAgree' ] ;
2017-06-30 10:45:54 +02:00
2017-12-21 22:08:54 +01:00
this . _defaultCopyrightNotice = 'All rights reserved.' ;
2017-08-30 15:02:40 +02:00
this . _defaultPaidPrice = 0.01 ;
2017-06-30 10:45:54 +02:00
this . state = {
2017-09-17 03:50:44 +02:00
id : null ,
2017-09-23 01:02:23 +02:00
uri : null ,
2017-12-21 22:08:54 +01:00
rawName : '' ,
name : '' ,
2017-06-30 10:45:54 +02:00
bid : 10 ,
hasFile : false ,
2017-12-21 22:08:54 +01:00
feeAmount : '' ,
feeCurrency : 'LBC' ,
channel : 'anonymous' ,
newChannelName : '@' ,
2017-06-30 10:45:54 +02:00
newChannelBid : 10 ,
2017-12-21 22:08:54 +01:00
meta _title : '' ,
meta _thumbnail : '' ,
meta _description : '' ,
meta _language : 'en' ,
meta _nsfw : '0' ,
licenseType : '' ,
2017-06-30 10:45:54 +02:00
copyrightNotice : this . _defaultCopyrightNotice ,
2017-12-21 22:08:54 +01:00
otherLicenseDescription : '' ,
otherLicenseUrl : '' ,
2017-06-30 10:45:54 +02:00
tosAgree : false ,
prefillDone : false ,
uploadProgress : 0.0 ,
uploaded : false ,
errorMessage : null ,
submitting : false ,
creatingChannel : false ,
modal : null ,
2017-07-18 08:45:00 +02:00
isFee : false ,
2017-07-22 11:10:37 +02:00
customUrl : false ,
2017-08-31 02:57:50 +02:00
source : null ,
2017-12-21 22:08:54 +01:00
mode : 'publish' ,
2017-06-30 10:45:54 +02:00
} ;
}
_updateChannelList ( channel ) {
const { fetchingChannels , fetchChannelListMine } = this . props ;
if ( ! fetchingChannels ) fetchChannelListMine ( ) ;
}
2017-09-11 03:25:24 +02:00
handleSubmit ( ) {
2017-06-30 10:45:54 +02:00
this . setState ( {
submitting : true ,
} ) ;
2017-12-21 22:08:54 +01:00
const checkFields = this . _requiredFields ;
2017-06-30 10:45:54 +02:00
if ( ! this . myClaimExists ( ) ) {
2017-12-21 22:08:54 +01:00
checkFields . unshift ( 'file' ) ;
2017-06-30 10:45:54 +02:00
}
let missingFieldFound = false ;
2017-12-21 22:08:54 +01:00
for ( const fieldName of checkFields ) {
2017-06-30 10:45:54 +02:00
const field = this . refs [ fieldName ] ;
if ( field ) {
2017-12-21 22:08:54 +01:00
if ( field . getValue ( ) === '' || field . getValue ( ) === false ) {
2017-06-30 10:45:54 +02:00
field . showRequiredError ( ) ;
if ( ! missingFieldFound ) {
field . focus ( ) ;
missingFieldFound = true ;
}
} else {
field . clearError ( ) ;
}
}
}
if ( missingFieldFound ) {
this . setState ( {
submitting : false ,
} ) ;
return ;
}
2017-12-21 22:08:54 +01:00
const metadata = { } ;
2017-06-30 10:45:54 +02:00
2017-12-21 22:08:54 +01:00
for ( const metaField of [ 'title' , 'description' , 'thumbnail' , 'language' ] ) {
const value = this . state [ ` meta_ ${ metaField } ` ] ;
2017-06-30 10:45:54 +02:00
if ( value ) {
metadata [ metaField ] = value ;
}
}
metadata . license = this . getLicense ( ) ;
metadata . licenseUrl = this . getLicenseUrl ( ) ;
metadata . nsfw = ! ! parseInt ( this . state . meta _nsfw ) ;
2017-12-21 22:08:54 +01:00
const doPublish = ( ) => {
const publishArgs = {
2017-06-30 10:45:54 +02:00
name : this . state . name ,
bid : parseFloat ( this . state . bid ) ,
2017-12-21 22:08:54 +01:00
metadata ,
... ( this . state . channel != 'new' && this . state . channel != 'anonymous'
2017-06-30 10:45:54 +02:00
? { channel _name : this . state . channel }
: { } ) ,
} ;
2017-08-31 02:57:50 +02:00
const { source } = this . state ;
2017-06-30 10:45:54 +02:00
2017-12-21 22:08:54 +01:00
if ( this . refs . file . getValue ( ) !== '' ) {
2017-06-30 10:45:54 +02:00
publishArgs . file _path = this . refs . file . getValue ( ) ;
2017-08-31 02:57:50 +02:00
} else if ( source ) {
publishArgs . sources = source ;
2017-06-30 10:45:54 +02:00
}
const success = claim => { } ;
const failure = error => this . handlePublishError ( error ) ;
this . handlePublishStarted ( ) ;
this . props . publish ( publishArgs ) . then ( success , failure ) ;
} ;
2017-08-07 00:24:55 +02:00
if ( this . state . isFee && parseFloat ( this . state . feeAmount ) > 0 ) {
2017-06-30 10:45:54 +02:00
lbry . wallet _unused _address ( ) . then ( address => {
metadata . fee = {
currency : this . state . feeCurrency ,
amount : parseFloat ( this . state . feeAmount ) ,
2017-12-21 22:08:54 +01:00
address ,
2017-06-30 10:45:54 +02:00
} ;
doPublish ( ) ;
} ) ;
} else {
doPublish ( ) ;
}
}
handlePublishStarted ( ) {
this . setState ( {
2017-12-21 22:08:54 +01:00
modal : 'publishStarted' ,
2017-06-30 10:45:54 +02:00
} ) ;
}
handlePublishStartedConfirmed ( ) {
2017-12-21 22:08:54 +01:00
this . props . navigate ( '/published' ) ;
2017-06-30 10:45:54 +02:00
}
handlePublishError ( error ) {
this . setState ( {
submitting : false ,
2017-12-21 22:08:54 +01:00
modal : 'error' ,
2017-06-30 10:45:54 +02:00
errorMessage : error . message ,
} ) ;
}
claim ( ) {
const { claimsByUri } = this . props ;
const { uri } = this . state ;
return claimsByUri [ uri ] ;
}
topClaimValue ( ) {
if ( ! this . claim ( ) ) return null ;
2017-10-11 15:57:33 +02:00
return parseFloat ( this . claim ( ) . effective _amount ) ;
2017-06-30 10:45:54 +02:00
}
myClaimExists ( ) {
const { myClaims } = this . props ;
const { name } = this . state ;
if ( ! name ) return false ;
return ! ! myClaims . find ( claim => claim . name === name ) ;
}
2017-08-26 04:09:56 +02:00
handleEditClaim ( ) {
2017-09-17 03:50:44 +02:00
const claimInfo = this . claim ( ) || this . myClaimInfo ( ) ;
2017-08-26 04:09:56 +02:00
2017-09-17 03:50:44 +02:00
if ( claimInfo ) {
this . handlePrefillClaim ( claimInfo ) ;
2017-08-26 04:09:56 +02:00
}
}
2017-06-30 10:45:54 +02:00
topClaimIsMine ( ) {
const myClaimInfo = this . myClaimInfo ( ) ;
const { claimsByUri } = this . props ;
const { uri } = this . state ;
if ( ! uri ) return null ;
const claim = claimsByUri [ uri ] ;
if ( ! claim ) return true ;
if ( ! myClaimInfo ) return false ;
2017-07-12 09:05:10 +02:00
return myClaimInfo . amount >= claim . amount ;
2017-06-30 10:45:54 +02:00
}
myClaimInfo ( ) {
2017-09-17 03:50:44 +02:00
const { id } = this . state ;
2017-06-30 10:45:54 +02:00
2017-12-21 22:08:54 +01:00
return Object . values ( this . props . myClaims ) . find ( claim => claim . claim _id === id ) ;
2017-06-30 10:45:54 +02:00
}
handleNameChange ( event ) {
2017-12-21 22:08:54 +01:00
const rawName = event . target . value ;
2017-07-22 11:10:37 +02:00
this . setState ( {
customUrl : Boolean ( rawName . length ) ,
} ) ;
2017-06-30 10:45:54 +02:00
this . nameChanged ( rawName ) ;
}
nameChanged ( rawName ) {
if ( ! rawName ) {
this . setState ( {
2017-12-21 22:08:54 +01:00
rawName : '' ,
name : '' ,
uri : '' ,
2017-06-30 10:45:54 +02:00
prefillDone : false ,
2017-12-21 22:08:54 +01:00
mode : 'publish' ,
2017-06-30 10:45:54 +02:00
} ) ;
return ;
}
2018-01-19 16:12:28 +01:00
if ( ! isNameValid ( rawName , false ) ) {
2017-12-21 22:08:54 +01:00
this . refs . name . showError ( _ _ ( 'LBRY names must contain only letters, numbers and dashes.' ) ) ;
2017-06-30 10:45:54 +02:00
return ;
}
2017-12-21 22:08:54 +01:00
let channel = '' ;
if ( this . state . channel !== 'anonymous' ) channel = this . state . channel ;
2017-06-30 10:45:54 +02:00
const name = rawName . toLowerCase ( ) ;
2018-01-19 16:12:28 +01:00
const uri = buildURI ( { contentName : name , channelName : channel } ) ;
2017-06-30 10:45:54 +02:00
this . setState ( {
2017-12-21 22:08:54 +01:00
rawName ,
name ,
2017-06-30 10:45:54 +02:00
prefillDone : false ,
2017-12-21 22:08:54 +01:00
mode : 'publish' ,
2017-06-30 10:45:54 +02:00
uri ,
} ) ;
if ( this . resolveUriTimeout ) {
clearTimeout ( this . resolveUriTimeout ) ;
this . resolveUriTimeout = undefined ;
}
const resolve = ( ) => this . props . resolveUri ( uri ) ;
this . resolveUriTimeout = setTimeout ( resolve . bind ( this ) , 500 , {
once : true ,
} ) ;
}
2017-09-17 03:50:44 +02:00
handlePrefillClaim ( claimInfo ) {
const { claim _id , name , channel _name , amount } = claimInfo ;
const { source , metadata } = claimInfo . value . stream ;
2017-12-21 22:08:54 +01:00
const { license , licenseUrl , title , thumbnail , description , language , nsfw } = metadata ;
const newState = {
2017-09-17 03:50:44 +02:00
id : claim _id ,
2017-12-21 22:08:54 +01:00
channel : channel _name || 'anonymous' ,
2017-09-17 03:50:44 +02:00
bid : amount ,
2017-06-30 10:45:54 +02:00
meta _title : title ,
meta _thumbnail : thumbnail ,
meta _description : description ,
meta _language : language ,
meta _nsfw : nsfw ,
2017-12-21 22:08:54 +01:00
mode : 'edit' ,
2017-06-30 10:45:54 +02:00
prefillDone : true ,
2017-09-17 03:50:44 +02:00
rawName : name ,
name ,
2017-08-31 02:57:50 +02:00
source ,
2017-06-30 10:45:54 +02:00
} ;
if ( license == this . _defaultCopyrightNotice ) {
2017-12-21 22:08:54 +01:00
newState . licenseType = 'copyright' ;
2017-06-30 10:45:54 +02:00
newState . copyrightNotice = this . _defaultCopyrightNotice ;
} else {
// If the license URL or description matches one of the drop-down options, use that
2017-12-21 22:08:54 +01:00
let licenseType = 'other' ; // Will be overridden if we find a match
for ( const option of this . _meta _license . getOptions ( ) ) {
if ( option . getAttribute ( 'data-url' ) === licenseUrl || option . text === license ) {
2017-06-30 10:45:54 +02:00
licenseType = option . value ;
}
}
2017-12-21 22:08:54 +01:00
if ( licenseType == 'other' ) {
2017-06-30 10:45:54 +02:00
newState . otherLicenseDescription = license ;
newState . otherLicenseUrl = licenseUrl ;
}
newState . licenseType = licenseType ;
}
this . setState ( newState ) ;
}
handleBidChange ( event ) {
this . setState ( {
2017-08-13 00:20:33 +02:00
bid : event . target . value ,
2017-06-30 10:45:54 +02:00
} ) ;
}
2017-08-07 00:24:55 +02:00
handleFeeChange ( newValue ) {
2017-08-07 04:21:20 +02:00
this . setState ( {
feeAmount : newValue . amount ,
feeCurrency : newValue . currency ,
} ) ;
2017-06-30 10:45:54 +02:00
}
handleFeePrefChange ( feeEnabled ) {
this . setState ( {
isFee : feeEnabled ,
2017-12-21 22:08:54 +01:00
feeAmount : this . state . feeAmount == '' ? this . _defaultPaidPrice : this . state . feeAmount ,
2017-06-30 10:45:54 +02:00
} ) ;
}
handleMetadataChange ( event ) {
/ * *
* This function is used for all metadata inputs that store the final value directly into state .
* The only exceptions are inputs related to license description and license URL , which require
* more complex logic and the final value is determined at submit time .
* /
this . setState ( {
2017-12-21 22:08:54 +01:00
[ ` meta_ ${ event . target . name } ` ] : event . target . value ,
2017-06-30 10:45:54 +02:00
} ) ;
}
handleDescriptionChanged ( text ) {
this . setState ( {
meta _description : text ,
} ) ;
}
handleLicenseTypeChange ( event ) {
this . setState ( {
licenseType : event . target . value ,
} ) ;
}
handleCopyrightNoticeChange ( event ) {
this . setState ( {
copyrightNotice : event . target . value ,
} ) ;
}
handleOtherLicenseDescriptionChange ( event ) {
this . setState ( {
otherLicenseDescription : event . target . value ,
} ) ;
}
handleOtherLicenseUrlChange ( event ) {
this . setState ( {
otherLicenseUrl : event . target . value ,
} ) ;
}
handleChannelChange ( channelName ) {
this . setState ( {
2017-12-21 22:08:54 +01:00
mode : 'publish' ,
2017-06-30 10:45:54 +02:00
channel : channelName ,
} ) ;
const nameChanged = ( ) => this . nameChanged ( this . state . rawName ) ;
setTimeout ( nameChanged . bind ( this ) , 500 , { once : true } ) ;
}
handleTOSChange ( event ) {
this . setState ( {
tosAgree : event . target . checked ,
} ) ;
}
getLicense ( ) {
switch ( this . state . licenseType ) {
2017-12-21 22:08:54 +01:00
case 'copyright' :
2017-06-30 10:45:54 +02:00
return this . state . copyrightNotice ;
2017-12-21 22:08:54 +01:00
case 'other' :
2017-06-30 10:45:54 +02:00
return this . state . otherLicenseDescription ;
default :
return this . _meta _license . getSelectedElement ( ) . text ;
}
}
getLicenseUrl ( ) {
switch ( this . state . licenseType ) {
2017-12-21 22:08:54 +01:00
case 'copyright' :
return '' ;
case 'other' :
2017-06-30 10:45:54 +02:00
return this . state . otherLicenseUrl ;
default :
2017-12-21 22:08:54 +01:00
return this . _meta _license . getSelectedElement ( ) . getAttribute ( 'data-url' ) ;
2017-06-30 10:45:54 +02:00
}
}
componentWillMount ( ) {
this . props . fetchClaimListMine ( ) ;
this . _updateChannelList ( ) ;
2017-08-26 04:09:56 +02:00
2017-09-17 03:50:44 +02:00
const { id } = this . props . params ;
this . setState ( { id } ) ;
2017-08-26 04:09:56 +02:00
}
componentDidMount ( ) {
this . handleEditClaim ( ) ;
2017-06-30 10:45:54 +02:00
}
onFileChange ( ) {
2017-09-23 01:02:23 +02:00
const { mode } = this . state ;
2017-06-30 10:45:54 +02:00
if ( this . refs . file . getValue ( ) ) {
this . setState ( { hasFile : true } ) ;
2017-12-21 22:08:54 +01:00
if ( ! this . state . customUrl && mode !== 'edit' ) {
const fileName = this . _getFileName ( this . refs . file . getValue ( ) ) ;
2017-07-22 11:10:37 +02:00
this . nameChanged ( fileName ) ;
}
2017-06-30 10:45:54 +02:00
} else {
this . setState ( { hasFile : false } ) ;
}
}
2017-07-22 11:10:37 +02:00
_getFileName ( fileName ) {
2017-12-21 22:08:54 +01:00
const path = require ( 'path' ) ;
2017-07-22 11:10:37 +02:00
const extension = path . extname ( fileName ) ;
fileName = path . basename ( fileName , extension ) ;
2018-01-19 16:12:28 +01:00
fileName = fileName . replace ( regexInvalidURI , '' ) ;
2017-07-22 11:10:37 +02:00
return fileName ;
}
2017-06-30 10:45:54 +02:00
getNameBidHelpText ( ) {
2017-09-17 03:50:44 +02:00
const { prefillDone , name , uri } = this . state ;
const { resolvingUris } = this . props ;
const claim = this . claim ( ) ;
if ( prefillDone ) {
2017-12-21 22:08:54 +01:00
return _ _ ( 'Existing claim data was prefilled' ) ;
2017-06-30 10:45:54 +02:00
}
2017-09-17 03:50:44 +02:00
if ( uri && resolvingUris . indexOf ( uri ) !== - 1 && claim === undefined ) {
2017-12-21 22:08:54 +01:00
return _ _ ( 'Checking...' ) ;
2017-09-17 03:50:44 +02:00
} else if ( ! name ) {
2017-12-21 22:08:54 +01:00
return _ _ ( 'Select a URL for this publish.' ) ;
2017-09-17 03:50:44 +02:00
} else if ( ! claim ) {
2017-12-21 22:08:54 +01:00
return _ _ ( 'This URL is unused.' ) ;
2017-09-17 03:50:44 +02:00
} else if ( this . myClaimExists ( ) && ! prefillDone ) {
2017-06-30 10:45:54 +02:00
return (
2017-07-12 09:05:10 +02:00
< span >
2017-12-21 22:08:54 +01:00
{ _ _ ( 'You already have a claim with this name.' ) } { ' ' }
< Link label = { _ _ ( 'Edit existing claim' ) } onClick = { ( ) => this . handleEditClaim ( ) } / >
2017-07-12 09:05:10 +02:00
< / span >
2017-06-30 10:45:54 +02:00
) ;
2017-09-17 03:50:44 +02:00
} else if ( claim ) {
const topClaimValue = this . topClaimValue ( ) ;
if ( topClaimValue === 1 ) {
2017-06-30 10:45:54 +02:00
return (
< span >
{ _ _ (
'A deposit of at least one credit is required to win "%s". However, you can still get a permanent URL for any amount.' ,
2017-09-17 03:50:44 +02:00
name
2017-06-30 10:45:54 +02:00
) }
< / span >
) ;
}
2017-12-21 22:08:54 +01:00
return (
< span >
{ _ _ (
'A deposit of at least "%s" credits is required to win "%s". However, you can still get a permanent URL for any amount.' ,
topClaimValue ,
name
) }
< / span >
) ;
2017-06-30 10:45:54 +02:00
}
2017-12-21 22:08:54 +01:00
return '' ;
2017-06-30 10:45:54 +02:00
}
closeModal ( ) {
this . setState ( {
modal : null ,
} ) ;
}
render ( ) {
2017-09-05 03:03:48 +02:00
const { mode , submitting } = this . state ;
2017-12-21 22:08:54 +01:00
const lbcInputHelp = _ _ ( 'This LBC remains yours and the deposit can be undone at any time.' ) ;
2017-06-30 10:45:54 +02:00
2017-12-21 22:08:54 +01:00
let submitLabel = ! submitting ? _ _ ( 'Publish' ) : _ _ ( 'Publishing...' ) ;
2017-09-05 03:03:48 +02:00
2017-12-21 22:08:54 +01:00
if ( mode === 'edit' ) {
submitLabel = ! submitting ? _ _ ( 'Update' ) : _ _ ( 'Updating...' ) ;
2017-09-05 03:03:48 +02:00
}
2017-06-30 10:45:54 +02:00
return (
< main className = "main--single-column" >
2017-09-11 03:25:24 +02:00
< Form onSubmit = { this . handleSubmit . bind ( this ) } >
2017-06-30 10:45:54 +02:00
< section className = "card" >
< div className = "card__title-primary" >
2017-12-21 22:08:54 +01:00
< h4 > { _ _ ( 'Content' ) } < / h4 >
< div className = "card__subtitle" > { _ _ ( 'What are you publishing?' ) } < / div >
2017-06-30 10:45:54 +02:00
< / div >
< div className = "card__content" >
< FormRow
name = "file"
ref = "file"
type = "file"
onChange = { event => {
this . onFileChange ( event ) ;
} }
helper = {
this . myClaimExists ( )
? _ _ (
"If you don't choose a file, the file from your existing claim will be used."
)
: null
}
/ >
< / div >
2017-11-21 20:51:12 +01:00
{ ! this . state . hasFile && ! this . myClaimExists ( ) ? null : (
< div >
< div className = "card__content" >
< FormRow
ref = "meta_title"
2017-12-21 22:08:54 +01:00
label = { _ _ ( 'Title' ) }
2017-11-21 20:51:12 +01:00
type = "text"
name = "title"
value = { this . state . meta _title }
placeholder = "Titular Title"
onChange = { event => {
this . handleMetadataChange ( event ) ;
} }
/ >
< / div >
< div className = "card__content" >
< FormRow
type = "text"
2017-12-21 22:08:54 +01:00
label = { _ _ ( 'Thumbnail URL' ) }
2017-11-21 20:51:12 +01:00
name = "thumbnail"
value = { this . state . meta _thumbnail }
placeholder = "http://spee.ch/mylogo"
onChange = { event => {
this . handleMetadataChange ( event ) ;
} }
/ >
< / div >
< div className = "card__content" >
< FormRow
type = "SimpleMDE"
2017-12-21 22:08:54 +01:00
label = { _ _ ( 'Description' ) }
2017-11-21 20:51:12 +01:00
ref = "meta_description"
name = "description"
value = { this . state . meta _description }
2017-12-21 22:08:54 +01:00
placeholder = { _ _ ( 'Description of your content' ) }
2017-11-21 20:51:12 +01:00
onChange = { text => {
this . handleDescriptionChanged ( text ) ;
} }
/ >
< / div >
< div className = "card__content" >
< FormRow
2017-12-21 22:08:54 +01:00
label = { _ _ ( 'Language' ) }
2017-11-21 20:51:12 +01:00
type = "select"
value = { this . state . meta _language }
name = "language"
onChange = { event => {
this . handleMetadataChange ( event ) ;
} }
>
2017-12-21 22:08:54 +01:00
< option value = "en" > { _ _ ( 'English' ) } < / option >
< option value = "zh" > { _ _ ( 'Chinese' ) } < / option >
< option value = "fr" > { _ _ ( 'French' ) } < / option >
< option value = "de" > { _ _ ( 'German' ) } < / option >
< option value = "jp" > { _ _ ( 'Japanese' ) } < / option >
< option value = "ru" > { _ _ ( 'Russian' ) } < / option >
< option value = "es" > { _ _ ( 'Spanish' ) } < / option >
2017-11-21 20:51:12 +01:00
< / FormRow >
< / div >
< div className = "card__content" >
< FormRow
type = "select"
2017-12-21 22:08:54 +01:00
label = { _ _ ( 'Maturity' ) }
2017-11-21 20:51:12 +01:00
value = { this . state . meta _nsfw }
name = "nsfw"
onChange = { event => {
this . handleMetadataChange ( event ) ;
} }
>
{ /* <option value=""></option> */ }
2017-12-21 22:08:54 +01:00
< option value = "0" > { _ _ ( 'All Ages' ) } < / option >
< option value = "1" > { _ _ ( 'Adults Only' ) } < / option >
2017-11-21 20:51:12 +01:00
< / FormRow >
< / div >
< / div >
) }
2017-06-30 10:45:54 +02:00
< / section >
< section className = "card" >
< div className = "card__title-primary" >
2017-12-21 22:08:54 +01:00
< h4 > { _ _ ( 'Price' ) } < / h4 >
< div className = "card__subtitle" > { _ _ ( 'How much does this content cost?' ) } < / div >
2017-06-30 10:45:54 +02:00
< / div >
< div className = "card__content" >
< FormRow
2017-12-21 22:08:54 +01:00
label = { _ _ ( 'Free' ) }
2017-06-30 10:45:54 +02:00
type = "radio"
name = "isFree"
2017-07-18 08:45:00 +02:00
onChange = { ( ) => this . handleFeePrefChange ( false ) }
checked = { ! this . state . isFee }
2017-06-30 10:45:54 +02:00
/ >
< FormField
type = "radio"
name = "isFree"
2017-12-21 22:08:54 +01:00
label = { ! this . state . isFee ? _ _ ( 'Choose price...' ) : _ _ ( 'Price ' ) }
2017-06-30 10:45:54 +02:00
onChange = { ( ) => {
this . handleFeePrefChange ( true ) ;
} }
2017-07-18 08:45:00 +02:00
checked = { this . state . isFee }
2017-06-30 10:45:54 +02:00
/ >
2017-12-21 22:08:54 +01:00
< span className = { ! this . state . isFee ? 'hidden' : '' } >
2017-08-04 05:31:53 +02:00
< FormFieldPrice
2017-08-07 00:24:55 +02:00
min = "0"
2017-11-10 16:41:22 +01:00
defaultValue = { {
amount : this . _defaultPaidPrice ,
2017-12-21 22:08:54 +01:00
currency : 'LBC' ,
2017-11-10 16:41:22 +01:00
} }
2017-08-07 00:24:55 +02:00
onChange = { val => this . handleFeeChange ( val ) }
2017-08-04 05:31:53 +02:00
/ >
2017-06-30 10:45:54 +02:00
< / span >
2017-12-21 22:08:54 +01:00
{ this . state . isFee && this . state . feeCurrency . toUpperCase ( ) != 'LBC' ? (
2017-11-21 20:51:12 +01:00
< div className = "form-field__helper" >
{ _ _ (
2017-12-21 22:08:54 +01:00
'All content fees are charged in LBC. For non-LBC payment methods, the number of credits charged will be adjusted based on the value of LBRY credits at the time of purchase.'
2017-11-21 20:51:12 +01:00
) }
< / div >
) : null }
2017-10-14 21:41:04 +02:00
< / div >
< / section >
< section className = "card" >
< div className = "card__title-primary" >
2017-12-21 22:08:54 +01:00
< h4 > { _ _ ( 'License' ) } < / h4 >
2017-10-14 21:41:04 +02:00
< / div >
< div className = "card__content" >
2017-06-30 10:45:54 +02:00
< FormRow
type = "select"
value = { this . state . licenseType }
ref = { row => {
this . _meta _license = row ;
} }
onChange = { event => {
this . handleLicenseTypeChange ( event ) ;
} }
>
2017-12-21 22:08:54 +01:00
< option > { _ _ ( 'None' ) } < / option >
< option value = "publicDomain" > { _ _ ( 'Public Domain' ) } < / option >
2017-06-30 10:45:54 +02:00
< option
value = "cc-by"
data - url = "https://creativecommons.org/licenses/by/4.0/legalcode"
>
2017-12-21 22:08:54 +01:00
{ _ _ ( 'Creative Commons Attribution 4.0 International' ) }
2017-06-30 10:45:54 +02:00
< / option >
< option
value = "cc-by-sa"
data - url = "https://creativecommons.org/licenses/by-sa/4.0/legalcode"
>
2017-12-21 22:08:54 +01:00
{ _ _ ( 'Creative Commons Attribution-ShareAlike 4.0 International' ) }
2017-06-30 10:45:54 +02:00
< / option >
< option
value = "cc-by-nd"
data - url = "https://creativecommons.org/licenses/by-nd/4.0/legalcode"
>
2017-12-21 22:08:54 +01:00
{ _ _ ( 'Creative Commons Attribution-NoDerivatives 4.0 International' ) }
2017-06-30 10:45:54 +02:00
< / option >
< option
value = "cc-by-nc"
data - url = "https://creativecommons.org/licenses/by-nc/4.0/legalcode"
>
2017-12-21 22:08:54 +01:00
{ _ _ ( 'Creative Commons Attribution-NonCommercial 4.0 International' ) }
2017-06-30 10:45:54 +02:00
< / option >
< option
value = "cc-by-nc-sa"
data - url = "https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode"
>
2017-12-21 22:08:54 +01:00
{ _ _ ( 'Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International' ) }
2017-06-30 10:45:54 +02:00
< / option >
< option
value = "cc-by-nc-nd"
data - url = "https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode"
>
2017-12-21 22:08:54 +01:00
{ _ _ ( 'Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International' ) }
2017-06-30 10:45:54 +02:00
< / option >
2017-12-21 22:08:54 +01:00
< option value = "copyright" > { _ _ ( 'Copyrighted...' ) } < / option >
< option value = "other" > { _ _ ( 'Other...' ) } < / option >
2017-06-30 10:45:54 +02:00
< / FormRow >
2017-12-21 22:08:54 +01:00
{ this . state . licenseType == 'copyright' ? (
2017-11-21 20:51:12 +01:00
< FormRow
2017-12-21 22:08:54 +01:00
label = { _ _ ( 'Copyright notice' ) }
2017-11-21 20:51:12 +01:00
type = "text"
name = "copyright-notice"
value = { this . state . copyrightNotice }
onChange = { event => {
this . handleCopyrightNoticeChange ( event ) ;
} }
/ >
) : null }
2017-12-21 22:08:54 +01:00
{ this . state . licenseType == 'other' ? (
2017-11-21 20:51:12 +01:00
< FormRow
2017-12-21 22:08:54 +01:00
label = { _ _ ( 'License description' ) }
2017-11-21 20:51:12 +01:00
type = "text"
name = "other-license-description"
value = { this . state . otherLicenseDescription }
onChange = { event => {
this . handleOtherLicenseDescriptionChange ( event ) ;
} }
/ >
) : null }
2017-12-21 22:08:54 +01:00
{ this . state . licenseType == 'other' ? (
2017-11-21 20:51:12 +01:00
< FormRow
2017-12-21 22:08:54 +01:00
label = { _ _ ( 'License URL' ) }
2017-11-21 20:51:12 +01:00
type = "text"
name = "other-license-url"
value = { this . state . otherLicenseUrl }
onChange = { event => {
this . handleOtherLicenseUrlChange ( event ) ;
} }
/ >
) : null }
2017-06-30 10:45:54 +02:00
< / div >
< / section >
< ChannelSection
{ ... this . props }
handleChannelChange = { this . handleChannelChange . bind ( this ) }
channel = { this . state . channel }
/ >
< section className = "card" >
< div className = "card__title-primary" >
2017-12-21 22:08:54 +01:00
< h4 > { _ _ ( 'Content URL' ) } < / h4 >
2017-06-30 10:45:54 +02:00
< div className = "card__subtitle" >
2017-07-19 17:23:32 +02:00
{ _ _ (
2017-12-21 22:08:54 +01:00
'This is the exact address where people find your content (ex. lbry://myvideo).'
) } { ' ' }
< Link label = { _ _ ( 'Learn more' ) } href = "https://lbry.io/faq/naming" / > .
2017-06-30 10:45:54 +02:00
< / div >
< / div >
< div className = "card__content" >
< FormRow
2017-11-21 20:51:12 +01:00
prefix = { ` lbry:// ${
2017-12-21 22:08:54 +01:00
this . state . channel === 'anonymous' ? '' : ` ${ this . state . channel } / `
2017-11-21 20:51:12 +01:00
} ` }
2017-06-30 10:45:54 +02:00
type = "text"
ref = "name"
placeholder = "myname"
value = { this . state . rawName }
onChange = { event => {
this . handleNameChange ( event ) ;
} }
helper = { this . getNameBidHelpText ( ) }
/ >
< / div >
2017-11-21 20:51:12 +01:00
{ this . state . rawName ? (
< div className = "card__content" >
< FormRow
ref = "bid"
type = "number"
step = "any"
2017-12-21 22:08:54 +01:00
label = { _ _ ( 'Deposit' ) }
2017-11-21 20:51:12 +01:00
postfix = "LBC"
onChange = { event => {
this . handleBidChange ( event ) ;
} }
value = { this . state . bid }
placeholder = { this . claim ( ) ? this . topClaimValue ( ) + 10 : 100 }
helper = { lbcInputHelp }
min = "0"
/ >
< / div >
) : (
2017-12-21 22:08:54 +01:00
''
2017-11-21 20:51:12 +01:00
) }
2017-06-30 10:45:54 +02:00
< / section >
< section className = "card" >
< div className = "card__title-primary" >
2017-12-21 22:08:54 +01:00
< h4 > { _ _ ( 'Terms of Service' ) } < / h4 >
2017-06-30 10:45:54 +02:00
< / div >
< div className = "card__content" >
< FormRow
2017-08-09 23:03:06 +02:00
ref = "tosAgree"
2017-06-30 10:45:54 +02:00
label = {
< span >
2017-12-21 22:08:54 +01:00
{ _ _ ( 'I agree to the' ) } { ' ' }
2017-06-30 10:45:54 +02:00
< Link
href = "https://www.lbry.io/termsofservice"
2017-12-21 22:08:54 +01:00
label = { _ _ ( 'LBRY terms of service' ) }
2017-06-30 10:45:54 +02:00
/ >
< / span >
}
type = "checkbox"
checked = { this . state . tosAgree }
onChange = { event => {
this . handleTOSChange ( event ) ;
} }
/ >
< / div >
< / section >
< div className = "card-series-submit" >
2017-09-11 03:25:24 +02:00
< Submit
2017-12-21 22:08:54 +01:00
label = { ! this . state . submitting ? _ _ ( 'Publish' ) : _ _ ( 'Publishing...' ) }
2017-07-08 10:03:12 +02:00
disabled = {
2017-12-07 19:07:30 +01:00
this . props . balance <= 0 ||
2017-07-08 10:03:12 +02:00
this . state . submitting ||
2017-12-21 22:08:54 +01:00
( this . state . uri && this . props . resolvingUris . indexOf ( this . state . uri ) !== - 1 ) ||
( this . claim ( ) && ! this . topClaimIsMine ( ) && this . state . bid <= this . topClaimValue ( ) )
2017-07-08 10:03:12 +02:00
}
2017-06-30 10:45:54 +02:00
/ >
2017-12-21 22:08:54 +01:00
< Link button = "cancel" onClick = { this . props . back } label = { _ _ ( 'Cancel' ) } / >
2017-06-30 10:45:54 +02:00
< / div >
2017-09-11 03:25:24 +02:00
< / Form >
2017-06-30 10:45:54 +02:00
< Modal
2017-12-21 22:08:54 +01:00
isOpen = { this . state . modal == 'publishStarted' }
contentLabel = { _ _ ( 'File published' ) }
2017-06-30 10:45:54 +02:00
onConfirmed = { event => {
this . handlePublishStartedConfirmed ( event ) ;
} }
>
< p >
2017-12-21 22:08:54 +01:00
{ _ _ ( 'Your file has been published to LBRY at the address' ) } { ' ' }
2017-11-21 20:51:12 +01:00
< code > { this . state . uri } < / code > !
2017-06-30 10:45:54 +02:00
< / p >
< p >
{ _ _ (
'The file will take a few minutes to appear for other LBRY users. Until then it will be listed as "pending" under your published files.'
) }
< / p >
< / Modal >
< Modal
2017-12-21 22:08:54 +01:00
isOpen = { this . state . modal == 'error' }
contentLabel = { _ _ ( 'Error publishing file' ) }
2017-06-30 10:45:54 +02:00
onConfirmed = { event => {
this . closeModal ( event ) ;
} }
>
2017-12-21 22:08:54 +01:00
{ _ _ ( 'The following error occurred when attempting to publish your file' ) } : { ' ' }
{ this . state . errorMessage }
2017-06-30 10:45:54 +02:00
< / Modal >
< / main >
) ;
}
}
export default PublishForm ;