Break out a separate mute modal with a hide-notifications checkbox.
This commit is contained in:
		
							parent
							
								
									0c547faf92
								
							
						
					
					
						commit
						4612f7caea
					
				
					 9 changed files with 168 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -43,6 +43,7 @@ import {
 | 
			
		|||
  blockAccount,
 | 
			
		||||
  muteAccount,
 | 
			
		||||
} from '../../../mastodon/actions/accounts';
 | 
			
		||||
import { initMuteModal } from '../../../mastodon/actions/mutes';
 | 
			
		||||
import {
 | 
			
		||||
  muteStatus,
 | 
			
		||||
  unmuteStatus,
 | 
			
		||||
| 
						 | 
				
			
			@ -80,10 +81,6 @@ const messages = defineMessages({
 | 
			
		|||
    id             : 'confirmations.block.confirm',
 | 
			
		||||
    defaultMessage : 'Block',
 | 
			
		||||
  },
 | 
			
		||||
  muteConfirm : {
 | 
			
		||||
    id             : 'confirmations.mute.confirm',
 | 
			
		||||
    defaultMessage : 'Mute',
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
                            /* * * * */
 | 
			
		||||
| 
						 | 
				
			
			@ -230,11 +227,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
 | 
			
		|||
  },
 | 
			
		||||
 | 
			
		||||
  onMute (account) {
 | 
			
		||||
    dispatch(openModal('CONFIRM', {
 | 
			
		||||
      message: <FormattedMessage id='confirmations.mute.message' defaultMessage='Are you sure you want to mute {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
 | 
			
		||||
      confirm: intl.formatMessage(messages.muteConfirm),
 | 
			
		||||
      onConfirm: () => dispatch(muteAccount(account.get('id'))),
 | 
			
		||||
    }));
 | 
			
		||||
    dispatch(initMuteModal(account));
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onMuteConversation (status) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -240,11 +240,11 @@ export function unblockAccountFail(error) {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export function muteAccount(id) {
 | 
			
		||||
export function muteAccount(id, notifications) {
 | 
			
		||||
  return (dispatch, getState) => {
 | 
			
		||||
    dispatch(muteAccountRequest(id));
 | 
			
		||||
 | 
			
		||||
    api(getState).post(`/api/v1/accounts/${id}/mute`).then(response => {
 | 
			
		||||
    api(getState).post(`/api/v1/accounts/${id}/mute`, { notifications }).then(response => {
 | 
			
		||||
      // Pass in entire statuses map so we can use it to filter stuff in different parts of the reducers
 | 
			
		||||
      dispatch(muteAccountSuccess(response.data, getState().get('statuses')));
 | 
			
		||||
    }).catch(error => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
import api, { getLinks } from '../api';
 | 
			
		||||
import { fetchRelationships } from './accounts';
 | 
			
		||||
import { openModal } from '../../mastodon/actions/modal';
 | 
			
		||||
 | 
			
		||||
export const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST';
 | 
			
		||||
export const MUTES_FETCH_SUCCESS = 'MUTES_FETCH_SUCCESS';
 | 
			
		||||
| 
						 | 
				
			
			@ -9,6 +10,9 @@ export const MUTES_EXPAND_REQUEST = 'MUTES_EXPAND_REQUEST';
 | 
			
		|||
export const MUTES_EXPAND_SUCCESS = 'MUTES_EXPAND_SUCCESS';
 | 
			
		||||
export const MUTES_EXPAND_FAIL    = 'MUTES_EXPAND_FAIL';
 | 
			
		||||
 | 
			
		||||
export const MUTES_INIT_MODAL = 'MUTES_INIT_MODAL';
 | 
			
		||||
export const MUTES_TOGGLE_HIDE_NOTIFICATIONS = 'MUTES_TOGGLE_HIDE_NOTIFICATIONS';
 | 
			
		||||
 | 
			
		||||
export function fetchMutes() {
 | 
			
		||||
  return (dispatch, getState) => {
 | 
			
		||||
    dispatch(fetchMutesRequest());
 | 
			
		||||
| 
						 | 
				
			
			@ -80,3 +84,20 @@ export function expandMutesFail(error) {
 | 
			
		|||
    error,
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function initMuteModal(account) {
 | 
			
		||||
  return dispatch => {
 | 
			
		||||
    dispatch({
 | 
			
		||||
      type: MUTES_INIT_MODAL,
 | 
			
		||||
      account,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    dispatch(openModal('MUTE'));
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function toggleHideNotifications() {
 | 
			
		||||
  return dispatch => {
 | 
			
		||||
    dispatch({ type: MUTES_TOGGLE_HIDE_NOTIFICATIONS });
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +12,7 @@ import BoostModal from './boost_modal';
 | 
			
		|||
import ConfirmationModal from './confirmation_modal';
 | 
			
		||||
import {
 | 
			
		||||
  OnboardingModal,
 | 
			
		||||
  MuteModal,
 | 
			
		||||
  ReportModal,
 | 
			
		||||
  SettingsModal,
 | 
			
		||||
  EmbedModal,
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +24,7 @@ const MODAL_COMPONENTS = {
 | 
			
		|||
  'VIDEO': () => Promise.resolve({ default: VideoModal }),
 | 
			
		||||
  'BOOST': () => Promise.resolve({ default: BoostModal }),
 | 
			
		||||
  'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }),
 | 
			
		||||
  'MUTE': MuteModal,
 | 
			
		||||
  'REPORT': ReportModal,
 | 
			
		||||
  'SETTINGS': SettingsModal,
 | 
			
		||||
  'ACTIONS': () => Promise.resolve({ default: ActionsModal }),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										98
									
								
								app/javascript/mastodon/features/ui/components/mute_modal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								app/javascript/mastodon/features/ui/components/mute_modal.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,98 @@
 | 
			
		|||
import React from 'react';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { injectIntl, FormattedMessage } from 'react-intl';
 | 
			
		||||
import Button from '../../../components/button';
 | 
			
		||||
import { closeModal } from '../../../actions/modal';
 | 
			
		||||
import { muteAccount } from '../../../actions/accounts';
 | 
			
		||||
import { toggleHideNotifications } from '../../../actions/mutes';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const mapStateToProps = state => {
 | 
			
		||||
  return {
 | 
			
		||||
    isSubmitting: state.getIn(['reports', 'new', 'isSubmitting']),
 | 
			
		||||
    account: state.getIn(['mutes', 'new', 'account']),
 | 
			
		||||
    notifications: state.getIn(['mutes', 'new', 'notifications']),
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const mapDispatchToProps = dispatch => {
 | 
			
		||||
  return {
 | 
			
		||||
    onConfirm(account, notifications) {
 | 
			
		||||
      dispatch(muteAccount(account.get('id'), notifications))
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    onClose() {
 | 
			
		||||
      dispatch(closeModal());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    onToggleNotifications() {
 | 
			
		||||
      dispatch(toggleHideNotifications());
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@connect(mapStateToProps, mapDispatchToProps)
 | 
			
		||||
@injectIntl
 | 
			
		||||
export default class MuteModal extends React.PureComponent {
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    isSubmitting: PropTypes.bool.isRequired,
 | 
			
		||||
    account: PropTypes.object.isRequired,
 | 
			
		||||
    notifications: PropTypes.bool.isRequired,
 | 
			
		||||
    onClose: PropTypes.func.isRequired,
 | 
			
		||||
    onConfirm: PropTypes.func.isRequired,
 | 
			
		||||
    onToggleNotifications: PropTypes.func.isRequired,
 | 
			
		||||
    intl: PropTypes.object.isRequired,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  componentDidMount() {
 | 
			
		||||
    this.button.focus();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleClick = () => {
 | 
			
		||||
    this.props.onClose();
 | 
			
		||||
    this.props.onConfirm(this.props.account, this.props.notifications);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleCancel = () => {
 | 
			
		||||
    this.props.onClose();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setRef = (c) => {
 | 
			
		||||
    this.button = c;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  toggleNotifications = () => {
 | 
			
		||||
    this.props.onToggleNotifications();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render () {
 | 
			
		||||
    const { account, notifications } = this.props;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div className='modal-root__modal mute-modal'>
 | 
			
		||||
        <div className='mute-modal__container'>
 | 
			
		||||
          <p>
 | 
			
		||||
            <FormattedMessage id='confirmations.mute.message'
 | 
			
		||||
              defaultMessage='Are you sure you want to mute {name}?'
 | 
			
		||||
              values={{ name: <strong>@{account.get('acct')}</strong> }}
 | 
			
		||||
            />
 | 
			
		||||
          </p>
 | 
			
		||||
          <p>
 | 
			
		||||
            <FormattedMessage id='mute_modal.hide_notifications' defaultMessage='Hide notifications from this user?' />
 | 
			
		||||
            <input type="checkbox" checked={notifications} onChange={this.toggleNotifications} />
 | 
			
		||||
          </p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div className='mute-modal__action-bar'>
 | 
			
		||||
          <Button onClick={this.handleCancel} className='mute-modal__cancel-button'>
 | 
			
		||||
            <FormattedMessage id='confirmation_modal.cancel' defaultMessage='Cancel' />
 | 
			
		||||
          </Button>
 | 
			
		||||
          <Button onClick={this.handleClick} ref={this.setRef}>
 | 
			
		||||
            <FormattedMessage id='confirmations.mute.confirm' defaultMessage='Mute' />
 | 
			
		||||
          </Button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -86,6 +86,10 @@ export function OnboardingModal () {
 | 
			
		|||
  return import(/* webpackChunkName: "modals/onboarding_modal" */'../components/onboarding_modal');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function MuteModal () {
 | 
			
		||||
  return import(/* webpackChunkName: "modals/mute_modal" */'../components/mute_modal');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function ReportModal () {
 | 
			
		||||
  return import(/* webpackChunkName: "modals/report_modal" */'../components/report_modal');
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@ import local_settings from '../../glitch/reducers/local_settings';
 | 
			
		|||
import push_notifications from './push_notifications';
 | 
			
		||||
import status_lists from './status_lists';
 | 
			
		||||
import cards from './cards';
 | 
			
		||||
import mutes from './mutes';
 | 
			
		||||
import reports from './reports';
 | 
			
		||||
import contexts from './contexts';
 | 
			
		||||
import compose from './compose';
 | 
			
		||||
| 
						 | 
				
			
			@ -37,6 +38,7 @@ const reducers = {
 | 
			
		|||
  local_settings,
 | 
			
		||||
  push_notifications,
 | 
			
		||||
  cards,
 | 
			
		||||
  mutes,
 | 
			
		||||
  reports,
 | 
			
		||||
  contexts,
 | 
			
		||||
  compose,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										29
									
								
								app/javascript/mastodon/reducers/mutes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								app/javascript/mastodon/reducers/mutes.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
import Immutable from 'immutable';
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
	MUTES_INIT_MODAL,
 | 
			
		||||
	MUTES_TOGGLE_HIDE_NOTIFICATIONS,
 | 
			
		||||
} from '../actions/mutes';
 | 
			
		||||
 | 
			
		||||
const initialState = Immutable.Map({
 | 
			
		||||
	new: Immutable.Map({
 | 
			
		||||
		isSubmitting: false,
 | 
			
		||||
		account: null,
 | 
			
		||||
		notifications: true,
 | 
			
		||||
	}),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default function mutes(state = initialState, action) {
 | 
			
		||||
	switch (action.type) {
 | 
			
		||||
	case MUTES_INIT_MODAL:
 | 
			
		||||
		return state.withMutations((state) => {
 | 
			
		||||
			state.setIn(['new', 'isSubmitting'], false);
 | 
			
		||||
			state.setIn(['new', 'account'], action.account);
 | 
			
		||||
			state.setIn(['new', 'notifications'], true);
 | 
			
		||||
		});
 | 
			
		||||
	case MUTES_TOGGLE_HIDE_NOTIFICATIONS:
 | 
			
		||||
		return state.setIn(['new', 'notifications'], !state.getIn(['new', 'notifications']));
 | 
			
		||||
	default:
 | 
			
		||||
		return state;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3879,7 +3879,8 @@ button.icon-button.active i.fa-retweet {
 | 
			
		|||
.boost-modal,
 | 
			
		||||
.confirmation-modal,
 | 
			
		||||
.report-modal,
 | 
			
		||||
.actions-modal {
 | 
			
		||||
.actions-modal,
 | 
			
		||||
.mute-modal {
 | 
			
		||||
  background: lighten($ui-secondary-color, 8%);
 | 
			
		||||
  color: $ui-base-color;
 | 
			
		||||
  border-radius: 8px;
 | 
			
		||||
| 
						 | 
				
			
			@ -3925,6 +3926,7 @@ button.icon-button.active i.fa-retweet {
 | 
			
		|||
 | 
			
		||||
.boost-modal__action-bar,
 | 
			
		||||
.confirmation-modal__action-bar,
 | 
			
		||||
.mute-modal__action-bar,
 | 
			
		||||
.report-modal__action-bar {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
| 
						 | 
				
			
			@ -4020,8 +4022,10 @@ button.icon-button.active i.fa-retweet {
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.confirmation-modal__action-bar {
 | 
			
		||||
  .confirmation-modal__cancel-button {
 | 
			
		||||
.confirmation-modal__action-bar,
 | 
			
		||||
.mute-modal__action-bar {
 | 
			
		||||
  .confirmation-modal__cancel-button,
 | 
			
		||||
  .mute-modal__cancel-button {
 | 
			
		||||
    background-color: transparent;
 | 
			
		||||
    color: darken($ui-secondary-color, 34%);
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
| 
						 | 
				
			
			@ -4036,6 +4040,7 @@ button.icon-button.active i.fa-retweet {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
.confirmation-modal__container,
 | 
			
		||||
.mute-modal__container,
 | 
			
		||||
.report-modal__target {
 | 
			
		||||
  padding: 30px;
 | 
			
		||||
  font-size: 16px;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue