React/Redux - publish component #323

Merged
bones7242 merged 80 commits from react-upload into master 2018-01-25 22:43:20 +01:00
11 changed files with 46 additions and 52 deletions
Showing only changes of commit 6b685f5183 - Show all commits

View file

@ -58,3 +58,10 @@ export function updateSelectedChannel (value) {
value, value,
}; };
}; };
export function toggleMetadataInputs (value) {
return {
type: actions.TOGGLE_METADATA_INPUTS,
value,
};
};

View file

@ -3,11 +3,11 @@ import PropTypes from 'prop-types';
class ExpandingTextarea extends Component { class ExpandingTextarea extends Component {
componentDidMount () { componentDidMount () {
this._adjustTextarea({}); this.adjustTextarea({});
} }
render () { render () {
const { onChange, maxHeight, ...rest } = this.props; const { onChange, ...rest } = this.props;
return ( return (
<textarea <textarea
{ ...rest } { ...rest }
@ -17,25 +17,20 @@ class ExpandingTextarea extends Component {
); );
} }
_handleChange (e) { _handleChange (event) {
const { onChange } = this.props; const { onChange } = this.props;
if (onChange) onChange(e); if (onChange) onChange(event);
this._adjustTextarea(e); this.adjustTextarea(event);
} }
_adjustTextarea ({ target = this.el }) { adjustTextarea ({ target = this.el }) {
target.style.height = 0; target.style.height = 0;
if (this.props.maxHeight) {
target.style.height = `${Math.min(target.scrollHeight, this.props.maxHeight)}px`;
} else {
target.style.height = `${target.scrollHeight}px`; target.style.height = `${target.scrollHeight}px`;
} }
} }
}
ExpandingTextarea.propTypes = { ExpandingTextarea.propTypes = {
onChange: PropTypes.func, onChange: PropTypes.func,
maxHeight: PropTypes.number,
}; };
export default ExpandingTextarea; export default ExpandingTextarea;

View file

@ -10,3 +10,4 @@ export const SET_PUBLISH_IN_CHANNEL = 'SET_PUBLISH_IN_CHANNEL';
export const PUBLISH_STATUS_UPDATE = 'PUBLISH_STATUS_UPDATE'; export const PUBLISH_STATUS_UPDATE = 'PUBLISH_STATUS_UPDATE';
export const ERROR_UPDATE = 'ERROR_UPDATE'; export const ERROR_UPDATE = 'ERROR_UPDATE';
export const SELECTED_CHANNEL_UPDATE = 'SELECTED_CHANNEL_UPDATE'; export const SELECTED_CHANNEL_UPDATE = 'SELECTED_CHANNEL_UPDATE';
export const TOGGLE_METADATA_INPUTS = 'TOGGLE_METADATA_INPUTS';

View file

@ -26,7 +26,6 @@ class ChannelCreateForm extends React.Component {
return input; return input;
} }
handleChannelInput (event) { handleChannelInput (event) {
event.preventDefault();
let value = event.target.value; let value = event.target.value;
value = this.cleanseChannelInput(value); value = this.cleanseChannelInput(value);
this.setState({channel: value}); this.setState({channel: value});
@ -38,7 +37,6 @@ class ChannelCreateForm extends React.Component {
console.log('end of handlechannelinput'); console.log('end of handlechannelinput');
} }
handleInput (event) { handleInput (event) {
event.preventDefault();
const name = event.target.name; const name = event.target.name;
const value = event.target.value; const value = event.target.value;
this.setState({[name]: value}); this.setState({[name]: value});

View file

@ -14,7 +14,6 @@ class ChannelLoginForm extends React.Component {
neb-b commented 2018-01-18 06:19:30 +01:00 (Migrated from github.com)
Review

Forms are one of the most painful things in React. It might be worth looking into 3rd party React form elements. I've done a fair bit of work with forms and think that Formik is really nice. Hoping to add it to more parts of the app soon. https://github.com/jaredpalmer/formik

I really like how they use the render prop, I think it's a really nice way to interact with React elements

Forms are one of the most painful things in React. It might be worth looking into 3rd party React form elements. I've done a fair bit of work with forms and think that Formik is really nice. Hoping to add it to more parts of the app soon. https://github.com/jaredpalmer/formik I really like how they use the `render` prop, I think it's a really nice way to interact with React elements
neb-b commented 2018-01-18 06:19:30 +01:00 (Migrated from github.com)
Review

Forms are one of the most painful things in React. It might be worth looking into 3rd party React form elements. I've done a fair bit of work with forms and think that Formik is really nice. Hoping to add it to more parts of the app soon. https://github.com/jaredpalmer/formik

I really like how they use the render prop, I think it's a really nice way to interact with React elements

Forms are one of the most painful things in React. It might be worth looking into 3rd party React form elements. I've done a fair bit of work with forms and think that Formik is really nice. Hoping to add it to more parts of the app soon. https://github.com/jaredpalmer/formik I really like how they use the `render` prop, I think it's a really nice way to interact with React elements
this.loginToChannel = this.loginToChannel.bind(this); this.loginToChannel = this.loginToChannel.bind(this);
} }
handleInput (event) { handleInput (event) {
event.preventDefault();
neb-b commented 2018-01-18 06:19:30 +01:00 (Migrated from github.com)
Review

Forms are one of the most painful things in React. It might be worth looking into 3rd party React form elements. I've done a fair bit of work with forms and think that Formik is really nice. Hoping to add it to more parts of the app soon. https://github.com/jaredpalmer/formik

I really like how they use the render prop, I think it's a really nice way to interact with React elements

Forms are one of the most painful things in React. It might be worth looking into 3rd party React form elements. I've done a fair bit of work with forms and think that Formik is really nice. Hoping to add it to more parts of the app soon. https://github.com/jaredpalmer/formik I really like how they use the `render` prop, I think it's a really nice way to interact with React elements
const name = event.target.name; const name = event.target.name;
const value = event.target.value; const value = event.target.value;
this.setState({[name]: value}); this.setState({[name]: value});

neb-b commented 2018-01-18 06:19:30 +01:00 (Migrated from github.com)
Review

Forms are one of the most painful things in React. It might be worth looking into 3rd party React form elements. I've done a fair bit of work with forms and think that Formik is really nice. Hoping to add it to more parts of the app soon. https://github.com/jaredpalmer/formik

I really like how they use the render prop, I think it's a really nice way to interact with React elements

Forms are one of the most painful things in React. It might be worth looking into 3rd party React form elements. I've done a fair bit of work with forms and think that Formik is really nice. Hoping to add it to more parts of the app soon. https://github.com/jaredpalmer/formik I really like how they use the `render` prop, I think it's a really nice way to interact with React elements
neb-b commented 2018-01-18 06:19:30 +01:00 (Migrated from github.com)
Review

Forms are one of the most painful things in React. It might be worth looking into 3rd party React form elements. I've done a fair bit of work with forms and think that Formik is really nice. Hoping to add it to more parts of the app soon. https://github.com/jaredpalmer/formik

I really like how they use the render prop, I think it's a really nice way to interact with React elements

Forms are one of the most painful things in React. It might be worth looking into 3rd party React form elements. I've done a fair bit of work with forms and think that Formik is really nice. Hoping to add it to more parts of the app soon. https://github.com/jaredpalmer/formik I really like how they use the `render` prop, I think it's a really nice way to interact with React elements

View file

@ -1,9 +1,10 @@
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import {updateMetadata} from 'actions/publish'; import {updateMetadata, toggleMetadataInputs} from 'actions/publish';
import View from './view'; import View from './view';
const mapStateToProps = ({ publish }) => { const mapStateToProps = ({ publish }) => {
return { return {
showMetadataInputs: publish.showMetadataInputs,
description : publish.metadata.description, description : publish.metadata.description,
license : publish.metadata.license, license : publish.metadata.license,
nsfw : publish.metadata.nsfw, nsfw : publish.metadata.nsfw,
@ -15,6 +16,9 @@ const mapDispatchToProps = dispatch => {
onMetadataChange: (name, value) => { onMetadataChange: (name, value) => {
dispatch(updateMetadata(name, value)); dispatch(updateMetadata(name, value));
}, },
onToggleMetadataInputs: (value) => {
dispatch(toggleMetadataInputs(value));
},
}; };
}; };

View file

@ -4,31 +4,20 @@ import ExpandingTextArea from 'components/ExpandingTextArea';
class PublishMetadataInputs extends React.Component { class PublishMetadataInputs extends React.Component {
constructor (props) { constructor (props) {
super(props); super(props);
this.state = {
showInputs: false,
};
this.toggleShowInputs = this.toggleShowInputs.bind(this); this.toggleShowInputs = this.toggleShowInputs.bind(this);
this.handleDescriptionInput = this.handleDescriptionInput.bind(this); this.handleInput = this.handleInput.bind(this);
this.handleNsfwCheck = this.handleNsfwCheck.bind(this); this.handleSelect = this.handleSelect.bind(this);
this.handleLicenseSelection = this.handleLicenseSelection.bind(this);
} }
toggleShowInputs () { toggleShowInputs () {
this.setState({'showInputs': !this.state.showInputs}); this.props.onToggleMetadataInputs(!this.props.showMetadataInputs);
} }
handleDescriptionInput (event) { handleInput (event) {
event.preventDefault(); const target = event.target;
const name = event.target.name; const value = target.type === 'checkbox' ? target.checked : target.value;
const value = event.target.value; const name = target.name;
this.props.onMetadataChange(name, value); this.props.onMetadataChange(name, value);
} }
handleNsfwCheck (event) { handleSelect (event) {
console.log('handle input', event);
event.preventDefault();
const name = event.target.name;
const value = event.target.checked;
this.props.onMetadataChange(name, value);
}
handleLicenseSelection (event) {
const name = event.target.name; const name = event.target.name;
const selectedOption = event.target.selectedOptions[0].value; const selectedOption = event.target.selectedOptions[0].value;
this.props.onMetadataChange(name, selectedOption); this.props.onMetadataChange(name, selectedOption);
@ -36,8 +25,8 @@ class PublishMetadataInputs extends React.Component {
render () { render () {
return ( return (
<div id="publish-details" className="row row--padded row--no-top row--wide"> <div id="publish-details" className="row row--padded row--no-top row--wide">
<a className="label link--primary" id="publish-details-toggle" href="#" onClick={this.toggleShowInputs}>{this.state.showInputs ? '[less]' : '[more]'}</a> <a className="label link--primary" id="publish-details-toggle" href="#" onClick={this.toggleShowInputs}>{this.props.showMetadataInputs ? '[less]' : '[more]'}</a>
{this.state.showInputs && ( {this.props.showMetadataInputs && (
<div> <div>
<div className="row row--no-top"> <div className="row row--no-top">
<div className="column column--3 column--med-10 align-content-top"> <div className="column column--3 column--med-10 align-content-top">
@ -48,12 +37,11 @@ class PublishMetadataInputs extends React.Component {
className="textarea textarea--primary textarea--full-width" className="textarea textarea--primary textarea--full-width"
rows={1} rows={1}
maxLength={2000} maxLength={2000}
maxHeight={150} style={{ maxHeight: 200 }}
name="description" name="description"
placeholder="Optional description" placeholder="Optional description"
value={this.props.description} value={this.props.description}
style={{height: this.state.descriptionHeight}} onChange={this.handleInput} />
onChange={this.handleDescriptionInput} />
</div> </div>
</div> </div>
@ -61,7 +49,7 @@ class PublishMetadataInputs extends React.Component {
<div className="column column--3 column--med-10"> <div className="column column--3 column--med-10">
<label htmlFor="publish-license" className="label">License:</label> <label htmlFor="publish-license" className="label">License:</label>
</div><div className="column column--7 column--sml-10"> </div><div className="column column--7 column--sml-10">
<select type="text" name="license" id="publish-license" className="select select--primary" onChange={this.handleLicenseSelection}> <select type="text" name="license" id="publish-license" className="select select--primary" onChange={this.handleSelect}>
<option value=" ">Unspecified</option> <option value=" ">Unspecified</option>
<option value="Public Domain">Public Domain</option> <option value="Public Domain">Public Domain</option>
<option value="Creative Commons">Creative Commons</option> <option value="Creative Commons">Creative Commons</option>
@ -73,7 +61,7 @@ class PublishMetadataInputs extends React.Component {
<div className="column column--3"> <div className="column column--3">
<label htmlFor="publish-nsfw" className="label">Mature:</label> <label htmlFor="publish-nsfw" className="label">Mature:</label>
</div><div className="column column--7"> </div><div className="column column--7">
<input className="input-checkbox" type="checkbox" id="publish-nsfw" name="nsfw" checked={this.props.nsfw} onChange={this.handleNsfwCheck} /> <input className="input-checkbox" type="checkbox" id="publish-nsfw" name="nsfw" value={this.props.nsfw} onChange={this.handleInput} />
</div> </div>
</div> </div>
</div> </div>

View file

@ -14,7 +14,6 @@ class PublishThumbnailInput extends React.Component {
this.updateVideoThumb = this.updateVideoThumb.bind(this); this.updateVideoThumb = this.updateVideoThumb.bind(this);
} }
handleInput (event) { handleInput (event) {
event.preventDefault();
const value = event.target.value; const value = event.target.value;
this.setState({thumbnailInput: value}); this.setState({thumbnailInput: value});
} }

View file

@ -6,7 +6,6 @@ class PublishTitleInput extends React.Component {
this.handleInput = this.handleInput.bind(this); this.handleInput = this.handleInput.bind(this);
} }
handleInput (e) { handleInput (e) {
e.preventDefault();
const name = e.target.name; const name = e.target.name;
const value = e.target.value; const value = e.target.value;
this.props.onMetadataChange(name, value); this.props.onMetadataChange(name, value);

View file

@ -27,7 +27,6 @@ class PublishUrlInput extends React.Component {
} }
} }
handleInput (event) { handleInput (event) {
event.preventDefault();
let value = event.target.value; let value = event.target.value;
value = this.cleanseInput(value); value = this.cleanseInput(value);
// update the state // update the state

View file

@ -4,6 +4,7 @@ import * as channelSelectStates from 'constants/channel_select_states';
const initialState = { const initialState = {
publishInChannel : false, publishInChannel : false,
selectedChannel : channelSelectStates.LOGIN, selectedChannel : channelSelectStates.LOGIN,
showMetadataInputs: false,
status : { status : {
status : null, status : null,
message: null, message: null,
@ -67,6 +68,10 @@ export default function (state = initialState, action) {
return Object.assign({}, state, { return Object.assign({}, state, {
selectedChannel: action.value, selectedChannel: action.value,
}); });
case actions.TOGGLE_METADATA_INPUTS:
return Object.assign({}, state, {
showMetadataInputs: action.value,
});
default: default:
return state; return state;
} }