Unverified Commit b7eb3032 authored by Eric Rosenbaum's avatar Eric Rosenbaum Committed by GitHub

Merge pull request #5568 from ericrosenbaum/hide-validation

Hide validation message on click outside 
parents b65ab82a d9169e18
...@@ -173,13 +173,14 @@ const mutateFollowingStudio = shouldFollow => ((dispatch, getState) => { ...@@ -173,13 +173,14 @@ const mutateFollowingStudio = shouldFollow => ((dispatch, getState) => {
}); });
const mutateStudioImage = input => ((dispatch, getState) => { const mutateStudioImage = input => ((dispatch, getState) => {
if (!input.files || !input.files[0]) return; if (!input.files || !input.files[0]) return Promise.reject(new Error('no file'));
const state = getState(); const state = getState();
const studioId = selectStudioId(state); const studioId = selectStudioId(state);
const currentImage = selectStudioImage(state); const currentImage = selectStudioImage(state);
dispatch(startMutation('image')); dispatch(startMutation('image'));
if (input.files[0].size && input.files[0].size > MAX_IMAGE_BYTES) { if (input.files[0].size && input.files[0].size > MAX_IMAGE_BYTES) {
return dispatch(completeMutation('image', currentImage, Errors.THUMBNAIL_TOO_LARGE)); dispatch(completeMutation('image', currentImage, Errors.THUMBNAIL_TOO_LARGE));
return Promise.reject(new Error('thumbnail too large'));
} }
const formData = new FormData(); const formData = new FormData();
formData.append('file', input.files[0]); formData.append('file', input.files[0]);
......
...@@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; ...@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import classNames from 'classnames'; import classNames from 'classnames';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import onClickOutside from 'react-onclickoutside';
import {selectStudioDescription, selectIsFetchingInfo} from '../../redux/studio'; import {selectStudioDescription, selectIsFetchingInfo} from '../../redux/studio';
import {selectCanEditInfo, selectShowEditMuteError} from '../../redux/studio-permissions'; import {selectCanEditInfo, selectShowEditMuteError} from '../../redux/studio-permissions';
...@@ -28,6 +29,11 @@ const StudioDescription = ({ ...@@ -28,6 +29,11 @@ const StudioDescription = ({
descriptionError, isFetching, isMutating, isMutedEditor, description, canEditInfo, handleUpdate descriptionError, isFetching, isMutating, isMutedEditor, description, canEditInfo, handleUpdate
}) => { }) => {
const [showMuteMessage, setShowMuteMessage] = useState(false); const [showMuteMessage, setShowMuteMessage] = useState(false);
const [hideValidationMessage, setHideValidationMessage] = useState(false);
StudioDescription.handleClickOutside = () => {
setHideValidationMessage(true);
};
const fieldClassName = classNames('studio-description', { const fieldClassName = classNames('studio-description', {
'mod-fetching': isFetching, 'mod-fetching': isFetching,
...@@ -49,10 +55,12 @@ const StudioDescription = ({ ...@@ -49,10 +55,12 @@ const StudioDescription = ({
className={fieldClassName} className={fieldClassName}
disabled={isMutating || isFetching || isMutedEditor} disabled={isMutating || isFetching || isMutedEditor}
defaultValue={description} defaultValue={description}
onBlur={e => e.target.value !== description && onBlur={e => {
handleUpdate(e.target.value)} if (e.target.value !== description) handleUpdate(e.target.value);
setHideValidationMessage(false);
}}
/> />
{descriptionError && <ValidationMessage {descriptionError && !hideValidationMessage && <ValidationMessage
mode="error" mode="error"
message={<FormattedMessage id={errorToMessageId(descriptionError)} />} message={<FormattedMessage id={errorToMessageId(descriptionError)} />}
/>} />}
...@@ -71,6 +79,10 @@ const StudioDescription = ({ ...@@ -71,6 +79,10 @@ const StudioDescription = ({
); );
}; };
const clickOutsideConfig = {
handleClickOutside: () => StudioDescription.handleClickOutside
};
StudioDescription.propTypes = { StudioDescription.propTypes = {
descriptionError: PropTypes.string, descriptionError: PropTypes.string,
canEditInfo: PropTypes.bool, canEditInfo: PropTypes.bool,
...@@ -81,7 +93,7 @@ StudioDescription.propTypes = { ...@@ -81,7 +93,7 @@ StudioDescription.propTypes = {
handleUpdate: PropTypes.func handleUpdate: PropTypes.func
}; };
export default connect( const connectedStudioDescription = connect(
state => ({ state => ({
description: selectStudioDescription(state), description: selectStudioDescription(state),
canEditInfo: selectCanEditInfo(state), canEditInfo: selectCanEditInfo(state),
...@@ -94,3 +106,5 @@ export default connect( ...@@ -94,3 +106,5 @@ export default connect(
handleUpdate: mutateStudioDescription handleUpdate: mutateStudioDescription
} }
)(StudioDescription); )(StudioDescription);
export default onClickOutside(connectedStudioDescription, clickOutsideConfig);
...@@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; ...@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import classNames from 'classnames'; import classNames from 'classnames';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import onClickOutside from 'react-onclickoutside';
import {selectStudioImage, selectIsFetchingInfo} from '../../redux/studio'; import {selectStudioImage, selectIsFetchingInfo} from '../../redux/studio';
import {selectCanEditInfo, selectShowEditMuteError} from '../../redux/studio-permissions'; import {selectCanEditInfo, selectShowEditMuteError} from '../../redux/studio-permissions';
...@@ -14,7 +15,6 @@ import { ...@@ -14,7 +15,6 @@ import {
import ValidationMessage from '../../components/forms/validation-message.jsx'; import ValidationMessage from '../../components/forms/validation-message.jsx';
import StudioMuteEditMessage from './studio-mute-edit-message.jsx'; import StudioMuteEditMessage from './studio-mute-edit-message.jsx';
import editIcon from './icons/edit-icon.svg'; import editIcon from './icons/edit-icon.svg';
const errorToMessageId = error => { const errorToMessageId = error => {
...@@ -43,6 +43,11 @@ const StudioImage = ({ ...@@ -43,6 +43,11 @@ const StudioImage = ({
}); });
const [showMuteMessage, setShowMuteMessage] = useState(false); const [showMuteMessage, setShowMuteMessage] = useState(false);
const [hideValidationMessage, setHideValidationMessage] = useState(false);
StudioImage.handleClickOutside = () => {
setHideValidationMessage(true);
};
return ( return (
<div <div
className={fieldClassName} className={fieldClassName}
...@@ -76,11 +81,13 @@ const StudioImage = ({ ...@@ -76,11 +81,13 @@ const StudioImage = ({
accept="image/*" accept="image/*"
onChange={e => { onChange={e => {
handleUpdate(e.target) handleUpdate(e.target)
.catch(() => { /* errors are handled in the reducer */ })
.then(dataUrl => setUploadPreview(dataUrl)); .then(dataUrl => setUploadPreview(dataUrl));
e.target.value = ''; e.target.value = '';
setHideValidationMessage(false);
}} }}
/> />
{imageError && <ValidationMessage {imageError && !hideValidationMessage && <ValidationMessage
mode="error" mode="error"
message={<FormattedMessage id={errorToMessageId(imageError)} />} message={<FormattedMessage id={errorToMessageId(imageError)} />}
/>} />}
...@@ -91,6 +98,10 @@ const StudioImage = ({ ...@@ -91,6 +98,10 @@ const StudioImage = ({
); );
}; };
const clickOutsideConfig = {
handleClickOutside: () => StudioImage.handleClickOutside
};
StudioImage.propTypes = { StudioImage.propTypes = {
imageError: PropTypes.string, imageError: PropTypes.string,
canEditInfo: PropTypes.bool, canEditInfo: PropTypes.bool,
...@@ -101,7 +112,7 @@ StudioImage.propTypes = { ...@@ -101,7 +112,7 @@ StudioImage.propTypes = {
handleUpdate: PropTypes.func handleUpdate: PropTypes.func
}; };
export default connect( const connectedStudioImage = connect(
state => ({ state => ({
image: selectStudioImage(state), image: selectStudioImage(state),
canEditInfo: selectCanEditInfo(state), canEditInfo: selectCanEditInfo(state),
...@@ -114,3 +125,5 @@ export default connect( ...@@ -114,3 +125,5 @@ export default connect(
handleUpdate: mutateStudioImage handleUpdate: mutateStudioImage
} }
)(StudioImage); )(StudioImage);
export default onClickOutside(connectedStudioImage, clickOutsideConfig);
...@@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; ...@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import classNames from 'classnames'; import classNames from 'classnames';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import onClickOutside from 'react-onclickoutside';
import {selectStudioTitle, selectIsFetchingInfo} from '../../redux/studio'; import {selectStudioTitle, selectIsFetchingInfo} from '../../redux/studio';
import {selectCanEditInfo, selectShowEditMuteError} from '../../redux/studio-permissions'; import {selectCanEditInfo, selectShowEditMuteError} from '../../redux/studio-permissions';
...@@ -31,6 +32,11 @@ const StudioTitle = ({ ...@@ -31,6 +32,11 @@ const StudioTitle = ({
}); });
const [showMuteMessage, setShowMuteMessage] = useState(false); const [showMuteMessage, setShowMuteMessage] = useState(false);
const [hideValidationMessage, setHideValidationMessage] = useState(false);
StudioTitle.handleClickOutside = () => {
setHideValidationMessage(true);
};
return ( return (
<div <div
...@@ -45,10 +51,12 @@ const StudioTitle = ({ ...@@ -45,10 +51,12 @@ const StudioTitle = ({
disabled={isMutating || !canEditInfo || isFetching} disabled={isMutating || !canEditInfo || isFetching}
defaultValue={title} defaultValue={title}
onKeyDown={e => e.key === 'Enter' && e.target.blur()} onKeyDown={e => e.key === 'Enter' && e.target.blur()}
onBlur={e => e.target.value !== title && onBlur={e => {
handleUpdate(e.target.value)} if (e.target.value !== title) handleUpdate(e.target.value);
setHideValidationMessage(false);
}}
/> />
{titleError && <ValidationMessage {titleError && !hideValidationMessage && <ValidationMessage
mode="error" mode="error"
message={<FormattedMessage id={errorToMessageId(titleError)} />} message={<FormattedMessage id={errorToMessageId(titleError)} />}
/>} />}
...@@ -61,6 +69,10 @@ const StudioTitle = ({ ...@@ -61,6 +69,10 @@ const StudioTitle = ({
); );
}; };
const clickOutsideConfig = {
handleClickOutside: () => StudioTitle.handleClickOutside
};
StudioTitle.propTypes = { StudioTitle.propTypes = {
titleError: PropTypes.string, titleError: PropTypes.string,
canEditInfo: PropTypes.bool, canEditInfo: PropTypes.bool,
...@@ -71,7 +83,7 @@ StudioTitle.propTypes = { ...@@ -71,7 +83,7 @@ StudioTitle.propTypes = {
handleUpdate: PropTypes.func handleUpdate: PropTypes.func
}; };
export default connect( const connectedStudioTitle = connect(
state => ({ state => ({
title: selectStudioTitle(state), title: selectStudioTitle(state),
canEditInfo: selectCanEditInfo(state), canEditInfo: selectCanEditInfo(state),
...@@ -84,3 +96,5 @@ export default connect( ...@@ -84,3 +96,5 @@ export default connect(
handleUpdate: mutateStudioTitle handleUpdate: mutateStudioTitle
} }
)(StudioTitle); )(StudioTitle);
export default onClickOutside(connectedStudioTitle, clickOutsideConfig);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment