Files
talk/plugins/coral-plugin-respect/client/containers/RespectButton.js
T
2017-04-25 23:00:11 +07:00

164 lines
4.3 KiB
JavaScript

import {compose, gql, graphql} from 'react-apollo';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import get from 'lodash/get';
import withFragments from 'coral-framework/hocs/withFragments';
import {showSignInDialog} from 'coral-framework/actions/auth';
import RespectButton from '../components/RespectButton';
const isRespectAction = (a) => a.__typename === 'RespectActionSummary';
const COMMENT_FRAGMENT = gql`
fragment RespectButton_updateFragment on Comment {
action_summaries {
... on RespectActionSummary {
count
current_user {
id
}
}
}
}
`;
const withDeleteAction = graphql(gql`
mutation deleteAction($id: ID!) {
deleteAction(id:$id) {
errors {
translation_key
}
}
}
`, {
props: ({mutate}) => ({
deleteAction: (id, commentId) => {
return mutate({
variables: {id},
optimisticResponse: {
deleteAction: {
__typename: 'DeleteActionResponse',
errors: null,
}
},
update: (proxy) => {
const fragmentId = `Comment_${commentId}`;
// Read the data from our cache for this query.
const data = proxy.readFragment({fragment: COMMENT_FRAGMENT, id: fragmentId});
// Check whether we respected this comment.
const idx = data.action_summaries.findIndex(isRespectAction);
if (idx < 0 || get(data.action_summaries[idx], 'current_user.id') !== id) {
return;
}
data.action_summaries[idx] = {
...data.action_summaries[idx],
count: data.action_summaries[idx].count - 1,
current_user: null,
};
// Write our data back to the cache.
proxy.writeFragment({fragment: COMMENT_FRAGMENT, id: fragmentId, data});
},
});
},
}),
});
const withPostRespect = graphql(gql`
mutation createRespect($respect: CreateRespectInput!) {
createRespect(respect: $respect) {
respect {
id
}
errors {
translation_key
}
}
}
`, {
props: ({mutate}) => ({
postRespect: (respect) => {
return mutate({
variables: {respect},
optimisticResponse: {
createRespect: {
__typename: 'CreateRespectResponse',
errors: null,
respect: {
__typename: 'RespectAction',
id: 'pending',
},
}
},
update: (proxy, mutationResult) => {
const fragmentId = `Comment_${respect.item_id}`;
// Read the data from our cache for this query.
const data = proxy.readFragment({fragment: COMMENT_FRAGMENT, id: fragmentId});
// Add our comment from the mutation to the end.
let idx = data.action_summaries.findIndex(isRespectAction);
// Check whether we already respected this comment.
if (idx >= 0 && data.action_summaries[idx].current_user) {
return;
}
if (idx < 0) {
// Add initial action when it doesn't exist.
data.action_summaries.push({
__typename: 'RespectActionSummary',
count: 0,
current_user: null,
});
idx = data.action_summaries.length - 1;
}
data.action_summaries[idx] = {
...data.action_summaries[idx],
count: data.action_summaries[idx].count + 1,
current_user: mutationResult.data.createRespect.respect,
};
// Write our data back to the cache.
proxy.writeFragment({fragment: COMMENT_FRAGMENT, id: fragmentId, data});
},
});
},
}),
});
const mapDispatchToProps = dispatch =>
bindActionCreators({showSignInDialog}, dispatch);
const enhance = compose(
withFragments({
root: gql`
fragment RespectButton_root on RootQuery {
me {
status
}
}
`,
comment: gql`
fragment RespectButton_comment on Comment {
action_summaries {
... on RespectActionSummary {
count
current_user {
id
}
}
}
}`,
}),
connect(null, mapDispatchToProps),
withDeleteAction,
withPostRespect,
);
export default enhance(RespectButton);