React/Redux - publish component #323
7 changed files with 186 additions and 55 deletions
97
react/components/channelCreateForm.jsx
Normal file
97
react/components/channelCreateForm.jsx
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
function ChannelSuccess (message) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>{this.props.message}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ChannelInProgress () {
|
||||||
|
return (
|
||||||
|
<div id="channel-publish-in-progress">
|
||||||
|
<p>Creating your new channel. This may take a few seconds...</p>
|
||||||
|
<div id="create-channel-progress-bar"></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelCreateForm extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
error : null,
|
||||||
|
channel : null,
|
||||||
|
password: null,
|
||||||
|
status : null,
|
||||||
|
};
|
||||||
|
this.handleChannelInput = this.handleChannelInput.bind(this);
|
||||||
|
this.handleInput = this.handleInput.bind(this);
|
||||||
|
this.checkChannelIsAvailable = this.checkChannelIsAvailable.bind(this);
|
||||||
|
this.createChannel = this.createChannel.bind(this);
|
||||||
|
}
|
||||||
|
handleChannelInput (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const name = event.target.name;
|
||||||
|
let value = event.target.value;
|
||||||
|
value = this.props.cleanseInput(value);
|
||||||
|
this.setState({[name]: value});
|
||||||
|
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;
|
||||||
|
this.props.makeGetRequest(`/api/channel-is-available/${channel}`)
|
||||||
|
.then(() => {
|
||||||
|
that.setState({urlError: null});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
that.setState({error: error.message});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
createChannel (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
// publishNewChannel(event)
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<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>
|
||||||
|
<input type="text" name="new-channel-name" id="new-channel-name" className="input-text" placeholder="exampleChannelName" value={this.channel} onChange={this.handleChannelInput} />
|
||||||
|
<span id="input-success-channel-name" className="info-message--success">{'\u2713'}</span>
|
||||||
|
</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">
|
||||||
|
<input type="password" name="new-channel-password" id="new-channel-password" className="input-text" placeholder="" value={this.password} onChange={this.handleInput} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row row--wide">
|
||||||
|
<button className="button--primary" onClick={this.createChannel}>Create</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ChannelCreateForm;
|
55
react/components/channelLoginForm.jsx
Normal file
55
react/components/channelLoginForm.jsx
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
class ChannelLoginForm extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
error : null,
|
||||||
|
name : null,
|
||||||
|
password: null,
|
||||||
|
};
|
||||||
|
this.handleInput = this.handleInput.bind(this);
|
||||||
|
this.loginToChannel = this.loginToChannel.bind(this);
|
||||||
|
}
|
||||||
|
handleInput (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const name = event.target.name;
|
||||||
|
const value = event.target.value;
|
||||||
|
this.setState({[name]: value});
|
||||||
|
}
|
||||||
|
loginToChannel (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<form id="channel-login-form">
|
||||||
|
<p id="login-error-display-element" 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="channel-login-name-input">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>
|
||||||
|
<input type="text" id="channel-login-name-input" className="input-text" name="name" placeholder="Your Channel Name" value={this.state.channelName} onChange={this.handleInput}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row row--wide row--short">
|
||||||
|
<div className="column column--3 column--sml-10">
|
||||||
|
<label className="label" htmlFor="channel-login-password-input" >Password:</label>
|
||||||
|
</div><div className="column column--6 column--sml-10">
|
||||||
|
<div className="input-text--primary">
|
||||||
|
<input type="password" id="channel-login-password-input" name="password" className="input-text" placeholder="" value={this.state.channelPassword} onChange={this.handleInput}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row row--wide">
|
||||||
|
<button className="button--primary" onClick={this.loginToChannel}>Authenticate</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ChannelLoginForm;
|
|
@ -1,42 +1,23 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import ChannelLoginForm from './channelLoginForm.jsx';
|
||||||
|
import ChannelCreateForm from './channelCreateForm.jsx';
|
||||||
|
|
||||||
const LOGIN = 'login';
|
const LOGIN = 'login';
|
||||||
const CREATE = 'create';
|
const CREATE = 'create';
|
||||||
|
|
||||||
class ChannelLoginForm extends React.Component {
|
|
||||||
constructor (props) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
render () {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h4>Channel Login Form</h4>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ChannelCreateForm extends React.Component {
|
|
||||||
constructor (props) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
render () {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h4>Create Channel Form</h4>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ChannelSelector extends React.Component {
|
class ChannelSelector extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
displayCreateOrLogin: null,
|
displayCreateOrLogin: LOGIN,
|
||||||
};
|
};
|
||||||
this.toggleCreateOrLogin = this.toggleCreateOrLogin.bind(this);
|
this.toggleCreateOrLogin = this.toggleCreateOrLogin.bind(this);
|
||||||
}
|
}
|
||||||
|
componentWillMount () {
|
||||||
|
if (this.props.loggedInChannelName) {
|
||||||
|
this.setState({ displayCreateOrLogin: null });
|
||||||
|
}
|
||||||
|
}
|
||||||
toggleCreateOrLogin (event) {
|
toggleCreateOrLogin (event) {
|
||||||
const selectedOption = event.target.selectedOptions[0].value;
|
const selectedOption = event.target.selectedOptions[0].value;
|
||||||
if (selectedOption === 'login') {
|
if (selectedOption === 'login') {
|
||||||
|
@ -66,7 +47,11 @@ class ChannelSelector extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ (this.state.displayCreateOrLogin === LOGIN) && <ChannelLoginForm /> }
|
{ (this.state.displayCreateOrLogin === LOGIN) && <ChannelLoginForm /> }
|
||||||
{ (this.state.displayCreateOrLogin === CREATE) && <ChannelCreateForm /> }
|
{ (this.state.displayCreateOrLogin === CREATE) &&
|
||||||
|
<ChannelCreateForm
|
||||||
|
makeGetRequest={this.props.makeGetRequest}
|
||||||
|
cleanseInput={this.props.cleanseInput}
|
||||||
|
/> }
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -126,7 +126,7 @@ class Dropzone extends React.Component {
|
||||||
setClaimNameFromFileName (fileName) {
|
setClaimNameFromFileName (fileName) {
|
||||||
console.log('setClaimNameFromFileName', fileName);
|
console.log('setClaimNameFromFileName', fileName);
|
||||||
const fileNameWithoutEnding = fileName.substring(0, fileName.lastIndexOf('.'));
|
const fileNameWithoutEnding = fileName.substring(0, fileName.lastIndexOf('.'));
|
||||||
const cleanClaimName = this.props.cleanseClaimName(fileNameWithoutEnding);
|
const cleanClaimName = this.props.cleanseInput(fileNameWithoutEnding);
|
||||||
this.props.updateUploaderState('claim', cleanClaimName);
|
this.props.updateUploaderState('claim', cleanClaimName);
|
||||||
}
|
}
|
||||||
render () {
|
render () {
|
||||||
|
|
|
@ -42,9 +42,6 @@ class AnonymousOrChannelSelect extends React.Component {
|
||||||
class PublishForm extends React.Component {
|
class PublishForm extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
|
||||||
channelError: null,
|
|
||||||
}
|
|
||||||
// set defaults
|
// set defaults
|
||||||
this.updateUploaderState = this.updateUploaderState.bind(this);
|
this.updateUploaderState = this.updateUploaderState.bind(this);
|
||||||
this.clearUploaderState = this.clearUploaderState.bind(this);
|
this.clearUploaderState = this.clearUploaderState.bind(this);
|
||||||
|
@ -73,7 +70,7 @@ class PublishForm extends React.Component {
|
||||||
<PreviewDropzone
|
<PreviewDropzone
|
||||||
file={this.props.file}
|
file={this.props.file}
|
||||||
/>
|
/>
|
||||||
|
{ (this.props.file.type === 'video/mp4') && <ThumbnailInput thumbnail={this.props.thumbnail}/> }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="column column--5 column--sml-10 align-content-top">
|
<div className="column column--5 column--sml-10 align-content-top">
|
||||||
|
@ -85,26 +82,23 @@ class PublishForm extends React.Component {
|
||||||
publishToChannel={this.props.publishToChannel}
|
publishToChannel={this.props.publishToChannel}
|
||||||
loggedInChannelName={this.props.loggedInChannelName}
|
loggedInChannelName={this.props.loggedInChannelName}
|
||||||
loggedInChannelShortId={this.props.loggedInChannelShortId}
|
loggedInChannelShortId={this.props.loggedInChannelShortId}
|
||||||
cleanseClaimName={this.props.cleanseClaimName}
|
cleanseInput={this.props.cleanseInput}
|
||||||
updateUploaderState={this.updateUploaderState}
|
updateUploaderState={this.updateUploaderState}
|
||||||
makeGetRequest={this.props.makeGetRequest}
|
makeGetRequest={this.props.makeGetRequest}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<AnonymousOrChannelSelect
|
<AnonymousOrChannelSelect
|
||||||
publishToChannel={this.props.publishToChannel}
|
publishToChannel={this.props.publishToChannel}
|
||||||
updateUploaderState={this.props.updateUploaderState}
|
updateUploaderState={this.props.updateUploaderState}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ChannelSelector
|
<ChannelSelector
|
||||||
channel={this.props.channel}
|
channel={this.props.channel}
|
||||||
loggedInChannelName={this.props.loggedInChannelName}
|
loggedInChannelName={this.props.loggedInChannelName}
|
||||||
publishToChannel={this.props.publishToChannel}
|
publishToChannel={this.props.publishToChannel}
|
||||||
|
cleanseInput={this.props.cleanseInput}
|
||||||
updateUploaderState={this.updateUploaderState}
|
updateUploaderState={this.updateUploaderState}
|
||||||
channelError={this.state.channelError}
|
makeGetRequest={this.props.makeGetRequest}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{ (this.props.file.type === 'video/mp4') && <ThumbnailInput thumbnail={this.props.thumbnail}/> }
|
|
||||||
|
|
||||||
<MetadataInputs />
|
<MetadataInputs />
|
||||||
|
|
||||||
<div className="row row--padded row--wide">
|
<div className="row row--padded row--wide">
|
||||||
|
|
|
@ -17,9 +17,9 @@ class UrlChooser extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
urlError : null,
|
error : null,
|
||||||
urlBeginning: 'spee.ch',
|
host : 'spee.ch',
|
||||||
urlMiddle : null,
|
urlMiddle: null,
|
||||||
};
|
};
|
||||||
this.handleInput = this.handleInput.bind(this);
|
this.handleInput = this.handleInput.bind(this);
|
||||||
this.checkClaimIsAvailable = this.checkClaimIsAvailable.bind(this);
|
this.checkClaimIsAvailable = this.checkClaimIsAvailable.bind(this);
|
||||||
|
@ -28,7 +28,7 @@ class UrlChooser extends React.Component {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let value = event.target.value;
|
let value = event.target.value;
|
||||||
const name = event.target.name;
|
const name = event.target.name;
|
||||||
value = this.props.cleanseClaimName(value);
|
value = this.props.cleanseInput(value);
|
||||||
this.props.updateUploaderState(name, value);
|
this.props.updateUploaderState(name, value);
|
||||||
this.checkClaimIsAvailable(value);
|
this.checkClaimIsAvailable(value);
|
||||||
}
|
}
|
||||||
|
@ -36,10 +36,10 @@ class UrlChooser extends React.Component {
|
||||||
const that = this;
|
const that = this;
|
||||||
this.props.makeGetRequest(`/api/claim-is-available/${claim}`)
|
this.props.makeGetRequest(`/api/claim-is-available/${claim}`)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
that.setState({urlError: null});
|
that.setState({'error': null});
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
that.setState({urlError: error.message});
|
that.setState({'error': error.message});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
render () {
|
render () {
|
||||||
|
@ -47,18 +47,18 @@ class UrlChooser extends React.Component {
|
||||||
<div>
|
<div>
|
||||||
<div className="row row--padded row--no-top row--wide">
|
<div className="row row--padded row--no-top row--wide">
|
||||||
|
|
||||||
<p id="input-error-claim-name" className="info-message-placeholder info-message--failure">{this.state.urlError}</p>
|
<p id="input-error-claim-name" className="info-message-placeholder info-message--failure">{this.state.error}</p>
|
||||||
|
|
||||||
<div className="column column--3 column--sml-10">
|
<div className="column column--3 column--sml-10">
|
||||||
<label className="label">URL:</label>
|
<label className="label">URL:</label>
|
||||||
</div><div className="column column--7 column--sml-10 input-text--primary span--relative">
|
</div><div className="column column--7 column--sml-10 input-text--primary span--relative">
|
||||||
|
|
||||||
<span className="url-text--secondary">{this.state.urlBeginning} / </span>
|
<span className="url-text--secondary">{this.state.host} / </span>
|
||||||
|
|
||||||
<UrlMiddle publishToChannel={this.props.publishToChannel} loggedInChannelName={this.props.loggedInChannelName} loggedInChannelShortId={this.props.loggedInChannelShortId}/>
|
<UrlMiddle publishToChannel={this.props.publishToChannel} loggedInChannelName={this.props.loggedInChannelName} loggedInChannelShortId={this.props.loggedInChannelShortId}/>
|
||||||
|
|
||||||
<input type="text" id="claim-name-input" className="input-text" name='claim' placeholder="your-url-here" onChange={this.handleInput} value={this.props.claim}/>
|
<input type="text" id="claim-name-input" className="input-text" name='claim' placeholder="your-url-here" onChange={this.handleInput} value={this.props.claim}/>
|
||||||
{ (this.props.claim && !this.state.urlError) && (
|
{ (this.props.claim && !this.state.error) && (
|
||||||
<span id="input-success-claim-name" className="info-message--success span--absolute">{'\u2713'}</span>
|
<span id="input-success-claim-name" className="info-message--success span--absolute">{'\u2713'}</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ class Uploader extends React.Component {
|
||||||
this.clearUploaderState = this.clearUploaderState.bind(this);
|
this.clearUploaderState = this.clearUploaderState.bind(this);
|
||||||
this.makeGetRequest = this.makeGetRequest.bind(this);
|
this.makeGetRequest = this.makeGetRequest.bind(this);
|
||||||
this.makePostRequest = this.makePostRequest.bind(this);
|
this.makePostRequest = this.makePostRequest.bind(this);
|
||||||
this.cleanseClaimName = this.cleanseClaimName.bind(this);
|
this.cleanseInput = this.cleanseInput.bind(this);
|
||||||
this.getCookie = this.getCookie.bind(this);
|
this.getCookie = this.getCookie.bind(this);
|
||||||
}
|
}
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
|
@ -88,10 +88,10 @@ class Uploader extends React.Component {
|
||||||
xhttp.send(params);
|
xhttp.send(params);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
cleanseClaimName (name) {
|
cleanseInput (input) {
|
||||||
name = name.replace(/\s+/g, '-'); // replace spaces with dashes
|
input = input.replace(/\s+/g, '-'); // replace spaces with dashes
|
||||||
name = name.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-'
|
input = input.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-'
|
||||||
return name;
|
return input;
|
||||||
}
|
}
|
||||||
getCookie (cname) {
|
getCookie (cname) {
|
||||||
const name = cname + '=';
|
const name = cname + '=';
|
||||||
|
@ -114,7 +114,7 @@ class Uploader extends React.Component {
|
||||||
{ this.state.showComponent === DROPZONE &&
|
{ this.state.showComponent === DROPZONE &&
|
||||||
<Dropzone
|
<Dropzone
|
||||||
updateUploaderState={this.updateUploaderState}
|
updateUploaderState={this.updateUploaderState}
|
||||||
cleanseClaimName={this.cleanseClaimName}
|
cleanseInput={this.cleanseInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
{ this.state.showComponent === DETAILS &&
|
{ this.state.showComponent === DETAILS &&
|
||||||
|
@ -122,7 +122,7 @@ class Uploader extends React.Component {
|
||||||
updateUploaderState={this.updateUploaderState}
|
updateUploaderState={this.updateUploaderState}
|
||||||
clearUploaderState={this.clearUploaderState}
|
clearUploaderState={this.clearUploaderState}
|
||||||
makeGetRequest={this.makeGetRequest}
|
makeGetRequest={this.makeGetRequest}
|
||||||
cleanseClaimName={this.cleanseClaimName}
|
cleanseInput={this.cleanseInput}
|
||||||
loggedInChannelName={this.state.loggedInChannelName}
|
loggedInChannelName={this.state.loggedInChannelName}
|
||||||
loggedInChannelShortId={this.state.loggedInChannelShortId}
|
loggedInChannelShortId={this.state.loggedInChannelShortId}
|
||||||
publishToChannel={this.state.publishToChannel}
|
publishToChannel={this.state.publishToChannel}
|
||||||
|
|
Loading…
Reference in a new issue