mirror of
https://github.com/wassname/talk.git
synced 2026-06-30 14:43:30 +08:00
186 lines
4.6 KiB
JavaScript
186 lines
4.6 KiB
JavaScript
import get from 'lodash/get';
|
|
import { connect } from 'react-redux';
|
|
import { bindActionCreators } from 'redux';
|
|
import { compose, gql, graphql } from 'react-apollo';
|
|
import LikeButton from '../components/LikeButton';
|
|
import withFragments from 'coral-framework/hocs/withFragments';
|
|
import { showSignInDialog } from 'coral-framework/actions/auth';
|
|
|
|
const isLikeAction = a => a.__typename === 'LikeActionSummary';
|
|
|
|
const COMMENT_FRAGMENT = gql`
|
|
fragment LikeButton_updateFragment on Comment {
|
|
action_summaries {
|
|
... on LikeActionSummary {
|
|
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 liked this comment.
|
|
const idx = data.action_summaries.findIndex(isLikeAction);
|
|
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 withPostLike = graphql(
|
|
gql`
|
|
mutation createLike($like: CreateLikeInput!) {
|
|
createLike(like: $like) {
|
|
like {
|
|
id
|
|
}
|
|
errors {
|
|
translation_key
|
|
}
|
|
}
|
|
}
|
|
`,
|
|
{
|
|
props: ({ mutate }) => ({
|
|
postLike: like => {
|
|
return mutate({
|
|
variables: { like },
|
|
optimisticResponse: {
|
|
createLike: {
|
|
__typename: 'CreateLikeResponse',
|
|
errors: null,
|
|
like: {
|
|
__typename: 'LikeAction',
|
|
id: 'pending'
|
|
}
|
|
}
|
|
},
|
|
update: (proxy, mutationResult) => {
|
|
const fragmentId = `Comment_${like.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(isLikeAction);
|
|
|
|
// Check whether we already liked 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: 'LikeActionSummary',
|
|
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.createLike.like
|
|
};
|
|
|
|
// 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 LikeButton_root on RootQuery {
|
|
me {
|
|
status
|
|
}
|
|
}
|
|
`,
|
|
comment: gql`
|
|
fragment LikeButton_comment on Comment {
|
|
action_summaries {
|
|
... on LikeActionSummary {
|
|
count
|
|
current_user {
|
|
id
|
|
}
|
|
}
|
|
}
|
|
}`
|
|
}),
|
|
connect(null, mapDispatchToProps),
|
|
withDeleteAction,
|
|
withPostLike
|
|
);
|
|
|
|
export default enhance(LikeButton);
|