mirror of
https://github.com/mastodon/mastodon.git
synced 2024-11-08 08:44:27 +00:00
Change design of confirmation modals in web UI (#30884)
Co-authored-by: Renaud Chaput <renchap@gmail.com>
This commit is contained in:
parent
ff6d2ec343
commit
8818748b90
|
@ -3,6 +3,8 @@ import { useCallback } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import LockOpenIcon from '@/material-icons/400-24px/lock_open.svg?react';
|
import LockOpenIcon from '@/material-icons/400-24px/lock_open.svg?react';
|
||||||
|
import { unblockDomain } from 'mastodon/actions/domain_blocks';
|
||||||
|
import { useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
import { IconButton } from './icon_button';
|
import { IconButton } from './icon_button';
|
||||||
|
|
||||||
|
@ -13,17 +15,15 @@ const messages = defineMessages({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Props {
|
export const Domain: React.FC<{
|
||||||
domain: string;
|
domain: string;
|
||||||
onUnblockDomain: (domain: string) => void;
|
}> = ({ domain }) => {
|
||||||
}
|
|
||||||
|
|
||||||
export const Domain: React.FC<Props> = ({ domain, onUnblockDomain }) => {
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const handleDomainUnblock = useCallback(() => {
|
const handleDomainUnblock = useCallback(() => {
|
||||||
onUnblockDomain(domain);
|
dispatch(unblockDomain(domain));
|
||||||
}, [domain, onUnblockDomain]);
|
}, [dispatch, domain]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='domain'>
|
<div className='domain'>
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
|
|
||||||
import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
|
import { useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
import { useIdentity } from '@/mastodon/identity_context';
|
import { useIdentity } from '@/mastodon/identity_context';
|
||||||
import {
|
import { fetchRelationships, followAccount } from 'mastodon/actions/accounts';
|
||||||
fetchRelationships,
|
|
||||||
followAccount,
|
|
||||||
unfollowAccount,
|
|
||||||
} from 'mastodon/actions/accounts';
|
|
||||||
import { openModal } from 'mastodon/actions/modal';
|
import { openModal } from 'mastodon/actions/modal';
|
||||||
import { Button } from 'mastodon/components/button';
|
import { Button } from 'mastodon/components/button';
|
||||||
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
||||||
|
@ -60,29 +56,14 @@ export const FollowButton: React.FC<{
|
||||||
|
|
||||||
if (accountId === me) {
|
if (accountId === me) {
|
||||||
return;
|
return;
|
||||||
} else if (relationship.following || relationship.requested) {
|
} else if (account && (relationship.following || relationship.requested)) {
|
||||||
dispatch(
|
dispatch(
|
||||||
openModal({
|
openModal({ modalType: 'CONFIRM_UNFOLLOW', modalProps: { account } }),
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: (
|
|
||||||
<FormattedMessage
|
|
||||||
id='confirmations.unfollow.message'
|
|
||||||
defaultMessage='Are you sure you want to unfollow {name}?'
|
|
||||||
values={{ name: <strong>@{account?.acct}</strong> }}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
confirm: intl.formatMessage(messages.unfollow),
|
|
||||||
onConfirm: () => {
|
|
||||||
dispatch(unfollowAccount(accountId));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
dispatch(followAccount(accountId));
|
dispatch(followAccount(accountId));
|
||||||
}
|
}
|
||||||
}, [dispatch, intl, accountId, relationship, account, signedIn]);
|
}, [dispatch, accountId, relationship, account, signedIn]);
|
||||||
|
|
||||||
let label;
|
let label;
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,20 @@
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { injectIntl } from 'react-intl';
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { openModal } from 'mastodon/actions/modal';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
followAccount,
|
followAccount,
|
||||||
unfollowAccount,
|
|
||||||
blockAccount,
|
blockAccount,
|
||||||
unblockAccount,
|
unblockAccount,
|
||||||
muteAccount,
|
muteAccount,
|
||||||
unmuteAccount,
|
unmuteAccount,
|
||||||
} from '../actions/accounts';
|
} from '../actions/accounts';
|
||||||
import { openModal } from '../actions/modal';
|
|
||||||
import { initMuteModal } from '../actions/mutes';
|
import { initMuteModal } from '../actions/mutes';
|
||||||
import Account from '../components/account';
|
import Account from '../components/account';
|
||||||
import { makeGetAccount } from '../selectors';
|
import { makeGetAccount } from '../selectors';
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const makeMapStateToProps = () => {
|
const makeMapStateToProps = () => {
|
||||||
const getAccount = makeGetAccount();
|
const getAccount = makeGetAccount();
|
||||||
|
|
||||||
|
@ -29,18 +25,11 @@ const makeMapStateToProps = () => {
|
||||||
return mapStateToProps;
|
return mapStateToProps;
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
|
||||||
onFollow (account) {
|
onFollow (account) {
|
||||||
if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
|
if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_UNFOLLOW', modalProps: { account } }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
|
|
||||||
confirm: intl.formatMessage(messages.unfollowConfirm),
|
|
||||||
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
} else {
|
} else {
|
||||||
dispatch(followAccount(account.get('id')));
|
dispatch(followAccount(account.get('id')));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { blockDomain, unblockDomain } from '../actions/domain_blocks';
|
|
||||||
import { openModal } from '../actions/modal';
|
|
||||||
import { Domain } from '../components/domain';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Block entire domain' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const makeMapStateToProps = () => {
|
|
||||||
const mapStateToProps = () => ({});
|
|
||||||
|
|
||||||
return mapStateToProps;
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
|
||||||
onBlockDomain (domain) {
|
|
||||||
dispatch(openModal({
|
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: <FormattedMessage id='confirmations.domain_block.message' defaultMessage='Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.' values={{ domain: <strong>{domain}</strong> }} />,
|
|
||||||
confirm: intl.formatMessage(messages.blockDomainConfirm),
|
|
||||||
onConfirm: () => dispatch(blockDomain(domain)),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
onUnblockDomain (domain) {
|
|
||||||
dispatch(unblockDomain(domain));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Domain));
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { injectIntl } from 'react-intl';
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
@ -46,18 +46,6 @@ import Status from '../components/status';
|
||||||
import { deleteModal } from '../initial_state';
|
import { deleteModal } from '../initial_state';
|
||||||
import { makeGetStatus, makeGetPictureInPicture } from '../selectors';
|
import { makeGetStatus, makeGetPictureInPicture } from '../selectors';
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
|
||||||
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
|
|
||||||
redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
|
|
||||||
redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.' },
|
|
||||||
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
|
|
||||||
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
|
|
||||||
editConfirm: { id: 'confirmations.edit.confirm', defaultMessage: 'Edit' },
|
|
||||||
editMessage: { id: 'confirmations.edit.message', defaultMessage: 'Editing now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
|
|
||||||
blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Block entire domain' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const makeMapStateToProps = () => {
|
const makeMapStateToProps = () => {
|
||||||
const getStatus = makeGetStatus();
|
const getStatus = makeGetStatus();
|
||||||
const getPictureInPicture = makeGetPictureInPicture();
|
const getPictureInPicture = makeGetPictureInPicture();
|
||||||
|
@ -71,20 +59,14 @@ const makeMapStateToProps = () => {
|
||||||
return mapStateToProps;
|
return mapStateToProps;
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl, contextType }) => ({
|
const mapDispatchToProps = (dispatch, { contextType }) => ({
|
||||||
|
|
||||||
onReply (status) {
|
onReply (status) {
|
||||||
dispatch((_, getState) => {
|
dispatch((_, getState) => {
|
||||||
let state = getState();
|
let state = getState();
|
||||||
|
|
||||||
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_REPLY', modalProps: { status } }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.replyMessage),
|
|
||||||
confirm: intl.formatMessage(messages.replyConfirm),
|
|
||||||
onConfirm: () => dispatch(replyCompose(status)) },
|
|
||||||
}));
|
|
||||||
} else {
|
} else {
|
||||||
dispatch(replyCompose(status));
|
dispatch(replyCompose(status));
|
||||||
}
|
}
|
||||||
|
@ -129,14 +111,7 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({
|
||||||
if (!deleteModal) {
|
if (!deleteModal) {
|
||||||
dispatch(deleteStatus(status.get('id'), withRedraft));
|
dispatch(deleteStatus(status.get('id'), withRedraft));
|
||||||
} else {
|
} else {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_DELETE_STATUS', modalProps: { statusId: status.get('id'), withRedraft } }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
|
|
||||||
confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
|
|
||||||
onConfirm: () => dispatch(deleteStatus(status.get('id'), withRedraft)),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -144,14 +119,7 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({
|
||||||
dispatch((_, getState) => {
|
dispatch((_, getState) => {
|
||||||
let state = getState();
|
let state = getState();
|
||||||
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_EDIT_STATUS', modalProps: { statusId: status.get('id') } }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.editMessage),
|
|
||||||
confirm: intl.formatMessage(messages.editConfirm),
|
|
||||||
onConfirm: () => dispatch(editStatus(status.get('id'))),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
} else {
|
} else {
|
||||||
dispatch(editStatus(status.get('id')));
|
dispatch(editStatus(status.get('id')));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { injectIntl } from 'react-intl';
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import { openURL } from 'mastodon/actions/search';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
followAccount,
|
followAccount,
|
||||||
unfollowAccount,
|
|
||||||
unblockAccount,
|
unblockAccount,
|
||||||
unmuteAccount,
|
unmuteAccount,
|
||||||
pinAccount,
|
pinAccount,
|
||||||
|
@ -24,11 +23,6 @@ import { initReport } from '../../../actions/reports';
|
||||||
import { makeGetAccount, getAccountHidden } from '../../../selectors';
|
import { makeGetAccount, getAccountHidden } from '../../../selectors';
|
||||||
import Header from '../components/header';
|
import Header from '../components/header';
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' },
|
|
||||||
blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Block entire domain' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const makeMapStateToProps = () => {
|
const makeMapStateToProps = () => {
|
||||||
const getAccount = makeGetAccount();
|
const getAccount = makeGetAccount();
|
||||||
|
|
||||||
|
@ -41,18 +35,11 @@ const makeMapStateToProps = () => {
|
||||||
return mapStateToProps;
|
return mapStateToProps;
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
|
||||||
onFollow (account) {
|
onFollow (account) {
|
||||||
if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
|
if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_UNFOLLOW', modalProps: { account } }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
|
|
||||||
confirm: intl.formatMessage(messages.unfollowConfirm),
|
|
||||||
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
} else {
|
} else {
|
||||||
dispatch(followAccount(account.get('id')));
|
dispatch(followAccount(account.get('id')));
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import { useDispatch } from 'react-redux';
|
||||||
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
|
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
|
||||||
import { openModal } from 'mastodon/actions/modal';
|
import { openModal } from 'mastodon/actions/modal';
|
||||||
import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
|
import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
|
||||||
import { logOut } from 'mastodon/utils/log_out';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
|
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
|
||||||
|
@ -23,8 +22,6 @@ const messages = defineMessages({
|
||||||
filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
|
filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
|
||||||
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
||||||
bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' },
|
bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' },
|
||||||
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
|
|
||||||
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ActionBar = () => {
|
export const ActionBar = () => {
|
||||||
|
@ -32,16 +29,8 @@ export const ActionBar = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const handleLogoutClick = useCallback(() => {
|
const handleLogoutClick = useCallback(() => {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_LOG_OUT' }));
|
||||||
modalType: 'CONFIRM',
|
}, [dispatch]);
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.logoutMessage),
|
|
||||||
confirm: intl.formatMessage(messages.logoutConfirm),
|
|
||||||
closeWhenConfirm: false,
|
|
||||||
onConfirm: () => logOut(),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
}, [dispatch, intl]);
|
|
||||||
|
|
||||||
let menu = [];
|
let menu = [];
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ import SettingsIcon from '@/material-icons/400-24px/settings-fill.svg?react';
|
||||||
import { openModal } from 'mastodon/actions/modal';
|
import { openModal } from 'mastodon/actions/modal';
|
||||||
import Column from 'mastodon/components/column';
|
import Column from 'mastodon/components/column';
|
||||||
import { Icon } from 'mastodon/components/icon';
|
import { Icon } from 'mastodon/components/icon';
|
||||||
import { logOut } from 'mastodon/utils/log_out';
|
|
||||||
|
|
||||||
import elephantUIPlane from '../../../images/elephant_ui_plane.svg';
|
import elephantUIPlane from '../../../images/elephant_ui_plane.svg';
|
||||||
import { changeComposing, mountCompose, unmountCompose } from '../../actions/compose';
|
import { changeComposing, mountCompose, unmountCompose } from '../../actions/compose';
|
||||||
|
@ -42,8 +41,6 @@ const messages = defineMessages({
|
||||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||||
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
||||||
compose: { id: 'navigation_bar.compose', defaultMessage: 'Compose new post' },
|
compose: { id: 'navigation_bar.compose', defaultMessage: 'Compose new post' },
|
||||||
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
|
|
||||||
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => ({
|
const mapStateToProps = (state, ownProps) => ({
|
||||||
|
@ -72,20 +69,12 @@ class Compose extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLogoutClick = e => {
|
handleLogoutClick = e => {
|
||||||
const { dispatch, intl } = this.props;
|
const { dispatch } = this.props;
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_LOG_OUT' }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.logoutMessage),
|
|
||||||
confirm: intl.formatMessage(messages.logoutConfirm),
|
|
||||||
closeWhenConfirm: false,
|
|
||||||
onConfirm: () => logOut(),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,8 +36,6 @@ const messages = defineMessages({
|
||||||
delete: { id: 'conversation.delete', defaultMessage: 'Delete conversation' },
|
delete: { id: 'conversation.delete', defaultMessage: 'Delete conversation' },
|
||||||
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
|
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
|
||||||
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
|
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
|
||||||
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
|
|
||||||
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const getAccounts = createSelector(
|
const getAccounts = createSelector(
|
||||||
|
@ -103,19 +101,12 @@ export const Conversation = ({ conversation, scrollKey, onMoveUp, onMoveDown })
|
||||||
let state = getState();
|
let state = getState();
|
||||||
|
|
||||||
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_REPLY', modalProps: { status: lastStatus } }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.replyMessage),
|
|
||||||
confirm: intl.formatMessage(messages.replyConfirm),
|
|
||||||
onConfirm: () => dispatch(replyCompose(lastStatus)),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
} else {
|
} else {
|
||||||
dispatch(replyCompose(lastStatus));
|
dispatch(replyCompose(lastStatus));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [dispatch, lastStatus, intl]);
|
}, [dispatch, lastStatus]);
|
||||||
|
|
||||||
const handleDelete = useCallback(() => {
|
const handleDelete = useCallback(() => {
|
||||||
dispatch(deleteConversation(id));
|
dispatch(deleteConversation(id));
|
||||||
|
|
|
@ -8,7 +8,6 @@ import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
followAccount,
|
followAccount,
|
||||||
unfollowAccount,
|
|
||||||
unblockAccount,
|
unblockAccount,
|
||||||
unmuteAccount,
|
unmuteAccount,
|
||||||
} from 'mastodon/actions/accounts';
|
} from 'mastodon/actions/accounts';
|
||||||
|
@ -29,20 +28,12 @@ const messages = defineMessages({
|
||||||
id: 'account.cancel_follow_request',
|
id: 'account.cancel_follow_request',
|
||||||
defaultMessage: 'Withdraw follow request',
|
defaultMessage: 'Withdraw follow request',
|
||||||
},
|
},
|
||||||
cancelFollowRequestConfirm: {
|
|
||||||
id: 'confirmations.cancel_follow_request.confirm',
|
|
||||||
defaultMessage: 'Withdraw request',
|
|
||||||
},
|
|
||||||
requested: {
|
requested: {
|
||||||
id: 'account.requested',
|
id: 'account.requested',
|
||||||
defaultMessage: 'Awaiting approval. Click to cancel follow request',
|
defaultMessage: 'Awaiting approval. Click to cancel follow request',
|
||||||
},
|
},
|
||||||
unblock: { id: 'account.unblock_short', defaultMessage: 'Unblock' },
|
unblock: { id: 'account.unblock_short', defaultMessage: 'Unblock' },
|
||||||
unmute: { id: 'account.unmute_short', defaultMessage: 'Unmute' },
|
unmute: { id: 'account.unmute_short', defaultMessage: 'Unmute' },
|
||||||
unfollowConfirm: {
|
|
||||||
id: 'confirmations.unfollow.confirm',
|
|
||||||
defaultMessage: 'Unfollow',
|
|
||||||
},
|
|
||||||
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
|
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -89,48 +80,17 @@ export const AccountCard: React.FC<{ accountId: string }> = ({ accountId }) => {
|
||||||
const handleFollow = useCallback(() => {
|
const handleFollow = useCallback(() => {
|
||||||
if (!account) return;
|
if (!account) return;
|
||||||
|
|
||||||
if (account.getIn(['relationship', 'following'])) {
|
if (
|
||||||
|
account.getIn(['relationship', 'following']) ||
|
||||||
|
account.getIn(['relationship', 'requested'])
|
||||||
|
) {
|
||||||
dispatch(
|
dispatch(
|
||||||
openModal({
|
openModal({ modalType: 'CONFIRM_UNFOLLOW', modalProps: { account } }),
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: (
|
|
||||||
<FormattedMessage
|
|
||||||
id='confirmations.unfollow.message'
|
|
||||||
defaultMessage='Are you sure you want to unfollow {name}?'
|
|
||||||
values={{ name: <strong>@{account.get('acct')}</strong> }}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
confirm: intl.formatMessage(messages.unfollowConfirm),
|
|
||||||
onConfirm: () => {
|
|
||||||
dispatch(unfollowAccount(account.get('id')));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
} else if (account.getIn(['relationship', 'requested'])) {
|
|
||||||
dispatch(
|
|
||||||
openModal({
|
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: (
|
|
||||||
<FormattedMessage
|
|
||||||
id='confirmations.cancel_follow_request.message'
|
|
||||||
defaultMessage='Are you sure you want to withdraw your request to follow {name}?'
|
|
||||||
values={{ name: <strong>@{account.get('acct')}</strong> }}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
confirm: intl.formatMessage(messages.cancelFollowRequestConfirm),
|
|
||||||
onConfirm: () => {
|
|
||||||
dispatch(unfollowAccount(account.get('id')));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
dispatch(followAccount(account.get('id')));
|
dispatch(followAccount(account.get('id')));
|
||||||
}
|
}
|
||||||
}, [account, dispatch, intl]);
|
}, [account, dispatch]);
|
||||||
|
|
||||||
const handleBlock = useCallback(() => {
|
const handleBlock = useCallback(() => {
|
||||||
if (account?.relationship?.blocking) {
|
if (account?.relationship?.blocking) {
|
||||||
|
|
|
@ -11,16 +11,15 @@ import { connect } from 'react-redux';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
import BlockIcon from '@/material-icons/400-24px/block-fill.svg?react';
|
import BlockIcon from '@/material-icons/400-24px/block-fill.svg?react';
|
||||||
|
import { Domain } from 'mastodon/components/domain';
|
||||||
|
|
||||||
import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks';
|
import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks';
|
||||||
import { LoadingIndicator } from '../../components/loading_indicator';
|
import { LoadingIndicator } from '../../components/loading_indicator';
|
||||||
import ScrollableList from '../../components/scrollable_list';
|
import ScrollableList from '../../components/scrollable_list';
|
||||||
import DomainContainer from '../../containers/domain_container';
|
|
||||||
import Column from '../ui/components/column';
|
import Column from '../ui/components/column';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
heading: { id: 'column.domain_blocks', defaultMessage: 'Blocked domains' },
|
heading: { id: 'column.domain_blocks', defaultMessage: 'Blocked domains' },
|
||||||
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
|
@ -70,7 +69,7 @@ class Blocks extends ImmutablePureComponent {
|
||||||
bindToDocument={!multiColumn}
|
bindToDocument={!multiColumn}
|
||||||
>
|
>
|
||||||
{domains.map(domain =>
|
{domains.map(domain =>
|
||||||
<DomainContainer key={domain} domain={domain} />,
|
<Domain key={domain} domain={domain} />,
|
||||||
)}
|
)}
|
||||||
</ScrollableList>
|
</ScrollableList>
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import DeleteIcon from '@/material-icons/400-24px/delete.svg?react';
|
||||||
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
|
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
|
||||||
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
|
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
|
||||||
import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns';
|
import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns';
|
||||||
import { fetchList, deleteList, updateList } from 'mastodon/actions/lists';
|
import { fetchList, updateList } from 'mastodon/actions/lists';
|
||||||
import { openModal } from 'mastodon/actions/modal';
|
import { openModal } from 'mastodon/actions/modal';
|
||||||
import { connectListStream } from 'mastodon/actions/streaming';
|
import { connectListStream } from 'mastodon/actions/streaming';
|
||||||
import { expandListTimeline } from 'mastodon/actions/timelines';
|
import { expandListTimeline } from 'mastodon/actions/timelines';
|
||||||
|
@ -29,8 +29,6 @@ import StatusListContainer from 'mastodon/features/ui/containers/status_list_con
|
||||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
deleteMessage: { id: 'confirmations.delete_list.message', defaultMessage: 'Are you sure you want to permanently delete this list?' },
|
|
||||||
deleteConfirm: { id: 'confirmations.delete_list.confirm', defaultMessage: 'Delete' },
|
|
||||||
followed: { id: 'lists.replies_policy.followed', defaultMessage: 'Any followed user' },
|
followed: { id: 'lists.replies_policy.followed', defaultMessage: 'Any followed user' },
|
||||||
none: { id: 'lists.replies_policy.none', defaultMessage: 'No one' },
|
none: { id: 'lists.replies_policy.none', defaultMessage: 'No one' },
|
||||||
list: { id: 'lists.replies_policy.list', defaultMessage: 'Members of the list' },
|
list: { id: 'lists.replies_policy.list', defaultMessage: 'Members of the list' },
|
||||||
|
@ -125,25 +123,10 @@ class ListTimeline extends PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
handleDeleteClick = () => {
|
handleDeleteClick = () => {
|
||||||
const { dispatch, columnId, intl } = this.props;
|
const { dispatch, columnId } = this.props;
|
||||||
const { id } = this.props.params;
|
const { id } = this.props.params;
|
||||||
|
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_DELETE_LIST', modalProps: { listId: id, columnId } }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.deleteMessage),
|
|
||||||
confirm: intl.formatMessage(messages.deleteConfirm),
|
|
||||||
onConfirm: () => {
|
|
||||||
dispatch(deleteList(id));
|
|
||||||
|
|
||||||
if (columnId) {
|
|
||||||
dispatch(removeColumn(columnId));
|
|
||||||
} else {
|
|
||||||
this.props.history.push('/lists');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
handleRepliesPolicyChange = ({ target }) => {
|
handleRepliesPolicyChange = ({ target }) => {
|
||||||
|
|
|
@ -2,11 +2,10 @@ import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { openModal } from 'mastodon/actions/modal';
|
||||||
import { initializeNotifications } from 'mastodon/actions/notifications_migration';
|
import { initializeNotifications } from 'mastodon/actions/notifications_migration';
|
||||||
|
|
||||||
import { showAlert } from '../../../actions/alerts';
|
import { showAlert } from '../../../actions/alerts';
|
||||||
import { openModal } from '../../../actions/modal';
|
|
||||||
import { clearNotifications } from '../../../actions/notification_groups';
|
|
||||||
import { updateNotificationsPolicy } from '../../../actions/notification_policies';
|
import { updateNotificationsPolicy } from '../../../actions/notification_policies';
|
||||||
import { setFilter, requestBrowserPermission } from '../../../actions/notifications';
|
import { setFilter, requestBrowserPermission } from '../../../actions/notifications';
|
||||||
import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications';
|
import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications';
|
||||||
|
@ -14,8 +13,6 @@ import { changeSetting } from '../../../actions/settings';
|
||||||
import ColumnSettings from '../components/column_settings';
|
import ColumnSettings from '../components/column_settings';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
clearMessage: { id: 'notifications.clear_confirmation', defaultMessage: 'Are you sure you want to permanently clear all your notifications?' },
|
|
||||||
clearConfirm: { id: 'notifications.clear', defaultMessage: 'Clear notifications' },
|
|
||||||
permissionDenied: { id: 'notifications.permission_denied_alert', defaultMessage: 'Desktop notifications can\'t be enabled, as browser permission has been denied before' },
|
permissionDenied: { id: 'notifications.permission_denied_alert', defaultMessage: 'Desktop notifications can\'t be enabled, as browser permission has been denied before' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -31,7 +28,7 @@ const mapStateToProps = state => ({
|
||||||
notificationPolicy: state.notificationPolicy,
|
notificationPolicy: state.notificationPolicy,
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
|
||||||
onChange (path, checked) {
|
onChange (path, checked) {
|
||||||
if (path[0] === 'push') {
|
if (path[0] === 'push') {
|
||||||
|
@ -70,14 +67,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
},
|
},
|
||||||
|
|
||||||
onClear () {
|
onClear () {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_CLEAR_NOTIFICATIONS' }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.clearMessage),
|
|
||||||
confirm: intl.formatMessage(messages.clearConfirm),
|
|
||||||
onConfirm: () => dispatch(clearNotifications()),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onRequestNotificationPermission () {
|
onRequestNotificationPermission () {
|
||||||
|
|
|
@ -31,8 +31,6 @@ const messages = defineMessages({
|
||||||
cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
|
cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
|
||||||
cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' },
|
cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' },
|
||||||
favourite: { id: 'status.favourite', defaultMessage: 'Favorite' },
|
favourite: { id: 'status.favourite', defaultMessage: 'Favorite' },
|
||||||
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
|
|
||||||
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
|
|
||||||
open: { id: 'status.open', defaultMessage: 'Expand this status' },
|
open: { id: 'status.open', defaultMessage: 'Expand this status' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -71,19 +69,13 @@ class Footer extends ImmutablePureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
handleReplyClick = () => {
|
handleReplyClick = () => {
|
||||||
const { dispatch, askReplyConfirmation, status, intl } = this.props;
|
const { dispatch, askReplyConfirmation, status, onClose } = this.props;
|
||||||
const { signedIn } = this.props.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (signedIn) {
|
if (signedIn) {
|
||||||
if (askReplyConfirmation) {
|
if (askReplyConfirmation) {
|
||||||
dispatch(openModal({
|
onClose(true);
|
||||||
modalType: 'CONFIRM',
|
dispatch(openModal({ modalType: 'CONFIRM_REPLY', modalProps: { status } }));
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.replyMessage),
|
|
||||||
confirm: intl.formatMessage(messages.replyConfirm),
|
|
||||||
onConfirm: this._performReply,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
} else {
|
} else {
|
||||||
this._performReply();
|
this._performReply();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { injectIntl } from 'react-intl';
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
@ -28,15 +28,6 @@ import { deleteModal } from '../../../initial_state';
|
||||||
import { makeGetStatus, makeGetPictureInPicture } from '../../../selectors';
|
import { makeGetStatus, makeGetPictureInPicture } from '../../../selectors';
|
||||||
import DetailedStatus from '../components/detailed_status';
|
import DetailedStatus from '../components/detailed_status';
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
|
||||||
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
|
|
||||||
redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
|
|
||||||
redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.' },
|
|
||||||
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
|
|
||||||
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const makeMapStateToProps = () => {
|
const makeMapStateToProps = () => {
|
||||||
const getStatus = makeGetStatus();
|
const getStatus = makeGetStatus();
|
||||||
const getPictureInPicture = makeGetPictureInPicture();
|
const getPictureInPicture = makeGetPictureInPicture();
|
||||||
|
@ -50,20 +41,13 @@ const makeMapStateToProps = () => {
|
||||||
return mapStateToProps;
|
return mapStateToProps;
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
|
||||||
onReply (status) {
|
onReply (status) {
|
||||||
dispatch((_, getState) => {
|
dispatch((_, getState) => {
|
||||||
let state = getState();
|
let state = getState();
|
||||||
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_REPLY', modalProps: { status } }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.replyMessage),
|
|
||||||
confirm: intl.formatMessage(messages.replyConfirm),
|
|
||||||
onConfirm: () => dispatch(replyCompose(status)),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
} else {
|
} else {
|
||||||
dispatch(replyCompose(status));
|
dispatch(replyCompose(status));
|
||||||
}
|
}
|
||||||
|
@ -100,14 +84,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
if (!deleteModal) {
|
if (!deleteModal) {
|
||||||
dispatch(deleteStatus(status.get('id'), withRedraft));
|
dispatch(deleteStatus(status.get('id'), withRedraft));
|
||||||
} else {
|
} else {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_DELETE_STATUS', modalProps: { statusId: status.get('id'), withRedraft } }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
|
|
||||||
confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
|
|
||||||
onConfirm: () => dispatch(deleteStatus(status.get('id'), withRedraft)),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -72,17 +72,10 @@ import DetailedStatus from './components/detailed_status';
|
||||||
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
|
||||||
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
|
|
||||||
redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
|
|
||||||
redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.' },
|
|
||||||
revealAll: { id: 'status.show_more_all', defaultMessage: 'Show more for all' },
|
revealAll: { id: 'status.show_more_all', defaultMessage: 'Show more for all' },
|
||||||
hideAll: { id: 'status.show_less_all', defaultMessage: 'Show less for all' },
|
hideAll: { id: 'status.show_less_all', defaultMessage: 'Show less for all' },
|
||||||
statusTitleWithAttachments: { id: 'status.title.with_attachments', defaultMessage: '{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}' },
|
statusTitleWithAttachments: { id: 'status.title.with_attachments', defaultMessage: '{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}' },
|
||||||
detailedStatus: { id: 'status.detailed_status', defaultMessage: 'Detailed conversation view' },
|
detailedStatus: { id: 'status.detailed_status', defaultMessage: 'Detailed conversation view' },
|
||||||
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
|
|
||||||
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
|
|
||||||
blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Block entire domain' },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const makeMapStateToProps = () => {
|
const makeMapStateToProps = () => {
|
||||||
|
@ -264,19 +257,12 @@ class Status extends ImmutablePureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
handleReplyClick = (status) => {
|
handleReplyClick = (status) => {
|
||||||
const { askReplyConfirmation, dispatch, intl } = this.props;
|
const { askReplyConfirmation, dispatch } = this.props;
|
||||||
const { signedIn } = this.props.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (signedIn) {
|
if (signedIn) {
|
||||||
if (askReplyConfirmation) {
|
if (askReplyConfirmation) {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_REPLY', modalProps: { status } }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.replyMessage),
|
|
||||||
confirm: intl.formatMessage(messages.replyConfirm),
|
|
||||||
onConfirm: () => dispatch(replyCompose(status)),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
} else {
|
} else {
|
||||||
dispatch(replyCompose(status));
|
dispatch(replyCompose(status));
|
||||||
}
|
}
|
||||||
|
@ -319,24 +305,23 @@ class Status extends ImmutablePureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
handleDeleteClick = (status, withRedraft = false) => {
|
handleDeleteClick = (status, withRedraft = false) => {
|
||||||
const { dispatch, intl } = this.props;
|
const { dispatch } = this.props;
|
||||||
|
|
||||||
if (!deleteModal) {
|
if (!deleteModal) {
|
||||||
dispatch(deleteStatus(status.get('id'), withRedraft));
|
dispatch(deleteStatus(status.get('id'), withRedraft));
|
||||||
} else {
|
} else {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_DELETE_STATUS', modalProps: { statusId: status.get('id'), withRedraft } }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
|
|
||||||
confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
|
|
||||||
onConfirm: () => dispatch(deleteStatus(status.get('id'), withRedraft)),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleEditClick = (status) => {
|
handleEditClick = (status) => {
|
||||||
this.props.dispatch(editStatus(status.get('id')));
|
const { dispatch, askReplyConfirmation } = this.props;
|
||||||
|
|
||||||
|
if (askReplyConfirmation) {
|
||||||
|
dispatch(openModal({ modalType: 'CONFIRM_EDIT_STATUS', modalProps: { statusId: status.get('id') } }));
|
||||||
|
} else {
|
||||||
|
dispatch(editStatus(status.get('id')));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleDirectClick = (account) => {
|
handleDirectClick = (account) => {
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { PureComponent } from 'react';
|
|
||||||
|
|
||||||
import { injectIntl, FormattedMessage } from 'react-intl';
|
|
||||||
|
|
||||||
import { Button } from '../../../components/button';
|
|
||||||
|
|
||||||
class ConfirmationModal extends PureComponent {
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
message: PropTypes.node.isRequired,
|
|
||||||
confirm: PropTypes.string.isRequired,
|
|
||||||
onClose: PropTypes.func.isRequired,
|
|
||||||
onConfirm: PropTypes.func.isRequired,
|
|
||||||
secondary: PropTypes.string,
|
|
||||||
onSecondary: PropTypes.func,
|
|
||||||
closeWhenConfirm: PropTypes.bool,
|
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
closeWhenConfirm: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
handleClick = () => {
|
|
||||||
if (this.props.closeWhenConfirm) {
|
|
||||||
this.props.onClose();
|
|
||||||
}
|
|
||||||
this.props.onConfirm();
|
|
||||||
};
|
|
||||||
|
|
||||||
handleSecondary = () => {
|
|
||||||
this.props.onClose();
|
|
||||||
this.props.onSecondary();
|
|
||||||
};
|
|
||||||
|
|
||||||
handleCancel = () => {
|
|
||||||
this.props.onClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
render () {
|
|
||||||
const { message, confirm, secondary } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='modal-root__modal confirmation-modal'>
|
|
||||||
<div className='confirmation-modal__container'>
|
|
||||||
{message}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='confirmation-modal__action-bar'>
|
|
||||||
<Button onClick={this.handleCancel} className='confirmation-modal__cancel-button'>
|
|
||||||
<FormattedMessage id='confirmation_modal.cancel' defaultMessage='Cancel' />
|
|
||||||
</Button>
|
|
||||||
{secondary !== undefined && (
|
|
||||||
<Button text={secondary} onClick={this.handleSecondary} className='confirmation-modal__secondary-button' />
|
|
||||||
)}
|
|
||||||
<Button text={confirm} onClick={this.handleClick} autoFocus />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default injectIntl(ConfirmationModal);
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { clearNotifications } from 'mastodon/actions/notification_groups';
|
||||||
|
import { useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
|
import type { BaseConfirmationModalProps } from './confirmation_modal';
|
||||||
|
import { ConfirmationModal } from './confirmation_modal';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
clearTitle: {
|
||||||
|
id: 'notifications.clear_title',
|
||||||
|
defaultMessage: 'Clear notifications?',
|
||||||
|
},
|
||||||
|
clearMessage: {
|
||||||
|
id: 'notifications.clear_confirmation',
|
||||||
|
defaultMessage:
|
||||||
|
'Are you sure you want to permanently clear all your notifications?',
|
||||||
|
},
|
||||||
|
clearConfirm: {
|
||||||
|
id: 'notifications.clear',
|
||||||
|
defaultMessage: 'Clear notifications',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ConfirmClearNotificationsModal: React.FC<
|
||||||
|
BaseConfirmationModalProps
|
||||||
|
> = ({ onClose }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const onConfirm = useCallback(() => {
|
||||||
|
void dispatch(clearNotifications());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmationModal
|
||||||
|
title={intl.formatMessage(messages.clearTitle)}
|
||||||
|
message={intl.formatMessage(messages.clearMessage)}
|
||||||
|
confirm={intl.formatMessage(messages.clearConfirm)}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,79 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import { Button } from 'mastodon/components/button';
|
||||||
|
|
||||||
|
export interface BaseConfirmationModalProps {
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ConfirmationModal: React.FC<
|
||||||
|
{
|
||||||
|
title: React.ReactNode;
|
||||||
|
message: React.ReactNode;
|
||||||
|
confirm: React.ReactNode;
|
||||||
|
secondary?: React.ReactNode;
|
||||||
|
onSecondary?: () => void;
|
||||||
|
onConfirm: () => void;
|
||||||
|
closeWhenConfirm?: boolean;
|
||||||
|
} & BaseConfirmationModalProps
|
||||||
|
> = ({
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
confirm,
|
||||||
|
onClose,
|
||||||
|
onConfirm,
|
||||||
|
secondary,
|
||||||
|
onSecondary,
|
||||||
|
closeWhenConfirm = true,
|
||||||
|
}) => {
|
||||||
|
const handleClick = useCallback(() => {
|
||||||
|
if (closeWhenConfirm) {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
onConfirm();
|
||||||
|
}, [onClose, onConfirm, closeWhenConfirm]);
|
||||||
|
|
||||||
|
const handleSecondary = useCallback(() => {
|
||||||
|
onClose();
|
||||||
|
onSecondary?.();
|
||||||
|
}, [onClose, onSecondary]);
|
||||||
|
|
||||||
|
const handleCancel = useCallback(() => {
|
||||||
|
onClose();
|
||||||
|
}, [onClose]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='modal-root__modal safety-action-modal'>
|
||||||
|
<div className='safety-action-modal__top'>
|
||||||
|
<div className='safety-action-modal__confirmation'>
|
||||||
|
<h1>{title}</h1>
|
||||||
|
<p>{message}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='safety-action-modal__bottom'>
|
||||||
|
<div className='safety-action-modal__actions'>
|
||||||
|
{secondary && (
|
||||||
|
<>
|
||||||
|
<Button onClick={handleSecondary}>{secondary}</Button>
|
||||||
|
|
||||||
|
<div className='spacer' />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<button onClick={handleCancel} className='link-button'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='confirmation_modal.cancel'
|
||||||
|
defaultMessage='Cancel'
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Button onClick={handleClick}>{confirm}</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { useHistory } from 'react-router';
|
||||||
|
|
||||||
|
import { removeColumn } from 'mastodon/actions/columns';
|
||||||
|
import { deleteList } from 'mastodon/actions/lists';
|
||||||
|
import { useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
|
import type { BaseConfirmationModalProps } from './confirmation_modal';
|
||||||
|
import { ConfirmationModal } from './confirmation_modal';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
deleteListTitle: {
|
||||||
|
id: 'confirmations.delete_list.title',
|
||||||
|
defaultMessage: 'Delete list?',
|
||||||
|
},
|
||||||
|
deleteListMessage: {
|
||||||
|
id: 'confirmations.delete_list.message',
|
||||||
|
defaultMessage: 'Are you sure you want to permanently delete this list?',
|
||||||
|
},
|
||||||
|
deleteListConfirm: {
|
||||||
|
id: 'confirmations.delete_list.confirm',
|
||||||
|
defaultMessage: 'Delete',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ConfirmDeleteListModal: React.FC<
|
||||||
|
{
|
||||||
|
listId: string;
|
||||||
|
columnId: string;
|
||||||
|
} & BaseConfirmationModalProps
|
||||||
|
> = ({ listId, columnId, onClose }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
const onConfirm = useCallback(() => {
|
||||||
|
dispatch(deleteList(listId));
|
||||||
|
|
||||||
|
if (columnId) {
|
||||||
|
dispatch(removeColumn(columnId));
|
||||||
|
} else {
|
||||||
|
history.push('/lists');
|
||||||
|
}
|
||||||
|
}, [dispatch, history, columnId, listId]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmationModal
|
||||||
|
title={intl.formatMessage(messages.deleteListTitle)}
|
||||||
|
message={intl.formatMessage(messages.deleteListMessage)}
|
||||||
|
confirm={intl.formatMessage(messages.deleteListConfirm)}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,67 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { deleteStatus } from 'mastodon/actions/statuses';
|
||||||
|
import { useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
|
import type { BaseConfirmationModalProps } from './confirmation_modal';
|
||||||
|
import { ConfirmationModal } from './confirmation_modal';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
deleteAndRedraftTitle: {
|
||||||
|
id: 'confirmations.redraft.title',
|
||||||
|
defaultMessage: 'Delete & redraft post?',
|
||||||
|
},
|
||||||
|
deleteAndRedraftMessage: {
|
||||||
|
id: 'confirmations.redraft.message',
|
||||||
|
defaultMessage:
|
||||||
|
'Are you sure you want to delete this status and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.',
|
||||||
|
},
|
||||||
|
deleteAndRedraftConfirm: {
|
||||||
|
id: 'confirmations.redraft.confirm',
|
||||||
|
defaultMessage: 'Delete & redraft',
|
||||||
|
},
|
||||||
|
deleteTitle: {
|
||||||
|
id: 'confirmations.delete.title',
|
||||||
|
defaultMessage: 'Delete post?',
|
||||||
|
},
|
||||||
|
deleteMessage: {
|
||||||
|
id: 'confirmations.delete.message',
|
||||||
|
defaultMessage: 'Are you sure you want to delete this status?',
|
||||||
|
},
|
||||||
|
deleteConfirm: {
|
||||||
|
id: 'confirmations.delete.confirm',
|
||||||
|
defaultMessage: 'Delete',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ConfirmDeleteStatusModal: React.FC<
|
||||||
|
{
|
||||||
|
statusId: string;
|
||||||
|
withRedraft: boolean;
|
||||||
|
} & BaseConfirmationModalProps
|
||||||
|
> = ({ statusId, withRedraft, onClose }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const onConfirm = useCallback(() => {
|
||||||
|
dispatch(deleteStatus(statusId, withRedraft));
|
||||||
|
}, [dispatch, statusId, withRedraft]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmationModal
|
||||||
|
title={intl.formatMessage(
|
||||||
|
withRedraft ? messages.deleteAndRedraftTitle : messages.deleteTitle,
|
||||||
|
)}
|
||||||
|
message={intl.formatMessage(
|
||||||
|
withRedraft ? messages.deleteAndRedraftMessage : messages.deleteMessage,
|
||||||
|
)}
|
||||||
|
confirm={intl.formatMessage(
|
||||||
|
withRedraft ? messages.deleteAndRedraftConfirm : messages.deleteConfirm,
|
||||||
|
)}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { editStatus } from 'mastodon/actions/statuses';
|
||||||
|
import { useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
|
import type { BaseConfirmationModalProps } from './confirmation_modal';
|
||||||
|
import { ConfirmationModal } from './confirmation_modal';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
editTitle: {
|
||||||
|
id: 'confirmations.edit.title',
|
||||||
|
defaultMessage: 'Overwrite post?',
|
||||||
|
},
|
||||||
|
editConfirm: { id: 'confirmations.edit.confirm', defaultMessage: 'Edit' },
|
||||||
|
editMessage: {
|
||||||
|
id: 'confirmations.edit.message',
|
||||||
|
defaultMessage:
|
||||||
|
'Editing now will overwrite the message you are currently composing. Are you sure you want to proceed?',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ConfirmEditStatusModal: React.FC<
|
||||||
|
{
|
||||||
|
statusId: string;
|
||||||
|
} & BaseConfirmationModalProps
|
||||||
|
> = ({ statusId, onClose }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const onConfirm = useCallback(() => {
|
||||||
|
dispatch(editStatus(statusId));
|
||||||
|
}, [dispatch, statusId]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmationModal
|
||||||
|
title={intl.formatMessage(messages.editTitle)}
|
||||||
|
message={intl.formatMessage(messages.editMessage)}
|
||||||
|
confirm={intl.formatMessage(messages.editConfirm)}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
export { ConfirmationModal } from './confirmation_modal';
|
||||||
|
export { ConfirmDeleteStatusModal } from './delete_status';
|
||||||
|
export { ConfirmDeleteListModal } from './delete_list';
|
||||||
|
export { ConfirmReplyModal } from './reply';
|
||||||
|
export { ConfirmEditStatusModal } from './edit_status';
|
||||||
|
export { ConfirmUnfollowModal } from './unfollow';
|
||||||
|
export { ConfirmClearNotificationsModal } from './clear_notifications';
|
||||||
|
export { ConfirmLogOutModal } from './log_out';
|
|
@ -0,0 +1,40 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { logOut } from 'mastodon/utils/log_out';
|
||||||
|
|
||||||
|
import type { BaseConfirmationModalProps } from './confirmation_modal';
|
||||||
|
import { ConfirmationModal } from './confirmation_modal';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
logoutTitle: { id: 'confirmations.logout.title', defaultMessage: 'Log out?' },
|
||||||
|
logoutMessage: {
|
||||||
|
id: 'confirmations.logout.message',
|
||||||
|
defaultMessage: 'Are you sure you want to log out?',
|
||||||
|
},
|
||||||
|
logoutConfirm: {
|
||||||
|
id: 'confirmations.logout.confirm',
|
||||||
|
defaultMessage: 'Log out',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ConfirmLogOutModal: React.FC<BaseConfirmationModalProps> = ({
|
||||||
|
onClose,
|
||||||
|
}) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const onConfirm = useCallback(() => {
|
||||||
|
logOut();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmationModal
|
||||||
|
title={intl.formatMessage(messages.logoutTitle)}
|
||||||
|
message={intl.formatMessage(messages.logoutMessage)}
|
||||||
|
confirm={intl.formatMessage(messages.logoutConfirm)}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { replyCompose } from 'mastodon/actions/compose';
|
||||||
|
import type { Status } from 'mastodon/models/status';
|
||||||
|
import { useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
|
import type { BaseConfirmationModalProps } from './confirmation_modal';
|
||||||
|
import { ConfirmationModal } from './confirmation_modal';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
replyTitle: {
|
||||||
|
id: 'confirmations.reply.title',
|
||||||
|
defaultMessage: 'Overwrite post?',
|
||||||
|
},
|
||||||
|
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
|
||||||
|
replyMessage: {
|
||||||
|
id: 'confirmations.reply.message',
|
||||||
|
defaultMessage:
|
||||||
|
'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ConfirmReplyModal: React.FC<
|
||||||
|
{
|
||||||
|
status: Status;
|
||||||
|
} & BaseConfirmationModalProps
|
||||||
|
> = ({ status, onClose }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const onConfirm = useCallback(() => {
|
||||||
|
dispatch(replyCompose(status));
|
||||||
|
}, [dispatch, status]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmationModal
|
||||||
|
title={intl.formatMessage(messages.replyTitle)}
|
||||||
|
message={intl.formatMessage(messages.replyMessage)}
|
||||||
|
confirm={intl.formatMessage(messages.replyConfirm)}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,50 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { unfollowAccount } from 'mastodon/actions/accounts';
|
||||||
|
import type { Account } from 'mastodon/models/account';
|
||||||
|
import { useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
|
import type { BaseConfirmationModalProps } from './confirmation_modal';
|
||||||
|
import { ConfirmationModal } from './confirmation_modal';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
unfollowTitle: {
|
||||||
|
id: 'confirmations.unfollow.title',
|
||||||
|
defaultMessage: 'Unfollow user?',
|
||||||
|
},
|
||||||
|
unfollowConfirm: {
|
||||||
|
id: 'confirmations.unfollow.confirm',
|
||||||
|
defaultMessage: 'Unfollow',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ConfirmUnfollowModal: React.FC<
|
||||||
|
{
|
||||||
|
account: Account;
|
||||||
|
} & BaseConfirmationModalProps
|
||||||
|
> = ({ account, onClose }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const onConfirm = useCallback(() => {
|
||||||
|
dispatch(unfollowAccount(account.id));
|
||||||
|
}, [dispatch, account.id]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmationModal
|
||||||
|
title={intl.formatMessage(messages.unfollowTitle)}
|
||||||
|
message={
|
||||||
|
<FormattedMessage
|
||||||
|
id='confirmations.unfollow.message'
|
||||||
|
defaultMessage='Are you sure you want to unfollow {name}?'
|
||||||
|
values={{ name: <strong>@{account.acct}</strong> }}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
confirm={intl.formatMessage(messages.unfollowConfirm)}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { PureComponent } from 'react';
|
import { PureComponent } from 'react';
|
||||||
|
|
||||||
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
import { FormattedMessage, injectIntl } from 'react-intl';
|
||||||
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
@ -9,29 +9,15 @@ import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { openModal } from 'mastodon/actions/modal';
|
import { openModal } from 'mastodon/actions/modal';
|
||||||
import { disabledAccountId, movedToAccountId, domain } from 'mastodon/initial_state';
|
import { disabledAccountId, movedToAccountId, domain } from 'mastodon/initial_state';
|
||||||
import { logOut } from 'mastodon/utils/log_out';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
|
|
||||||
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
disabledAcct: state.getIn(['accounts', disabledAccountId, 'acct']),
|
disabledAcct: state.getIn(['accounts', disabledAccountId, 'acct']),
|
||||||
movedToAcct: movedToAccountId ? state.getIn(['accounts', movedToAccountId, 'acct']) : undefined,
|
movedToAcct: movedToAccountId ? state.getIn(['accounts', movedToAccountId, 'acct']) : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
onLogout () {
|
onLogout () {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_LOG_OUT' }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.logoutMessage),
|
|
||||||
confirm: intl.formatMessage(messages.logoutConfirm),
|
|
||||||
closeWhenConfirm: false,
|
|
||||||
onConfirm: () => logOut(),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { PureComponent } from 'react';
|
import { PureComponent } from 'react';
|
||||||
|
|
||||||
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
import { FormattedMessage, injectIntl } from 'react-intl';
|
||||||
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
@ -11,24 +11,11 @@ import { openModal } from 'mastodon/actions/modal';
|
||||||
import { identityContextPropShape, withIdentity } from 'mastodon/identity_context';
|
import { identityContextPropShape, withIdentity } from 'mastodon/identity_context';
|
||||||
import { domain, version, source_url, statusPageUrl, profile_directory as profileDirectory } from 'mastodon/initial_state';
|
import { domain, version, source_url, statusPageUrl, profile_directory as profileDirectory } from 'mastodon/initial_state';
|
||||||
import { PERMISSION_INVITE_USERS } from 'mastodon/permissions';
|
import { PERMISSION_INVITE_USERS } from 'mastodon/permissions';
|
||||||
import { logOut } from 'mastodon/utils/log_out';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
|
|
||||||
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
|
||||||
onLogout () {
|
onLogout () {
|
||||||
dispatch(openModal({
|
dispatch(openModal({ modalType: 'CONFIRM_LOG_OUT' }));
|
||||||
modalType: 'CONFIRM',
|
|
||||||
modalProps: {
|
|
||||||
message: intl.formatMessage(messages.logoutMessage),
|
|
||||||
confirm: intl.formatMessage(messages.logoutConfirm),
|
|
||||||
closeWhenConfirm: false,
|
|
||||||
onConfirm: () => logOut(),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,16 @@ import ActionsModal from './actions_modal';
|
||||||
import AudioModal from './audio_modal';
|
import AudioModal from './audio_modal';
|
||||||
import { BoostModal } from './boost_modal';
|
import { BoostModal } from './boost_modal';
|
||||||
import BundleModalError from './bundle_modal_error';
|
import BundleModalError from './bundle_modal_error';
|
||||||
import ConfirmationModal from './confirmation_modal';
|
import {
|
||||||
|
ConfirmationModal,
|
||||||
|
ConfirmDeleteStatusModal,
|
||||||
|
ConfirmDeleteListModal,
|
||||||
|
ConfirmReplyModal,
|
||||||
|
ConfirmEditStatusModal,
|
||||||
|
ConfirmUnfollowModal,
|
||||||
|
ConfirmClearNotificationsModal,
|
||||||
|
ConfirmLogOutModal,
|
||||||
|
} from './confirmation_modals';
|
||||||
import FocalPointModal from './focal_point_modal';
|
import FocalPointModal from './focal_point_modal';
|
||||||
import ImageModal from './image_modal';
|
import ImageModal from './image_modal';
|
||||||
import MediaModal from './media_modal';
|
import MediaModal from './media_modal';
|
||||||
|
@ -40,6 +49,13 @@ export const MODAL_COMPONENTS = {
|
||||||
'IMAGE': () => Promise.resolve({ default: ImageModal }),
|
'IMAGE': () => Promise.resolve({ default: ImageModal }),
|
||||||
'BOOST': () => Promise.resolve({ default: BoostModal }),
|
'BOOST': () => Promise.resolve({ default: BoostModal }),
|
||||||
'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }),
|
'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }),
|
||||||
|
'CONFIRM_DELETE_STATUS': () => Promise.resolve({ default: ConfirmDeleteStatusModal }),
|
||||||
|
'CONFIRM_DELETE_LIST': () => Promise.resolve({ default: ConfirmDeleteListModal }),
|
||||||
|
'CONFIRM_REPLY': () => Promise.resolve({ default: ConfirmReplyModal }),
|
||||||
|
'CONFIRM_EDIT_STATUS': () => Promise.resolve({ default: ConfirmEditStatusModal }),
|
||||||
|
'CONFIRM_UNFOLLOW': () => Promise.resolve({ default: ConfirmUnfollowModal }),
|
||||||
|
'CONFIRM_CLEAR_NOTIFICATIONS': () => Promise.resolve({ default: ConfirmClearNotificationsModal }),
|
||||||
|
'CONFIRM_LOG_OUT': () => Promise.resolve({ default: ConfirmLogOutModal }),
|
||||||
'MUTE': MuteModal,
|
'MUTE': MuteModal,
|
||||||
'BLOCK': BlockModal,
|
'BLOCK': BlockModal,
|
||||||
'DOMAIN_BLOCK': DomainBlockModal,
|
'DOMAIN_BLOCK': DomainBlockModal,
|
||||||
|
|
|
@ -169,27 +169,30 @@
|
||||||
"compose_form.spoiler_placeholder": "Content warning (optional)",
|
"compose_form.spoiler_placeholder": "Content warning (optional)",
|
||||||
"confirmation_modal.cancel": "Cancel",
|
"confirmation_modal.cancel": "Cancel",
|
||||||
"confirmations.block.confirm": "Block",
|
"confirmations.block.confirm": "Block",
|
||||||
"confirmations.cancel_follow_request.confirm": "Withdraw request",
|
|
||||||
"confirmations.cancel_follow_request.message": "Are you sure you want to withdraw your request to follow {name}?",
|
|
||||||
"confirmations.delete.confirm": "Delete",
|
"confirmations.delete.confirm": "Delete",
|
||||||
"confirmations.delete.message": "Are you sure you want to delete this post?",
|
"confirmations.delete.message": "Are you sure you want to delete this post?",
|
||||||
|
"confirmations.delete.title": "Delete post?",
|
||||||
"confirmations.delete_list.confirm": "Delete",
|
"confirmations.delete_list.confirm": "Delete",
|
||||||
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
||||||
|
"confirmations.delete_list.title": "Delete list?",
|
||||||
"confirmations.discard_edit_media.confirm": "Discard",
|
"confirmations.discard_edit_media.confirm": "Discard",
|
||||||
"confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?",
|
"confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?",
|
||||||
"confirmations.domain_block.confirm": "Block server",
|
|
||||||
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
|
|
||||||
"confirmations.edit.confirm": "Edit",
|
"confirmations.edit.confirm": "Edit",
|
||||||
"confirmations.edit.message": "Editing now will overwrite the message you are currently composing. Are you sure you want to proceed?",
|
"confirmations.edit.message": "Editing now will overwrite the message you are currently composing. Are you sure you want to proceed?",
|
||||||
|
"confirmations.edit.title": "Overwrite post?",
|
||||||
"confirmations.logout.confirm": "Log out",
|
"confirmations.logout.confirm": "Log out",
|
||||||
"confirmations.logout.message": "Are you sure you want to log out?",
|
"confirmations.logout.message": "Are you sure you want to log out?",
|
||||||
|
"confirmations.logout.title": "Log out?",
|
||||||
"confirmations.mute.confirm": "Mute",
|
"confirmations.mute.confirm": "Mute",
|
||||||
"confirmations.redraft.confirm": "Delete & redraft",
|
"confirmations.redraft.confirm": "Delete & redraft",
|
||||||
"confirmations.redraft.message": "Are you sure you want to delete this post and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.",
|
"confirmations.redraft.message": "Are you sure you want to delete this post and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.",
|
||||||
|
"confirmations.redraft.title": "Delete & redraft post?",
|
||||||
"confirmations.reply.confirm": "Reply",
|
"confirmations.reply.confirm": "Reply",
|
||||||
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
|
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
|
||||||
|
"confirmations.reply.title": "Overwrite post?",
|
||||||
"confirmations.unfollow.confirm": "Unfollow",
|
"confirmations.unfollow.confirm": "Unfollow",
|
||||||
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
|
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
|
||||||
|
"confirmations.unfollow.title": "Unfollow user?",
|
||||||
"conversation.delete": "Delete conversation",
|
"conversation.delete": "Delete conversation",
|
||||||
"conversation.mark_as_read": "Mark as read",
|
"conversation.mark_as_read": "Mark as read",
|
||||||
"conversation.open": "View conversation",
|
"conversation.open": "View conversation",
|
||||||
|
@ -507,6 +510,7 @@
|
||||||
"notification_requests.title": "Filtered notifications",
|
"notification_requests.title": "Filtered notifications",
|
||||||
"notifications.clear": "Clear notifications",
|
"notifications.clear": "Clear notifications",
|
||||||
"notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
|
"notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
|
||||||
|
"notifications.clear_title": "Clear notifications?",
|
||||||
"notifications.column_settings.admin.report": "New reports:",
|
"notifications.column_settings.admin.report": "New reports:",
|
||||||
"notifications.column_settings.admin.sign_up": "New sign-ups:",
|
"notifications.column_settings.admin.sign_up": "New sign-ups:",
|
||||||
"notifications.column_settings.alert": "Desktop notifications",
|
"notifications.column_settings.alert": "Desktop notifications",
|
||||||
|
|
|
@ -6055,6 +6055,25 @@ a.status-card {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__confirmation {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 700;
|
||||||
|
color: $primary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__bullet-points {
|
&__bullet-points {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -6140,11 +6159,8 @@ a.status-card {
|
||||||
}
|
}
|
||||||
|
|
||||||
.boost-modal,
|
.boost-modal,
|
||||||
.confirmation-modal,
|
|
||||||
.report-modal,
|
.report-modal,
|
||||||
.actions-modal,
|
.actions-modal,
|
||||||
.mute-modal,
|
|
||||||
.block-modal,
|
|
||||||
.compare-history-modal {
|
.compare-history-modal {
|
||||||
background: lighten($ui-secondary-color, 8%);
|
background: lighten($ui-secondary-color, 8%);
|
||||||
color: $inverted-text-color;
|
color: $inverted-text-color;
|
||||||
|
@ -6166,10 +6182,7 @@ a.status-card {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.boost-modal__action-bar,
|
.boost-modal__action-bar {
|
||||||
.confirmation-modal__action-bar,
|
|
||||||
.mute-modal__action-bar,
|
|
||||||
.block-modal__action-bar {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -6192,16 +6205,6 @@ a.status-card {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mute-modal,
|
|
||||||
.block-modal {
|
|
||||||
line-height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mute-modal .react-toggle,
|
|
||||||
.block-modal .react-toggle {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.report-modal {
|
.report-modal {
|
||||||
width: 90vw;
|
width: 90vw;
|
||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
|
@ -6596,34 +6599,6 @@ a.status-card {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.confirmation-modal__action-bar,
|
|
||||||
.mute-modal__action-bar,
|
|
||||||
.block-modal__action-bar {
|
|
||||||
.confirmation-modal__secondary-button {
|
|
||||||
flex-shrink: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.confirmation-modal__secondary-button,
|
|
||||||
.confirmation-modal__cancel-button,
|
|
||||||
.mute-modal__cancel-button,
|
|
||||||
.block-modal__cancel-button {
|
|
||||||
background-color: transparent;
|
|
||||||
color: $lighter-text-color;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus,
|
|
||||||
&:active {
|
|
||||||
color: darken($lighter-text-color, 4%);
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.confirmation-modal__container,
|
|
||||||
.mute-modal__container,
|
|
||||||
.block-modal__container,
|
|
||||||
.report-modal__target {
|
.report-modal__target {
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
@ -6657,31 +6632,10 @@ a.status-card {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.confirmation-modal__container,
|
|
||||||
.report-modal__target {
|
.report-modal__target {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.block-modal,
|
|
||||||
.mute-modal {
|
|
||||||
&__explanation {
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-toggle {
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&__label {
|
|
||||||
color: $inverted-text-color;
|
|
||||||
margin: 0;
|
|
||||||
margin-inline-start: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.report-modal__target {
|
.report-modal__target {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue