From c8e7ec6cbfb814c911e4587c7dc24530569a7bd0 Mon Sep 17 00:00:00 2001 From: Benjamin Goering Date: Wed, 3 May 2017 13:25:54 -0700 Subject: [PATCH] streamQuery reduces editComment mutations to reflect edits without contacting server --- .../graphql/mutations/editComment.graphql | 2 +- .../coral-framework/graphql/queries/index.js | 61 ++++++++++++++++++- package.json | 1 + yarn.lock | 6 ++ 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/client/coral-framework/graphql/mutations/editComment.graphql b/client/coral-framework/graphql/mutations/editComment.graphql index 7becd6def..e143af064 100644 --- a/client/coral-framework/graphql/mutations/editComment.graphql +++ b/client/coral-framework/graphql/mutations/editComment.graphql @@ -1,4 +1,4 @@ -mutation EditComment ($id: ID!, $edit: EditCommentInput) { +mutation editComment ($id: ID!, $edit: EditCommentInput) { editComment(id:$id, edit:$edit) { errors { translation_key diff --git a/client/coral-framework/graphql/queries/index.js b/client/coral-framework/graphql/queries/index.js index 5dbea5822..1cab53e2a 100644 --- a/client/coral-framework/graphql/queries/index.js +++ b/client/coral-framework/graphql/queries/index.js @@ -1,4 +1,5 @@ import {graphql} from 'react-apollo'; +import update from 'immutability-helper'; import STREAM_QUERY from './streamQuery.graphql'; import LOAD_MORE from './loadMore.graphql'; import GET_COUNTS from './getCounts.graphql'; @@ -139,7 +140,10 @@ export const variablesForStreamQuery = ({auth}) => { export const queryStream = graphql(STREAM_QUERY, { options: (props) => { return { - variables: variablesForStreamQuery(props) + variables: variablesForStreamQuery(props), + reducer: (previousResult, action, variables) => { + return reduceEditCommentActionsToUpdateStreamQuery(previousResult, action, variables); + }, }; }, props: ({data}) => ({ @@ -149,6 +153,61 @@ export const queryStream = graphql(STREAM_QUERY, { }) }); +/** + * Reduce editComment mutation actions + * producing a new queryStream result where asset.comments reflects the edit + */ +function reduceEditCommentActionsToUpdateStreamQuery(previousResult, action) { + if ( ! (action.type === 'APOLLO_MUTATION_RESULT' && action.operationName === 'editComment')) { + return previousResult; + } + const resultHasErrors = (result) => { + try { + return result.data.editComment.errors.length > 0; + } catch (error) { + + // expected if no errors; + return false; + } + }; + if (resultHasErrors(action.result)) { + return previousResult; + } + const {variables: {id, edit}} = action; + const updateCommentWithEdit = (comment, edit) => { + const {body} = edit; + const editedComment = update(comment, { + $merge: { + body + }, + editing: {$merge:{edited:true}} + }); + return editedComment; + }; + const resultReflectingEdit = update(previousResult, { + asset: { + comments: { + $apply: comments => comments.map(comment => { + if (comment.id === id) { + return updateCommentWithEdit(comment, edit); + } + return update(comment, { + replies: { + $apply: (comments) => comments.map(comment => { + if (comment.id === id) { + return updateCommentWithEdit(comment, edit); + } + return comment; + }) + }, + }); + }) + } + } + }); + return resultReflectingEdit; +} + export const myCommentHistory = graphql(MY_COMMENT_HISTORY, {}); export const myIgnoredUsers = graphql(MY_IGNORED_USERS, { diff --git a/package.json b/package.json index 87ab01076..9db7fa033 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "graphql-server-express": "^0.5.0", "graphql-tools": "^0.9.0", "helmet": "^3.5.0", + "immutability-helper": "^2.2.0", "inquirer": "^3.0.6", "joi": "^10.4.1", "jsonwebtoken": "^7.3.0", diff --git a/yarn.lock b/yarn.lock index adb8ea366..3acfb232b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3819,6 +3819,12 @@ ignore@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.2.tgz#1c51e1ef53bab6ddc15db4d9ac4ec139eceb3410" +immutability-helper: + version "2.2.0" + resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-2.2.0.tgz#c4385ad4f68315843efaf0cff3575ee82ffa405f" + dependencies: + invariant "^2.2.0" + immutable@^3.8.1: version "3.8.1" resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.1.tgz#200807f11ab0f72710ea485542de088075f68cd2"