diff --git a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js
index 74ce8fc60..e9724568c 100644
--- a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js
+++ b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js
@@ -5,6 +5,7 @@ import { connect } from 'react-redux';
import {
changeCompose,
changeComposeSpoilerText,
+ changeComposeSpoilerness,
changeComposeVisibility,
clearComposeSuggestions,
fetchComposeSuggestions,
@@ -116,6 +117,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
dispatch(insertEmojiCompose(position, emoji));
},
+ onChangeSpoilerness() {
+ dispatch(changeComposeSpoilerness());
+ },
+
onChangeVisibility(value) {
dispatch(changeComposeVisibility(value));
},
diff --git a/app/javascript/flavours/glitch/features/ui/index.jsx b/app/javascript/flavours/glitch/features/ui/index.jsx
index 7bc5daae1..0697cc5e1 100644
--- a/app/javascript/flavours/glitch/features/ui/index.jsx
+++ b/app/javascript/flavours/glitch/features/ui/index.jsx
@@ -13,7 +13,7 @@ import { debounce } from 'lodash';
import { HotKeys } from 'react-hotkeys';
import { changeLayout } from 'flavours/glitch/actions/app';
-import { uploadCompose, resetCompose } from 'flavours/glitch/actions/compose';
+import { uploadCompose, resetCompose, changeComposeSpoilerness } from 'flavours/glitch/actions/compose';
import { clearHeight } from 'flavours/glitch/actions/height_cache';
import { synchronouslySubmitMarkers, submitMarkers, fetchMarkers } from 'flavours/glitch/actions/markers';
import { expandNotifications, notificationsSetVisibility } from 'flavours/glitch/actions/notifications';
@@ -518,6 +518,11 @@ class UI extends Component {
this.props.dispatch(resetCompose());
};
+ handleHotkeyToggleComposeSpoilers = e => {
+ e.preventDefault();
+ this.props.dispatch(changeComposeSpoilerness());
+ };
+
handleHotkeyFocusColumn = e => {
const index = (e.key * 1) + 1; // First child is drawer, skip that
const column = this.node.querySelector(`.column:nth-child(${index})`);
diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js
index 6072333d6..0915ecba0 100644
--- a/app/javascript/flavours/glitch/reducers/compose.js
+++ b/app/javascript/flavours/glitch/reducers/compose.js
@@ -30,6 +30,7 @@ import {
COMPOSE_TAG_HISTORY_UPDATE,
COMPOSE_ADVANCED_OPTIONS_CHANGE,
COMPOSE_SENSITIVITY_CHANGE,
+ COMPOSE_SPOILERNESS_CHANGE,
COMPOSE_SPOILER_TEXT_CHANGE,
COMPOSE_VISIBILITY_CHANGE,
COMPOSE_LANGUAGE_CHANGE,
@@ -382,6 +383,15 @@ export default function compose(state = initialState, action) {
map.set('idempotencyKey', uuid());
});
+ case COMPOSE_SPOILERNESS_CHANGE:
+ return state.withMutations(map => {
+ map.set('spoiler', !state.get('spoiler'));
+ map.set('idempotencyKey', uuid());
+
+ if (!state.get('sensitive') && state.get('media_attachments').size >= 1) {
+ map.set('sensitive', true);
+ }
+ });
case COMPOSE_SPOILER_TEXT_CHANGE:
return state
.set('spoiler_text', action.text)
diff --git a/app/javascript/flavours/glitch/reducers/local_settings.js b/app/javascript/flavours/glitch/reducers/local_settings.js
index a01053045..96a3938c0 100644
--- a/app/javascript/flavours/glitch/reducers/local_settings.js
+++ b/app/javascript/flavours/glitch/reducers/local_settings.js
@@ -11,7 +11,7 @@ const initialState = ImmutableMap({
side_arm : 'none',
side_arm_reply_mode : 'keep',
show_reply_count : false,
- always_show_spoilers_field: false,
+ always_show_spoilers_field: true,
confirm_missing_media_description: false,
confirm_boost_missing_media_description: false,
confirm_before_clearing_draft: true,
diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js
index 48ddf8082..e68afcbf9 100644
--- a/app/javascript/mastodon/actions/compose.js
+++ b/app/javascript/mastodon/actions/compose.js
@@ -52,6 +52,7 @@ export const COMPOSE_MOUNT = 'COMPOSE_MOUNT';
export const COMPOSE_UNMOUNT = 'COMPOSE_UNMOUNT';
export const COMPOSE_SENSITIVITY_CHANGE = 'COMPOSE_SENSITIVITY_CHANGE';
+export const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE';
export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE';
export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE';
export const COMPOSE_COMPOSING_CHANGE = 'COMPOSE_COMPOSING_CHANGE';
@@ -732,6 +733,12 @@ export const changeComposeLanguage = language => ({
language,
});
+export function changeComposeSpoilerness() {
+ return {
+ type: COMPOSE_SPOILERNESS_CHANGE,
+ };
+}
+
export function changeComposeSpoilerText(text) {
return {
type: COMPOSE_SPOILER_TEXT_CHANGE,
diff --git a/app/javascript/mastodon/features/compose/components/compose_form.jsx b/app/javascript/mastodon/features/compose/components/compose_form.jsx
index addb3e381..1b335fa7c 100644
--- a/app/javascript/mastodon/features/compose/components/compose_form.jsx
+++ b/app/javascript/mastodon/features/compose/components/compose_form.jsx
@@ -21,6 +21,7 @@ import PollButtonContainer from '../containers/poll_button_container';
import PollFormContainer from '../containers/poll_form_container';
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
import ReplyIndicatorContainer from '../containers/reply_indicator_container';
+import SpoilerButtonContainer from '../containers/spoiler_button_container';
import UploadButtonContainer from '../containers/upload_button_container';
import UploadFormContainer from '../containers/upload_form_container';
import WarningContainer from '../containers/warning_container';
@@ -48,6 +49,7 @@ class ComposeForm extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
text: PropTypes.string.isRequired,
suggestions: ImmutablePropTypes.list,
+ spoiler: PropTypes.bool,
privacy: PropTypes.string,
spoilerText: PropTypes.string,
focusDate: PropTypes.instanceOf(Date),
@@ -242,12 +244,13 @@ class ComposeForm extends ImmutablePureComponent {
-
+
diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
index b3bf71fec..ba20698ba 100644
--- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js
+++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
@@ -15,6 +15,7 @@ import ComposeForm from '../components/compose_form';
const mapStateToProps = state => ({
text: state.getIn(['compose', 'text']),
suggestions: state.getIn(['compose', 'suggestions']),
+ spoiler: state.getIn(['compose', 'spoiler']),
spoilerText: state.getIn(['compose', 'spoiler_text']),
privacy: state.getIn(['compose', 'privacy']),
focusDate: state.getIn(['compose', 'focusDate']),
diff --git a/app/javascript/mastodon/features/compose/containers/spoiler_button_container.js b/app/javascript/mastodon/features/compose/containers/spoiler_button_container.js
new file mode 100644
index 000000000..b3d7a7133
--- /dev/null
+++ b/app/javascript/mastodon/features/compose/containers/spoiler_button_container.js
@@ -0,0 +1,28 @@
+import { injectIntl, defineMessages } from 'react-intl';
+
+import { connect } from 'react-redux';
+
+import { changeComposeSpoilerness } from '../../../actions/compose';
+import TextIconButton from '../components/text_icon_button';
+
+const messages = defineMessages({
+ marked: { id: 'compose_form.spoiler.marked', defaultMessage: 'Text is hidden behind warning' },
+ unmarked: { id: 'compose_form.spoiler.unmarked', defaultMessage: 'Text is not hidden' },
+});
+
+const mapStateToProps = (state, { intl }) => ({
+ label: 'CW',
+ title: intl.formatMessage(state.getIn(['compose', 'spoiler']) ? messages.marked : messages.unmarked),
+ active: state.getIn(['compose', 'spoiler']),
+ ariaControls: 'cw-spoiler-input',
+});
+
+const mapDispatchToProps = dispatch => ({
+
+ onClick () {
+ dispatch(changeComposeSpoilerness());
+ },
+
+});
+
+export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(TextIconButton));
diff --git a/app/javascript/mastodon/features/ui/index.jsx b/app/javascript/mastodon/features/ui/index.jsx
index dabc3f870..4211f14e7 100644
--- a/app/javascript/mastodon/features/ui/index.jsx
+++ b/app/javascript/mastodon/features/ui/index.jsx
@@ -17,7 +17,7 @@ import { INTRODUCTION_VERSION } from 'mastodon/actions/onboarding';
import PictureInPicture from 'mastodon/features/picture_in_picture';
import { layoutFromWindow } from 'mastodon/is_mobile';
-import { uploadCompose, resetCompose } from '../../actions/compose';
+import { uploadCompose, resetCompose, changeComposeSpoilerness } from '../../actions/compose';
import { clearHeight } from '../../actions/height_cache';
import { expandNotifications } from '../../actions/notifications';
import { fetchServer } from '../../actions/server';
@@ -455,6 +455,11 @@ class UI extends PureComponent {
this.props.dispatch(resetCompose());
};
+ handleHotkeyToggleComposeSpoilers = e => {
+ e.preventDefault();
+ this.props.dispatch(changeComposeSpoilerness());
+ };
+
handleHotkeyFocusColumn = e => {
const index = (e.key * 1) + 1; // First child is drawer, skip that
const column = this.node.querySelector(`.column:nth-child(${index})`);
diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js
index 671ea2f13..e6b2509f6 100644
--- a/app/javascript/mastodon/reducers/compose.js
+++ b/app/javascript/mastodon/reducers/compose.js
@@ -28,6 +28,7 @@ import {
COMPOSE_SUGGESTION_TAGS_UPDATE,
COMPOSE_TAG_HISTORY_UPDATE,
COMPOSE_SENSITIVITY_CHANGE,
+ COMPOSE_SPOILERNESS_CHANGE,
COMPOSE_SPOILER_TEXT_CHANGE,
COMPOSE_VISIBILITY_CHANGE,
COMPOSE_LANGUAGE_CHANGE,
@@ -299,6 +300,15 @@ export default function compose(state = initialState, action) {
map.set('idempotencyKey', uuid());
});
+ case COMPOSE_SPOILERNESS_CHANGE:
+ return state.withMutations(map => {
+ map.set('spoiler', !state.get('spoiler'));
+ map.set('idempotencyKey', uuid());
+
+ if (!state.get('sensitive') && state.get('media_attachments').size >= 1) {
+ map.set('sensitive', true);
+ }
+ });
case COMPOSE_SPOILER_TEXT_CHANGE:
if (!state.get('spoiler')) return state;
return state