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,
 | 
					  blockAccount,
 | 
				
			||||||
  muteAccount,
 | 
					  muteAccount,
 | 
				
			||||||
} from '../../../mastodon/actions/accounts';
 | 
					} from '../../../mastodon/actions/accounts';
 | 
				
			||||||
 | 
					import { initMuteModal } from '../../../mastodon/actions/mutes';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  muteStatus,
 | 
					  muteStatus,
 | 
				
			||||||
  unmuteStatus,
 | 
					  unmuteStatus,
 | 
				
			||||||
| 
						 | 
					@ -80,10 +81,6 @@ const messages = defineMessages({
 | 
				
			||||||
    id             : 'confirmations.block.confirm',
 | 
					    id             : 'confirmations.block.confirm',
 | 
				
			||||||
    defaultMessage : 'Block',
 | 
					    defaultMessage : 'Block',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  muteConfirm : {
 | 
					 | 
				
			||||||
    id             : 'confirmations.mute.confirm',
 | 
					 | 
				
			||||||
    defaultMessage : 'Mute',
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            /* * * * */
 | 
					                            /* * * * */
 | 
				
			||||||
| 
						 | 
					@ -230,11 +227,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onMute (account) {
 | 
					  onMute (account) {
 | 
				
			||||||
    dispatch(openModal('CONFIRM', {
 | 
					    dispatch(initMuteModal(account));
 | 
				
			||||||
      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'))),
 | 
					 | 
				
			||||||
    }));
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onMuteConversation (status) {
 | 
					  onMuteConversation (status) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -240,11 +240,11 @@ export function unblockAccountFail(error) {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function muteAccount(id) {
 | 
					export function muteAccount(id, notifications) {
 | 
				
			||||||
  return (dispatch, getState) => {
 | 
					  return (dispatch, getState) => {
 | 
				
			||||||
    dispatch(muteAccountRequest(id));
 | 
					    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
 | 
					      // 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')));
 | 
					      dispatch(muteAccountSuccess(response.data, getState().get('statuses')));
 | 
				
			||||||
    }).catch(error => {
 | 
					    }).catch(error => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
import api, { getLinks } from '../api';
 | 
					import api, { getLinks } from '../api';
 | 
				
			||||||
import { fetchRelationships } from './accounts';
 | 
					import { fetchRelationships } from './accounts';
 | 
				
			||||||
 | 
					import { openModal } from '../../mastodon/actions/modal';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST';
 | 
					export const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST';
 | 
				
			||||||
export const MUTES_FETCH_SUCCESS = 'MUTES_FETCH_SUCCESS';
 | 
					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_SUCCESS = 'MUTES_EXPAND_SUCCESS';
 | 
				
			||||||
export const MUTES_EXPAND_FAIL    = 'MUTES_EXPAND_FAIL';
 | 
					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() {
 | 
					export function fetchMutes() {
 | 
				
			||||||
  return (dispatch, getState) => {
 | 
					  return (dispatch, getState) => {
 | 
				
			||||||
    dispatch(fetchMutesRequest());
 | 
					    dispatch(fetchMutesRequest());
 | 
				
			||||||
| 
						 | 
					@ -80,3 +84,20 @@ export function expandMutesFail(error) {
 | 
				
			||||||
    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 ConfirmationModal from './confirmation_modal';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  OnboardingModal,
 | 
					  OnboardingModal,
 | 
				
			||||||
 | 
					  MuteModal,
 | 
				
			||||||
  ReportModal,
 | 
					  ReportModal,
 | 
				
			||||||
  SettingsModal,
 | 
					  SettingsModal,
 | 
				
			||||||
  EmbedModal,
 | 
					  EmbedModal,
 | 
				
			||||||
| 
						 | 
					@ -23,6 +24,7 @@ const MODAL_COMPONENTS = {
 | 
				
			||||||
  'VIDEO': () => Promise.resolve({ default: VideoModal }),
 | 
					  'VIDEO': () => Promise.resolve({ default: VideoModal }),
 | 
				
			||||||
  'BOOST': () => Promise.resolve({ default: BoostModal }),
 | 
					  'BOOST': () => Promise.resolve({ default: BoostModal }),
 | 
				
			||||||
  'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }),
 | 
					  'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }),
 | 
				
			||||||
 | 
					  'MUTE': MuteModal,
 | 
				
			||||||
  'REPORT': ReportModal,
 | 
					  'REPORT': ReportModal,
 | 
				
			||||||
  'SETTINGS': SettingsModal,
 | 
					  'SETTINGS': SettingsModal,
 | 
				
			||||||
  'ACTIONS': () => Promise.resolve({ default: ActionsModal }),
 | 
					  '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');
 | 
					  return import(/* webpackChunkName: "modals/onboarding_modal" */'../components/onboarding_modal');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function MuteModal () {
 | 
				
			||||||
 | 
					  return import(/* webpackChunkName: "modals/mute_modal" */'../components/mute_modal');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function ReportModal () {
 | 
					export function ReportModal () {
 | 
				
			||||||
  return import(/* webpackChunkName: "modals/report_modal" */'../components/report_modal');
 | 
					  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 push_notifications from './push_notifications';
 | 
				
			||||||
import status_lists from './status_lists';
 | 
					import status_lists from './status_lists';
 | 
				
			||||||
import cards from './cards';
 | 
					import cards from './cards';
 | 
				
			||||||
 | 
					import mutes from './mutes';
 | 
				
			||||||
import reports from './reports';
 | 
					import reports from './reports';
 | 
				
			||||||
import contexts from './contexts';
 | 
					import contexts from './contexts';
 | 
				
			||||||
import compose from './compose';
 | 
					import compose from './compose';
 | 
				
			||||||
| 
						 | 
					@ -37,6 +38,7 @@ const reducers = {
 | 
				
			||||||
  local_settings,
 | 
					  local_settings,
 | 
				
			||||||
  push_notifications,
 | 
					  push_notifications,
 | 
				
			||||||
  cards,
 | 
					  cards,
 | 
				
			||||||
 | 
					  mutes,
 | 
				
			||||||
  reports,
 | 
					  reports,
 | 
				
			||||||
  contexts,
 | 
					  contexts,
 | 
				
			||||||
  compose,
 | 
					  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,
 | 
					.boost-modal,
 | 
				
			||||||
.confirmation-modal,
 | 
					.confirmation-modal,
 | 
				
			||||||
.report-modal,
 | 
					.report-modal,
 | 
				
			||||||
.actions-modal {
 | 
					.actions-modal,
 | 
				
			||||||
 | 
					.mute-modal {
 | 
				
			||||||
  background: lighten($ui-secondary-color, 8%);
 | 
					  background: lighten($ui-secondary-color, 8%);
 | 
				
			||||||
  color: $ui-base-color;
 | 
					  color: $ui-base-color;
 | 
				
			||||||
  border-radius: 8px;
 | 
					  border-radius: 8px;
 | 
				
			||||||
| 
						 | 
					@ -3925,6 +3926,7 @@ button.icon-button.active i.fa-retweet {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.boost-modal__action-bar,
 | 
					.boost-modal__action-bar,
 | 
				
			||||||
.confirmation-modal__action-bar,
 | 
					.confirmation-modal__action-bar,
 | 
				
			||||||
 | 
					.mute-modal__action-bar,
 | 
				
			||||||
.report-modal__action-bar {
 | 
					.report-modal__action-bar {
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  justify-content: space-between;
 | 
					  justify-content: space-between;
 | 
				
			||||||
| 
						 | 
					@ -4020,8 +4022,10 @@ button.icon-button.active i.fa-retweet {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.confirmation-modal__action-bar {
 | 
					.confirmation-modal__action-bar,
 | 
				
			||||||
  .confirmation-modal__cancel-button {
 | 
					.mute-modal__action-bar {
 | 
				
			||||||
 | 
					  .confirmation-modal__cancel-button,
 | 
				
			||||||
 | 
					  .mute-modal__cancel-button {
 | 
				
			||||||
    background-color: transparent;
 | 
					    background-color: transparent;
 | 
				
			||||||
    color: darken($ui-secondary-color, 34%);
 | 
					    color: darken($ui-secondary-color, 34%);
 | 
				
			||||||
    font-size: 14px;
 | 
					    font-size: 14px;
 | 
				
			||||||
| 
						 | 
					@ -4036,6 +4040,7 @@ button.icon-button.active i.fa-retweet {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.confirmation-modal__container,
 | 
					.confirmation-modal__container,
 | 
				
			||||||
 | 
					.mute-modal__container,
 | 
				
			||||||
.report-modal__target {
 | 
					.report-modal__target {
 | 
				
			||||||
  padding: 30px;
 | 
					  padding: 30px;
 | 
				
			||||||
  font-size: 16px;
 | 
					  font-size: 16px;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue