diff --git a/app/javascript/flavours/glitch/features/composer/index.js b/app/javascript/flavours/glitch/features/composer/index.js
index cf6f45b34aa..b823f966fca 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.
diff --git a/app/javascript/flavours/glitch/features/local_settings/page/index.js b/app/javascript/flavours/glitch/features/local_settings/page/index.js
index ad5c1197948..1e61c67c0bb 100644
--- a/app/javascript/flavours/glitch/features/local_settings/page/index.js
+++ b/app/javascript/flavours/glitch/features/local_settings/page/index.js
@@ -83,6 +83,14 @@ export default class LocalSettingsPage extends React.PureComponent {
>
+
+
+