lol i think i fixed the privacy dropdown

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2024-08-29 21:09:42 +02:00
parent cb5dbb8ab6
commit fbcbe3fe1e

View file

@ -1,6 +1,6 @@
import clsx from 'clsx'; import clsx from 'clsx';
import React, { useEffect, useRef } from 'react'; import React, { useEffect, useMemo, useRef } from 'react';
import { useIntl, defineMessages, FormattedMessage } from 'react-intl'; import { useIntl, defineMessages, FormattedMessage, IntlShape } from 'react-intl';
import { changeComposeFederated, changeComposeVisibility } from 'pl-fe/actions/compose'; import { changeComposeFederated, changeComposeVisibility } from 'pl-fe/actions/compose';
import DropdownMenu from 'pl-fe/components/dropdown-menu'; import DropdownMenu from 'pl-fe/components/dropdown-menu';
@ -8,6 +8,8 @@ import Icon from 'pl-fe/components/icon';
import { Button, Toggle } from 'pl-fe/components/ui'; import { Button, Toggle } from 'pl-fe/components/ui';
import { useAppDispatch, useCompose, useFeatures } from 'pl-fe/hooks'; import { useAppDispatch, useCompose, useFeatures } from 'pl-fe/hooks';
import type { Features } from 'pl-api';
const messages = defineMessages({ const messages = defineMessages({
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
public_long: { id: 'privacy.public.long', defaultMessage: 'Post to public timelines' }, public_long: { id: 'privacy.public.long', defaultMessage: 'Post to public timelines' },
@ -34,19 +36,33 @@ interface Option {
} }
interface IPrivacyDropdownMenu { interface IPrivacyDropdownMenu {
items: any[]; handleClose: () => any;
value: string;
onClose: () => void;
onChange: (value: string | null) => void;
unavailable?: boolean;
showFederated?: boolean;
federated?: boolean;
onChangeFederated: () => void;
} }
const PrivacyDropdownMenu: React.FC<IPrivacyDropdownMenu> = ({ const getItems = (features: Features, intl: IntlShape) => [
items, value, onClose, onChange, showFederated, federated, onChangeFederated, { icon: require('@tabler/icons/outline/world.svg'), value: 'public', text: intl.formatMessage(messages.public_short), meta: intl.formatMessage(messages.public_long) },
}) => { { icon: require('@tabler/icons/outline/lock-open.svg'), value: 'unlisted', text: intl.formatMessage(messages.unlisted_short), meta: intl.formatMessage(messages.unlisted_long) },
{ icon: require('@tabler/icons/outline/lock.svg'), value: 'private', text: intl.formatMessage(messages.private_short), meta: intl.formatMessage(messages.private_long) },
features.visibilityMutualsOnly ? { icon: require('@tabler/icons/outline/users-group.svg'), value: 'mutuals_only', text: intl.formatMessage(messages.mutuals_only_short), meta: intl.formatMessage(messages.mutuals_only_long) } : undefined,
{ icon: require('@tabler/icons/outline/mail.svg'), value: 'direct', text: intl.formatMessage(messages.direct_short), meta: intl.formatMessage(messages.direct_long) },
features.visibilityLocalOnly ? { icon: require('@tabler/icons/outline/affiliate.svg'), value: 'local', text: intl.formatMessage(messages.local_short), meta: intl.formatMessage(messages.local_long) } : undefined,
].filter((option): option is Option => !!option);
const getPrivacyDropdown = (composeId: string): React.FC<IPrivacyDropdownMenu> => ({ handleClose: handleMenuClose }) => {
const dispatch = useAppDispatch();
const intl = useIntl();
const features = useFeatures();
const compose = useCompose(composeId);
const value = compose.privacy;
const items = getItems(features, intl);
const onChange = (value: string | null) => value && dispatch(changeComposeVisibility(composeId, value));
const onChangeFederated = () => dispatch(changeComposeFederated(composeId));
const node = useRef<HTMLUListElement>(null); const node = useRef<HTMLUListElement>(null);
const focusedItem = useRef<HTMLLIElement>(null); const focusedItem = useRef<HTMLLIElement>(null);
@ -56,7 +72,7 @@ const PrivacyDropdownMenu: React.FC<IPrivacyDropdownMenu> = ({
switch (e.key) { switch (e.key) {
case 'Escape': case 'Escape':
onClose(); handleMenuClose();
break; break;
case 'Enter': case 'Enter':
handleClick(e); handleClick(e);
@ -98,7 +114,7 @@ const PrivacyDropdownMenu: React.FC<IPrivacyDropdownMenu> = ({
if (value === 'local_switch') onChangeFederated(); if (value === 'local_switch') onChangeFederated();
else { else {
onClose(); handleMenuClose();
onChange(value); onChange(value);
} }
}; };
@ -143,7 +159,7 @@ const PrivacyDropdownMenu: React.FC<IPrivacyDropdownMenu> = ({
</li> </li>
); );
})} })}
{showFederated && ( {features.localOnlyStatuses && (
<li <li
role='option' role='option'
tabIndex={0} tabIndex={0}
@ -165,7 +181,7 @@ const PrivacyDropdownMenu: React.FC<IPrivacyDropdownMenu> = ({
<FormattedMessage id='privacy.local.long' defaultMessage='Only visible on your instance' /> <FormattedMessage id='privacy.local.long' defaultMessage='Only visible on your instance' />
</div> </div>
<Toggle checked={!federated} onChange={onChangeFederated} /> <Toggle checked={!compose.federated} onChange={onChangeFederated} />
</li> </li>
)} )}
@ -180,7 +196,6 @@ interface IPrivacyDropdown {
const PrivacyDropdown: React.FC<IPrivacyDropdown> = ({ const PrivacyDropdown: React.FC<IPrivacyDropdown> = ({
composeId, composeId,
}) => { }) => {
const dispatch = useAppDispatch();
const intl = useIntl(); const intl = useIntl();
const features = useFeatures(); const features = useFeatures();
@ -189,38 +204,20 @@ const PrivacyDropdown: React.FC<IPrivacyDropdown> = ({
const value = compose.privacy; const value = compose.privacy;
const unavailable = compose.id; const unavailable = compose.id;
const options = [ const items = getItems(features, intl);
{ icon: require('@tabler/icons/outline/world.svg'), value: 'public', text: intl.formatMessage(messages.public_short), meta: intl.formatMessage(messages.public_long) },
{ icon: require('@tabler/icons/outline/lock-open.svg'), value: 'unlisted', text: intl.formatMessage(messages.unlisted_short), meta: intl.formatMessage(messages.unlisted_long) },
{ icon: require('@tabler/icons/outline/lock.svg'), value: 'private', text: intl.formatMessage(messages.private_short), meta: intl.formatMessage(messages.private_long) },
features.visibilityMutualsOnly ? { icon: require('@tabler/icons/outline/users-group.svg'), value: 'mutuals_only', text: intl.formatMessage(messages.mutuals_only_short), meta: intl.formatMessage(messages.mutuals_only_long) } : undefined,
{ icon: require('@tabler/icons/outline/mail.svg'), value: 'direct', text: intl.formatMessage(messages.direct_short), meta: intl.formatMessage(messages.direct_long) },
features.visibilityLocalOnly ? { icon: require('@tabler/icons/outline/affiliate.svg'), value: 'local', text: intl.formatMessage(messages.local_short), meta: intl.formatMessage(messages.local_long) } : undefined,
].filter((option): option is Option => !!option);
const onChange = (value: string | null) => value && dispatch(changeComposeVisibility(composeId, value)); const PrivacyDropdownMenu = useMemo(() => getPrivacyDropdown(composeId), [composeId]);
const onChangeFederated = () => dispatch(changeComposeFederated(composeId));
if (unavailable) { if (unavailable) {
return null; return null;
} }
const valueOption = options.find(item => item.value === value); const valueOption = items.find(item => item.value === value);
return ( return (
<DropdownMenu <DropdownMenu
component={({ handleClose }) => ( component={PrivacyDropdownMenu}
<PrivacyDropdownMenu
items={options}
value={value}
onClose={handleClose}
onChange={onChange}
showFederated={features.localOnlyStatuses}
federated={compose.federated}
onChangeFederated={onChangeFederated}
/>
)}
> >
<Button <Button
theme='muted' theme='muted'