From 873838ebfea14401f50c23cbf6dd0228e0866bfa Mon Sep 17 00:00:00 2001 From: julia Date: Tue, 24 Dec 2024 14:03:51 +0000 Subject: [PATCH] [feature] Always show content warning: use existing glitch feature (#1) The modifications you made are somewhat janky; for instance, editing a toot with an existing content warning makes the UI look very weird and doesn't quite work. Glitch already has a feature for this, so simply turn it on by default. This should do the same thing. Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/1 Co-authored-by: julia Co-committed-by: julia --- .../flavours/glitch/actions/compose.js | 10 ++++++- .../compose/components/compose_form.jsx | 11 ++++++-- .../containers/compose_form_container.js | 5 ++++ .../flavours/glitch/features/ui/index.jsx | 7 ++++- .../flavours/glitch/reducers/compose.js | 10 +++++++ .../glitch/reducers/local_settings.js | 2 +- app/javascript/mastodon/actions/compose.js | 7 +++++ .../compose/components/compose_form.jsx | 6 +++- .../containers/compose_form_container.js | 1 + .../containers/spoiler_button_container.js | 28 +++++++++++++++++++ app/javascript/mastodon/features/ui/index.jsx | 7 ++++- app/javascript/mastodon/reducers/compose.js | 10 +++++++ 12 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 app/javascript/mastodon/features/compose/containers/spoiler_button_container.js diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js index 832a51c1d..f0dff3170 100644 --- a/app/javascript/flavours/glitch/actions/compose.js +++ b/app/javascript/flavours/glitch/actions/compose.js @@ -57,6 +57,7 @@ export const COMPOSE_UNMOUNT = 'COMPOSE_UNMOUNT'; export const COMPOSE_ADVANCED_OPTIONS_CHANGE = 'COMPOSE_ADVANCED_OPTIONS_CHANGE'; 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_LISTABILITY_CHANGE = 'COMPOSE_LISTABILITY_CHANGE'; @@ -171,7 +172,8 @@ export function submitCompose(routerHistory) { let status = getState().getIn(['compose', 'text'], ''); const media = getState().getIn(['compose', 'media_attachments']); const statusId = getState().getIn(['compose', 'id'], null); - let spoilerText = getState().getIn(['compose', 'spoiler_text'], ''); + const spoilers = getState().getIn(['compose', 'spoiler']) || getState().getIn(['local_settings', 'always_show_spoilers_field']); + let spoilerText = spoilers ? getState().getIn(['compose', 'spoiler_text'], '') : ''; if ((!status || !status.length) && media.size === 0) { return; @@ -743,6 +745,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/flavours/glitch/features/compose/components/compose_form.jsx b/app/javascript/flavours/glitch/features/compose/components/compose_form.jsx index c197d0a21..7ca2cdbd5 100644 --- a/app/javascript/flavours/glitch/features/compose/components/compose_form.jsx +++ b/app/javascript/flavours/glitch/features/compose/components/compose_form.jsx @@ -79,6 +79,7 @@ class ComposeForm extends ImmutablePureComponent { spoilersAlwaysOn: PropTypes.bool, mediaDescriptionConfirmation: PropTypes.bool, preselectOnReply: PropTypes.bool, + onChangeSpoilerness: PropTypes.func, onChangeVisibility: PropTypes.func, onMediaDescriptionConfirm: PropTypes.func, }; @@ -291,6 +292,7 @@ class ComposeForm extends ImmutablePureComponent { intl, isSubmitting, layout, + onChangeSpoilerness, onClearSuggestions, onFetchSuggestions, onPaste, @@ -298,8 +300,10 @@ class ComposeForm extends ImmutablePureComponent { sensitive, showSearch, sideArm, + spoiler, spoilerText, suggestions, + spoilersAlwaysOn, isEditing, } = this.props; @@ -311,12 +315,13 @@ class ComposeForm extends ImmutablePureComponent { -
+
0)} + sensitive={sensitive || (spoilersAlwaysOn && spoilerText && spoilerText.length > 0)} + spoiler={spoilersAlwaysOn ? (spoilerText && spoilerText.length > 0) : spoiler} />
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