forked from treehouse/mastodon
Break out a separate mute modal with a hide-notifications checkbox.
parent
0c547faf92
commit
4612f7caea
|
@ -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 }),
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 New Issue