React/Redux - publish component #323
|
@ -58,3 +58,10 @@ export function updateSelectedChannel (value) {
|
|||
value,
|
||||
};
|
||||
};
|
||||
|
||||
export function toggleMetadataInputs (value) {
|
||||
return {
|
||||
type: actions.TOGGLE_METADATA_INPUTS,
|
||||
value,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -3,11 +3,11 @@ import PropTypes from 'prop-types';
|
|||
|
||||
class ExpandingTextarea extends Component {
|
||||
componentDidMount () {
|
||||
this._adjustTextarea({});
|
||||
this.adjustTextarea({});
|
||||
}
|
||||
|
||||
render () {
|
||||
const { onChange, maxHeight, ...rest } = this.props;
|
||||
const { onChange, ...rest } = this.props;
|
||||
return (
|
||||
<textarea
|
||||
{ ...rest }
|
||||
|
@ -17,25 +17,20 @@ class ExpandingTextarea extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
_handleChange (e) {
|
||||
_handleChange (event) {
|
||||
const { onChange } = this.props;
|
||||
if (onChange) onChange(e);
|
||||
this._adjustTextarea(e);
|
||||
if (onChange) onChange(event);
|
||||
this.adjustTextarea(event);
|
||||
}
|
||||
|
||||
_adjustTextarea ({ target = this.el }) {
|
||||
adjustTextarea ({ target = this.el }) {
|
||||
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 = {
|
||||
onChange : PropTypes.func,
|
||||
maxHeight: PropTypes.number,
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
export default ExpandingTextarea;
|
||||
|
|
|
@ -10,3 +10,4 @@ export const SET_PUBLISH_IN_CHANNEL = 'SET_PUBLISH_IN_CHANNEL';
|
|||
export const PUBLISH_STATUS_UPDATE = 'PUBLISH_STATUS_UPDATE';
|
||||
export const ERROR_UPDATE = 'ERROR_UPDATE';
|
||||
export const SELECTED_CHANNEL_UPDATE = 'SELECTED_CHANNEL_UPDATE';
|
||||
export const TOGGLE_METADATA_INPUTS = 'TOGGLE_METADATA_INPUTS';
|
||||
|
|
|
@ -26,7 +26,6 @@ class ChannelCreateForm extends React.Component {
|
|||
return input;
|
||||
}
|
||||
handleChannelInput (event) {
|
||||
event.preventDefault();
|
||||
let value = event.target.value;
|
||||
value = this.cleanseChannelInput(value);
|
||||
this.setState({channel: value});
|
||||
|
@ -38,7 +37,6 @@ class ChannelCreateForm extends React.Component {
|
|||
console.log('end of handlechannelinput');
|
||||
}
|
||||
handleInput (event) {
|
||||
event.preventDefault();
|
||||
const name = event.target.name;
|
||||
const value = event.target.value;
|
||||
this.setState({[name]: value});
|
||||
|
|
|
@ -14,7 +14,6 @@ class ChannelLoginForm extends React.Component {
|
|||
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 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);
|
||||
}
|
||||
handleInput (event) {
|
||||
event.preventDefault();
|
||||
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 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 value = event.target.value;
|
||||
this.setState({[name]: value});
|
||||
|
|
|||
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 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 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
|
|
@ -1,12 +1,13 @@
|
|||
import {connect} from 'react-redux';
|
||||
import {updateMetadata} from 'actions/publish';
|
||||
import {updateMetadata, toggleMetadataInputs} from 'actions/publish';
|
||||
import View from './view';
|
||||
|
||||
const mapStateToProps = ({ publish }) => {
|
||||
return {
|
||||
description: publish.metadata.description,
|
||||
license : publish.metadata.license,
|
||||
nsfw : publish.metadata.nsfw,
|
||||
showMetadataInputs: publish.showMetadataInputs,
|
||||
description : publish.metadata.description,
|
||||
license : publish.metadata.license,
|
||||
nsfw : publish.metadata.nsfw,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -15,6 +16,9 @@ const mapDispatchToProps = dispatch => {
|
|||
onMetadataChange: (name, value) => {
|
||||
dispatch(updateMetadata(name, value));
|
||||
},
|
||||
onToggleMetadataInputs: (value) => {
|
||||
dispatch(toggleMetadataInputs(value));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -4,31 +4,20 @@ import ExpandingTextArea from 'components/ExpandingTextArea';
|
|||
class PublishMetadataInputs extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
showInputs: false,
|
||||
};
|
||||
this.toggleShowInputs = this.toggleShowInputs.bind(this);
|
||||
this.handleDescriptionInput = this.handleDescriptionInput.bind(this);
|
||||
this.handleNsfwCheck = this.handleNsfwCheck.bind(this);
|
||||
this.handleLicenseSelection = this.handleLicenseSelection.bind(this);
|
||||
this.handleInput = this.handleInput.bind(this);
|
||||
this.handleSelect = this.handleSelect.bind(this);
|
||||
}
|
||||
toggleShowInputs () {
|
||||
this.setState({'showInputs': !this.state.showInputs});
|
||||
this.props.onToggleMetadataInputs(!this.props.showMetadataInputs);
|
||||
}
|
||||
handleDescriptionInput (event) {
|
||||
event.preventDefault();
|
||||
const name = event.target.name;
|
||||
const value = event.target.value;
|
||||
handleInput (event) {
|
||||
const target = event.target;
|
||||
const value = target.type === 'checkbox' ? target.checked : target.value;
|
||||
const name = target.name;
|
||||
this.props.onMetadataChange(name, value);
|
||||
}
|
||||
handleNsfwCheck (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) {
|
||||
handleSelect (event) {
|
||||
const name = event.target.name;
|
||||
const selectedOption = event.target.selectedOptions[0].value;
|
||||
this.props.onMetadataChange(name, selectedOption);
|
||||
|
@ -36,8 +25,8 @@ class PublishMetadataInputs extends React.Component {
|
|||
render () {
|
||||
return (
|
||||
<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>
|
||||
{this.state.showInputs && (
|
||||
<a className="label link--primary" id="publish-details-toggle" href="#" onClick={this.toggleShowInputs}>{this.props.showMetadataInputs ? '[less]' : '[more]'}</a>
|
||||
{this.props.showMetadataInputs && (
|
||||
<div>
|
||||
<div className="row row--no-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"
|
||||
rows={1}
|
||||
maxLength={2000}
|
||||
maxHeight={150}
|
||||
style={{ maxHeight: 200 }}
|
||||
name="description"
|
||||
placeholder="Optional description"
|
||||
value={this.props.description}
|
||||
style={{height: this.state.descriptionHeight}}
|
||||
onChange={this.handleDescriptionInput} />
|
||||
onChange={this.handleInput} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -61,7 +49,7 @@ class PublishMetadataInputs extends React.Component {
|
|||
<div className="column column--3 column--med-10">
|
||||
<label htmlFor="publish-license" className="label">License:</label>
|
||||
</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="Public Domain">Public Domain</option>
|
||||
<option value="Creative Commons">Creative Commons</option>
|
||||
|
@ -73,7 +61,7 @@ class PublishMetadataInputs extends React.Component {
|
|||
<div className="column column--3">
|
||||
<label htmlFor="publish-nsfw" className="label">Mature:</label>
|
||||
</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>
|
||||
|
|
|
@ -14,7 +14,6 @@ class PublishThumbnailInput extends React.Component {
|
|||
this.updateVideoThumb = this.updateVideoThumb.bind(this);
|
||||
}
|
||||
handleInput (event) {
|
||||
event.preventDefault();
|
||||
const value = event.target.value;
|
||||
this.setState({thumbnailInput: value});
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ class PublishTitleInput extends React.Component {
|
|||
this.handleInput = this.handleInput.bind(this);
|
||||
}
|
||||
handleInput (e) {
|
||||
e.preventDefault();
|
||||
const name = e.target.name;
|
||||
const value = e.target.value;
|
||||
this.props.onMetadataChange(name, value);
|
||||
|
|
|
@ -27,7 +27,6 @@ class PublishUrlInput extends React.Component {
|
|||
}
|
||||
}
|
||||
handleInput (event) {
|
||||
event.preventDefault();
|
||||
let value = event.target.value;
|
||||
value = this.cleanseInput(value);
|
||||
// update the state
|
||||
|
|
|
@ -2,9 +2,10 @@ import * as actions from 'constants/action_types';
|
|||
import * as channelSelectStates from 'constants/channel_select_states';
|
||||
|
||||
const initialState = {
|
||||
publishInChannel: false,
|
||||
selectedChannel : channelSelectStates.LOGIN,
|
||||
status : {
|
||||
publishInChannel : false,
|
||||
selectedChannel : channelSelectStates.LOGIN,
|
||||
showMetadataInputs: false,
|
||||
status : {
|
||||
status : null,
|
||||
message: null,
|
||||
},
|
||||
|
@ -67,6 +68,10 @@ export default function (state = initialState, action) {
|
|||
return Object.assign({}, state, {
|
||||
selectedChannel: action.value,
|
||||
});
|
||||
case actions.TOGGLE_METADATA_INPUTS:
|
||||
return Object.assign({}, state, {
|
||||
showMetadataInputs: action.value,
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
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