From 3ad17f008feed884a410c95fbe27a5ab759ec751 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 6 Jun 2017 01:44:17 +0700 Subject: [PATCH] Refactor fetchMore updaters --- .../src/components/Comment.js | 2 + .../src/containers/Stream.js | 75 ++--------- .../coral-embed-stream/src/graphql/utils.js | 119 +++++++++++------- 3 files changed, 87 insertions(+), 109 deletions(-) diff --git a/client/coral-embed-stream/src/components/Comment.js b/client/coral-embed-stream/src/components/Comment.js index c853e5018..daefc4c4e 100644 --- a/client/coral-embed-stream/src/components/Comment.js +++ b/client/coral-embed-stream/src/components/Comment.js @@ -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(); } diff --git a/client/coral-embed-stream/src/containers/Stream.js b/client/coral-embed-stream/src/containers/Stream.js index ea42b5bd6..fa21c1ed2 100644 --- a/client/coral-embed-stream/src/containers/Stream.js +++ b/client/coral-embed-stream/src/containers/Stream.js @@ -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 diff --git a/client/coral-embed-stream/src/graphql/utils.js b/client/coral-embed-stream/src/graphql/utils.js index 3ab9c9e3b..d2a557f23 100644 --- a/client/coral-embed-stream/src/graphql/utils.js +++ b/client/coral-embed-stream/src/graphql/utils.js @@ -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)); +}