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 3e0613b10d..27544a2f80 100644 --- a/app/javascript/flavours/glitch/features/compose/components/compose_form.jsx +++ b/app/javascript/flavours/glitch/features/compose/components/compose_form.jsx @@ -29,6 +29,7 @@ import { countableText } from '../util/counter'; import { CharacterCounter } from './character_counter'; import { ContentTypeButton } from './content_type_button'; import { EditIndicator } from './edit_indicator'; +import { FederationButton } from './federation_button'; import { NavigationBar } from './navigation_bar'; import { PollForm } from "./poll_form"; import { ReplyIndicator } from './reply_indicator'; @@ -312,6 +313,7 @@ class ComposeForm extends ImmutablePureComponent { {!this.props.spoilerAlwaysOn && } + diff --git a/app/javascript/flavours/glitch/features/compose/components/federation_button.jsx b/app/javascript/flavours/glitch/features/compose/components/federation_button.jsx new file mode 100644 index 0000000000..a7ef0aa028 --- /dev/null +++ b/app/javascript/flavours/glitch/features/compose/components/federation_button.jsx @@ -0,0 +1,94 @@ +import { useCallback, useState, useRef } from 'react'; + +import { useIntl, defineMessages } from 'react-intl'; + +import Overlay from 'react-overlays/Overlay'; + +import ShareIcon from '@/material-icons/400-24px/share.svg?react'; +import ShareOffIcon from '@/material-icons/400-24px/share_off.svg?react'; +import { changeComposeAdvancedOption } from 'flavours/glitch/actions/compose'; +import { IconButton } from 'flavours/glitch/components/icon_button'; +import { useAppSelector, useAppDispatch } from 'flavours/glitch/store'; + +import DropdownMenu from './dropdown_menu'; + +const messages = defineMessages({ + change_federation_settings: { id: 'compose.change_federation', defaultMessage: 'Change federation settings' }, + local_only_label: { id: 'federation.local_only.short', defaultMessage: 'Local-only' }, + local_only_meta: { id: 'federation.local_only.long', defaultMessage: 'Prevent this post from reaching other servers' }, + federated_label: { id: 'federation.federated.short', defaultMessage: 'Federated' }, + federated_meta: { id: 'federation.federated.long', defaultMessage: 'Allow this post to reach other servers' }, +}); + +export const FederationButton = () => { + const intl = useIntl(); + + const do_not_federate = useAppSelector((state) => state.getIn(['compose', 'advanced_options', 'do_not_federate'])); + const dispatch = useAppDispatch(); + + const containerRef = useRef(null); + + const [activeElement, setActiveElement] = useState(null); + const [open, setOpen] = useState(false); + const [placement, setPlacement] = useState('bottom'); + + const handleToggle = useCallback(() => { + if (open && activeElement) { + activeElement.focus({ preventScroll: true }); + setActiveElement(null); + } + + setOpen(!open); + }, [open, setOpen, activeElement, setActiveElement]); + + const handleClose = useCallback(() => { + if (open && activeElement) { + activeElement.focus({ preventScroll: true }); + setActiveElement(null); + } + + setOpen(false); + }, [open, setOpen, activeElement, setActiveElement]); + + const handleChange = useCallback((value) => { + dispatch(changeComposeAdvancedOption('do_not_federate', value === 'local-only')); + }, [dispatch]); + + const handleOverlayEnter = useCallback((state) => { + setPlacement(state.placement); + }, [setPlacement]); + + const options = [ + { icon: 'link', iconComponent: ShareIcon, value: 'federated', text: intl.formatMessage(messages.federated_label), meta: intl.formatMessage(messages.federated_meta) }, + { icon: 'link-slash', iconComponent: ShareOffIcon, value: 'local-only', text: intl.formatMessage(messages.local_only_label), meta: intl.formatMessage(messages.local_only_meta) }, + ]; + + return ( +
+ + + + {({ props, placement }) => ( +
+
+ +
+
+ )} +
+
+ ); +}; diff --git a/app/javascript/flavours/glitch/locales/en.json b/app/javascript/flavours/glitch/locales/en.json index 1fd648c6e0..5b47393cab 100644 --- a/app/javascript/flavours/glitch/locales/en.json +++ b/app/javascript/flavours/glitch/locales/en.json @@ -14,6 +14,7 @@ "column_subheading.lists": "Lists", "column_subheading.navigation": "Navigation", "community.column_settings.allow_local_only": "Show local-only toots", + "compose.change_federation": "Change federation settings", "compose.content-type.change": "Change advanced formatting options", "compose.content-type.html": "HTML", "compose.content-type.html_meta": "Format your posts using HTML", @@ -34,6 +35,10 @@ "direct.group_by_conversations": "Group by conversation", "endorsed_accounts_editor.endorsed_accounts": "Featured accounts", "favourite_modal.combo": "You can press {combo} to skip this next time", + "federation.federated.long": "Allow this post to reach other servers", + "federation.federated.short": "Federated", + "federation.local_only.long": "Prevent this post from reaching other servers", + "federation.local_only.short": "Local-only", "firehose.column_settings.allow_local_only": "Show local-only posts in \"All\"", "home.column_settings.advanced": "Advanced", "home.column_settings.filter_regex": "Filter out by regular expressions", diff --git a/app/javascript/material-icons/400-24px/share_off-fill.svg b/app/javascript/material-icons/400-24px/share_off-fill.svg new file mode 100644 index 0000000000..3b6a05d118 --- /dev/null +++ b/app/javascript/material-icons/400-24px/share_off-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/share_off.svg b/app/javascript/material-icons/400-24px/share_off.svg new file mode 100644 index 0000000000..00bb28659b --- /dev/null +++ b/app/javascript/material-icons/400-24px/share_off.svg @@ -0,0 +1 @@ + \ No newline at end of file