mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-02-10 08:52:13 -05:00
[Glitch] Add reminder when about to post without alt text in web UI
Port 1e70da5e3c279c8e632abb6bdf90b1ddc67b035e to glitch-soc Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
parent
800bea7209
commit
a3399ed560
@ -192,6 +192,9 @@ export function directCompose(account) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {null | string} overridePrivacy
|
||||||
|
*/
|
||||||
export function submitCompose(overridePrivacy = null) {
|
export function submitCompose(overridePrivacy = null) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
let status = getState().getIn(['compose', 'text'], '');
|
let status = getState().getIn(['compose', 'text'], '');
|
||||||
|
@ -10,6 +10,8 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
|||||||
|
|
||||||
import { length } from 'stringz';
|
import { length } from 'stringz';
|
||||||
|
|
||||||
|
import { missingAltTextModal } from 'flavours/glitch/initial_state';
|
||||||
|
|
||||||
import AutosuggestInput from '../../../components/autosuggest_input';
|
import AutosuggestInput from '../../../components/autosuggest_input';
|
||||||
import AutosuggestTextarea from '../../../components/autosuggest_textarea';
|
import AutosuggestTextarea from '../../../components/autosuggest_textarea';
|
||||||
import { Button } from '../../../components/button';
|
import { Button } from '../../../components/button';
|
||||||
@ -72,9 +74,8 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
autoFocus: PropTypes.bool,
|
autoFocus: PropTypes.bool,
|
||||||
withoutNavigation: PropTypes.bool,
|
withoutNavigation: PropTypes.bool,
|
||||||
anyMedia: PropTypes.bool,
|
anyMedia: PropTypes.bool,
|
||||||
|
missingAltText: PropTypes.bool,
|
||||||
media: ImmutablePropTypes.list,
|
media: ImmutablePropTypes.list,
|
||||||
mediaDescriptionConfirmation: PropTypes.bool,
|
|
||||||
onMediaDescriptionConfirm: PropTypes.func.isRequired,
|
|
||||||
isInReply: PropTypes.bool,
|
isInReply: PropTypes.bool,
|
||||||
singleColumn: PropTypes.bool,
|
singleColumn: PropTypes.bool,
|
||||||
lang: PropTypes.string,
|
lang: PropTypes.string,
|
||||||
@ -131,17 +132,11 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.props.onSubmit(missingAltTextModal && this.props.missingAltText, overridePrivacy);
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Submit unless there are media with missing descriptions
|
|
||||||
if (this.props.mediaDescriptionConfirmation && this.props.media && this.props.media.some(item => !item.get('description'))) {
|
|
||||||
const firstWithoutDescription = this.props.media.find(item => !item.get('description'));
|
|
||||||
this.props.onMediaDescriptionConfirm(firstWithoutDescription.get('id'), overridePrivacy);
|
|
||||||
} else {
|
|
||||||
this.props.onSubmit(overridePrivacy);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSecondarySubmit = (e) => {
|
handleSecondarySubmit = (e) => {
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { injectIntl } from 'react-intl';
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { privacyPreference } from 'flavours/glitch/utils/privacy_preference';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
changeCompose,
|
changeCompose,
|
||||||
submitCompose,
|
submitCompose,
|
||||||
@ -13,27 +11,11 @@ import {
|
|||||||
changeComposeSpoilerText,
|
changeComposeSpoilerText,
|
||||||
insertEmojiCompose,
|
insertEmojiCompose,
|
||||||
uploadCompose,
|
uploadCompose,
|
||||||
} from '../../../actions/compose';
|
} from 'flavours/glitch/actions/compose';
|
||||||
import { changeLocalSetting } from '../../../actions/local_settings';
|
import { openModal } from 'flavours/glitch/actions/modal';
|
||||||
import {
|
import { privacyPreference } from 'flavours/glitch/utils/privacy_preference';
|
||||||
openModal,
|
|
||||||
} from '../../../actions/modal';
|
|
||||||
import ComposeForm from '../components/compose_form';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
import ComposeForm from '../components/compose_form';
|
||||||
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',
|
|
||||||
},
|
|
||||||
missingDescriptionEdit: {
|
|
||||||
id: 'confirmations.missing_media_description.edit',
|
|
||||||
defaultMessage: 'Edit media',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const sideArmPrivacy = state => {
|
const sideArmPrivacy = state => {
|
||||||
const inReplyTo = state.getIn(['compose', 'in_reply_to']);
|
const inReplyTo = state.getIn(['compose', 'in_reply_to']);
|
||||||
@ -68,22 +50,29 @@ const mapStateToProps = state => ({
|
|||||||
isChangingUpload: state.getIn(['compose', 'is_changing_upload']),
|
isChangingUpload: state.getIn(['compose', 'is_changing_upload']),
|
||||||
isUploading: state.getIn(['compose', 'is_uploading']),
|
isUploading: state.getIn(['compose', 'is_uploading']),
|
||||||
anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
|
anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
|
||||||
|
missingAltText: state.getIn(['compose', 'media_attachments']).some(media => ['image', 'gifv'].includes(media.get('type')) && (media.get('description') ?? '').length === 0),
|
||||||
isInReply: state.getIn(['compose', 'in_reply_to']) !== null,
|
isInReply: state.getIn(['compose', 'in_reply_to']) !== null,
|
||||||
lang: state.getIn(['compose', 'language']),
|
lang: state.getIn(['compose', 'language']),
|
||||||
sideArm: sideArmPrivacy(state),
|
sideArm: sideArmPrivacy(state),
|
||||||
media: state.getIn(['compose', 'media_attachments']),
|
media: state.getIn(['compose', 'media_attachments']),
|
||||||
mediaDescriptionConfirmation: state.getIn(['local_settings', 'confirm_missing_media_description']),
|
|
||||||
maxChars: state.getIn(['server', 'server', 'configuration', 'statuses', 'max_characters'], 500),
|
maxChars: state.getIn(['server', 'server', 'configuration', 'statuses', 'max_characters'], 500),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
|
||||||
onChange (text) {
|
onChange (text) {
|
||||||
dispatch(changeCompose(text));
|
dispatch(changeCompose(text));
|
||||||
},
|
},
|
||||||
|
|
||||||
onSubmit (overridePrivacy = null) {
|
onSubmit (missingAltText, overridePrivacy = null) {
|
||||||
dispatch(submitCompose(overridePrivacy));
|
if (missingAltText) {
|
||||||
|
dispatch(openModal({
|
||||||
|
modalType: 'CONFIRM_MISSING_ALT_TEXT',
|
||||||
|
modalProps: { overridePrivacy },
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
dispatch(submitCompose(overridePrivacy));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onClearSuggestions () {
|
onClearSuggestions () {
|
||||||
@ -110,25 +99,6 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
|||||||
dispatch(insertEmojiCompose(position, data, needsSpace));
|
dispatch(insertEmojiCompose(position, data, needsSpace));
|
||||||
},
|
},
|
||||||
|
|
||||||
onMediaDescriptionConfirm (mediaId, overridePrivacy = null) {
|
|
||||||
dispatch(openModal({
|
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.missingDescriptionMessage),
|
|
||||||
confirm: intl.formatMessage(messages.missingDescriptionConfirm),
|
|
||||||
onConfirm: () => {
|
|
||||||
dispatch(submitCompose(overridePrivacy));
|
|
||||||
},
|
|
||||||
secondary: intl.formatMessage(messages.missingDescriptionEdit),
|
|
||||||
onSecondary: () => dispatch(openModal({
|
|
||||||
modalType: 'FOCAL_POINT',
|
|
||||||
modalProps: { id: mediaId },
|
|
||||||
})),
|
|
||||||
onDoNotAsk: () => dispatch(changeLocalSetting(['confirm_missing_media_description'], false)),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ComposeForm));
|
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ComposeForm));
|
||||||
|
@ -200,14 +200,6 @@ class LocalSettingsPage extends PureComponent {
|
|||||||
<FormattedMessage id='settings.preselect_on_reply' defaultMessage='Pre-select usernames on reply' />
|
<FormattedMessage id='settings.preselect_on_reply' defaultMessage='Pre-select usernames on reply' />
|
||||||
<span className='hint'><FormattedMessage id='settings.preselect_on_reply_hint' defaultMessage='When replying to a conversation with multiple participants, pre-select usernames past the first' /></span>
|
<span className='hint'><FormattedMessage id='settings.preselect_on_reply_hint' defaultMessage='When replying to a conversation with multiple participants, pre-select usernames past the first' /></span>
|
||||||
</LocalSettingsPageItem>
|
</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
|
<LocalSettingsPageItem
|
||||||
settings={settings}
|
settings={settings}
|
||||||
item={['confirm_before_clearing_draft']}
|
item={['confirm_before_clearing_draft']}
|
||||||
|
@ -64,14 +64,6 @@ export const ConfirmationModal: React.FC<
|
|||||||
|
|
||||||
<div className='safety-action-modal__bottom'>
|
<div className='safety-action-modal__bottom'>
|
||||||
<div className='safety-action-modal__actions'>
|
<div className='safety-action-modal__actions'>
|
||||||
{secondary && (
|
|
||||||
<>
|
|
||||||
<Button onClick={handleSecondary}>{secondary}</Button>
|
|
||||||
|
|
||||||
<div className='spacer' />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<button onClick={handleCancel} className='link-button'>
|
<button onClick={handleCancel} className='link-button'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='confirmation_modal.cancel'
|
id='confirmation_modal.cancel'
|
||||||
@ -79,6 +71,15 @@ export const ConfirmationModal: React.FC<
|
|||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
{secondary && (
|
||||||
|
<>
|
||||||
|
<div className='spacer' />
|
||||||
|
<button onClick={handleSecondary} className='link-button'>
|
||||||
|
{secondary}
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* eslint-disable-next-line jsx-a11y/no-autofocus -- we are in a modal and thus autofocusing is justified */}
|
{/* eslint-disable-next-line jsx-a11y/no-autofocus -- we are in a modal and thus autofocusing is justified */}
|
||||||
<Button onClick={handleClick} autoFocus>
|
<Button onClick={handleClick} autoFocus>
|
||||||
{confirm}
|
{confirm}
|
||||||
|
@ -7,3 +7,4 @@ export { ConfirmUnfollowModal } from './unfollow';
|
|||||||
export { ConfirmClearNotificationsModal } from './clear_notifications';
|
export { ConfirmClearNotificationsModal } from './clear_notifications';
|
||||||
export { ConfirmLogOutModal } from './log_out';
|
export { ConfirmLogOutModal } from './log_out';
|
||||||
export { ConfirmFollowToListModal } from './follow_to_list';
|
export { ConfirmFollowToListModal } from './follow_to_list';
|
||||||
|
export { ConfirmMissingAltTextModal } from './missing_alt_text';
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import type { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||||
|
|
||||||
|
import { submitCompose } from 'flavours/glitch/actions/compose';
|
||||||
|
import { openModal } from 'flavours/glitch/actions/modal';
|
||||||
|
import type { MediaAttachment } from 'flavours/glitch/models/media_attachment';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'flavours/glitch/store';
|
||||||
|
|
||||||
|
import type { BaseConfirmationModalProps } from './confirmation_modal';
|
||||||
|
import { ConfirmationModal } from './confirmation_modal';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
title: {
|
||||||
|
id: 'confirmations.missing_alt_text.title',
|
||||||
|
defaultMessage: 'Add alt text?',
|
||||||
|
},
|
||||||
|
confirm: {
|
||||||
|
id: 'confirmations.missing_alt_text.confirm',
|
||||||
|
defaultMessage: 'Add alt text',
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
id: 'confirmations.missing_alt_text.message',
|
||||||
|
defaultMessage:
|
||||||
|
'Your post contains media without alt text. Adding descriptions helps make your content accessible to more people.',
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
id: 'confirmations.missing_alt_text.secondary',
|
||||||
|
defaultMessage: 'Post anyway',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ConfirmMissingAltTextModal: React.FC<
|
||||||
|
{
|
||||||
|
overridePrivacy: null | string;
|
||||||
|
} & BaseConfirmationModalProps
|
||||||
|
> = ({ onClose, overridePrivacy }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const mediaId = useAppSelector(
|
||||||
|
(state) =>
|
||||||
|
(
|
||||||
|
(state.compose as ImmutableMap<string, unknown>).get(
|
||||||
|
'media_attachments',
|
||||||
|
) as ImmutableList<MediaAttachment>
|
||||||
|
)
|
||||||
|
.find(
|
||||||
|
(media) =>
|
||||||
|
['image', 'gifv'].includes(media.get('type') as string) &&
|
||||||
|
((media.get('description') ?? '') as string).length === 0,
|
||||||
|
)
|
||||||
|
?.get('id') as string,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleConfirm = useCallback(() => {
|
||||||
|
dispatch(
|
||||||
|
openModal({
|
||||||
|
modalType: 'FOCAL_POINT',
|
||||||
|
modalProps: {
|
||||||
|
mediaId,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}, [dispatch, mediaId]);
|
||||||
|
|
||||||
|
const handleSecondary = useCallback(() => {
|
||||||
|
dispatch(submitCompose(overridePrivacy));
|
||||||
|
}, [dispatch, overridePrivacy]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmationModal
|
||||||
|
title={intl.formatMessage(messages.title)}
|
||||||
|
message={intl.formatMessage(messages.message)}
|
||||||
|
confirm={intl.formatMessage(messages.confirm)}
|
||||||
|
secondary={intl.formatMessage(messages.secondary)}
|
||||||
|
onConfirm={handleConfirm}
|
||||||
|
onSecondary={handleSecondary}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
@ -38,6 +38,7 @@ import {
|
|||||||
ConfirmClearNotificationsModal,
|
ConfirmClearNotificationsModal,
|
||||||
ConfirmLogOutModal,
|
ConfirmLogOutModal,
|
||||||
ConfirmFollowToListModal,
|
ConfirmFollowToListModal,
|
||||||
|
ConfirmMissingAltTextModal,
|
||||||
} from './confirmation_modals';
|
} from './confirmation_modals';
|
||||||
import DeprecatedSettingsModal from './deprecated_settings_modal';
|
import DeprecatedSettingsModal from './deprecated_settings_modal';
|
||||||
import DoodleModal from './doodle_modal';
|
import DoodleModal from './doodle_modal';
|
||||||
@ -64,6 +65,7 @@ export const MODAL_COMPONENTS = {
|
|||||||
'CONFIRM_CLEAR_NOTIFICATIONS': () => Promise.resolve({ default: ConfirmClearNotificationsModal }),
|
'CONFIRM_CLEAR_NOTIFICATIONS': () => Promise.resolve({ default: ConfirmClearNotificationsModal }),
|
||||||
'CONFIRM_LOG_OUT': () => Promise.resolve({ default: ConfirmLogOutModal }),
|
'CONFIRM_LOG_OUT': () => Promise.resolve({ default: ConfirmLogOutModal }),
|
||||||
'CONFIRM_FOLLOW_TO_LIST': () => Promise.resolve({ default: ConfirmFollowToListModal }),
|
'CONFIRM_FOLLOW_TO_LIST': () => Promise.resolve({ default: ConfirmFollowToListModal }),
|
||||||
|
'CONFIRM_MISSING_ALT_TEXT': () => Promise.resolve({ default: ConfirmMissingAltTextModal }),
|
||||||
'MUTE': MuteModal,
|
'MUTE': MuteModal,
|
||||||
'BLOCK': BlockModal,
|
'BLOCK': BlockModal,
|
||||||
'DOMAIN_BLOCK': DomainBlockModal,
|
'DOMAIN_BLOCK': DomainBlockModal,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
* @property {boolean=} favourite_modal
|
* @property {boolean=} favourite_modal
|
||||||
* @property {boolean} crop_images
|
* @property {boolean} crop_images
|
||||||
* @property {boolean=} delete_modal
|
* @property {boolean=} delete_modal
|
||||||
|
* @property {boolean=} missing_alt_text_modal
|
||||||
* @property {boolean=} disable_swiping
|
* @property {boolean=} disable_swiping
|
||||||
* @property {boolean=} disable_hover_cards
|
* @property {boolean=} disable_hover_cards
|
||||||
* @property {string=} disabled_account_id
|
* @property {string=} disabled_account_id
|
||||||
@ -107,6 +108,7 @@ export const autoPlayGif = getMeta('auto_play_gif');
|
|||||||
export const boostModal = getMeta('boost_modal');
|
export const boostModal = getMeta('boost_modal');
|
||||||
export const cropImages = getMeta('crop_images');
|
export const cropImages = getMeta('crop_images');
|
||||||
export const deleteModal = getMeta('delete_modal');
|
export const deleteModal = getMeta('delete_modal');
|
||||||
|
export const missingAltTextModal = getMeta('missing_alt_text_modal');
|
||||||
export const disableSwiping = getMeta('disable_swiping');
|
export const disableSwiping = getMeta('disable_swiping');
|
||||||
export const disableHoverCards = getMeta('disable_hover_cards');
|
export const disableHoverCards = getMeta('disable_hover_cards');
|
||||||
export const disabledAccountId = getMeta('disabled_account_id');
|
export const disabledAccountId = getMeta('disabled_account_id');
|
||||||
|
@ -31,9 +31,6 @@
|
|||||||
"confirmation_modal.do_not_ask_again": "Do not ask for confirmation again",
|
"confirmation_modal.do_not_ask_again": "Do not ask for confirmation again",
|
||||||
"confirmations.deprecated_settings.confirm": "Use Mastodon preferences",
|
"confirmations.deprecated_settings.confirm": "Use Mastodon preferences",
|
||||||
"confirmations.deprecated_settings.message": "Some of the glitch-soc device-specific {app_settings} you are using have been replaced by Mastodon {preferences} and will be overriden:",
|
"confirmations.deprecated_settings.message": "Some of the glitch-soc device-specific {app_settings} you are using have been replaced by Mastodon {preferences} and will be overriden:",
|
||||||
"confirmations.missing_media_description.confirm": "Send anyway",
|
|
||||||
"confirmations.missing_media_description.edit": "Edit media",
|
|
||||||
"confirmations.missing_media_description.message": "At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.",
|
|
||||||
"direct.group_by_conversations": "Group by conversation",
|
"direct.group_by_conversations": "Group by conversation",
|
||||||
"favourite_modal.favourite": "Favourite post?",
|
"favourite_modal.favourite": "Favourite post?",
|
||||||
"federation.federated.long": "Allow this post to reach other servers",
|
"federation.federated.long": "Allow this post to reach other servers",
|
||||||
@ -57,7 +54,6 @@
|
|||||||
"settings.compose_box_opts": "Compose box",
|
"settings.compose_box_opts": "Compose box",
|
||||||
"settings.confirm_before_clearing_draft": "Show confirmation dialog before overwriting the message being composed",
|
"settings.confirm_before_clearing_draft": "Show confirmation dialog before overwriting the message being composed",
|
||||||
"settings.confirm_boost_missing_media_description": "Show confirmation dialog before boosting toots lacking media descriptions",
|
"settings.confirm_boost_missing_media_description": "Show confirmation dialog before boosting toots lacking media descriptions",
|
||||||
"settings.confirm_missing_media_description": "Show confirmation dialog before sending toots lacking media descriptions",
|
|
||||||
"settings.content_warnings": "Content Warnings",
|
"settings.content_warnings": "Content Warnings",
|
||||||
"settings.content_warnings.regexp": "Regular expression",
|
"settings.content_warnings.regexp": "Regular expression",
|
||||||
"settings.content_warnings_filter": "Content warnings to not automatically unfold:",
|
"settings.content_warnings_filter": "Content warnings to not automatically unfold:",
|
||||||
|
@ -11,7 +11,6 @@ const initialState = ImmutableMap({
|
|||||||
side_arm_reply_mode : 'keep',
|
side_arm_reply_mode : 'keep',
|
||||||
show_reply_count : false,
|
show_reply_count : false,
|
||||||
always_show_spoilers_field: false,
|
always_show_spoilers_field: false,
|
||||||
confirm_missing_media_description: false,
|
|
||||||
confirm_boost_missing_media_description: false,
|
confirm_boost_missing_media_description: false,
|
||||||
confirm_before_clearing_draft: true,
|
confirm_before_clearing_draft: true,
|
||||||
prepend_cw_re: true,
|
prepend_cw_re: true,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user