lbry-react-native/src/component/channelSelector/view.js
Akinwale Ariwodola 88e450eb08 post-0.9.0 fixes
2019-09-25 23:21:39 +01:00

267 lines
8.6 KiB
JavaScript

import React from 'react';
import { CLAIM_VALUES, isNameValid } from 'lbry-redux';
import { ActivityIndicator, Picker, Text, TextInput, TouchableOpacity, View } from 'react-native';
import Button from 'component/button';
import Colors from 'styles/colors';
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
import Icon from 'react-native-vector-icons/FontAwesome5';
import Link from 'component/link';
import channelSelectorStyle from 'styles/channelSelector';
export default class ChannelSelector extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
currentSelectedValue: Constants.ITEM_ANONYMOUS,
newChannelName: '',
newChannelBid: 0.1,
addingChannel: false,
creatingChannel: false,
newChannelNameError: '',
newChannelBidError: '',
createChannelError: undefined,
showCreateChannel: false,
};
}
componentDidMount() {
const { channels = [], channelName, fetchChannelListMine, fetchingChannels } = this.props;
if ((!channels || channels.length === 0) && !fetchingChannels) {
fetchChannelListMine();
}
this.setState({ currentSelectedValue: channelName });
}
componentWillReceiveProps(nextProps) {
const { channels: prevChannels = [], channelName } = this.props;
const { channels = [] } = nextProps;
if (channels && channels.length !== prevChannels.length && channelName !== this.state.currentSelectedValue) {
this.setState({ currentSelectedValue: channelName });
}
}
handleCreateCancel = () => {
this.setState({ showCreateChannel: false, newChannelName: '', newChannelBid: 0.1 });
};
handlePickerValueChange = (itemValue, itemIndex) => {
if (Constants.ITEM_CREATE_A_CHANNEL === itemValue) {
this.setState({ showCreateChannel: true });
} else {
this.handleCreateCancel();
this.handleChannelChange(Constants.ITEM_ANONYMOUS === itemValue ? CLAIM_VALUES.CHANNEL_ANONYMOUS : itemValue);
}
this.setState({ currentSelectedValue: itemValue });
};
handleChannelChange = value => {
const { onChannelChange } = this.props;
const { newChannelBid } = this.state;
const channel = value;
if (channel === CLAIM_VALUES.CHANNEL_NEW) {
this.setState({ addingChannel: true });
if (onChannelChange) {
onChannelChange(value);
}
this.handleNewChannelBidChange(newChannelBid);
} else {
this.setState({ addingChannel: false });
if (onChannelChange) {
onChannelChange(value);
}
}
};
handleNewChannelNameChange = value => {
const { notify } = this.props;
let newChannelName = value,
newChannelNameError = '';
if (newChannelName.startsWith('@')) {
newChannelName = newChannelName.slice(1);
}
if (newChannelName.trim().length > 0 && !isNameValid(newChannelName)) {
newChannelNameError = 'Your channel name contains invalid characters.';
} else if (this.channelExists(newChannelName)) {
newChannelNameError = 'You have already created a channel with the same name.';
}
this.setState({
newChannelName,
newChannelNameError,
});
};
handleNewChannelBidChange = newChannelBid => {
const { balance, notify } = this.props;
let newChannelBidError;
if (newChannelBid <= 0) {
newChannelBidError = __('Please enter a deposit above 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');
}
notify({ message: newChannelBidError });
this.setState({
newChannelBid,
newChannelBidError,
});
};
handleCreateChannelClick = () => {
const { balance, createChannel, onChannelChange, notify } = this.props;
const { newChannelBid, newChannelName } = this.state;
if (newChannelName.trim().length === 0 || !isNameValid(newChannelName.substr(1), false)) {
notify({ message: 'Your channel name contains invalid characters.' });
return;
}
if (this.channelExists(newChannelName)) {
notify({ message: 'You have already created a channel with the same name.' });
return;
}
if (newChannelBid > balance) {
notify({ message: 'Deposit cannot be higher than your balance' });
return;
}
const channelName = `@${newChannelName}`;
this.setState({
creatingChannel: true,
createChannelError: undefined,
});
const success = () => {
this.setState({
creatingChannel: false,
addingChannel: false,
currentSelectedValue: channelName,
showCreateChannel: false,
});
if (onChannelChange) {
onChannelChange(channelName);
}
};
const failure = () => {
notify({ message: 'Unable to create channel due to an internal error.' });
this.setState({
creatingChannel: false,
});
};
createChannel(channelName, newChannelBid).then(success, failure);
};
channelExists = name => {
const { channels = [] } = this.props;
if (channels) {
for (let channel of channels) {
if (
name.toLowerCase() === channel.name.toLowerCase() ||
`@${name}`.toLowerCase() === channel.name.toLowerCase()
) {
return true;
}
}
}
return false;
};
render() {
const channel = this.state.addingChannel ? 'new' : this.props.channel;
const { enabled, fetchingChannels, channels = [] } = this.props;
const pickerItems = [Constants.ITEM_ANONYMOUS, Constants.ITEM_CREATE_A_CHANNEL].concat(
channels ? channels.map(ch => ch.name) : []
);
const {
newChannelName,
newChannelNameError,
newChannelBid,
newChannelBidError,
creatingChannel,
createChannelError,
addingChannel,
showCreateChannel,
} = this.state;
return (
<View style={channelSelectorStyle.container}>
<Picker
enabled={enabled}
selectedValue={this.state.currentSelectedValue}
style={channelSelectorStyle.channelPicker}
itemStyle={channelSelectorStyle.channelPickerItem}
onValueChange={this.handlePickerValueChange}
>
{pickerItems.map(item => (
<Picker.Item label={item} value={item} key={item} />
))}
</Picker>
{showCreateChannel && (
<View style={channelSelectorStyle.createChannelContainer}>
<View style={channelSelectorStyle.channelInputContainer}>
<Text style={channelSelectorStyle.channelAt}>@</Text>
<TextInput
style={channelSelectorStyle.channelNameInput}
value={this.state.newChannelName}
onChangeText={this.handleNewChannelNameChange}
placeholder={'Channel name'}
underlineColorAndroid={Colors.NextLbryGreen}
/>
</View>
{newChannelNameError.length > 0 && (
<Text style={channelSelectorStyle.inlineError}>{newChannelNameError}</Text>
)}
<View style={channelSelectorStyle.bidRow}>
<Text style={channelSelectorStyle.label}>Deposit</Text>
<TextInput
style={channelSelectorStyle.bidAmountInput}
value={String(newChannelBid)}
onChangeText={this.handleNewChannelBidChange}
placeholder={'0.00'}
keyboardType={'number-pad'}
underlineColorAndroid={Colors.NextLbryGreen}
/>
<Text style={channelSelectorStyle.currency}>LBC</Text>
</View>
<Text style={channelSelectorStyle.helpText}>
This LBC remains yours. It is a deposit to reserve the name and can be undone at any time.
</Text>
<View style={channelSelectorStyle.buttonContainer}>
{creatingChannel && <ActivityIndicator size={'small'} color={Colors.LbryGreen} />}
{!creatingChannel && (
<View style={channelSelectorStyle.buttons}>
<Link style={channelSelectorStyle.cancelLink} text="Cancel" onPress={this.handleCreateCancel} />
<Button
style={channelSelectorStyle.createButton}
disabled={!(newChannelName.trim().length > 0 && newChannelBid > 0)}
text="Create"
onPress={this.handleCreateChannelClick}
/>
</View>
)}
</View>
</View>
)}
</View>
);
}
}