mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-14 08:19:05 +00:00
[Glitch] Composer quote improvements
Port f85f0eee1b to glitch-soc
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
Co-authored-by: diondiondion <mail@diondiondion.com>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { changeComposeVisibility } from '@/flavours/glitch/actions/compose';
|
||||
import { setComposeQuotePolicy } from '@/flavours/glitch/actions/compose_typed';
|
||||
import { openModal } from '@/flavours/glitch/actions/modal';
|
||||
import type { ApiQuotePolicy } from '@/flavours/glitch/api_types/quotes';
|
||||
import type { StatusVisibility } from '@/flavours/glitch/api_types/statuses';
|
||||
import { Icon } from '@/flavours/glitch/components/icon';
|
||||
import { useAppSelector, useAppDispatch } from '@/flavours/glitch/store';
|
||||
import { isFeatureEnabled } from '@/flavours/glitch/utils/environment';
|
||||
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
|
||||
import LockIcon from '@/material-icons/400-24px/lock.svg?react';
|
||||
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
|
||||
import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react';
|
||||
|
||||
import type { VisibilityModalCallback } from '../../ui/components/visibility_modal';
|
||||
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
|
||||
|
||||
import { messages as privacyMessages } from './privacy_dropdown';
|
||||
|
||||
const messages = defineMessages({
|
||||
anyone_quote: {
|
||||
id: 'privacy.quote.anyone',
|
||||
defaultMessage: '{visibility}, anyone can quote',
|
||||
},
|
||||
limited_quote: {
|
||||
id: 'privacy.quote.limited',
|
||||
defaultMessage: '{visibility}, quotes limited',
|
||||
},
|
||||
disabled_quote: {
|
||||
id: 'privacy.quote.disabled',
|
||||
defaultMessage: '{visibility}, quotes disabled',
|
||||
},
|
||||
});
|
||||
|
||||
interface PrivacyDropdownProps {
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const VisibilityButton: FC<PrivacyDropdownProps> = (props) => {
|
||||
if (!isFeatureEnabled('outgoing_quotes')) {
|
||||
return <PrivacyDropdownContainer {...props} />;
|
||||
}
|
||||
return <PrivacyModalButton {...props} />;
|
||||
};
|
||||
|
||||
const visibilityOptions = {
|
||||
public: {
|
||||
icon: 'globe',
|
||||
iconComponent: PublicIcon,
|
||||
value: 'public',
|
||||
text: privacyMessages.public_short,
|
||||
},
|
||||
unlisted: {
|
||||
icon: 'unlock',
|
||||
iconComponent: QuietTimeIcon,
|
||||
value: 'unlisted',
|
||||
text: privacyMessages.unlisted_short,
|
||||
},
|
||||
private: {
|
||||
icon: 'lock',
|
||||
iconComponent: LockIcon,
|
||||
value: 'private',
|
||||
text: privacyMessages.private_short,
|
||||
},
|
||||
direct: {
|
||||
icon: 'at',
|
||||
iconComponent: AlternateEmailIcon,
|
||||
value: 'direct',
|
||||
text: privacyMessages.direct_short,
|
||||
},
|
||||
};
|
||||
|
||||
const PrivacyModalButton: FC<PrivacyDropdownProps> = ({ disabled = false }) => {
|
||||
const intl = useIntl();
|
||||
|
||||
const { visibility, quotePolicy } = useAppSelector((state) => ({
|
||||
visibility: state.compose.get('privacy') as StatusVisibility,
|
||||
quotePolicy: state.compose.get('quote_policy') as ApiQuotePolicy,
|
||||
}));
|
||||
|
||||
const { icon, iconComponent } = useMemo(() => {
|
||||
const option = visibilityOptions[visibility];
|
||||
return { icon: option.icon, iconComponent: option.iconComponent };
|
||||
}, [visibility]);
|
||||
const text = useMemo(() => {
|
||||
const visibilityText = intl.formatMessage(
|
||||
visibilityOptions[visibility].text,
|
||||
);
|
||||
if (visibility === 'private' || visibility === 'direct') {
|
||||
return visibilityText;
|
||||
}
|
||||
if (quotePolicy === 'nobody') {
|
||||
return intl.formatMessage(messages.disabled_quote, {
|
||||
visibility: visibilityText,
|
||||
});
|
||||
}
|
||||
if (quotePolicy !== 'public') {
|
||||
return intl.formatMessage(messages.limited_quote, {
|
||||
visibility: visibilityText,
|
||||
});
|
||||
}
|
||||
return intl.formatMessage(messages.anyone_quote, {
|
||||
visibility: visibilityText,
|
||||
});
|
||||
}, [quotePolicy, visibility, intl]);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const handleChange: VisibilityModalCallback = useCallback(
|
||||
(newVisibility, newQuotePolicy) => {
|
||||
if (newVisibility !== visibility) {
|
||||
dispatch(changeComposeVisibility(newVisibility));
|
||||
}
|
||||
if (newQuotePolicy !== quotePolicy) {
|
||||
dispatch(setComposeQuotePolicy(newQuotePolicy));
|
||||
}
|
||||
},
|
||||
[dispatch, quotePolicy, visibility],
|
||||
);
|
||||
|
||||
const handleOpen = useCallback(() => {
|
||||
dispatch(
|
||||
openModal({
|
||||
modalType: 'COMPOSE_PRIVACY',
|
||||
modalProps: { onChange: handleChange },
|
||||
}),
|
||||
);
|
||||
}, [dispatch, handleChange]);
|
||||
|
||||
return (
|
||||
<button
|
||||
type='button'
|
||||
title={intl.formatMessage(privacyMessages.change_privacy)}
|
||||
onClick={handleOpen}
|
||||
disabled={disabled}
|
||||
className={classNames('dropdown-button')}
|
||||
>
|
||||
<Icon id={icon} icon={iconComponent} />
|
||||
<span className='dropdown-button__label'>{text}</span>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user