diff --git a/app/soapbox/components/autosuggest_input.tsx b/app/soapbox/components/autosuggest_input.tsx index 277d87f96..155cd428a 100644 --- a/app/soapbox/components/autosuggest_input.tsx +++ b/app/soapbox/components/autosuggest_input.tsx @@ -45,7 +45,7 @@ const textAtCursorMatchesToken = (str: string, caretPosition: number, searchToke } }; -interface IAutosuggestInput extends Pick, 'onChange' | 'onKeyUp' | 'onKeyDown'> { +export interface IAutosuggestInput extends Pick, 'onChange' | 'onKeyUp' | 'onKeyDown'> { value: string, suggestions: ImmutableList, disabled?: boolean, diff --git a/app/soapbox/features/compose/components/compose-form.tsx b/app/soapbox/features/compose/components/compose-form.tsx index b9968ad3e..c0b64f1d1 100644 --- a/app/soapbox/features/compose/components/compose-form.tsx +++ b/app/soapbox/features/compose/components/compose-form.tsx @@ -10,7 +10,6 @@ import { clearComposeSuggestions, fetchComposeSuggestions, selectComposeSuggestion, - changeComposeSpoilerText, insertEmojiCompose, uploadCompose, } from 'soapbox/actions/compose'; @@ -38,6 +37,7 @@ import UploadButtonContainer from '../containers/upload_button_container'; import WarningContainer from '../containers/warning_container'; import { countableText } from '../util/counter'; +import SpoilerInput from './spoiler-input'; import TextCharacterCounter from './text_character_counter'; import VisualCharacterCounter from './visual_character_counter'; @@ -48,7 +48,7 @@ const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u20 const messages = defineMessages({ placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What\'s on your mind?' }, pollPlaceholder: { id: 'compose_form.poll_placeholder', defaultMessage: 'Add a poll topic...' }, - spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' }, + spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here (optional)' }, publish: { id: 'compose_form.publish', defaultMessage: 'Post' }, publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' }, message: { id: 'compose_form.message', defaultMessage: 'Message' }, @@ -165,10 +165,6 @@ const ComposeForm = ({ id, shouldCondense, autoFocus, clickab dispatch(selectComposeSuggestion(id, tokenStart, token, value, ['spoiler_text'])); }; - const handleChangeSpoilerText: React.ChangeEventHandler = (e) => { - dispatch(changeComposeSpoilerText(id, e.target.value)); - }; - const setCursor = (start: number, end: number = start) => { if (!autosuggestTextareaRef.current?.textarea) return; autosuggestTextareaRef.current.textarea.setSelectionRange(start, end); @@ -265,7 +261,7 @@ const ComposeForm = ({ id, shouldCondense, autoFocus, clickab } return ( - + {scheduledStatusCount > 0 && ( ({ id, shouldCondense, autoFocus, clickab {!shouldCondense && } -
- -
- ({ id, shouldCondense, autoFocus, clickab > { !condensed && -
+ -
+ + +
} diff --git a/app/soapbox/features/compose/components/spoiler-input.tsx b/app/soapbox/features/compose/components/spoiler-input.tsx new file mode 100644 index 000000000..129b972c8 --- /dev/null +++ b/app/soapbox/features/compose/components/spoiler-input.tsx @@ -0,0 +1,79 @@ +import classNames from 'clsx'; +import React from 'react'; +import { defineMessages, useIntl } from 'react-intl'; + +import { changeComposeSpoilerness, changeComposeSpoilerText } from 'soapbox/actions/compose'; +import AutosuggestInput, { IAutosuggestInput } from 'soapbox/components/autosuggest_input'; +import { Divider, Stack, Text } from 'soapbox/components/ui'; +import { useAppDispatch, useCompose } from 'soapbox/hooks'; + +const messages = defineMessages({ + title: { id: 'compose_form.spoiler_title', defaultMessage: 'Sensitive content' }, + placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here (optional)' }, + remove: { id: 'compose_form.spoiler_remove', defaultMessage: 'Remove sensitive' }, +}); + +interface ISpoilerInput extends Pick { + composeId: string extends 'default' ? never : string, +} + +/** Text input for content warning in composer. */ +const SpoilerInput: React.FC = ({ + composeId, + onSuggestionsFetchRequested, + onSuggestionsClearRequested, + onSuggestionSelected, +}) => { + const intl = useIntl(); + const dispatch = useAppDispatch(); + const compose = useCompose(composeId); + + const handleChangeSpoilerText: React.ChangeEventHandler = (e) => { + dispatch(changeComposeSpoilerText(composeId, e.target.value)); + }; + + const handleRemove = () => { + dispatch(changeComposeSpoilerness(composeId)); + }; + + return ( + + + + + + {intl.formatMessage(messages.title)} + + + + +
+ +
+
+
+ ); +}; + +export default SpoilerInput; \ No newline at end of file diff --git a/app/soapbox/locales/en.json b/app/soapbox/locales/en.json index 7397cc38d..f2eaf32c8 100644 --- a/app/soapbox/locales/en.json +++ b/app/soapbox/locales/en.json @@ -288,7 +288,7 @@ "compose_form.sensitive.unmarked": "Media is not marked as sensitive", "compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.unmarked": "Text is not hidden", - "compose_form.spoiler_placeholder": "Write your warning here", + "compose_form.spoiler_placeholder": "Write your warning here (optional)", "confirmation_modal.cancel": "Cancel", "confirmations.admin.deactivate_user.confirm": "Deactivate @{name}", "confirmations.admin.deactivate_user.heading": "Deactivate @{acct}",