Break out a separate mute modal with a hide-notifications checkbox.

signup-info-prompt
Surinna Curtis 2017-08-06 19:36:04 -03:00
parent 0c547faf92
commit 4612f7caea
9 changed files with 168 additions and 14 deletions

View File

@ -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) {

View File

@ -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 => {

View File

@ -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 });
};
}

View File

@ -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 }),

View 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>
);
}
}

View File

@ -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');
} }

View File

@ -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,

View 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;
}
}

View File

@ -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;