spee.ch/react/components/ChannelCreateForm.jsx

132 lines
5 KiB
React
Raw Normal View History

2018-01-05 22:59:25 +01:00
import React from 'react';
2018-01-10 20:26:01 +01:00
import {connect} from 'react-redux';
import {updateLoggedInChannel} from '../actions';
import { makeGetRequest, makePostRequest } from '../utils/xhr.js';
2018-01-10 20:26:01 +01:00
import { setUserCookies } from '../utils/cookies.js';
import { replaceChannelSelectionInNavBar } from '../utils/pageUpdate.js';
2018-01-05 22:59:25 +01:00
class ChannelCreateForm extends React.Component {
constructor (props) {
super(props);
this.state = {
error : null,
channel : null,
password: null,
status : null,
};
2018-01-10 20:26:01 +01:00
this.cleanseChannelInput = this.cleanseChannelInput.bind(this);
2018-01-05 22:59:25 +01:00
this.handleChannelInput = this.handleChannelInput.bind(this);
this.handleInput = this.handleInput.bind(this);
this.checkChannelIsAvailable = this.checkChannelIsAvailable.bind(this);
this.createChannel = this.createChannel.bind(this);
}
2018-01-10 20:26:01 +01:00
cleanseChannelInput (input) {
input = input.replace(/\s+/g, '-'); // replace spaces with dashes
input = input.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-'
return input;
}
2018-01-05 22:59:25 +01:00
handleChannelInput (event) {
event.preventDefault();
let value = event.target.value;
2018-01-10 20:26:01 +01:00
value = this.cleanseChannelInput(value);
this.setState({channel: value});
2018-01-05 22:59:25 +01:00
this.checkChannelIsAvailable(value);
}
handleInput (event) {
event.preventDefault();
const name = event.target.name;
const value = event.target.value;
this.setState({[name]: value});
}
checkChannelIsAvailable (channel) {
const that = this;
makeGetRequest(`/api/channel-is-available/${channel}`)
2018-01-05 22:59:25 +01:00
.then(() => {
that.setState({urlError: null});
})
.catch((error) => {
that.setState({error: error.message});
});
}
2018-01-06 01:47:55 +01:00
validatePassword (password) {
if (!password || password.length < 1) {
throw new Error('Please provide a password');
}
}
2018-01-05 22:59:25 +01:00
createChannel (event) {
event.preventDefault();
2018-01-06 01:47:55 +01:00
const params = `username=${this.state.channel}&password=${this.state.password}`;
const url = '/signup';
// validate submission data
try {
this.validatePassword(this.state.password);
} catch (error) {
return this.setState({error: error.message});
}
// publish the channel
const that = this;
this.setState({status: 'We are publishing your new channel. Sit tight...'});
makePostRequest(url, params)
2018-01-06 01:47:55 +01:00
.then(result => {
2018-01-10 20:26:01 +01:00
that.props.onChannelLogin(result.channelName, result.shortChannelId, result.channelClaimId);
setUserCookies(result.channelName, result.shortChannelId, result.channelClaimId);
replaceChannelSelectionInNavBar(result.channelName);
2018-01-06 01:47:55 +01:00
})
.catch(error => {
console.log('create channel failure:', error);
if (error.message) {
this.setState({'error': error.message});
} else {
this.setState({'error': 'Unfortunately, we encountered an error while creating your channel. Please let us know in Discord!'});
}
});
2018-01-05 22:59:25 +01:00
}
render () {
return (
2018-01-06 01:47:55 +01:00
<div>
{ !this.state.status ? (
<form id="publish-channel-form">
<p id="input-error-channel-name" className="info-message-placeholder info-message--failure">{this.state.error}</p>
<div className="row row--wide row--short">
<div className="column column--3 column--sml-10">
<label className="label" htmlFor="new-channel-name">Name:</label>
</div><div className="column column--6 column--sml-10">
<div className="input-text--primary flex-container--row flex-container--left-bottom">
<span>@</span>
2018-01-10 20:26:01 +01:00
<input type="text" name="channel" id="new-channel-name" className="input-text" placeholder="exampleChannelName" value={this.state.channel} onChange={this.handleChannelInput} />
2018-01-05 22:59:25 +01:00
<span id="input-success-channel-name" className="info-message--success">{'\u2713'}</span>
2018-01-06 01:47:55 +01:00
</div>
</div>
</div>
<div className="row row--wide row--short">
<div className="column column--3 column--sml-10">
<label className="label" htmlFor="new-channel-password">Password:</label>
</div><div className="column column--6 column--sml-10">
<div className="input-text--primary">
2018-01-10 20:26:01 +01:00
<input type="password" name="password" id="new-channel-password" className="input-text" placeholder="" value={this.state.password} onChange={this.handleInput} />
2018-01-06 01:47:55 +01:00
</div>
2018-01-05 22:59:25 +01:00
</div>
</div>
2018-01-06 01:47:55 +01:00
<div className="row row--wide">
2018-01-10 20:26:01 +01:00
<button className="button--primary" onClick={this.createChannel}>Create Channel</button>
2018-01-06 01:47:55 +01:00
</div>
</form>
) : (
<p>{this.state.status}</p>
)}
</div>
2018-01-05 22:59:25 +01:00
);
}
}
2018-01-10 20:26:01 +01:00
const mapDispatchToProps = dispatch => {
return {
onChannelLogin: (name, shortId, longId) => {
dispatch(updateLoggedInChannel(name, shortId, longId));
},
};
};
export default connect(null, mapDispatchToProps)(ChannelCreateForm);