155 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import PropTypes from 'prop-types';
 | |
| import { useCallback, useState } from 'react';
 | |
| 
 | |
| import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
 | |
| 
 | |
| import classNames from 'classnames';
 | |
| 
 | |
| import { useDispatch } from 'react-redux';
 | |
| 
 | |
| 
 | |
| import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
 | |
| import CampaignIcon from '@/material-icons/400-24px/campaign.svg?react';
 | |
| import ReplyIcon from '@/material-icons/400-24px/reply.svg?react';
 | |
| import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react';
 | |
| import VolumeOffIcon from '@/material-icons/400-24px/volume_off.svg?react';
 | |
| import { muteAccount } from 'mastodon/actions/accounts';
 | |
| import { closeModal } from 'mastodon/actions/modal';
 | |
| import { Button } from 'mastodon/components/button';
 | |
| import { CheckBox } from 'mastodon/components/check_box';
 | |
| import { Icon } from 'mastodon/components/icon';
 | |
| import { RadioButton } from 'mastodon/components/radio_button';
 | |
| 
 | |
| const messages = defineMessages({
 | |
|   minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' },
 | |
|   hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' },
 | |
|   days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' },
 | |
|   indefinite: { id: 'mute_modal.indefinite', defaultMessage: 'Until I unmute them' },
 | |
|   hideFromNotifications: { id: 'mute_modal.hide_from_notifications', defaultMessage: 'Hide from notifications' },
 | |
| });
 | |
| 
 | |
| const RadioButtonLabel = ({ name, value, currentValue, onChange, label }) => (
 | |
|   <RadioButton
 | |
|     name={name}
 | |
|     value={value}
 | |
|     checked={value === currentValue}
 | |
|     onChange={onChange}
 | |
|     label={label}
 | |
|   />
 | |
| );
 | |
| 
 | |
| RadioButtonLabel.propTypes = {
 | |
|   name: PropTypes.string,
 | |
|   value: PropTypes.oneOf([PropTypes.string, PropTypes.number, PropTypes.bool]),
 | |
|   currentValue: PropTypes.oneOf([PropTypes.string, PropTypes.number, PropTypes.bool]),
 | |
|   checked: PropTypes.bool,
 | |
|   onChange: PropTypes.func,
 | |
|   label: PropTypes.node,
 | |
| };
 | |
| 
 | |
| export const MuteModal = ({ accountId, acct }) => {
 | |
|   const intl = useIntl();
 | |
|   const dispatch = useDispatch();
 | |
|   const [notifications, setNotifications] = useState(true);
 | |
|   const [muteDuration, setMuteDuration] = useState('0');
 | |
|   const [expanded, setExpanded] = useState(false);
 | |
| 
 | |
|   const handleClick = useCallback(() => {
 | |
|     dispatch(closeModal({ modalType: undefined, ignoreFocus: false }));
 | |
|     dispatch(muteAccount(accountId, notifications, muteDuration));
 | |
|   }, [dispatch, accountId, notifications, muteDuration]);
 | |
| 
 | |
|   const handleCancel = useCallback(() => {
 | |
|     dispatch(closeModal({ modalType: undefined, ignoreFocus: false }));
 | |
|   }, [dispatch]);
 | |
| 
 | |
|   const handleToggleNotifications = useCallback(({ target }) => {
 | |
|     setNotifications(target.checked);
 | |
|   }, [setNotifications]);
 | |
| 
 | |
|   const handleChangeMuteDuration = useCallback(({ target }) => {
 | |
|     setMuteDuration(target.value);
 | |
|   }, [setMuteDuration]);
 | |
| 
 | |
|   const handleToggleSettings = useCallback(() => {
 | |
|     setExpanded(!expanded);
 | |
|   }, [expanded, setExpanded]);
 | |
| 
 | |
|   return (
 | |
|     <div className='modal-root__modal safety-action-modal'>
 | |
|       <div className='safety-action-modal__top'>
 | |
|         <div className='safety-action-modal__header'>
 | |
|           <div className='safety-action-modal__header__icon'>
 | |
|             <Icon icon={VolumeOffIcon} />
 | |
|           </div>
 | |
| 
 | |
|           <div>
 | |
|             <h1><FormattedMessage id='mute_modal.title' defaultMessage='Mute user?' /></h1>
 | |
|             <div>@{acct}</div>
 | |
|           </div>
 | |
|         </div>
 | |
| 
 | |
|         <div className='safety-action-modal__bullet-points'>
 | |
|           <div>
 | |
|             <div className='safety-action-modal__bullet-points__icon'><Icon icon={CampaignIcon} /></div>
 | |
|             <div><FormattedMessage id='mute_modal.they_wont_know' defaultMessage="They won't know they've been muted." /></div>
 | |
|           </div>
 | |
| 
 | |
|           <div>
 | |
|             <div className='safety-action-modal__bullet-points__icon'><Icon icon={VisibilityOffIcon} /></div>
 | |
|             <div><FormattedMessage id='mute_modal.you_wont_see_posts' defaultMessage="They can still see your posts, but you won't see theirs." /></div>
 | |
|           </div>
 | |
| 
 | |
|           <div>
 | |
|             <div className='safety-action-modal__bullet-points__icon'><Icon icon={AlternateEmailIcon} /></div>
 | |
|             <div><FormattedMessage id='mute_modal.you_wont_see_mentions' defaultMessage="You won't see posts that mention them." /></div>
 | |
|           </div>
 | |
| 
 | |
|           <div>
 | |
|             <div className='safety-action-modal__bullet-points__icon'><Icon icon={ReplyIcon} /></div>
 | |
|             <div><FormattedMessage id='mute_modal.they_can_mention_and_follow' defaultMessage="They can mention and follow you, but you won't see them." /></div>
 | |
|           </div>
 | |
|         </div>
 | |
|       </div>
 | |
| 
 | |
|       <div className={classNames('safety-action-modal__bottom', { active: expanded })}>
 | |
|         <div className='safety-action-modal__bottom__collapsible'>
 | |
|           <div className='safety-action-modal__field-group'>
 | |
|             <RadioButtonLabel name='duration' value='0' label={intl.formatMessage(messages.indefinite)} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
 | |
|             <RadioButtonLabel name='duration' value='86400' label={intl.formatMessage(messages.hours, { number: 24 })} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
 | |
|             <RadioButtonLabel name='duration' value='604800' label={intl.formatMessage(messages.days, { number: 7 })} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
 | |
|             <RadioButtonLabel name='duration' value='2592000' label={intl.formatMessage(messages.days, { number: 30 })} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
 | |
|           </div>
 | |
| 
 | |
|           <div className='safety-action-modal__field-group'>
 | |
|             <CheckBox label={intl.formatMessage(messages.hideFromNotifications)} checked={notifications} onChange={handleToggleNotifications} />
 | |
|           </div>
 | |
|         </div>
 | |
| 
 | |
|         <div className='safety-action-modal__actions'>
 | |
|           <button onClick={handleToggleSettings} className='link-button'>
 | |
|             {expanded ? <FormattedMessage id='mute_modal.hide_options' defaultMessage='Hide options' /> : <FormattedMessage id='mute_modal.show_options' defaultMessage='Show options' />}
 | |
|           </button>
 | |
| 
 | |
|           <div className='spacer' />
 | |
| 
 | |
|           <button onClick={handleCancel} className='link-button'>
 | |
|             <FormattedMessage id='confirmation_modal.cancel' defaultMessage='Cancel' />
 | |
|           </button>
 | |
| 
 | |
|           <Button onClick={handleClick} autoFocus>
 | |
|             <FormattedMessage id='confirmations.mute.confirm' defaultMessage='Mute' />
 | |
|           </Button>
 | |
|         </div>
 | |
|       </div>
 | |
|     </div>
 | |
|   );
 | |
| };
 | |
| 
 | |
| MuteModal.propTypes = {
 | |
|   accountId: PropTypes.string.isRequired,
 | |
|   acct: PropTypes.string.isRequired,
 | |
| };
 | |
| 
 | |
| export default MuteModal;
 |