Add button verify/unverify a user

merge-requests/446/head
Alex Gleason 4 years ago
parent 0596909858
commit 62d5a97939
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7

@ -45,6 +45,14 @@ export const ADMIN_LOG_FETCH_REQUEST = 'ADMIN_LOG_FETCH_REQUEST';
export const ADMIN_LOG_FETCH_SUCCESS = 'ADMIN_LOG_FETCH_SUCCESS'; export const ADMIN_LOG_FETCH_SUCCESS = 'ADMIN_LOG_FETCH_SUCCESS';
export const ADMIN_LOG_FETCH_FAIL = 'ADMIN_LOG_FETCH_FAIL'; export const ADMIN_LOG_FETCH_FAIL = 'ADMIN_LOG_FETCH_FAIL';
export const ADMIN_USERS_TAG_REQUEST = 'ADMIN_USERS_TAG_REQUEST';
export const ADMIN_USERS_TAG_SUCCESS = 'ADMIN_USERS_TAG_SUCCESS';
export const ADMIN_USERS_TAG_FAIL = 'ADMIN_USERS_TAG_FAIL';
export const ADMIN_USERS_UNTAG_REQUEST = 'ADMIN_USERS_UNTAG_REQUEST';
export const ADMIN_USERS_UNTAG_SUCCESS = 'ADMIN_USERS_UNTAG_SUCCESS';
export const ADMIN_USERS_UNTAG_FAIL = 'ADMIN_USERS_UNTAG_FAIL';
export function fetchConfig() { export function fetchConfig() {
return (dispatch, getState) => { return (dispatch, getState) => {
dispatch({ type: ADMIN_CONFIG_FETCH_REQUEST }); dispatch({ type: ADMIN_CONFIG_FETCH_REQUEST });
@ -197,3 +205,31 @@ export function fetchModerationLog(params) {
}); });
}; };
} }
export function tagUsers(accountIds, tags) {
return (dispatch, getState) => {
const nicknames = accountIds.map(id => getState().getIn(['accounts', id, 'acct']));
dispatch({ type: ADMIN_USERS_TAG_REQUEST, accountIds, tags });
return api(getState)
.put('/api/v1/pleroma/admin/users/tag', { nicknames, tags })
.then(() => {
dispatch({ type: ADMIN_USERS_TAG_SUCCESS, accountIds, tags });
}).catch(error => {
dispatch({ type: ADMIN_USERS_TAG_FAIL, error, accountIds, tags });
});
};
}
export function untagUsers(accountIds, tags) {
return (dispatch, getState) => {
const nicknames = accountIds.map(id => getState().getIn(['accounts', id, 'acct']));
dispatch({ type: ADMIN_USERS_UNTAG_REQUEST, accountIds, tags });
return api(getState)
.delete('/api/v1/pleroma/admin/users/tag', { data: { nicknames, tags } })
.then(() => {
dispatch({ type: ADMIN_USERS_UNTAG_SUCCESS, accountIds, tags });
}).catch(error => {
dispatch({ type: ADMIN_USERS_UNTAG_FAIL, error, accountIds, tags });
});
};
}

@ -19,6 +19,7 @@ import ProfileInfoPanel from '../../ui/components/profile_info_panel';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import StillImage from 'soapbox/components/still_image'; import StillImage from 'soapbox/components/still_image';
import ActionButton from 'soapbox/features/ui/components/action_button'; import ActionButton from 'soapbox/features/ui/components/action_button';
import { isVerified } from 'soapbox/utils/accounts';
const messages = defineMessages({ const messages = defineMessages({
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
@ -48,6 +49,8 @@ const messages = defineMessages({
add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' }, add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
deactivateUser: { id: 'admin.users.actions.deactivate_user', defaultMessage: 'Deactivate @{name}' }, deactivateUser: { id: 'admin.users.actions.deactivate_user', defaultMessage: 'Deactivate @{name}' },
deleteUser: { id: 'admin.users.actions.delete_user', defaultMessage: 'Delete @{name}' }, deleteUser: { id: 'admin.users.actions.delete_user', defaultMessage: 'Delete @{name}' },
verifyUser: { id: 'admin.users.actions.verify_user', defaultMessage: 'Verify @{name}' },
unverifyUser: { id: 'admin.users.actions.unverify_user', defaultMessage: 'Unverify @{name}' },
}); });
const mapStateToProps = state => { const mapStateToProps = state => {
@ -171,6 +174,13 @@ class Header extends ImmutablePureComponent {
if (account.get('id') !== me && isStaff) { if (account.get('id') !== me && isStaff) {
menu.push(null); menu.push(null);
menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/pleroma/admin/#/users/${account.get('id')}/`, newTab: true }); menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/pleroma/admin/#/users/${account.get('id')}/`, newTab: true });
if (isVerified(account)) {
menu.push({ text: intl.formatMessage(messages.unverifyUser, { name: account.get('username') }), action: this.props.onUnverifyUser });
} else {
menu.push({ text: intl.formatMessage(messages.verifyUser, { name: account.get('username') }), action: this.props.onVerifyUser });
}
menu.push({ text: intl.formatMessage(messages.deactivateUser, { name: account.get('username') }), action: this.props.onDeactivateUser }); menu.push({ text: intl.formatMessage(messages.deactivateUser, { name: account.get('username') }), action: this.props.onDeactivateUser });
menu.push({ text: intl.formatMessage(messages.deleteUser, { name: account.get('username') }), action: this.props.onDeleteUser }); menu.push({ text: intl.formatMessage(messages.deleteUser, { name: account.get('username') }), action: this.props.onDeleteUser });
} }

@ -92,6 +92,14 @@ export default class Header extends ImmutablePureComponent {
this.props.onDeleteUser(this.props.account); this.props.onDeleteUser(this.props.account);
} }
handleVerifyUser = () => {
this.props.onVerifyUser(this.props.account);
}
handleUnverifyUser = () => {
this.props.onUnverifyUser(this.props.account);
}
render() { render() {
const { account, identity_proofs } = this.props; const { account, identity_proofs } = this.props;
const moved = (account) ? account.get('moved') : false; const moved = (account) ? account.get('moved') : false;
@ -117,6 +125,8 @@ export default class Header extends ImmutablePureComponent {
onAddToList={this.handleAddToList} onAddToList={this.handleAddToList}
onDeactivateUser={this.handleDeactivateUser} onDeactivateUser={this.handleDeactivateUser}
onDeleteUser={this.handleDeleteUser} onDeleteUser={this.handleDeleteUser}
onVerifyUser={this.handleVerifyUser}
onUnverifyUser={this.handleUnverifyUser}
username={this.props.username} username={this.props.username}
/> />
</div> </div>

@ -25,12 +25,16 @@ import { getSettings } from 'soapbox/actions/settings';
import { startChat, openChat } from 'soapbox/actions/chats'; import { startChat, openChat } from 'soapbox/actions/chats';
import { isMobile } from 'soapbox/is_mobile'; import { isMobile } from 'soapbox/is_mobile';
import { deactivateUserModal, deleteUserModal } from 'soapbox/actions/moderation'; import { deactivateUserModal, deleteUserModal } from 'soapbox/actions/moderation';
import { tagUsers, untagUsers } from 'soapbox/actions/admin';
import snackbar from 'soapbox/actions/snackbar';
const messages = defineMessages({ const messages = defineMessages({
unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' }, unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' },
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' }, blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' }, blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' },
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' }, blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
userVerified: { id: 'admin.users.user_verified_message', defaultMessage: '@{acct} was verified' },
userUnverified: { id: 'admin.users.user_unverified_message', defaultMessage: '@{acct} was unverified' },
}); });
const makeMapStateToProps = () => { const makeMapStateToProps = () => {
@ -154,6 +158,20 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
onDeleteUser(account) { onDeleteUser(account) {
dispatch(deleteUserModal(intl, account.get('id'))); dispatch(deleteUserModal(intl, account.get('id')));
}, },
onVerifyUser(account) {
const message = intl.formatMessage(messages.userVerified, { acct: account.get('acct') });
dispatch(tagUsers([account.get('id')], ['verified'])).then(() => {
dispatch(snackbar.success(message));
}).catch(() => {});
},
onUnverifyUser(account) {
const message = intl.formatMessage(messages.userUnverified, { acct: account.get('acct') });
dispatch(untagUsers([account.get('id')], ['verified'])).then(() => {
dispatch(snackbar.info(message));
}).catch(() => {});
},
}); });
export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Header)); export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Header));

@ -21,6 +21,7 @@ import {
} from 'immutable'; } from 'immutable';
import { patchMe } from 'soapbox/actions/me'; import { patchMe } from 'soapbox/actions/me';
import { unescape } from 'lodash'; import { unescape } from 'lodash';
import { isVerified } from 'soapbox/utils/accounts';
const messages = defineMessages({ const messages = defineMessages({
heading: { id: 'column.edit_profile', defaultMessage: 'Edit profile' }, heading: { id: 'column.edit_profile', defaultMessage: 'Edit profile' },
@ -161,7 +162,7 @@ class EditProfile extends ImmutablePureComponent {
render() { render() {
const { intl, maxFields, account } = this.props; const { intl, maxFields, account } = this.props;
const verified = account.getIn(['pleroma', 'tags'], ImmutableList()).includes('verified'); const verified = isVerified(account);
return ( return (
<Column icon='user' heading={intl.formatMessage(messages.heading)} backBtnSlim> <Column icon='user' heading={intl.formatMessage(messages.heading)} backBtnSlim>

@ -6,8 +6,18 @@ import {
import { CHATS_FETCH_SUCCESS, CHAT_FETCH_SUCCESS } from 'soapbox/actions/chats'; import { CHATS_FETCH_SUCCESS, CHAT_FETCH_SUCCESS } from 'soapbox/actions/chats';
import { STREAMING_CHAT_UPDATE } from 'soapbox/actions/streaming'; import { STREAMING_CHAT_UPDATE } from 'soapbox/actions/streaming';
import { normalizeAccount as normalizeAccount2 } from 'soapbox/actions/importer/normalizer'; import { normalizeAccount as normalizeAccount2 } from 'soapbox/actions/importer/normalizer';
import { Map as ImmutableMap, fromJS } from 'immutable'; import {
Map as ImmutableMap,
List as ImmutableList,
fromJS,
} from 'immutable';
import { normalizePleromaUserFields } from 'soapbox/utils/pleroma'; import { normalizePleromaUserFields } from 'soapbox/utils/pleroma';
import {
ADMIN_USERS_TAG_REQUEST,
ADMIN_USERS_TAG_FAIL,
ADMIN_USERS_UNTAG_REQUEST,
ADMIN_USERS_UNTAG_FAIL,
} from 'soapbox/actions/admin';
const initialState = ImmutableMap(); const initialState = ImmutableMap();
@ -43,6 +53,26 @@ const importAccountsFromChats = (state, chats) =>
state.withMutations(mutable => state.withMutations(mutable =>
chats.forEach(chat => importAccountFromChat(mutable, chat))); chats.forEach(chat => importAccountFromChat(mutable, chat)));
const addTags = (state, accountIds, tags) => {
return state.withMutations(state => {
accountIds.forEach(id => {
state.updateIn([id, 'pleroma', 'tags'], ImmutableList(), v =>
v.toOrderedSet().union(tags).toList(),
);
});
});
};
const removeTags = (state, accountIds, tags) => {
return state.withMutations(state => {
accountIds.forEach(id => {
state.updateIn([id, 'pleroma', 'tags'], ImmutableList(), v =>
v.toOrderedSet().subtract(tags).toList(),
);
});
});
};
export default function accounts(state = initialState, action) { export default function accounts(state = initialState, action) {
switch(action.type) { switch(action.type) {
case ACCOUNT_IMPORT: case ACCOUNT_IMPORT:
@ -58,6 +88,12 @@ export default function accounts(state = initialState, action) {
case CHAT_FETCH_SUCCESS: case CHAT_FETCH_SUCCESS:
case STREAMING_CHAT_UPDATE: case STREAMING_CHAT_UPDATE:
return importAccountsFromChats(state, [action.chat]); return importAccountsFromChats(state, [action.chat]);
case ADMIN_USERS_TAG_REQUEST:
case ADMIN_USERS_UNTAG_FAIL:
return addTags(state, action.accountIds, action.tags);
case ADMIN_USERS_UNTAG_REQUEST:
case ADMIN_USERS_TAG_FAIL:
return removeTags(state, action.accountIds, action.tags);
default: default:
return state; return state;
} }

@ -45,3 +45,7 @@ export const isLocal = account => {
let domain = account.get('acct').split('@')[1]; let domain = account.get('acct').split('@')[1];
return domain === undefined ? true : false; return domain === undefined ? true : false;
}; };
export const isVerified = account => (
account.getIn(['pleroma', 'tags'], ImmutableList()).includes('verified')
);

Loading…
Cancel
Save