Refactor fetchMore updaters

This commit is contained in:
Chi Vinh Le
2017-06-06 01:44:17 +07:00
parent 9993350b7e
commit 3ad17f008f
3 changed files with 87 additions and 109 deletions
@@ -115,6 +115,7 @@ class Comment extends React.Component {
componentWillAppear(callback) {
callback();
}
componentWillEnter(callback) {
callback();
const userId = this.props.currentUser ? this.props.currentUser.id : null;
@@ -130,6 +131,7 @@ class Comment extends React.Component {
}
this.setState({animateEnter: true});
}
componentWillLeave(callback) {
callback();
}
@@ -7,7 +7,6 @@ import {
withPostComment, withPostFlag, withPostDontAgree, withDeleteAction,
withAddCommentTag, withRemoveCommentTag, withIgnoreUser, withEditComment,
} from 'coral-framework/graphql/mutations';
import update from 'immutability-helper';
import {notificationActions, authActions} from 'coral-framework';
import {editName} from 'coral-framework/actions/user';
@@ -16,7 +15,12 @@ import Stream from '../components/Stream';
import Comment from './Comment';
import {withFragments} from 'coral-framework/hocs';
import {getDefinitionName} from 'coral-framework/utils';
import {findCommentInEmbedQuery, insertCommentIntoEmbedQuery, removeCommentFromEmbedQuery} from '../graphql/utils';
import {
findCommentInEmbedQuery,
insertCommentIntoEmbedQuery,
removeCommentFromEmbedQuery,
insertFetchedCommentsIntoEmbedQuery,
} from '../graphql/utils';
const {showSignInDialog} = authActions;
const {addNotification} = notificationActions;
@@ -92,50 +96,7 @@ class StreamContainer extends React.Component {
excludeIgnored: this.props.data.variables.excludeIgnored,
},
updateQuery: (prev, {fetchMoreResult:{comments}}) => {
if (!comments.nodes.length) {
return prev;
}
const updateNode = (node) =>
update(node, {
replies: {
endCursor: {$set: comments.endCursor},
nodes: {$apply: (nodes) => nodes
.concat(comments.nodes.filter(
(comment) => !nodes.some((node) => node.id === comment.id)
))
.sort(ascending)
},
},
});
// highlighted comment.
if (prev.comment) {
if (prev.comment.parent) {
return update(prev, {
comment: {
parent: {$apply: (comment) => updateNode(comment)},
}
});
}
return update(prev, {
comment: {$apply: (comment) => updateNode(comment)},
});
}
return update(prev, {
asset: {
comments: {
nodes: {
$apply: (nodes) => nodes.map(
(node) => node.id !== parent_id
? node
: updateNode(node)
)
},
},
},
});
return insertFetchedCommentsIntoEmbedQuery(prev, comments, parent_id);
},
});
}
@@ -152,19 +113,7 @@ class StreamContainer extends React.Component {
excludeIgnored: this.props.data.variables.excludeIgnored,
},
updateQuery: (prev, {fetchMoreResult:{comments}}) => {
if (!comments.nodes.length) {
return prev;
}
return update(prev, {
asset: {
comments: {
hasNextPage: {$set: comments.hasNextPage},
endCursor: {$set: comments.endCursor},
nodes: {$push: comments.nodes},
},
},
});
return insertFetchedCommentsIntoEmbedQuery(prev, comments);
},
});
};
@@ -187,14 +136,6 @@ class StreamContainer extends React.Component {
}
}
const ascending = (a, b) => {
const dateA = new Date(a.created_at);
const dateB = new Date(b.created_at);
if (dateA < dateB) { return -1; }
if (dateA > dateB) { return 1; }
return 0;
};
const commentFragment = gql`
fragment CoralEmbedStream_Stream_comment on Comment {
id
+77 -42
View File
@@ -1,7 +1,29 @@
import update from 'immutability-helper';
function applyToCommentsOrigin(root, callback) {
if (root.comment) {
if (root.comment.parent) {
return update(root, {
comment: {
parent: {
$apply: (node) => callback(node),
},
},
});
}
return update(root, {
comment: {
$apply: (node) => callback(node),
},
});
}
return update(root, {
asset: {$apply: (asset) => callback(asset)},
});
}
function findAndInsertComment(parent, comment) {
const [connectionField, countField, action] = parent.comments
const [connectionField, countField, action] = parent.__typename === 'Asset'
? ['comments', 'commentCount', '$unshift']
: ['replies', 'replyCount', '$push'];
@@ -35,30 +57,11 @@ export function insertCommentIntoEmbedQuery(root, comment) {
totalCommentCount: {$apply: (c) => c + 1},
},
});
if (root.comment) {
if (root.comment.parent) {
return update(root, {
comment: {
parent: {
$apply: (node) => findAndInsertComment(node, comment),
},
},
});
}
return update(root, {
comment: {
$apply: (node) => findAndInsertComment(node, comment),
},
});
}
return update(root, {
asset: {$apply: (asset) => findAndInsertComment(asset, comment)},
});
return applyToCommentsOrigin(root, (origin) => findAndInsertComment(origin, comment));
}
function findAndRemoveComment(parent, id) {
const [connectionField, countField] = parent.comments
const [connectionField, countField] = parent.__typename === 'Asset'
? ['comments', 'commentCount']
: ['replies', 'replyCount'];
@@ -91,26 +94,7 @@ export function removeCommentFromEmbedQuery(root, id) {
totalCommentCount: {$apply: (c) => c - 1},
},
});
if (root.comment) {
if (root.comment.parent) {
return update(root, {
comment: {
parent: {
$apply: (node) => findAndRemoveComment(node, id),
},
},
});
}
return update(root, {
comment: {
$apply: (node) => findAndRemoveComment(node, id),
},
});
}
return update(root, {
asset: {$apply: (asset) => findAndRemoveComment(asset, id)},
});
return applyToCommentsOrigin(root, (origin) => findAndRemoveComment(origin, id));
}
function findComment(nodes, callback) {
@@ -147,3 +131,54 @@ export function findCommentInEmbedQuery(root, callbackOrId) {
}
return findComment(root.asset.comments.nodes, callback);
}
const ascending = (a, b) => {
const dateA = new Date(a.created_at);
const dateB = new Date(b.created_at);
if (dateA < dateB) { return -1; }
if (dateA > dateB) { return 1; }
return 0;
};
function findAndInsertFetchedComments(parent, comments, parent_id) {
const isAsset = parent.__typename === 'Asset';
const connectionField = isAsset ? 'comments' : 'replies';
if (!parent_id && connectionField === 'comments' || parent.id === parent_id) {
return update(parent, {
[connectionField]: {
hasNextPage: {$set: comments.hasNextPage},
endCursor: {$set: comments.endCursor},
nodes: {$apply: (nodes) => {
if (isAsset) {
return nodes.concat(comments.nodes);
}
return nodes
.concat(comments.nodes.filter(
(comment) => !nodes.some((node) => node.id === comment.id)
))
.sort(ascending);
}},
},
});
}
const connection = parent[connectionField];
if (!connection) {
return parent;
}
return update(parent, {
[connectionField]: {
nodes: {
$apply: (nodes) =>
nodes.map((node) => findAndInsertFetchedComments(node, comments, parent_id))
},
},
});
}
export function insertFetchedCommentsIntoEmbedQuery(root, comments, parent_id) {
if (!comments.nodes.length) {
return root;
}
return applyToCommentsOrigin(root, (origin) => findAndInsertFetchedComments(origin, comments, parent_id));
}