Merge branch 'preserve-spoilers' into 'develop'

Add option to preserve spoilers text when replying

See merge request soapbox-pub/soapbox!2609
This commit is contained in:
marcin mikołajczak 2023-07-21 22:43:05 +00:00
commit 5e765ead97
6 changed files with 22 additions and 0 deletions

View file

@ -145,6 +145,7 @@ interface ComposeReplyAction {
status: Status status: Status
account: Account account: Account
explicitAddressing: boolean explicitAddressing: boolean
preserveSpoilers: boolean
} }
const replyCompose = (status: Status) => const replyCompose = (status: Status) =>
@ -152,7 +153,9 @@ const replyCompose = (status: Status) =>
const state = getState(); const state = getState();
const instance = state.instance; const instance = state.instance;
const { explicitAddressing } = getFeatures(instance); const { explicitAddressing } = getFeatures(instance);
const preserveSpoilers = !!getSettings(state).get('preserveSpoilers');
const account = selectOwnAccount(state); const account = selectOwnAccount(state);
if (!account) return; if (!account) return;
const action: ComposeReplyAction = { const action: ComposeReplyAction = {
@ -161,6 +164,7 @@ const replyCompose = (status: Status) =>
status: status, status: status,
account, account,
explicitAddressing, explicitAddressing,
preserveSpoilers,
}; };
dispatch(action); dispatch(action);

View file

@ -44,6 +44,7 @@ const defaultSettings = ImmutableMap({
explanationBox: true, explanationBox: true,
autoloadTimelines: true, autoloadTimelines: true,
autoloadMore: true, autoloadMore: true,
preserveSpoilers: false,
systemFont: false, systemFont: false,
demetricator: false, demetricator: false,

View file

@ -118,6 +118,7 @@ export const Checkbox: React.FC<ICheckbox> = (props) => (
); );
interface ISelectDropdown { interface ISelectDropdown {
className?: string
label?: React.ReactNode label?: React.ReactNode
hint?: React.ReactNode hint?: React.ReactNode
items: Record<string, string> items: Record<string, string>

View file

@ -136,6 +136,7 @@ const Preferences = () => {
<ListItem label={<FormattedMessage id='preferences.fields.language_label' defaultMessage='Language' />}> <ListItem label={<FormattedMessage id='preferences.fields.language_label' defaultMessage='Language' />}>
<SelectDropdown <SelectDropdown
className='max-w-[200px]'
items={languages} items={languages}
defaultValue={settings.get('locale') as string | undefined} defaultValue={settings.get('locale') as string | undefined}
onChange={(event: React.ChangeEvent<HTMLSelectElement>) => onSelectChange(event, ['locale'])} onChange={(event: React.ChangeEvent<HTMLSelectElement>) => onSelectChange(event, ['locale'])}
@ -144,6 +145,7 @@ const Preferences = () => {
<ListItem label={<FormattedMessage id='preferences.fields.media_display_label' defaultMessage='Sensitive content' />}> <ListItem label={<FormattedMessage id='preferences.fields.media_display_label' defaultMessage='Sensitive content' />}>
<SelectDropdown <SelectDropdown
className='max-w-[200px]'
items={displayMediaOptions} items={displayMediaOptions}
defaultValue={settings.get('displayMedia') as string | undefined} defaultValue={settings.get('displayMedia') as string | undefined}
onChange={(event: React.ChangeEvent<HTMLSelectElement>) => onSelectChange(event, ['displayMedia'])} onChange={(event: React.ChangeEvent<HTMLSelectElement>) => onSelectChange(event, ['displayMedia'])}
@ -153,6 +155,7 @@ const Preferences = () => {
{features.privacyScopes && ( {features.privacyScopes && (
<ListItem label={<FormattedMessage id='preferences.fields.privacy_label' defaultMessage='Default post privacy' />}> <ListItem label={<FormattedMessage id='preferences.fields.privacy_label' defaultMessage='Default post privacy' />}>
<SelectDropdown <SelectDropdown
className='max-w-[200px]'
items={defaultPrivacyOptions} items={defaultPrivacyOptions}
defaultValue={settings.get('defaultPrivacy') as string | undefined} defaultValue={settings.get('defaultPrivacy') as string | undefined}
onChange={(event: React.ChangeEvent<HTMLSelectElement>) => onSelectChange(event, ['defaultPrivacy'])} onChange={(event: React.ChangeEvent<HTMLSelectElement>) => onSelectChange(event, ['defaultPrivacy'])}
@ -163,12 +166,19 @@ const Preferences = () => {
{features.richText && ( {features.richText && (
<ListItem label={<FormattedMessage id='preferences.fields.content_type_label' defaultMessage='Default post format' />}> <ListItem label={<FormattedMessage id='preferences.fields.content_type_label' defaultMessage='Default post format' />}>
<SelectDropdown <SelectDropdown
className='max-w-[200px]'
items={defaultContentTypeOptions} items={defaultContentTypeOptions}
defaultValue={settings.get('defaultContentType') as string | undefined} defaultValue={settings.get('defaultContentType') as string | undefined}
onChange={(event: React.ChangeEvent<HTMLSelectElement>) => onSelectChange(event, ['defaultContentType'])} onChange={(event: React.ChangeEvent<HTMLSelectElement>) => onSelectChange(event, ['defaultContentType'])}
/> />
</ListItem> </ListItem>
)} )}
{features.spoilers && (
<ListItem label={<FormattedMessage id='preferences.fields.preserve_spoilers_label' defaultMessage='Preserve content warning when replying' />}>
<SettingToggle settings={settings} settingPath={['preserveSpoilers']} onChange={onToggleChange} />
</ListItem>
)}
</List> </List>
<List> <List>

View file

@ -1196,6 +1196,7 @@
"preferences.fields.language_label": "Display Language", "preferences.fields.language_label": "Display Language",
"preferences.fields.media_display_label": "Sensitive content", "preferences.fields.media_display_label": "Sensitive content",
"preferences.fields.missing_description_modal_label": "Show confirmation dialog before sending a post without media descriptions", "preferences.fields.missing_description_modal_label": "Show confirmation dialog before sending a post without media descriptions",
"preferences.fields.preserve_spoilers_label": "Preserve content warning when replying",
"preferences.fields.privacy_label": "Default post privacy", "preferences.fields.privacy_label": "Default post privacy",
"preferences.fields.reduce_motion_label": "Reduce motion in animations", "preferences.fields.reduce_motion_label": "Reduce motion in animations",
"preferences.fields.system_font_label": "Use system's default font", "preferences.fields.system_font_label": "Use system's default font",

View file

@ -312,6 +312,11 @@ export default function compose(state = initialState, action: ComposeAction | Me
map.set('caretPosition', null); map.set('caretPosition', null);
map.set('idempotencyKey', uuid()); map.set('idempotencyKey', uuid());
map.set('content_type', defaultCompose.content_type); map.set('content_type', defaultCompose.content_type);
if (action.preserveSpoilers && action.status.spoiler_text) {
map.set('spoiler', true);
map.set('sensitive', true);
map.set('spoiler_text', action.status.spoiler_text);
}
})); }));
case COMPOSE_EVENT_REPLY: case COMPOSE_EVENT_REPLY:
return updateCompose(state, action.id, compose => compose.withMutations(map => { return updateCompose(state, action.id, compose => compose.withMutations(map => {