From 1544ac4e2798e969cb9d6d14a361f90517726cfc Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Wed, 29 Aug 2018 15:26:24 +0200 Subject: Add confirmation dialog when posting media without description Fixes #211 --- .../flavours/glitch/features/composer/index.js | 38 +++++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'app/javascript/flavours/glitch/features/composer/index.js') diff --git a/app/javascript/flavours/glitch/features/composer/index.js b/app/javascript/flavours/glitch/features/composer/index.js index cf6f45b34..b823f966f 100644 --- a/app/javascript/flavours/glitch/features/composer/index.js +++ b/app/javascript/flavours/glitch/features/composer/index.js @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; +import { defineMessages } from 'react-intl'; const APPROX_HASHTAG_RE = /(?:^|[^\/\)\w])#(\S+)/i; @@ -49,6 +50,13 @@ import { assignHandlers } from 'flavours/glitch/util/react_helpers'; import { wrap } from 'flavours/glitch/util/redux_helpers'; import { privacyPreference } from 'flavours/glitch/util/privacy_preference'; +const messages = defineMessages({ + missingDescriptionMessage: { id: 'confirmations.missing_media_description.message', + defaultMessage: 'At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.' }, + missingDescriptionConfirm: { id: 'confirmations.missing_media_description.confirm', + defaultMessage: 'Send anyway' }, +}); + // State mapping. function mapStateToProps (state) { const spoilersAlwaysOn = state.getIn(['local_settings', 'always_show_spoilers_field']); @@ -93,11 +101,12 @@ function mapStateToProps (state) { text: state.getIn(['compose', 'text']), anyMedia: state.getIn(['compose', 'media_attachments']).size > 0, spoilersAlwaysOn: spoilersAlwaysOn, + mediaDescriptionConfirmation: state.getIn(['local_settings', 'confirm_missing_media_description']), }; }; // Dispatch mapping. -const mapDispatchToProps = (dispatch) => ({ +const mapDispatchToProps = (dispatch, { intl }) => ({ onCancelReply() { dispatch(cancelReplyCompose()); }, @@ -149,6 +158,13 @@ const mapDispatchToProps = (dispatch) => ({ onSelectSuggestion(position, token, suggestion) { dispatch(selectComposeSuggestion(position, token, suggestion)); }, + onMediaDescriptionConfirm() { + dispatch(openModal('CONFIRM', { + message: intl.formatMessage(messages.missingDescriptionMessage), + confirm: intl.formatMessage(messages.missingDescriptionConfirm), + onConfirm: () => dispatch(submitCompose()), + })); + }, onSubmit() { dispatch(submitCompose()); }, @@ -212,8 +228,11 @@ const handlers = { onSubmit, isSubmitting, isUploading, + media, anyMedia, text, + mediaDescriptionConfirmation, + onMediaDescriptionConfirm, } = this.props; // If something changes inside the textarea, then we update the @@ -227,8 +246,15 @@ const handlers = { return; } - // Submits the status. - if (onSubmit) { + // Submit unless there are media with missing descriptions + if (mediaDescriptionConfirmation && onMediaDescriptionConfirm && media && media.some(item => !item.get('description'))) { + const firstWithoutDescription = media.findIndex(item => !item.get('description')); + const inputs = document.querySelectorAll('.composer--upload_form--item input'); + if (inputs.length == media.size && firstWithoutDescription !== -1) { + inputs[firstWithoutDescription].focus(); + } + onMediaDescriptionConfirm(); + } else if (onSubmit) { onSubmit(); } }, @@ -495,6 +521,9 @@ Composer.propTypes = { suggestionToken: PropTypes.string, suggestions: ImmutablePropTypes.list, text: PropTypes.string, + anyMedia: PropTypes.bool, + spoilersAlwaysOn: PropTypes.bool, + mediaDescriptionConfirmation: PropTypes.bool, // Dispatch props. onCancelReply: PropTypes.func, @@ -517,8 +546,7 @@ Composer.propTypes = { onUndoUpload: PropTypes.func, onUnmount: PropTypes.func, onUpload: PropTypes.func, - anyMedia: PropTypes.bool, - spoilersAlwaysOn: PropTypes.bool, + onMediaDescriptionConfirm: PropTypes.func, }; // Connecting and export. -- cgit From c20b27a9f44b69756624d7a15a52187d0486f03f Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Thu, 30 Aug 2018 11:46:45 +0200 Subject: Restrict querySelectorAll to the upload form component --- .../flavours/glitch/features/composer/index.js | 17 +++++++++++++---- .../glitch/features/composer/upload_form/index.js | 4 +++- 2 files changed, 16 insertions(+), 5 deletions(-) (limited to 'app/javascript/flavours/glitch/features/composer/index.js') diff --git a/app/javascript/flavours/glitch/features/composer/index.js b/app/javascript/flavours/glitch/features/composer/index.js index b823f966f..bc409f0a3 100644 --- a/app/javascript/flavours/glitch/features/composer/index.js +++ b/app/javascript/flavours/glitch/features/composer/index.js @@ -222,7 +222,7 @@ const handlers = { // Submits the status. handleSubmit () { - const { textarea: { value } } = this; + const { textarea: { value }, uploadForm } = this; const { onChangeText, onSubmit, @@ -249,9 +249,11 @@ const handlers = { // Submit unless there are media with missing descriptions if (mediaDescriptionConfirmation && onMediaDescriptionConfirm && media && media.some(item => !item.get('description'))) { const firstWithoutDescription = media.findIndex(item => !item.get('description')); - const inputs = document.querySelectorAll('.composer--upload_form--item input'); - if (inputs.length == media.size && firstWithoutDescription !== -1) { - inputs[firstWithoutDescription].focus(); + if (uploadForm) { + const inputs = uploadForm.querySelectorAll('.composer--upload_form--item input'); + if (inputs.length == media.size && firstWithoutDescription !== -1) { + inputs[firstWithoutDescription].focus(); + } } onMediaDescriptionConfirm(); } else if (onSubmit) { @@ -259,6 +261,11 @@ const handlers = { } }, + // Sets a reference to the upload form. + handleRefUploadForm (uploadFormComponent) { + this.uploadForm = uploadFormComponent; + }, + // Sets a reference to the textarea. handleRefTextarea (textareaComponent) { if (textareaComponent) { @@ -365,6 +372,7 @@ class Composer extends React.Component { handleSecondarySubmit, handleSelect, handleSubmit, + handleRefUploadForm, handleRefTextarea, handleRefSpoilerText, } = this.handlers; @@ -455,6 +463,7 @@ class Composer extends React.Component { onRemove={onUndoUpload} progress={progress} uploading={isUploading} + handleRef={handleRefUploadForm} /> ) : null} +
{uploading ? : null} {media ? (
@@ -55,4 +56,5 @@ ComposerUploadForm.propTypes = { onRemove: PropTypes.func.isRequired, progress: PropTypes.number, uploading: PropTypes.bool, + handleRef: PropTypes.func, }; -- cgit