React/Redux - publish component #323
|
@ -58,3 +58,10 @@ export function updateSelectedChannel (value) {
|
||||||
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 {
|
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 = `${target.scrollHeight}px`;
|
||||||
target.style.height = `${Math.min(target.scrollHeight, this.props.maxHeight)}px`;
|
|
||||||
} else {
|
|
||||||
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;
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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});
|
||||||
|
|
|
@ -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);
|
this.loginToChannel = this.loginToChannel.bind(this);
|
||||||
}
|
}
|
||||||
handleInput (event) {
|
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 name = event.target.name;
|
||||||
const value = event.target.value;
|
const value = event.target.value;
|
||||||
this.setState({[name]: 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 {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 {
|
||||||
description: publish.metadata.description,
|
showMetadataInputs: publish.showMetadataInputs,
|
||||||
license : publish.metadata.license,
|
description : publish.metadata.description,
|
||||||
nsfw : publish.metadata.nsfw,
|
license : publish.metadata.license,
|
||||||
|
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));
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -2,9 +2,10 @@ import * as actions from 'constants/action_types';
|
||||||
import * as channelSelectStates from 'constants/channel_select_states';
|
import * as channelSelectStates from 'constants/channel_select_states';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
publishInChannel: false,
|
publishInChannel : false,
|
||||||
selectedChannel : channelSelectStates.LOGIN,
|
selectedChannel : channelSelectStates.LOGIN,
|
||||||
status : {
|
showMetadataInputs: false,
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
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