From 6af78c45e5fd523861fb2ceb5c86acae15e7c86b Mon Sep 17 00:00:00 2001 From: Eric Rosenbaum Date: Tue, 8 Jun 2021 10:53:47 -0400 Subject: [PATCH 1/5] hide validation message on click outside --- src/views/studio/studio-title.jsx | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/views/studio/studio-title.jsx b/src/views/studio/studio-title.jsx index 6da4feae9..b4ebae87b 100644 --- a/src/views/studio/studio-title.jsx +++ b/src/views/studio/studio-title.jsx @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import classNames from 'classnames'; import {FormattedMessage} from 'react-intl'; +import onClickOutside from 'react-onclickoutside'; import {selectStudioTitle, selectIsFetchingInfo} from '../../redux/studio'; import {selectCanEditInfo, selectShowEditMuteError} from '../../redux/studio-permissions'; @@ -31,6 +32,11 @@ const StudioTitle = ({ }); const [showMuteMessage, setShowMuteMessage] = useState(false); + const [hideValidationMessage, setHideValidationMessage] = useState(false); + + StudioTitle.handleClickOutside = () => { + setHideValidationMessage(true); + }; return (
e.key === 'Enter' && e.target.blur()} - onBlur={e => e.target.value !== title && - handleUpdate(e.target.value)} + onBlur={e => { + if (e.target.value !== title) handleUpdate(e.target.value); + setHideValidationMessage(false); + }} /> - {titleError && } />} @@ -61,6 +69,10 @@ const StudioTitle = ({ ); }; +const clickOutsideConfig = { + handleClickOutside: () => StudioTitle.handleClickOutside +}; + StudioTitle.propTypes = { titleError: PropTypes.string, canEditInfo: PropTypes.bool, @@ -71,7 +83,7 @@ StudioTitle.propTypes = { handleUpdate: PropTypes.func }; -export default connect( +export default onClickOutside(connect( state => ({ title: selectStudioTitle(state), canEditInfo: selectCanEditInfo(state), @@ -83,4 +95,4 @@ export default connect( { handleUpdate: mutateStudioTitle } -)(StudioTitle); +)(StudioTitle), clickOutsideConfig); From 935ec7acadcffced43400bf6707f57ca1080b3a5 Mon Sep 17 00:00:00 2001 From: Eric Rosenbaum Date: Tue, 8 Jun 2021 11:01:54 -0400 Subject: [PATCH 2/5] simplify wrapping --- src/views/studio/studio-title.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/views/studio/studio-title.jsx b/src/views/studio/studio-title.jsx index b4ebae87b..606b992a7 100644 --- a/src/views/studio/studio-title.jsx +++ b/src/views/studio/studio-title.jsx @@ -83,7 +83,7 @@ StudioTitle.propTypes = { handleUpdate: PropTypes.func }; -export default onClickOutside(connect( +const connectedStudioTitle = connect( state => ({ title: selectStudioTitle(state), canEditInfo: selectCanEditInfo(state), @@ -95,4 +95,6 @@ export default onClickOutside(connect( { handleUpdate: mutateStudioTitle } -)(StudioTitle), clickOutsideConfig); +)(StudioTitle); + +export default onClickOutside(connectedStudioTitle, clickOutsideConfig); From b0a9bab71a37303a4fde81eac1db217fb32264e6 Mon Sep 17 00:00:00 2001 From: Eric Rosenbaum Date: Tue, 8 Jun 2021 13:58:21 -0400 Subject: [PATCH 3/5] hide validation on click outside for thumnbail image --- src/redux/studio-mutations.js | 5 +++-- src/views/studio/studio-image.jsx | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/redux/studio-mutations.js b/src/redux/studio-mutations.js index d2c398963..07919e6cb 100644 --- a/src/redux/studio-mutations.js +++ b/src/redux/studio-mutations.js @@ -173,13 +173,14 @@ const mutateFollowingStudio = shouldFollow => ((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 studioId = selectStudioId(state); const currentImage = selectStudioImage(state); dispatch(startMutation('image')); 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(); formData.append('file', input.files[0]); diff --git a/src/views/studio/studio-image.jsx b/src/views/studio/studio-image.jsx index 79948e14c..8a7ce2bab 100644 --- a/src/views/studio/studio-image.jsx +++ b/src/views/studio/studio-image.jsx @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import classNames from 'classnames'; import {FormattedMessage} from 'react-intl'; +import onClickOutside from 'react-onclickoutside'; import {selectStudioImage, selectIsFetchingInfo} from '../../redux/studio'; import {selectCanEditInfo, selectShowEditMuteError} from '../../redux/studio-permissions'; @@ -14,7 +15,6 @@ import { import ValidationMessage from '../../components/forms/validation-message.jsx'; import StudioMuteEditMessage from './studio-mute-edit-message.jsx'; - import editIcon from './icons/edit-icon.svg'; const errorToMessageId = error => { @@ -43,6 +43,11 @@ const StudioImage = ({ }); const [showMuteMessage, setShowMuteMessage] = useState(false); + const [hideValidationMessage, setHideValidationMessage] = useState(false); + + StudioImage.handleClickOutside = () => { + setHideValidationMessage(true); + }; return (
setUploadPreview(dataUrl)); e.target.value = ''; + setHideValidationMessage(false); }} /> - {imageError && } />} @@ -91,6 +97,10 @@ const StudioImage = ({ ); }; +const clickOutsideConfig = { + handleClickOutside: () => StudioImage.handleClickOutside +}; + StudioImage.propTypes = { imageError: PropTypes.string, canEditInfo: PropTypes.bool, @@ -101,7 +111,7 @@ StudioImage.propTypes = { handleUpdate: PropTypes.func }; -export default connect( +const connectedStudioImage = connect( state => ({ image: selectStudioImage(state), canEditInfo: selectCanEditInfo(state), @@ -114,3 +124,5 @@ export default connect( handleUpdate: mutateStudioImage } )(StudioImage); + +export default onClickOutside(connectedStudioImage, clickOutsideConfig); From 5ba6bb83b9de1a7981128c1d9ad19369431250d9 Mon Sep 17 00:00:00 2001 From: Eric Rosenbaum Date: Tue, 8 Jun 2021 14:16:23 -0400 Subject: [PATCH 4/5] hide validation on click outside for description --- src/views/studio/studio-description.jsx | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/views/studio/studio-description.jsx b/src/views/studio/studio-description.jsx index 11a16f7ff..aa1fe8163 100644 --- a/src/views/studio/studio-description.jsx +++ b/src/views/studio/studio-description.jsx @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import classNames from 'classnames'; import {FormattedMessage} from 'react-intl'; +import onClickOutside from 'react-onclickoutside'; import {selectStudioDescription, selectIsFetchingInfo} from '../../redux/studio'; import {selectCanEditInfo, selectShowEditMuteError} from '../../redux/studio-permissions'; @@ -28,6 +29,11 @@ const StudioDescription = ({ descriptionError, isFetching, isMutating, isMutedEditor, description, canEditInfo, handleUpdate }) => { const [showMuteMessage, setShowMuteMessage] = useState(false); + const [hideValidationMessage, setHideValidationMessage] = useState(false); + + StudioDescription.handleClickOutside = () => { + setHideValidationMessage(true); + }; const fieldClassName = classNames('studio-description', { 'mod-fetching': isFetching, @@ -49,10 +55,12 @@ const StudioDescription = ({ className={fieldClassName} disabled={isMutating || isFetching || isMutedEditor} defaultValue={description} - onBlur={e => e.target.value !== description && - handleUpdate(e.target.value)} + onBlur={e => { + if (e.target.value !== description) handleUpdate(e.target.value); + setHideValidationMessage(false); + }} /> - {descriptionError && } />} @@ -71,6 +79,10 @@ const StudioDescription = ({ ); }; +const clickOutsideConfig = { + handleClickOutside: () => StudioDescription.handleClickOutside +}; + StudioDescription.propTypes = { descriptionError: PropTypes.string, canEditInfo: PropTypes.bool, @@ -81,7 +93,7 @@ StudioDescription.propTypes = { handleUpdate: PropTypes.func }; -export default connect( +const connectedStudioDescription = connect( state => ({ description: selectStudioDescription(state), canEditInfo: selectCanEditInfo(state), @@ -94,3 +106,5 @@ export default connect( handleUpdate: mutateStudioDescription } )(StudioDescription); + +export default onClickOutside(connectedStudioDescription, clickOutsideConfig); From d9169e18925e4a428ed18b7bd9f49b4ca8f811d5 Mon Sep 17 00:00:00 2001 From: Eric Rosenbaum Date: Tue, 8 Jun 2021 14:55:37 -0400 Subject: [PATCH 5/5] catch errors --- src/views/studio/studio-image.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/studio/studio-image.jsx b/src/views/studio/studio-image.jsx index 8a7ce2bab..ef2c13cef 100644 --- a/src/views/studio/studio-image.jsx +++ b/src/views/studio/studio-image.jsx @@ -81,6 +81,7 @@ const StudioImage = ({ accept="image/*" onChange={e => { handleUpdate(e.target) + .catch(() => { /* errors are handled in the reducer */ }) .then(dataUrl => setUploadPreview(dataUrl)); e.target.value = ''; setHideValidationMessage(false);