2016-11-22 21:19:08 +01:00
|
|
|
import React from 'react';
|
2017-05-02 10:21:00 +02:00
|
|
|
import lbry from 'lbry';
|
2017-05-19 01:14:26 +02:00
|
|
|
import lbryuri from 'lbryuri'
|
2017-05-02 10:21:00 +02:00
|
|
|
import {FormField, FormRow} from 'component/form.js';
|
2017-04-07 07:15:22 +02:00
|
|
|
import Link from 'component/link';
|
2017-05-02 10:21:00 +02:00
|
|
|
import rewards from 'rewards';
|
|
|
|
import Modal from 'component/modal';
|
2016-11-22 21:19:08 +01:00
|
|
|
|
2017-05-17 10:10:25 +02:00
|
|
|
class PublishPage extends React.Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2016-07-26 12:09:09 +02:00
|
|
|
|
2017-05-17 10:10:25 +02:00
|
|
|
this._requiredFields = ['meta_title', 'name', 'bid', 'tos_agree'];
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
channels: null,
|
|
|
|
rawName: '',
|
|
|
|
name: '',
|
|
|
|
bid: 10,
|
|
|
|
hasFile: false,
|
|
|
|
feeAmount: '',
|
|
|
|
feeCurrency: 'USD',
|
|
|
|
channel: 'anonymous',
|
|
|
|
newChannelName: '@',
|
|
|
|
newChannelBid: 10,
|
|
|
|
nameResolved: null,
|
|
|
|
myClaimExists: null,
|
|
|
|
topClaimValue: 0.0,
|
|
|
|
myClaimValue: 0.0,
|
|
|
|
myClaimMetadata: null,
|
|
|
|
copyrightNotice: '',
|
|
|
|
otherLicenseDescription: '',
|
|
|
|
otherLicenseUrl: '',
|
|
|
|
uploadProgress: 0.0,
|
|
|
|
uploaded: false,
|
|
|
|
errorMessage: null,
|
|
|
|
submitting: false,
|
|
|
|
creatingChannel: false,
|
|
|
|
modal: null,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
_updateChannelList(channel) {
|
2017-04-10 10:06:15 +02:00
|
|
|
// Calls API to update displayed list of channels. If a channel name is provided, will select
|
|
|
|
// that channel at the same time (used immediately after creating a channel)
|
|
|
|
lbry.channel_list_mine().then((channels) => {
|
2017-04-15 00:23:42 +02:00
|
|
|
rewards.claimReward(rewards.TYPE_FIRST_CHANNEL).then(() => {}, () => {})
|
2017-04-10 10:06:15 +02:00
|
|
|
this.setState({
|
|
|
|
channels: channels,
|
|
|
|
... channel ? {channel} : {}
|
|
|
|
});
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleSubmit(event) {
|
2016-10-19 08:36:42 +02:00
|
|
|
if (typeof event !== 'undefined') {
|
|
|
|
event.preventDefault();
|
|
|
|
}
|
|
|
|
|
2016-07-21 08:58:06 +02:00
|
|
|
this.setState({
|
|
|
|
submitting: true,
|
|
|
|
});
|
|
|
|
|
2017-04-12 16:55:19 +02:00
|
|
|
let checkFields = this._requiredFields;
|
2016-09-17 07:45:42 +02:00
|
|
|
if (!this.state.myClaimExists) {
|
2017-04-12 16:55:19 +02:00
|
|
|
checkFields.unshift('file');
|
2016-08-08 11:53:41 +02:00
|
|
|
}
|
|
|
|
|
2017-04-12 16:55:19 +02:00
|
|
|
let missingFieldFound = false;
|
2016-08-08 11:53:41 +02:00
|
|
|
for (let fieldName of checkFields) {
|
2017-04-12 16:55:19 +02:00
|
|
|
const field = this.refs[fieldName];
|
|
|
|
if (field) {
|
|
|
|
if (field.getValue() === '' || field.getValue() === false) {
|
|
|
|
field.showRequiredError();
|
|
|
|
if (!missingFieldFound) {
|
|
|
|
field.focus();
|
|
|
|
missingFieldFound = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
field.clearError();
|
2016-07-26 12:09:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-08 20:11:58 +01:00
|
|
|
if (missingFieldFound) {
|
2016-07-26 12:09:09 +02:00
|
|
|
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
|
2016-09-17 07:45:42 +02:00
|
|
|
var metadata = Object.assign({}, this.state.myClaimMetadata);
|
2016-08-23 07:03:03 +02:00
|
|
|
if (this.refs.file.getValue() !== '') {
|
|
|
|
delete metadata.sources;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
var metadata = {};
|
|
|
|
}
|
2016-08-27 08:18:19 +02:00
|
|
|
|
2017-04-13 22:40:29 +02:00
|
|
|
for (let metaField of ['title', 'description', 'thumbnail', 'license', 'license_url', 'language']) {
|
2016-07-27 17:57:18 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-23 21:51:47 +02:00
|
|
|
metadata.nsfw = parseInt(this.refs.meta_nsfw.getValue()) === 1;
|
2017-04-13 22:40:29 +02:00
|
|
|
|
|
|
|
const licenseUrl = this.refs.meta_license_url.getValue();
|
2016-07-27 17:57:18 +02:00
|
|
|
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,
|
2017-04-10 10:07:48 +02:00
|
|
|
... this.state.channel != 'new' && this.state.channel != 'anonymous' ? {channel_name: this.state.channel} : {},
|
2016-08-08 11:53:41 +02:00
|
|
|
};
|
|
|
|
|
2016-08-23 07:03:03 +02:00
|
|
|
if (this.refs.file.getValue() !== '') {
|
2017-04-12 18:59:43 +02:00
|
|
|
publishArgs.file_path = this.refs.file.getValue();
|
2016-08-08 11:53:41 +02:00
|
|
|
}
|
2017-04-10 14:32:40 +02:00
|
|
|
|
2016-08-08 11:53:41 +02:00
|
|
|
lbry.publish(publishArgs, (message) => {
|
2016-09-16 17:23:39 +02:00
|
|
|
this.handlePublishStarted();
|
|
|
|
}, null, (error) => {
|
2016-07-21 08:58:06 +02:00
|
|
|
this.handlePublishError(error);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2016-07-20 08:25:22 +02:00
|
|
|
if (this.state.isFee) {
|
2017-05-18 19:58:28 +02:00
|
|
|
lbry.wallet_unused_address().then((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();
|
|
|
|
}
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handlePublishStarted() {
|
2016-10-21 09:56:37 +02:00
|
|
|
this.setState({
|
|
|
|
modal: 'publishStarted',
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handlePublishStartedConfirmed() {
|
2017-05-06 18:31:47 +02:00
|
|
|
this.props.navigate('/published')
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handlePublishError(error) {
|
2016-10-21 09:56:37 +02:00
|
|
|
this.setState({
|
|
|
|
submitting: false,
|
|
|
|
modal: 'error',
|
|
|
|
errorMessage: error.message,
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleNameChange(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({
|
2016-11-18 09:49:16 +01:00
|
|
|
rawName: '',
|
2016-07-15 14:04:47 +02:00
|
|
|
name: '',
|
|
|
|
nameResolved: false,
|
2016-07-20 08:25:22 +02:00
|
|
|
});
|
2016-07-15 14:04:47 +02:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-19 01:14:26 +02:00
|
|
|
if (!lbryuri.isValidName(rawName, false)) {
|
2017-04-09 17:06:23 +02:00
|
|
|
this.refs.name.showError('LBRY names must contain only letters, numbers and dashes.');
|
2016-11-18 10:01:25 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-14 19:44:06 +02:00
|
|
|
const name = rawName.toLowerCase();
|
2016-11-18 09:49:16 +01:00
|
|
|
this.setState({
|
|
|
|
rawName: rawName,
|
2017-04-14 19:44:06 +02:00
|
|
|
name: name,
|
|
|
|
nameResolved: null,
|
|
|
|
myClaimExists: null,
|
2016-11-18 09:49:16 +01:00
|
|
|
});
|
|
|
|
|
2017-05-19 01:14:26 +02:00
|
|
|
const myClaimInfo = Object.values(this.props.myClaims).find(claim => claim.name === name)
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
myClaimExists: !!myClaimInfo,
|
|
|
|
});
|
|
|
|
lbry.resolve({uri: name}).then((claimInfo) => {
|
2017-04-14 19:44:06 +02:00
|
|
|
if (name != this.state.name) {
|
2016-08-10 09:05:17 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-04-14 19:44:06 +02:00
|
|
|
|
2017-05-19 01:14:26 +02:00
|
|
|
if (!claimInfo) {
|
2017-04-11 06:12:34 +02:00
|
|
|
this.setState({
|
|
|
|
nameResolved: false,
|
2016-07-15 14:04:47 +02:00
|
|
|
});
|
2017-05-19 01:14:26 +02:00
|
|
|
} else {
|
2017-05-26 10:09:27 +02:00
|
|
|
const topClaimIsMine = myClaimInfo && myClaimInfo.amount >= claimInfo.amount;
|
2017-05-19 01:14:26 +02:00
|
|
|
const newState = {
|
|
|
|
nameResolved: true,
|
2017-05-26 10:09:27 +02:00
|
|
|
topClaimValue: parseFloat(claimInfo.amount),
|
2017-05-19 01:14:26 +02:00
|
|
|
myClaimExists: !!myClaimInfo,
|
2017-05-26 10:09:27 +02:00
|
|
|
myClaimValue: myClaimInfo ? parseFloat(myClaimInfo.amount) : null,
|
2017-05-19 01:14:26 +02:00
|
|
|
myClaimMetadata: myClaimInfo ? myClaimInfo.value : null,
|
|
|
|
topClaimIsMine: topClaimIsMine,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (topClaimIsMine) {
|
2017-05-26 10:09:27 +02:00
|
|
|
newState.bid = myClaimInfo.amount;
|
2017-05-19 01:14:26 +02:00
|
|
|
} else if (this.state.myClaimMetadata) {
|
|
|
|
// Just changed away from a name we have a claim on, so clear pre-fill
|
|
|
|
newState.bid = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setState(newState);
|
|
|
|
}
|
|
|
|
}, () => { // Assume an error means the name is available
|
|
|
|
this.setState({
|
|
|
|
name: name,
|
|
|
|
nameResolved: false,
|
|
|
|
myClaimExists: false,
|
2017-04-11 03:45:41 +02:00
|
|
|
});
|
2016-07-15 14:04:47 +02:00
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleBidChange(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
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleFeeAmountChange(event) {
|
2016-07-15 14:04:47 +02:00
|
|
|
this.setState({
|
2016-07-30 07:47:37 +02:00
|
|
|
feeAmount: event.target.value,
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleFeeCurrencyChange(event) {
|
2016-07-30 07:47:37 +02:00
|
|
|
this.setState({
|
|
|
|
feeCurrency: event.target.value,
|
2016-07-20 08:25:22 +02:00
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleFeePrefChange(feeEnabled) {
|
2016-07-20 08:25:22 +02:00
|
|
|
this.setState({
|
|
|
|
isFee: feeEnabled
|
2016-07-15 14:04:47 +02:00
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleLicenseChange(event) {
|
2016-09-20 12:40:24 +02:00
|
|
|
var licenseType = event.target.options[event.target.selectedIndex].getAttribute('data-license-type');
|
|
|
|
var newState = {
|
|
|
|
copyrightChosen: licenseType == 'copyright',
|
|
|
|
otherLicenseChosen: licenseType == 'other',
|
|
|
|
};
|
|
|
|
|
|
|
|
if (licenseType == 'copyright') {
|
2017-04-10 20:12:07 +02:00
|
|
|
newState.copyrightNotice = 'All rights reserved.'
|
2016-09-20 12:40:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
this.setState(newState);
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleCopyrightNoticeChange(event) {
|
2016-09-20 12:40:24 +02:00
|
|
|
this.setState({
|
|
|
|
copyrightNotice: event.target.value,
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleOtherLicenseDescriptionChange(event) {
|
2016-09-20 12:40:24 +02:00
|
|
|
this.setState({
|
|
|
|
otherLicenseDescription: event.target.value,
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleOtherLicenseUrlChange(event) {
|
2016-09-20 12:40:24 +02:00
|
|
|
this.setState({
|
|
|
|
otherLicenseUrl: event.target.value,
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleChannelChange(event) {
|
2017-04-08 14:30:17 +02:00
|
|
|
const channel = event.target.value;
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
channel: channel,
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleNewChannelNameChange(event) {
|
2017-04-08 14:30:17 +02:00
|
|
|
const newChannelName = (event.target.value.startsWith('@') ? event.target.value : '@' + event.target.value);
|
|
|
|
|
2017-05-19 01:14:26 +02:00
|
|
|
if (newChannelName.length > 1 && !lbryuri.isValidName(newChannelName.substr(1), false)) {
|
2017-04-10 20:12:07 +02:00
|
|
|
this.refs.newChannelName.showError('LBRY channel names must contain only letters, numbers and dashes.');
|
2017-04-08 14:30:17 +02:00
|
|
|
return;
|
2017-04-12 16:55:19 +02:00
|
|
|
} else {
|
|
|
|
this.refs.newChannelName.clearError()
|
2017-04-08 14:30:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
newChannelName: newChannelName,
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleNewChannelBidChange(event) {
|
2017-04-08 14:30:17 +02:00
|
|
|
this.setState({
|
|
|
|
newChannelBid: event.target.value,
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleTOSChange(event) {
|
2017-04-14 01:39:59 +02:00
|
|
|
this.setState({
|
|
|
|
TOSAgreed: event.target.checked,
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handleCreateChannelClick(event) {
|
2017-04-10 10:08:43 +02:00
|
|
|
if (this.state.newChannelName.length < 5) {
|
2017-04-10 20:12:07 +02:00
|
|
|
this.refs.newChannelName.showError('LBRY channel names must be at least 4 characters in length.');
|
2017-04-10 10:08:43 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-08 14:30:17 +02:00
|
|
|
this.setState({
|
|
|
|
creatingChannel: true,
|
|
|
|
});
|
|
|
|
|
2017-04-10 10:06:15 +02:00
|
|
|
const newChannelName = this.state.newChannelName;
|
|
|
|
lbry.channel_new({channel_name: newChannelName, amount: parseInt(this.state.newChannelBid)}).then(() => {
|
|
|
|
setTimeout(() => {
|
|
|
|
this.setState({
|
|
|
|
creatingChannel: false,
|
|
|
|
});
|
2017-04-08 14:30:17 +02:00
|
|
|
|
2017-04-10 10:06:15 +02:00
|
|
|
this._updateChannelList(newChannelName);
|
|
|
|
}, 5000);
|
2017-04-08 14:30:17 +02:00
|
|
|
}, (error) => {
|
2017-04-10 10:09:01 +02:00
|
|
|
// TODO: better error handling
|
2017-04-10 20:12:07 +02:00
|
|
|
this.refs.newChannelName.showError('Unable to create channel due to an internal error.');
|
2017-04-08 14:30:17 +02:00
|
|
|
this.setState({
|
|
|
|
creatingChannel: false,
|
|
|
|
});
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
getLicenseUrl() {
|
2016-09-20 12:40:24 +02:00
|
|
|
if (!this.refs.meta_license) {
|
|
|
|
return '';
|
|
|
|
} else if (this.state.otherLicenseChosen) {
|
|
|
|
return this.state.otherLicenseUrl;
|
|
|
|
} else {
|
2016-09-21 08:57:20 +02:00
|
|
|
return this.refs.meta_license.getSelectedElement().getAttribute('data-url') || '' ;
|
2016-09-20 12:40:24 +02:00
|
|
|
}
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
componentWillMount() {
|
2017-04-10 10:06:15 +02:00
|
|
|
this._updateChannelList();
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
onFileChange() {
|
2017-04-10 20:12:07 +02:00
|
|
|
if (this.refs.file.getValue()) {
|
|
|
|
this.setState({ hasFile: true })
|
|
|
|
} else {
|
|
|
|
this.setState({ hasFile: false })
|
|
|
|
}
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
getNameBidHelpText() {
|
2017-04-10 20:12:07 +02:00
|
|
|
if (!this.state.name) {
|
|
|
|
return "Select a URL for this publish.";
|
2017-04-14 19:44:06 +02:00
|
|
|
} else if (this.state.nameResolved === false) {
|
2017-04-10 20:12:07 +02:00
|
|
|
return "This URL is unused.";
|
|
|
|
} else if (this.state.myClaimExists) {
|
|
|
|
return "You have already used this URL. Publishing to it again will update your previous publish."
|
|
|
|
} else if (this.state.topClaimValue) {
|
2017-04-12 16:55:19 +02:00
|
|
|
return <span>A deposit of at least <strong>{this.state.topClaimValue}</strong> {this.state.topClaimValue == 1 ? 'credit ' : 'credits '}
|
2017-04-14 19:44:06 +02:00
|
|
|
is required to win <strong>{this.state.name}</strong>. However, you can still get a permanent URL for any amount.</span>
|
2017-04-10 20:12:07 +02:00
|
|
|
} else {
|
|
|
|
return '';
|
|
|
|
}
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
closeModal() {
|
2017-04-12 16:55:19 +02:00
|
|
|
this.setState({
|
|
|
|
modal: null,
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2017-04-08 14:30:17 +02:00
|
|
|
if (this.state.channels === null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2017-04-12 16:55:19 +02:00
|
|
|
const lbcInputHelp = "This LBC remains yours and the deposit can be undone at any time."
|
|
|
|
|
2016-05-23 17:14:21 +02:00
|
|
|
return (
|
2017-05-01 02:15:21 +02:00
|
|
|
<main className="main--single-column">
|
2017-05-18 03:37:39 +02:00
|
|
|
<form onSubmit={(event) => { this.handleSubmit(event) }}>
|
2016-10-19 04:30:57 +02:00
|
|
|
<section className="card">
|
2017-04-10 14:32:40 +02:00
|
|
|
<div className="card__title-primary">
|
2017-04-10 20:12:07 +02:00
|
|
|
<h4>Content</h4>
|
|
|
|
<div className="card__subtitle">
|
|
|
|
What are you publishing?
|
|
|
|
</div>
|
2017-04-10 14:32:40 +02:00
|
|
|
</div>
|
|
|
|
<div className="card__content">
|
2017-05-18 03:37:39 +02:00
|
|
|
<FormRow name="file" label="File" ref="file" type="file" onChange={(event) => { this.onFileChange(event) }}
|
2017-04-10 20:12:07 +02:00
|
|
|
helper={this.state.myClaimExists ? "If you don't choose a file, the file from your existing claim will be used." : null}/>
|
2016-10-19 04:30:57 +02:00
|
|
|
</div>
|
2017-04-10 20:12:07 +02:00
|
|
|
{ !this.state.hasFile ? '' :
|
2017-04-12 16:55:19 +02:00
|
|
|
<div>
|
|
|
|
<div className="card__content">
|
2017-04-12 18:59:43 +02:00
|
|
|
<FormRow label="Title" type="text" ref="meta_title" name="title" placeholder="Titular Title" />
|
2017-04-12 16:55:19 +02:00
|
|
|
</div>
|
2017-04-10 20:12:07 +02:00
|
|
|
<div className="card__content">
|
2017-04-12 18:59:43 +02:00
|
|
|
<FormRow type="text" label="Thumbnail URL" ref="meta_thumbnail" name="thumbnail" placeholder="http://spee.ch/mylogo" />
|
2017-04-12 16:55:19 +02:00
|
|
|
</div>
|
|
|
|
<div className="card__content">
|
2017-04-10 20:12:07 +02:00
|
|
|
<FormRow label="Description" type="textarea" ref="meta_description" name="description" placeholder="Description of your content" />
|
2017-04-12 16:55:19 +02:00
|
|
|
</div>
|
|
|
|
<div className="card__content">
|
2017-04-10 20:12:07 +02:00
|
|
|
<FormRow label="Language" type="select" defaultValue="en" ref="meta_language" name="language">
|
|
|
|
<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>
|
|
|
|
</FormRow>
|
2017-04-12 16:55:19 +02:00
|
|
|
</div>
|
|
|
|
<div className="card__content">
|
2017-04-10 20:12:07 +02:00
|
|
|
<FormRow type="select" label="Maturity" defaultValue="en" ref="meta_nsfw" name="nsfw">
|
2017-04-13 22:40:29 +02:00
|
|
|
{/* <option value=""></option> */}
|
2017-04-10 20:12:07 +02:00
|
|
|
<option value="0">All Ages</option>
|
|
|
|
<option value="1">Adults Only</option>
|
|
|
|
</FormRow>
|
2017-04-12 16:55:19 +02:00
|
|
|
</div>
|
|
|
|
</div>}
|
2016-10-19 04:30:57 +02:00
|
|
|
</section>
|
2016-05-23 17:14:21 +02:00
|
|
|
|
2017-04-08 14:30:17 +02:00
|
|
|
<section className="card">
|
2017-04-10 20:12:07 +02:00
|
|
|
<div className="card__title-primary">
|
|
|
|
<h4>Access</h4>
|
|
|
|
<div className="card__subtitle">
|
2017-04-14 19:44:06 +02:00
|
|
|
How much does this content cost?
|
2017-04-10 20:12:07 +02:00
|
|
|
</div>
|
2017-04-08 14:30:17 +02:00
|
|
|
</div>
|
2017-04-10 14:32:40 +02:00
|
|
|
<div className="card__content">
|
2017-04-10 20:12:07 +02:00
|
|
|
<div className="form-row__label-row">
|
|
|
|
<label className="form-row__label">Price</label>
|
2016-10-19 04:30:57 +02:00
|
|
|
</div>
|
2017-04-12 16:55:19 +02:00
|
|
|
<FormRow label="Free" type="radio" name="isFree" value="1" onChange={ () => { this.handleFeePrefChange(false) } } defaultChecked={!this.state.isFee} />
|
2017-04-10 20:12:07 +02:00
|
|
|
<FormField type="radio" name="isFree" label={!this.state.isFee ? 'Choose price...' : 'Price ' }
|
2017-04-12 16:55:19 +02:00
|
|
|
onChange={ () => { this.handleFeePrefChange(true) } } defaultChecked={this.state.isFee} />
|
2017-04-10 20:12:07 +02:00
|
|
|
<span className={!this.state.isFee ? 'hidden' : ''}>
|
2017-05-18 03:37:39 +02:00
|
|
|
<FormField type="number" className="form-field__input--inline" step="0.01" placeholder="1.00" onChange={(event) => this.handleFeeAmountChange(event)} /> <FormField type="select" onChange={(event) => { this.handleFeeCurrencyChange(event) }}>
|
2017-04-10 20:12:07 +02:00
|
|
|
<option value="USD">US Dollars</option>
|
|
|
|
<option value="LBC">LBRY credits</option>
|
|
|
|
</FormField>
|
|
|
|
</span>
|
|
|
|
{ this.state.isFee ?
|
2017-04-12 16:55:19 +02:00
|
|
|
<div className="form-field__helper">
|
2017-04-10 20:12:07 +02:00
|
|
|
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.
|
|
|
|
</div> : '' }
|
2017-05-18 03:37:39 +02:00
|
|
|
<FormRow label="License" type="select" ref="meta_license" name="license" onChange={(event) => { this.handleLicenseChange(event) }}>
|
2017-04-12 16:55:19 +02:00
|
|
|
<option></option>
|
|
|
|
<option>Public Domain</option>
|
2017-04-10 20:12:07 +02:00
|
|
|
<option data-url="https://creativecommons.org/licenses/by/4.0/legalcode">Creative Commons Attribution 4.0 International</option>
|
|
|
|
<option data-url="https://creativecommons.org/licenses/by-sa/4.0/legalcode">Creative Commons Attribution-ShareAlike 4.0 International</option>
|
|
|
|
<option data-url="https://creativecommons.org/licenses/by-nd/4.0/legalcode">Creative Commons Attribution-NoDerivatives 4.0 International</option>
|
|
|
|
<option data-url="https://creativecommons.org/licenses/by-nc/4.0/legalcode">Creative Commons Attribution-NonCommercial 4.0 International</option>
|
|
|
|
<option data-url="https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International</option>
|
|
|
|
<option data-url="https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode">Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International</option>
|
|
|
|
<option data-license-type="copyright" {... this.state.copyrightChosen ? {value: this.state.copyrightNotice} : {}}>Copyrighted...</option>
|
|
|
|
<option data-license-type="other" {... this.state.otherLicenseChosen ? {value: this.state.otherLicenseDescription} : {}}>Other...</option>
|
|
|
|
</FormRow>
|
|
|
|
<FormField type="hidden" ref="meta_license_url" name="license_url" value={this.getLicenseUrl()} />
|
|
|
|
{this.state.copyrightChosen
|
|
|
|
? <FormRow label="Copyright notice" type="text" name="copyright-notice"
|
2017-05-18 03:37:39 +02:00
|
|
|
value={this.state.copyrightNotice} onChange={(event) => { this.handleCopyrightNoticeChange(event) }} />
|
2017-04-10 20:12:07 +02:00
|
|
|
: null}
|
|
|
|
{this.state.otherLicenseChosen ?
|
2017-05-18 03:37:39 +02:00
|
|
|
<FormRow label="License description" type="text" name="other-license-description" onChange={(event) => { this.handleOtherLicenseDescriptionChange() }} />
|
2017-04-10 20:12:07 +02:00
|
|
|
: null}
|
|
|
|
{this.state.otherLicenseChosen ?
|
2017-05-18 03:37:39 +02:00
|
|
|
<FormRow label="License URL" type="text" name="other-license-url" onChange={(event) => { this.handleOtherLicenseUrlChange(event) }} />
|
2017-04-10 20:12:07 +02:00
|
|
|
: null}
|
2016-08-08 05:31:21 +02:00
|
|
|
</div>
|
2016-10-19 04:30:57 +02:00
|
|
|
</section>
|
|
|
|
|
|
|
|
<section className="card">
|
2017-04-10 20:12:07 +02:00
|
|
|
<div className="card__title-primary">
|
|
|
|
<h4>Identity</h4>
|
|
|
|
<div className="card__subtitle">
|
|
|
|
Who created this content?
|
2016-10-19 04:30:57 +02:00
|
|
|
</div>
|
2016-08-08 05:31:21 +02:00
|
|
|
</div>
|
2017-04-10 20:12:07 +02:00
|
|
|
<div className="card__content">
|
2017-05-18 03:37:39 +02:00
|
|
|
<FormRow type="select" tabIndex="1" onChange={(event) => { this.handleChannelChange(event) }} value={this.state.channel}>
|
2017-04-10 20:12:07 +02:00
|
|
|
<option key="anonymous" value="anonymous">Anonymous</option>
|
|
|
|
{this.state.channels.map(({name}) => <option key={name} value={name}>{name}</option>)}
|
|
|
|
<option key="new" value="new">New identity...</option>
|
|
|
|
</FormRow>
|
2016-10-19 04:30:57 +02:00
|
|
|
</div>
|
2017-04-10 20:12:07 +02:00
|
|
|
{this.state.channel == 'new' ?
|
|
|
|
<div className="card__content">
|
2017-05-18 03:37:39 +02:00
|
|
|
<FormRow label="Name" type="text" onChange={(event) => { this.handleNewChannelNameChange(event) }} ref={newChannelName => { this.refs.newChannelName = newChannelName }}
|
2017-04-10 20:12:07 +02:00
|
|
|
value={this.state.newChannelName} />
|
2017-04-12 16:55:19 +02:00
|
|
|
<FormRow label="Deposit"
|
|
|
|
postfix="LBC"
|
|
|
|
step="0.01"
|
|
|
|
type="number"
|
|
|
|
helper={lbcInputHelp}
|
2017-05-18 03:37:39 +02:00
|
|
|
onChange={(event) => { this.handleNewChannelBidChange(event) }}
|
2017-04-12 18:59:43 +02:00
|
|
|
value={this.state.newChannelBid} />
|
2017-04-10 20:12:07 +02:00
|
|
|
<div className="form-row-submit">
|
2017-05-18 03:37:39 +02:00
|
|
|
<Link button="primary" label={!this.state.creatingChannel ? 'Create identity' : 'Creating identity...'} onClick={(event) => { this.handleCreateChannelClick(event) }} disabled={this.state.creatingChannel} />
|
2017-04-10 20:12:07 +02:00
|
|
|
</div>
|
2016-10-19 04:30:57 +02:00
|
|
|
</div>
|
|
|
|
: null}
|
|
|
|
</section>
|
2016-07-20 08:25:22 +02:00
|
|
|
|
2016-08-07 17:27:00 +02:00
|
|
|
|
2016-10-19 04:30:57 +02:00
|
|
|
<section className="card">
|
2017-04-10 20:12:07 +02:00
|
|
|
<div className="card__title-primary">
|
|
|
|
<h4>Address</h4>
|
2017-04-12 16:55:19 +02:00
|
|
|
<div className="card__subtitle">Where should this content permanently reside? <Link label="Read more" href="https://lbry.io/faq/naming" />.</div>
|
2017-04-10 20:12:07 +02:00
|
|
|
</div>
|
|
|
|
<div className="card__content">
|
2017-05-18 03:37:39 +02:00
|
|
|
<FormRow prefix="lbry://" type="text" ref="name" placeholder="myname" value={this.state.rawName} onChange={(event) => { this.handleNameChange(event) }}
|
2017-04-12 16:55:19 +02:00
|
|
|
helper={this.getNameBidHelpText()} />
|
2016-10-19 04:30:57 +02:00
|
|
|
</div>
|
2017-04-10 20:12:07 +02:00
|
|
|
{ this.state.rawName ?
|
|
|
|
<div className="card__content">
|
|
|
|
<FormRow ref="bid"
|
|
|
|
type="number"
|
|
|
|
step="0.01"
|
|
|
|
label="Deposit"
|
2017-04-12 16:55:19 +02:00
|
|
|
postfix="LBC"
|
2017-05-18 03:37:39 +02:00
|
|
|
onChange={(event) => { this.handleBidChange(event) }}
|
2017-04-12 18:59:43 +02:00
|
|
|
value={this.state.bid}
|
2017-04-10 20:12:07 +02:00
|
|
|
placeholder={this.state.nameResolved ? this.state.topClaimValue + 10 : 100}
|
2017-04-12 16:55:19 +02:00
|
|
|
helper={lbcInputHelp} />
|
2017-04-10 20:12:07 +02:00
|
|
|
</div> : '' }
|
2016-10-19 04:30:57 +02:00
|
|
|
</section>
|
2016-05-23 17:14:21 +02:00
|
|
|
|
2017-04-14 01:39:59 +02:00
|
|
|
<section className="card">
|
|
|
|
<div className="card__title-primary">
|
|
|
|
<h4>Terms of Service</h4>
|
|
|
|
</div>
|
|
|
|
<div className="card__content">
|
|
|
|
<FormRow label={
|
|
|
|
<span>I agree to the <Link href="https://www.lbry.io/termsofservice" label="LBRY terms of service" checked={this.state.TOSAgreed} /></span>
|
2017-05-18 03:37:39 +02:00
|
|
|
} type="checkbox" name="tos_agree" ref={(field) => { this.refs.tos_agree = field }} onChange={(event) => { this.handleTOSChange(event)}} />
|
2017-04-14 01:39:59 +02:00
|
|
|
</div>
|
|
|
|
</section>
|
|
|
|
|
2016-10-19 04:30:57 +02:00
|
|
|
<div className="card-series-submit">
|
2017-05-18 03:37:39 +02:00
|
|
|
<Link button="primary" label={!this.state.submitting ? 'Publish' : 'Publishing...'} onClick={(event) => { this.handleSubmit(event) }} disabled={this.state.submitting} />
|
2017-05-21 18:15:41 +02:00
|
|
|
<Link button="cancel" onClick={this.props.back} label="Cancel" />
|
2017-03-01 00:23:49 +01:00
|
|
|
<input type="submit" className="hidden" />
|
2016-10-19 04:30:57 +02:00
|
|
|
</div>
|
|
|
|
</form>
|
2016-10-21 09:56:37 +02:00
|
|
|
|
2017-01-13 23:05:09 +01:00
|
|
|
<Modal isOpen={this.state.modal == 'publishStarted'} contentLabel="File published"
|
2017-05-18 03:37:39 +02:00
|
|
|
onConfirmed={(event) => { this.handlePublishStartedConfirmed(event) }}>
|
2016-10-21 09:56:37 +02:00
|
|
|
<p>Your file has been published to LBRY at the address <code>lbry://{this.state.name}</code>!</p>
|
2017-04-17 14:27:39 +02:00
|
|
|
<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>
|
2016-10-21 09:56:37 +02:00
|
|
|
</Modal>
|
2017-01-13 23:05:09 +01:00
|
|
|
<Modal isOpen={this.state.modal == 'error'} contentLabel="Error publishing file"
|
2017-05-18 03:37:39 +02:00
|
|
|
onConfirmed={(event) => { this.closeModal(event) }}>
|
2016-10-21 09:56:37 +02:00
|
|
|
The following error occurred when attempting to publish your file: {this.state.errorMessage}
|
|
|
|
</Modal>
|
2016-10-19 04:30:57 +02:00
|
|
|
</main>
|
2016-05-23 17:14:21 +02:00
|
|
|
);
|
|
|
|
}
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
2016-11-22 21:19:08 +01:00
|
|
|
|
|
|
|
export default PublishPage;
|