Add option to not automatically unfold content warnings matching a regexp

Fixes #678
This commit is contained in:
Thibaut Girka 2018-08-28 17:16:30 +02:00 committed by ThibG
parent 5c400a2842
commit c6942a5283
5 changed files with 52 additions and 3 deletions

View file

@ -13,6 +13,7 @@ import { MediaGallery, Video } from 'flavours/glitch/util/async-components';
import { HotKeys } from 'react-hotkeys'; import { HotKeys } from 'react-hotkeys';
import NotificationOverlayContainer from 'flavours/glitch/features/notifications/containers/overlay_container'; import NotificationOverlayContainer from 'flavours/glitch/features/notifications/containers/overlay_container';
import classNames from 'classnames'; import classNames from 'classnames';
import { autoUnfoldCW } from 'flavours/glitch/util/content_warning';
// We use the component (and not the container) since we do not want // We use the component (and not the container) since we do not want
// to use the progress bar to show download progress // to use the progress bar to show download progress
@ -56,7 +57,7 @@ export default class Status extends ImmutablePureComponent {
state = { state = {
isCollapsed: false, isCollapsed: false,
autoCollapsed: false, autoCollapsed: false,
isExpanded: this.props.settings.getIn(['content_warnings', 'auto_unfold']), isExpanded: undefined,
} }
// Avoid checking props that are functions (and whose equality will always // Avoid checking props that are functions (and whose equality will always
@ -124,6 +125,17 @@ export default class Status extends ImmutablePureComponent {
updated = true; updated = true;
} }
if (nextProps.expanded === undefined &&
prevState.isExpanded === undefined &&
update.isExpanded === undefined
) {
const isExpanded = autoUnfoldCW(nextProps.settings, nextProps.status);
if (isExpanded !== undefined) {
update.isExpanded = isExpanded;
updated = true;
}
}
return updated ? update : null; return updated ? update : null;
} }

View file

@ -17,6 +17,7 @@ const messages = defineMessages({
side_arm_keep: { id: 'settings.side_arm_reply_mode.keep', defaultMessage: 'Keep secondary toot button to set privacy' }, side_arm_keep: { id: 'settings.side_arm_reply_mode.keep', defaultMessage: 'Keep secondary toot button to set privacy' },
side_arm_copy: { id: 'settings.side_arm_reply_mode.copy', defaultMessage: 'Copy privacy setting of the toot being replied to' }, side_arm_copy: { id: 'settings.side_arm_reply_mode.copy', defaultMessage: 'Copy privacy setting of the toot being replied to' },
side_arm_restrict: { id: 'settings.side_arm_reply_mode.restrict', defaultMessage: 'Restrict privacy setting to that of the toot being replied to' }, side_arm_restrict: { id: 'settings.side_arm_reply_mode.restrict', defaultMessage: 'Restrict privacy setting to that of the toot being replied to' },
regexp: { id: 'settings.content_warnings.regexp', defaultMessage: 'Regular expression' },
}); });
@injectIntl @injectIntl
@ -122,7 +123,7 @@ export default class LocalSettingsPage extends React.PureComponent {
</section> </section>
</div> </div>
), ),
({ onChange, settings }) => ( ({ intl, onChange, settings }) => (
<div className='glitch local-settings__page content_warnings'> <div className='glitch local-settings__page content_warnings'>
<h1><FormattedMessage id='settings.content_warnings' defaultMessage='Content warnings' /></h1> <h1><FormattedMessage id='settings.content_warnings' defaultMessage='Content warnings' /></h1>
<LocalSettingsPageItem <LocalSettingsPageItem
@ -133,6 +134,16 @@ export default class LocalSettingsPage extends React.PureComponent {
> >
<FormattedMessage id='settings.enable_content_warnings_auto_unfold' defaultMessage='Automatically unfold content-warnings' /> <FormattedMessage id='settings.enable_content_warnings_auto_unfold' defaultMessage='Automatically unfold content-warnings' />
</LocalSettingsPageItem> </LocalSettingsPageItem>
<LocalSettingsPageItem
settings={settings}
item={['content_warnings', 'filter']}
id='mastodon-settings--content_warnings-auto_unfold'
onChange={onChange}
dependsOn={[['content_warnings', 'auto_unfold']]}
placeholder={intl.formatMessage(messages.regexp)}
>
<FormattedMessage id='settings.content_warnings_filter' defaultMessage='Content warnings to not automatically unfold:' />
</LocalSettingsPageItem>
</div> </div>
), ),
({ onChange, settings }) => ( ({ onChange, settings }) => (

View file

@ -38,6 +38,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { HotKeys } from 'react-hotkeys'; import { HotKeys } from 'react-hotkeys';
import { boostModal, favouriteModal, deleteModal } from 'flavours/glitch/util/initial_state'; import { boostModal, favouriteModal, deleteModal } from 'flavours/glitch/util/initial_state';
import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from 'flavours/glitch/util/fullscreen'; import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from 'flavours/glitch/util/fullscreen';
import { autoUnfoldCW } from 'flavours/glitch/util/content_warning';
const messages = defineMessages({ const messages = defineMessages({
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' }, deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
@ -82,7 +83,7 @@ export default class Status extends ImmutablePureComponent {
state = { state = {
fullscreen: false, fullscreen: false,
isExpanded: this.props.settings.getIn(['content_warnings', 'auto_unfold']), isExpanded: undefined,
threadExpanded: undefined, threadExpanded: undefined,
}; };
@ -95,9 +96,14 @@ export default class Status extends ImmutablePureComponent {
} }
componentWillReceiveProps (nextProps) { componentWillReceiveProps (nextProps) {
if (this.state.isExpanded === undefined) {
const isExpanded = autoUnfoldCW(nextProps.settings, nextProps.status);
if (isExpanded !== undefined) this.setState({ isExpanded: isExpanded });
}
if (nextProps.params.statusId !== this.props.params.statusId && nextProps.params.statusId) { if (nextProps.params.statusId !== this.props.params.statusId && nextProps.params.statusId) {
this._scrolledIntoView = false; this._scrolledIntoView = false;
this.props.dispatch(fetchStatus(nextProps.params.statusId)); this.props.dispatch(fetchStatus(nextProps.params.statusId));
this.setState({ isExpanded: autoUnfoldCW(nextProps.settings, nextProps.status) });
} }
} }

View file

@ -16,6 +16,7 @@ const initialState = ImmutableMap({
confirm_missing_media_description: false, confirm_missing_media_description: false,
content_warnings : ImmutableMap({ content_warnings : ImmutableMap({
auto_unfold : false, auto_unfold : false,
filter : null,
}), }),
collapsed : ImmutableMap({ collapsed : ImmutableMap({
enabled : true, enabled : true,

View file

@ -0,0 +1,19 @@
export function autoUnfoldCW (settings, status) {
if (!settings.getIn(['content_warnings', 'auto_unfold'])) {
return false;
}
const rawRegex = settings.getIn(['content_warnings', 'filter']);
let regex = null;
try {
regex = rawRegex && new RegExp(rawRegex.trim(), 'i');
} catch (e) {
// Bad regex, don't affect filters
}
if (!(status && regex)) {
return undefined;
}
return !regex.test(status.get('spoiler_text'));
}