React/Redux - publish component #323
4 changed files with 44 additions and 49 deletions
|
@ -1,5 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
const DETAILS = 'DETAILS';
|
||||||
|
|
||||||
class Dropzone extends React.Component {
|
class Dropzone extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -14,6 +16,8 @@ class Dropzone extends React.Component {
|
||||||
this.handleDragLeave = this.handleDragLeave.bind(this);
|
this.handleDragLeave = this.handleDragLeave.bind(this);
|
||||||
this.handleClick = this.handleClick.bind(this);
|
this.handleClick = this.handleClick.bind(this);
|
||||||
this.handleFileInput = this.handleFileInput.bind(this);
|
this.handleFileInput = this.handleFileInput.bind(this);
|
||||||
|
this.stageFile = this.stageFile.bind(this);
|
||||||
|
this.setClaimNameFromFileName = this.setClaimNameFromFileName.bind(this);
|
||||||
}
|
}
|
||||||
validateFile (file) {
|
validateFile (file) {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
|
@ -68,7 +72,8 @@ class Dropzone extends React.Component {
|
||||||
return this.setState({fileError: error.message});
|
return this.setState({fileError: error.message});
|
||||||
}
|
}
|
||||||
// stage it so it will be ready when the publish button is clicked
|
// stage it so it will be ready when the publish button is clicked
|
||||||
this.props.stageFileAndShowDetails(droppedFile);
|
this.setClaimNameFromFileName(droppedFile.name);
|
||||||
|
this.stageFile(droppedFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,9 +112,23 @@ class Dropzone extends React.Component {
|
||||||
return this.setState({fileError: error.message});
|
return this.setState({fileError: error.message});
|
||||||
}
|
}
|
||||||
// stage it so it will be ready when the publish button is clicked
|
// stage it so it will be ready when the publish button is clicked
|
||||||
this.props.stageFileAndShowDetails(chosenFile);
|
this.setClaimNameFromFileName(chosenFile.name);
|
||||||
|
this.stageFile(chosenFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stageFile (selectedFile) {
|
||||||
|
console.log('stageFileAndShowDetails', selectedFile);
|
||||||
|
// store the selected file for upload
|
||||||
|
this.props.updateUploaderState('file', selectedFile);
|
||||||
|
// show the publish form
|
||||||
|
this.props.updateUploaderState('showComponent', DETAILS);
|
||||||
|
}
|
||||||
|
setClaimNameFromFileName (fileName) {
|
||||||
|
console.log('setClaimNameFromFileName', fileName);
|
||||||
|
const fileNameWithoutEnding = fileName.substring(0, fileName.lastIndexOf('.'));
|
||||||
|
const cleanClaimName = this.props.cleanseClaimName(fileNameWithoutEnding);
|
||||||
|
this.props.updateUploaderState('claim', cleanClaimName);
|
||||||
|
}
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div className="row row--tall flex-container--column">
|
<div className="row row--tall flex-container--column">
|
||||||
|
|
|
@ -85,11 +85,15 @@ 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}
|
||||||
updateUploaderState={this.updateUploaderState}
|
updateUploaderState={this.updateUploaderState}
|
||||||
makeGetRequest={this.props.makeGetRequest}
|
makeGetRequest={this.props.makeGetRequest}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<AnonymousOrChannelSelect publishToChannel={this.props.publishToChannel} updateUploaderState={this.props.updateUploaderState}/>
|
<AnonymousOrChannelSelect
|
||||||
|
publishToChannel={this.props.publishToChannel}
|
||||||
|
updateUploaderState={this.props.updateUploaderState}
|
||||||
|
/>
|
||||||
|
|
||||||
<ChannelSelector
|
<ChannelSelector
|
||||||
channel={this.props.channel}
|
channel={this.props.channel}
|
||||||
|
|
|
@ -13,7 +13,7 @@ function UrlMiddle ({publishToChannel, loggedInChannelName, loggedInChannelShort
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class UrlInput extends React.Component {
|
class UrlChooser extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -22,43 +22,17 @@ class UrlInput extends React.Component {
|
||||||
urlMiddle : null,
|
urlMiddle : null,
|
||||||
};
|
};
|
||||||
this.handleInput = this.handleInput.bind(this);
|
this.handleInput = this.handleInput.bind(this);
|
||||||
this.validateClaimName = this.validateClaimName.bind(this);
|
this.checkClaimIsAvailable = this.checkClaimIsAvailable.bind(this);
|
||||||
this.cleanseClaimName = this.cleanseClaimName.bind(this);
|
|
||||||
this.checkClaimIsValidAndAvailable = this.checkClaimIsValidAndAvailable.bind(this);
|
|
||||||
}
|
}
|
||||||
handleInput (event) {
|
handleInput (event) {
|
||||||
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.cleanseClaimName(value);
|
value = this.props.cleanseClaimName(value);
|
||||||
this.props.updateUploaderState(name, value);
|
this.props.updateUploaderState(name, value);
|
||||||
this.checkClaimIsValidAndAvailable(value);
|
this.checkClaimIsAvailable(value);
|
||||||
}
|
}
|
||||||
validateClaimName (claim) {
|
checkClaimIsAvailable (claim) {
|
||||||
// ensure a name was entered
|
|
||||||
if (!claim || claim.length < 1) {
|
|
||||||
throw new Error('You must enter a name for your url');
|
|
||||||
}
|
|
||||||
// validate the characters in the 'name' field
|
|
||||||
const invalidCharacters = /[^A-Za-z0-9,-]/g.exec(claim);
|
|
||||||
if (invalidCharacters) {
|
|
||||||
throw new Error('"' + invalidCharacters + '" characters are not allowed');
|
|
||||||
}
|
|
||||||
return claim;
|
|
||||||
}
|
|
||||||
cleanseClaimName (name) {
|
|
||||||
name = name.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 '-'
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
checkClaimIsValidAndAvailable (claim) {
|
|
||||||
// validationFunctions.checkClaimName(event.target.value)
|
|
||||||
try {
|
|
||||||
claim = this.validateClaimName(claim);
|
|
||||||
} catch (error) {
|
|
||||||
this.setState({urlError: error.message});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const that = this;
|
const that = this;
|
||||||
this.props.makeGetRequest(`/api/claim-is-available/${claim}`)
|
this.props.makeGetRequest(`/api/claim-is-available/${claim}`)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
@ -83,7 +57,7 @@ class UrlInput extends React.Component {
|
||||||
|
|
||||||
<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" onInput={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.urlError) && (
|
||||||
<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>
|
||||||
)}
|
)}
|
||||||
|
@ -96,4 +70,4 @@ class UrlInput extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = UrlInput;
|
module.exports = UrlChooser;
|
||||||
|
|
|
@ -29,10 +29,9 @@ class Uploader extends React.Component {
|
||||||
// bind class methods with `this`
|
// bind class methods with `this`
|
||||||
this.updateUploaderState = this.updateUploaderState.bind(this);
|
this.updateUploaderState = this.updateUploaderState.bind(this);
|
||||||
this.clearUploaderState = this.clearUploaderState.bind(this);
|
this.clearUploaderState = this.clearUploaderState.bind(this);
|
||||||
this.showComponent = this.showComponent.bind(this);
|
|
||||||
this.stageFileAndShowDetails = this.stageFileAndShowDetails.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);
|
||||||
}
|
}
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
// check for whether a channel is logged in
|
// check for whether a channel is logged in
|
||||||
|
@ -49,16 +48,6 @@ class Uploader extends React.Component {
|
||||||
clearUploaderState () {
|
clearUploaderState () {
|
||||||
this.setState(initialState);
|
this.setState(initialState);
|
||||||
}
|
}
|
||||||
showComponent (component) {
|
|
||||||
this.setState({showComponent: component});
|
|
||||||
}
|
|
||||||
stageFileAndShowDetails (selectedFile) {
|
|
||||||
console.log('stageFileAndShowDetails', selectedFile);
|
|
||||||
// store the selected file for upload
|
|
||||||
this.setState({'file': selectedFile});
|
|
||||||
// hide the dropzone and show the details
|
|
||||||
this.showComponent(DETAILS);
|
|
||||||
}
|
|
||||||
makeGetRequest (url) {
|
makeGetRequest (url) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let xhttp = new XMLHttpRequest();
|
let xhttp = new XMLHttpRequest();
|
||||||
|
@ -98,17 +87,26 @@ class Uploader extends React.Component {
|
||||||
xhttp.send(params);
|
xhttp.send(params);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
cleanseClaimName (name) {
|
||||||
|
name = name.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 '-'
|
||||||
|
return name;
|
||||||
|
}
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div className="row row--tall flex-container--column">
|
<div className="row row--tall flex-container--column">
|
||||||
{ this.state.showComponent === DROPZONE &&
|
{ this.state.showComponent === DROPZONE &&
|
||||||
<Dropzone stageFileAndShowDetails={this.stageFileAndShowDetails}/>
|
<Dropzone
|
||||||
|
updateUploaderState={this.updateUploaderState}
|
||||||
|
cleanseClaimName={this.cleanseClaimName}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
{ this.state.showComponent === DETAILS &&
|
{ this.state.showComponent === DETAILS &&
|
||||||
<PublishForm
|
<PublishForm
|
||||||
updateUploaderState={this.updateUploaderState}
|
updateUploaderState={this.updateUploaderState}
|
||||||
clearUploaderState={this.clearUploaderState}
|
clearUploaderState={this.clearUploaderState}
|
||||||
makeGetRequest={this.makeGetRequest}
|
makeGetRequest={this.makeGetRequest}
|
||||||
|
cleanseClaimName={this.cleanseClaimName}
|
||||||
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