React/Redux - publish component #323

Merged
bones7242 merged 80 commits from react-upload into master 2018-01-25 22:43:20 +01:00
4 changed files with 44 additions and 49 deletions
Showing only changes of commit bd10aaedeb - Show all commits

View file

@ -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">

View file

@ -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}

View file

@ -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;

View file

@ -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}