diff options
author | Thibaut Girka <thib@sitedethib.com> | 2018-08-29 15:26:24 +0200 |
---|---|---|
committer | ThibG <thib@sitedethib.com> | 2018-08-30 13:20:37 +0200 |
commit | 1544ac4e2798e969cb9d6d14a361f90517726cfc (patch) | |
tree | 53ff2bc13e4938396e77137a88f1ba1d90a4f974 /app/javascript | |
parent | 5ce67276691c37baad149f2f89f765543f70e6f9 (diff) |
Add confirmation dialog when posting media without description
Fixes #211
Diffstat (limited to 'app/javascript')
3 files changed, 42 insertions, 5 deletions
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. 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 ad5c11979..1e61c67c0 100644 --- a/app/javascript/flavours/glitch/features/local_settings/page/index.js +++ b/app/javascript/flavours/glitch/features/local_settings/page/index.js @@ -85,6 +85,14 @@ export default class LocalSettingsPage extends React.PureComponent { </LocalSettingsPageItem> <LocalSettingsPageItem settings={settings} + item={['confirm_missing_media_description']} + id='mastodon-settings--confirm_missing_media_description' + onChange={onChange} + > + <FormattedMessage id='settings.confirm_missing_media_description' defaultMessage='Show confirmation dialog before sending toots lacking media descriptions' /> + </LocalSettingsPageItem> + <LocalSettingsPageItem + settings={settings} item={['side_arm']} id='mastodon-settings--side_arm' options={[ diff --git a/app/javascript/flavours/glitch/reducers/local_settings.js b/app/javascript/flavours/glitch/reducers/local_settings.js index 1d24f0e9a..ebe0b1292 100644 --- a/app/javascript/flavours/glitch/reducers/local_settings.js +++ b/app/javascript/flavours/glitch/reducers/local_settings.js @@ -13,6 +13,7 @@ const initialState = ImmutableMap({ side_arm_reply_mode : 'keep', show_reply_count : false, always_show_spoilers_field: false, + confirm_missing_media_description: false, collapsed : ImmutableMap({ enabled : true, auto : ImmutableMap({ |