Add confirmation dialog when posting media without description
Fixes #211
This commit is contained in:
parent
5ce6727669
commit
1544ac4e27
|
@ -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.
|
||||
|
|
|
@ -83,6 +83,14 @@ export default class LocalSettingsPage extends React.PureComponent {
|
|||
>
|
||||
<FormattedMessage id='settings.always_show_spoilers_field' defaultMessage='Always enable the Content Warning field' />
|
||||
</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']}
|
||||
|
|
|
@ -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({
|
||||
|
|
Loading…
Reference in a new issue