Handle sensitive and spoiler separately when writing a post
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
@ -12,11 +12,10 @@ import {
|
||||
selectComposeSuggestion,
|
||||
uploadCompose,
|
||||
} from 'soapbox/actions/compose';
|
||||
import AutosuggestInput, { AutoSuggestion } from 'soapbox/components/autosuggest-input';
|
||||
import { Button, HStack, Stack } from 'soapbox/components/ui';
|
||||
import EmojiPickerDropdown from 'soapbox/features/emoji/containers/emoji-picker-dropdown-container';
|
||||
import { ComposeEditor } from 'soapbox/features/ui/util/async-components';
|
||||
import { useAppDispatch, useAppSelector, useCompose, useDraggedFiles, useFeatures, useInstance, usePrevious } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector, useCompose, useDraggedFiles, useFeatures, useInstance } from 'soapbox/hooks';
|
||||
|
||||
import QuotedStatusContainer from '../containers/quoted-status-container';
|
||||
import ReplyIndicatorContainer from '../containers/reply-indicator-container';
|
||||
@ -41,6 +40,7 @@ import UploadForm from './upload-form';
|
||||
import VisualCharacterCounter from './visual-character-counter';
|
||||
import Warning from './warning';
|
||||
|
||||
import type { AutoSuggestion } from 'soapbox/components/autosuggest-input';
|
||||
import type { Emoji } from 'soapbox/features/emoji';
|
||||
|
||||
const messages = defineMessages({
|
||||
@ -77,7 +77,6 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
|
||||
const features = useFeatures();
|
||||
|
||||
const {
|
||||
spoiler,
|
||||
spoiler_text: spoilerText,
|
||||
privacy,
|
||||
is_submitting: isSubmitting,
|
||||
@ -90,17 +89,13 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
|
||||
modified_language: modifiedLanguage,
|
||||
} = compose;
|
||||
|
||||
const prevSpoiler = usePrevious(spoiler);
|
||||
|
||||
const hasPoll = !!compose.poll;
|
||||
const isEditing = compose.id !== null;
|
||||
const anyMedia = compose.media_attachments.size > 0;
|
||||
|
||||
const [composeFocused, setComposeFocused] = useState(false);
|
||||
|
||||
const firstRender = useRef(true);
|
||||
const formRef = useRef<HTMLDivElement>(null);
|
||||
const spoilerTextRef = useRef<AutosuggestInput>(null);
|
||||
const editorRef = useRef<LexicalEditor>(null);
|
||||
|
||||
const { isDraggedOver } = useDraggedFiles(formRef);
|
||||
@ -171,10 +166,6 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
|
||||
dispatch(uploadCompose(id, files, intl));
|
||||
};
|
||||
|
||||
const focusSpoilerInput = () => {
|
||||
spoilerTextRef.current?.input?.focus();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener('click', handleClick, true);
|
||||
|
||||
@ -183,16 +174,6 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (spoiler && firstRender.current) {
|
||||
firstRender.current = false;
|
||||
} else if (!spoiler && prevSpoiler) {
|
||||
//
|
||||
} else if (spoiler && !prevSpoiler) {
|
||||
focusSpoilerInput();
|
||||
}
|
||||
}, [spoiler]);
|
||||
|
||||
const renderButtons = useCallback(() => (
|
||||
<HStack alignItems='center' space={2}>
|
||||
<UploadButtonContainer composeId={id} />
|
||||
@ -208,14 +189,6 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
|
||||
<UploadForm composeId={id} onSubmit={handleSubmit} />
|
||||
<PollForm composeId={id} />
|
||||
|
||||
<SpoilerInput
|
||||
composeId={id}
|
||||
onSuggestionsFetchRequested={onSuggestionsFetchRequested}
|
||||
onSuggestionsClearRequested={onSuggestionsClearRequested}
|
||||
onSuggestionSelected={onSpoilerSuggestionSelected}
|
||||
ref={spoilerTextRef}
|
||||
/>
|
||||
|
||||
<ScheduleForm composeId={id} />
|
||||
</Stack>
|
||||
);
|
||||
@ -280,6 +253,13 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
|
||||
</HStack>
|
||||
)}
|
||||
|
||||
<SpoilerInput
|
||||
composeId={id}
|
||||
onSuggestionsFetchRequested={onSuggestionsFetchRequested}
|
||||
onSuggestionsClearRequested={onSuggestionsClearRequested}
|
||||
onSuggestionSelected={onSpoilerSuggestionSelected}
|
||||
/>
|
||||
|
||||
<div>
|
||||
<Suspense>
|
||||
<ComposeEditor
|
||||
|
||||
@ -7,8 +7,8 @@ import { useAppDispatch, useCompose } from 'soapbox/hooks';
|
||||
import ComposeFormButton from './compose-form-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' },
|
||||
marked: { id: 'compose_form.spoiler.marked', defaultMessage: 'Media is marked as sensitive' },
|
||||
unmarked: { id: 'compose_form.spoiler.unmarked', defaultMessage: 'Media is not marked as sensitive' },
|
||||
});
|
||||
|
||||
interface ISpoilerButton {
|
||||
@ -19,7 +19,7 @@ const SpoilerButton: React.FC<ISpoilerButton> = ({ composeId }) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const active = useCompose(composeId).spoiler;
|
||||
const active = useCompose(composeId).sensitive;
|
||||
|
||||
const onClick = () =>
|
||||
dispatch(changeComposeSpoilerness(composeId));
|
||||
|
||||
@ -1,16 +1,13 @@
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import { changeComposeSpoilerness, changeComposeSpoilerText } from 'soapbox/actions/compose';
|
||||
import { 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' },
|
||||
placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Subject (optional)' },
|
||||
|
||||
});
|
||||
|
||||
interface ISpoilerInput extends Pick<IAutosuggestInput, 'onSuggestionsFetchRequested' | 'onSuggestionsClearRequested' | 'onSuggestionSelected'> {
|
||||
@ -26,56 +23,28 @@ const SpoilerInput = React.forwardRef<AutosuggestInput, ISpoilerInput>(({
|
||||
}, ref) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
const { language, modified_language, spoiler, spoiler_text: spoilerText, spoilerTextMap, suggestions } = useCompose(composeId);
|
||||
const { language, modified_language, spoiler_text: spoilerText, spoilerTextMap, suggestions } = useCompose(composeId);
|
||||
|
||||
const handleChangeSpoilerText: React.ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||
dispatch(changeComposeSpoilerText(composeId, e.target.value));
|
||||
};
|
||||
|
||||
const handleRemove = () => {
|
||||
dispatch(changeComposeSpoilerness(composeId));
|
||||
};
|
||||
|
||||
const value = !modified_language || modified_language === language ? spoilerText : spoilerTextMap.get(modified_language, '');
|
||||
|
||||
return (
|
||||
<Stack
|
||||
space={4}
|
||||
className={clsx({
|
||||
'relative transition-height': true,
|
||||
'hidden': !spoiler,
|
||||
})}
|
||||
>
|
||||
<Divider />
|
||||
|
||||
<Stack space={2}>
|
||||
<Text weight='medium'>
|
||||
{intl.formatMessage(messages.title)}
|
||||
</Text>
|
||||
|
||||
<AutosuggestInput
|
||||
placeholder={intl.formatMessage(messages.placeholder)}
|
||||
value={value}
|
||||
onChange={handleChangeSpoilerText}
|
||||
disabled={!spoiler}
|
||||
suggestions={suggestions}
|
||||
onSuggestionsFetchRequested={onSuggestionsFetchRequested}
|
||||
onSuggestionsClearRequested={onSuggestionsClearRequested}
|
||||
onSuggestionSelected={onSuggestionSelected}
|
||||
searchTokens={[':']}
|
||||
id='cw-spoiler-input'
|
||||
className='rounded-md !bg-transparent dark:!bg-transparent'
|
||||
ref={ref}
|
||||
autoFocus
|
||||
/>
|
||||
|
||||
<div className='text-center'>
|
||||
<button type='button' className='text-danger-500' onClick={handleRemove}>
|
||||
{intl.formatMessage(messages.remove)}
|
||||
</button>
|
||||
</div>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<AutosuggestInput
|
||||
placeholder={intl.formatMessage(messages.placeholder)}
|
||||
value={value}
|
||||
onChange={handleChangeSpoilerText}
|
||||
suggestions={suggestions}
|
||||
onSuggestionsFetchRequested={onSuggestionsFetchRequested}
|
||||
onSuggestionsClearRequested={onSuggestionsClearRequested}
|
||||
onSuggestionSelected={onSuggestionSelected}
|
||||
searchTokens={[':']}
|
||||
id='cw-spoiler-input'
|
||||
className='rounded-md !bg-transparent dark:!bg-transparent'
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user