mirror of
https://github.com/wassname/talk.git
synced 2026-07-27 11:28:12 +08:00
Add stopIgnoringUser mutation and Embed uses it
This commit is contained in:
@@ -15,7 +15,7 @@ import {NEW_COMMENT_COUNT_POLL_INTERVAL} from 'coral-framework/constants/comment
|
||||
|
||||
import {queryStream} from 'coral-framework/graphql/queries';
|
||||
import {postComment, postFlag, postLike, postDontAgree, deleteAction, addCommentTag, removeCommentTag, ignoreUser} from 'coral-framework/graphql/mutations';
|
||||
import {editName, ignoreUserSuccess} from 'coral-framework/actions/user';
|
||||
import {editName} from 'coral-framework/actions/user';
|
||||
import {updateCountCache, viewAllComments} from 'coral-framework/actions/asset';
|
||||
import {notificationActions, authActions, assetActions, pym} from 'coral-framework';
|
||||
|
||||
@@ -117,15 +117,6 @@ class Embed extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
ignoreUser = async ({id}) => {
|
||||
const {ignoreUser, dispatch} = this.props;
|
||||
await ignoreUser({id});
|
||||
|
||||
// dispatch ignoreUserSuccess so other reducers can know about the newly
|
||||
// ignored user (e.g. to hide coments by that user)
|
||||
dispatch(ignoreUserSuccess({id}));
|
||||
}
|
||||
|
||||
render () {
|
||||
const {activeTab} = this.state;
|
||||
const {closedAt, countCache = {}} = this.props.asset;
|
||||
@@ -264,7 +255,7 @@ class Embed extends Component {
|
||||
postDontAgree={this.props.postDontAgree}
|
||||
addCommentTag={this.props.addCommentTag}
|
||||
removeCommentTag={this.props.removeCommentTag}
|
||||
ignoreUser={this.ignoreUser}
|
||||
ignoreUser={this.props.ignoreUser}
|
||||
loadMore={this.props.loadMore}
|
||||
deleteAction={this.props.deleteAction}
|
||||
showSignInDialog={this.props.showSignInDialog}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {addNotification} from '../actions/notification';
|
||||
import coralApi from '../helpers/response';
|
||||
import * as actions from '../constants/auth';
|
||||
import {IGNORE_USER_SUCCESS} from '../constants/user';
|
||||
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from './../translations';
|
||||
@@ -20,6 +19,3 @@ export const editName = (username) => (dispatch) => {
|
||||
dispatch(editUsernameFailure(lang.t(`error.${error.translation_key}`)));
|
||||
});
|
||||
};
|
||||
|
||||
// a user was successfully ignored
|
||||
export const ignoreUserSuccess = ({id}) => ({type: IGNORE_USER_SUCCESS, id});
|
||||
|
||||
@@ -7,3 +7,4 @@ export const COMMENTS_BY_USER_FAILURE = 'COMMENTS_BY_USER_FAILURE';
|
||||
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
|
||||
export const UPDATE_USERNAME = 'UPDATE_USERNAME';
|
||||
export const IGNORE_USER_SUCCESS = 'IGNORE_USER_SUCCESS';
|
||||
export const STOP_IGNORING_USER_SUCCESS = 'STOP_IGNORING_USER_SUCCESS';
|
||||
|
||||
@@ -7,6 +7,9 @@ import DELETE_ACTION from './deleteAction.graphql';
|
||||
import ADD_COMMENT_TAG from './addCommentTag.graphql';
|
||||
import REMOVE_COMMENT_TAG from './removeCommentTag.graphql';
|
||||
import IGNORE_USER from './ignoreUser.graphql';
|
||||
import STOP_IGNORING_USER from './stopIgnoringUser.graphql';
|
||||
|
||||
import MY_IGNORED_USERS from '../queries/myIgnoredUsers.graphql';
|
||||
|
||||
import commentView from '../fragments/commentView.graphql';
|
||||
|
||||
@@ -156,7 +159,24 @@ export const ignoreUser = graphql(IGNORE_USER, {
|
||||
return mutate({
|
||||
variables: {
|
||||
id,
|
||||
}
|
||||
},
|
||||
refetchQueries: [{
|
||||
query: MY_IGNORED_USERS,
|
||||
}]
|
||||
});
|
||||
}}),
|
||||
});
|
||||
|
||||
export const stopIgnoringUser = graphql(STOP_IGNORING_USER, {
|
||||
props: ({mutate}) => ({
|
||||
stopIgnoringUser: ({id}) => {
|
||||
return mutate({
|
||||
variables: {
|
||||
id,
|
||||
},
|
||||
refetchQueries: [{
|
||||
query: MY_IGNORED_USERS,
|
||||
}]
|
||||
});
|
||||
}}),
|
||||
});
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
mutation stopIgnoringUser ($id: ID!) {
|
||||
stopIgnoringUser(id:$id) {
|
||||
errors {
|
||||
translation_key
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,9 +39,14 @@ export default function user (state = initialState, action) {
|
||||
return state.set('myAssets', action.assets);
|
||||
case actions.LOGOUT_SUCCESS:
|
||||
return initialState;
|
||||
case actions.IGNORE_USER_SUCCESS:
|
||||
return state.updateIn(['ignoredUsers'], i => i.add(action.id));
|
||||
default :
|
||||
return state;
|
||||
case 'APOLLO_MUTATION_RESULT':
|
||||
switch (action.operationName) {
|
||||
case 'ignoreUser':
|
||||
return state.updateIn(['ignoredUsers'], i => i.add(action.variables.id));
|
||||
case 'stopIgnoringUser':
|
||||
return state.updateIn(['ignoredUsers'], i => i.delete(action.variables.id));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
import React, {Component} from 'react';
|
||||
import React, {Component, PropTypes} from 'react';
|
||||
|
||||
import styles from './IgnoredUsers.css';
|
||||
|
||||
export class IgnoredUsers extends Component {
|
||||
static propTypes = {
|
||||
users: PropTypes.arrayOf(PropTypes.shape({
|
||||
username: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
})).isRequired,
|
||||
|
||||
// accepts { id }
|
||||
stopIgnoring: PropTypes.func.isRequired,
|
||||
}
|
||||
render() {
|
||||
const {users} = this.props;
|
||||
const {users, stopIgnoring} = this.props;
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
@@ -15,10 +24,12 @@ export class IgnoredUsers extends Component {
|
||||
<dl className={styles.ignoredUserList}>
|
||||
{
|
||||
users.map(({username, id}) => (
|
||||
<span className={styles.ignoredUser}>
|
||||
<span className={styles.ignoredUser} key={id}>
|
||||
<dt key={id}>{ username }</dt>
|
||||
<dd className={styles.stopListening}>
|
||||
<a className={styles.link}>Stop ignoring</a>
|
||||
<a
|
||||
onClick={() => stopIgnoring({id})}
|
||||
className={styles.link}>Stop ignoring</a>
|
||||
</dd>
|
||||
</span>
|
||||
))
|
||||
|
||||
@@ -4,6 +4,7 @@ import React, {Component} from 'react';
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
|
||||
import {myCommentHistory, myIgnoredUsers} from 'coral-framework/graphql/queries';
|
||||
import {stopIgnoringUser} from 'coral-framework/graphql/mutations';
|
||||
|
||||
import {link} from 'coral-framework/services/PymConnection';
|
||||
import NotLoggedIn from '../components/NotLoggedIn';
|
||||
@@ -31,7 +32,7 @@ class ProfileContainer extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const {loggedIn, asset, showSignInDialog, data, myIgnoredUsersData} = this.props;
|
||||
const {loggedIn, asset, showSignInDialog, data, myIgnoredUsersData, stopIgnoringUser} = this.props;
|
||||
const {me} = this.props.data;
|
||||
|
||||
if (!loggedIn || !me) {
|
||||
@@ -60,6 +61,7 @@ class ProfileContainer extends Component {
|
||||
<h3>Ignored users</h3>
|
||||
<IgnoredUsers
|
||||
users={myIgnoredUsersData.myIgnoredUsers}
|
||||
stopIgnoring={stopIgnoringUser}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
@@ -100,4 +102,5 @@ export default compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
myCommentHistory,
|
||||
myIgnoredUsers,
|
||||
stopIgnoringUser,
|
||||
)(ProfileContainer);
|
||||
|
||||
@@ -17,12 +17,18 @@ const ignoreUser = async ({user}, userToIgnore) => {
|
||||
return await UsersService.ignoreUsers(user.id, [userToIgnore.id]);
|
||||
};
|
||||
|
||||
const stopIgnoringUser = async ({user}, userToStopIgnoring) => {
|
||||
console.log('stopIgnoringUser!!');
|
||||
return await UsersService.stopIgnoringUsers(user.id, [userToStopIgnoring.id]);
|
||||
};
|
||||
|
||||
module.exports = (context) => {
|
||||
let mutators = {
|
||||
User: {
|
||||
setUserStatus: () => Promise.reject(errors.ErrNotAuthorized),
|
||||
suspendUser: () => Promise.reject(errors.ErrNotAuthorized),
|
||||
ignoreUser: (action) => ignoreUser(context, action),
|
||||
stopIgnoringUser: (action) => stopIgnoringUser(context, action),
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@ const RootMutation = {
|
||||
ignoreUser(_, {id}, {mutators: {User}}) {
|
||||
return wrapResponse(null)(User.ignoreUser({id}));
|
||||
},
|
||||
stopIgnoringUser(_, {id}, {mutators: {User}}) {
|
||||
return wrapResponse(null)(User.stopIgnoringUser({id}));
|
||||
},
|
||||
setCommentStatus(_, {id, status}, {mutators: {Comment}}) {
|
||||
return wrapResponse(null)(Comment.setCommentStatus({id, status}));
|
||||
},
|
||||
|
||||
@@ -712,6 +712,11 @@ type IgnoreUserResponse implements Response {
|
||||
errors: [UserError]
|
||||
}
|
||||
|
||||
# Response to stopIgnoringUser mutation
|
||||
type StopIgnoringUserResponse implements Response {
|
||||
# An array of errors relating to the mutation that occured.
|
||||
errors: [UserError]
|
||||
}
|
||||
|
||||
# All mutations for the application are defined on this object.
|
||||
type RootMutation {
|
||||
@@ -748,6 +753,9 @@ type RootMutation {
|
||||
|
||||
# Ignore comments by another user
|
||||
ignoreUser(id: ID!): IgnoreUserResponse
|
||||
|
||||
# Stop Ignoring comments by another user
|
||||
stopIgnoringUser(id: ID!): StopIgnoringUserResponse
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -854,4 +854,20 @@ module.exports = class UsersService {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop ignoring other users
|
||||
* @param {String} userId the id of the user that is ignoring another users
|
||||
* @param {String[]} usersToStopIgnoring Array of user IDs to stop ignoring
|
||||
*/
|
||||
static async stopIgnoringUsers(userId, usersToStopIgnoring) {
|
||||
assert(Array.isArray(usersToStopIgnoring), 'usersToStopIgnoring is an array');
|
||||
assert(usersToStopIgnoring.every(u => typeof u === 'string'), 'usersToStopIgnoring is an array of string user IDs');
|
||||
await UserModel.update({id: userId}, {
|
||||
$pullAll: {
|
||||
ignoresUsers: usersToStopIgnoring
|
||||
}
|
||||
});
|
||||
console.log('Mongo wrote stopIgnoringUsers', usersToStopIgnoring);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,30 +6,30 @@ const Context = require('../../../graph/context');
|
||||
const UsersService = require('../../../services/users');
|
||||
const SettingsService = require('../../../services/settings');
|
||||
|
||||
const ignoreUserMutation = `
|
||||
mutation ignoreUser ($id: ID!) {
|
||||
ignoreUser(id:$id) {
|
||||
errors {
|
||||
translation_key
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const getMyIgnoredUsersQuery = `
|
||||
query myIgnoredUsers {
|
||||
myIgnoredUsers {
|
||||
id,
|
||||
username
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
describe('graph.mutations.ignoreUser', () => {
|
||||
beforeEach(async () => {
|
||||
await SettingsService.init();
|
||||
});
|
||||
|
||||
const ignoreUserMutation = `
|
||||
mutation ignoreUser ($id: ID!) {
|
||||
ignoreUser(id:$id) {
|
||||
errors {
|
||||
translation_key
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const getMyIgnoredUsersQuery = `
|
||||
query myIgnoredUsers {
|
||||
myIgnoredUsers {
|
||||
id,
|
||||
username
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
// @TODO (bengo) - test a user can't ignore themselves
|
||||
it('users can ignoreUser', async () => {
|
||||
const user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
|
||||
@@ -54,3 +54,60 @@ describe('graph.mutations.ignoreUser', () => {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('graph.mutations.stopIgnoringUser', () => {
|
||||
beforeEach(async () => {
|
||||
await SettingsService.init();
|
||||
});
|
||||
|
||||
it('users can stop ignoring another user they ignore', async () => {
|
||||
|
||||
// We're going to ignore 2 users,
|
||||
// then stopIgnoring 1 of them
|
||||
// then assert myIgnoredUsers only lists the one remaining
|
||||
const user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
|
||||
const usersToIgnore = await Promise.all([
|
||||
UsersService.createLocalUser('usernameB@example.com', 'password', 'usernameB'),
|
||||
UsersService.createLocalUser('usernameC@example.com', 'password', 'usernameC'),
|
||||
]);
|
||||
const context = new Context({user});
|
||||
|
||||
// ignore two users
|
||||
const ignoreUserResponses = await Promise.all(usersToIgnore.map(u => graphql(schema, ignoreUserMutation, {}, context, {id: u.id})));
|
||||
ignoreUserResponses.forEach(response => {
|
||||
if (response.errors && response.errors.length) {
|
||||
console.error(response.errors);
|
||||
}
|
||||
expect(response.errors).to.be.empty;
|
||||
});
|
||||
|
||||
const stopIgnoringUserMutation = `
|
||||
mutation stopIgnoringUser ($id: ID!) {
|
||||
stopIgnoringUser(id:$id) {
|
||||
errors {
|
||||
translation_key
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
// stop ignoring one user
|
||||
const stopIgnoringUserResponse = await graphql(schema, stopIgnoringUserMutation, {}, context, {id: usersToIgnore[0].id});
|
||||
if (stopIgnoringUserResponse.errors && stopIgnoringUserResponse.errors.length) {
|
||||
console.error(stopIgnoringUserResponse.errors);
|
||||
}
|
||||
expect(stopIgnoringUserResponse.errors).to.be.empty;
|
||||
|
||||
// now check my ignored users
|
||||
const myIgnoredUsersResponse = await graphql(schema, getMyIgnoredUsersQuery, {}, context, {});
|
||||
if (myIgnoredUsersResponse.errors && myIgnoredUsersResponse.errors.length) {
|
||||
console.error(myIgnoredUsersResponse.errors);
|
||||
}
|
||||
expect(myIgnoredUsersResponse.errors).to.be.empty;
|
||||
const myIgnoredUsers = myIgnoredUsersResponse.data.myIgnoredUsers;
|
||||
expect(myIgnoredUsers.length).to.equal(1);
|
||||
expect(myIgnoredUsers[0].id).to.equal(usersToIgnore[1].id);
|
||||
expect(myIgnoredUsers[0].username).to.equal(usersToIgnore[1].username);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user