lbry-desktop/ui/component/channelCreate/view.jsx
2020-01-28 09:36:56 -05:00

168 lines
4.7 KiB
JavaScript

// @flow
import React from 'react';
import { isNameValid } from 'lbry-redux';
import { Form, FormField } from 'component/common/form';
import Button from 'component/button';
import analytics from 'analytics';
import { MINIMUM_PUBLISH_BID, INVALID_NAME_ERROR } from 'constants/claim';
type Props = {
balance: number,
createChannel: (string, number) => Promise<any>,
onSuccess?: ({}) => void,
};
type State = {
newChannelName: string,
newChannelBid: number,
creatingChannel: boolean,
newChannelNameError: string,
newChannelBidError: string,
createChannelError: ?string,
};
class ChannelCreate extends React.PureComponent<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
newChannelName: '',
newChannelBid: 0.1,
creatingChannel: false,
newChannelNameError: '',
newChannelBidError: '',
createChannelError: undefined,
};
(this: any).handleNewChannelNameChange = this.handleNewChannelNameChange.bind(this);
(this: any).handleNewChannelBidChange = this.handleNewChannelBidChange.bind(this);
(this: any).handleCreateChannel = this.handleCreateChannel.bind(this);
}
handleNewChannelNameChange(event: SyntheticInputEvent<*>) {
let newChannelName = event.target.value;
if (newChannelName.startsWith('@')) {
newChannelName = newChannelName.slice(1);
}
let newChannelNameError;
if (newChannelName.length > 0 && !isNameValid(newChannelName, false)) {
newChannelNameError = INVALID_NAME_ERROR;
}
this.setState({
newChannelNameError,
newChannelName,
});
}
handleNewChannelBidChange(newChannelBid: number) {
const { balance } = this.props;
let newChannelBidError;
if (newChannelBid === 0) {
newChannelBidError = __('Your deposit cannot be 0');
} else if (newChannelBid === balance) {
newChannelBidError = __('Please decrease your deposit to account for transaction fees');
} else if (newChannelBid > balance) {
newChannelBidError = __('Deposit cannot be higher than your balance');
} else if (newChannelBid < MINIMUM_PUBLISH_BID) {
newChannelBidError = __('Your deposit must be higher');
}
this.setState({
newChannelBid,
newChannelBidError,
});
}
handleCreateChannel() {
const { balance, createChannel, onSuccess } = this.props;
const { newChannelBid, newChannelName } = this.state;
const channelName = `@${newChannelName.trim()}`;
if (newChannelBid > balance) {
return;
}
this.setState({
creatingChannel: true,
createChannelError: undefined,
});
const success = channelClaim => {
this.setState({
creatingChannel: false,
});
analytics.apiLogPublish(channelClaim);
if (onSuccess !== undefined) {
onSuccess({ ...this.props, ...this.state });
}
};
const failure = () => {
this.setState({
creatingChannel: false,
createChannelError: __('Unable to create channel due to an internal error.'),
});
};
createChannel(channelName, newChannelBid).then(success, failure);
}
render() {
const {
newChannelName,
newChannelNameError,
newChannelBid,
newChannelBidError,
creatingChannel,
createChannelError,
} = this.state;
return (
<Form onSubmit={this.handleCreateChannel}>
{createChannelError && <div className="error-text">{createChannelError}</div>}
<div>
<FormField
label={__('Name')}
name="channel-input"
type="text"
placeholder={__('ChannelName')}
error={newChannelNameError}
value={newChannelName}
onChange={this.handleNewChannelNameChange}
/>
<FormField
className="form-field--price-amount"
name="channel-deposit"
label={__('Deposit (LBC)')}
step="any"
min="0"
type="number"
helper={__('This LBC remains yours. It is a deposit to reserve the name and can be undone at any time.')}
error={newChannelBidError}
value={newChannelBid}
onChange={event => this.handleNewChannelBidChange(parseFloat(event.target.value))}
onWheel={e => e.stopPropagation()}
/>
<div className="card__actions">
<Button
type="submit"
button="primary"
label={!creatingChannel ? __('Create channel') : __('Creating channel...')}
disabled={
!newChannelName || !newChannelBid || creatingChannel || newChannelNameError || newChannelBidError
}
/>
</div>
</div>
</Form>
);
}
}
export default ChannelCreate;