From 686eb614f7a61356ce889f6a6b389aedb564ca4a Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 17 Aug 2017 16:43:55 -0600 Subject: [PATCH] changed cursor to Cursor scalar type, changed SORT_ORDER --- .../coral-admin/src/containers/UserDetail.js | 2 +- client/coral-admin/src/reducers/moderation.js | 2 +- .../Moderation/components/ModerationMenu.js | 4 +-- .../Moderation/containers/Moderation.js | 2 +- .../src/routes/Moderation/graphql.js | 4 +-- .../src/containers/Stream.js | 6 ++-- client/coral-framework/utils/index.js | 6 ++-- .../containers/ProfileContainer.js | 4 +-- graph/loaders/comments.js | 8 ++--- graph/loaders/users.js | 4 +-- graph/resolvers/cursor.js | 35 +++++++++++++++++++ graph/resolvers/index.js | 6 ++-- graph/typeDefs.graphql | 23 ++++++------ .../client/containers/TabPane.js | 6 ++-- .../client/index.js | 2 +- 15 files changed, 77 insertions(+), 37 deletions(-) create mode 100644 graph/resolvers/cursor.js diff --git a/client/coral-admin/src/containers/UserDetail.js b/client/coral-admin/src/containers/UserDetail.js index 2ae6e4c9c..edde4b585 100644 --- a/client/coral-admin/src/containers/UserDetail.js +++ b/client/coral-admin/src/containers/UserDetail.js @@ -124,7 +124,7 @@ class UserDetailContainer extends React.Component { } const LOAD_MORE_QUERY = gql` - query CoralAdmin_Moderation_LoadMore($limit: Int = 10, $cursor: Date, $author_id: ID!, $statuses: [COMMENT_STATUS!]) { + query CoralAdmin_Moderation_LoadMore($limit: Int = 10, $cursor: Cursor, $author_id: ID!, $statuses: [COMMENT_STATUS!]) { comments(query: {limit: $limit, cursor: $cursor, author_id: $author_id, statuses: $statuses}) { ...CoralAdmin_Moderation_CommentConnection } diff --git a/client/coral-admin/src/reducers/moderation.js b/client/coral-admin/src/reducers/moderation.js index e0a608488..cf08bda60 100644 --- a/client/coral-admin/src/reducers/moderation.js +++ b/client/coral-admin/src/reducers/moderation.js @@ -6,7 +6,7 @@ const initialState = { storySearchVisible: false, storySearchString: '', shortcutsNoteVisible: window.localStorage.getItem('coral:shortcutsNote') || 'show', - sortOrder: 'REVERSE_CHRONOLOGICAL', + sortOrder: 'DESC', }; export default function moderation (state = initialState, action) { diff --git a/client/coral-admin/src/routes/Moderation/components/ModerationMenu.js b/client/coral-admin/src/routes/Moderation/components/ModerationMenu.js index 7b427ac54..a28e90c65 100644 --- a/client/coral-admin/src/routes/Moderation/components/ModerationMenu.js +++ b/client/coral-admin/src/routes/Moderation/components/ModerationMenu.js @@ -36,8 +36,8 @@ const ModerationMenu = ({ label="Sort" value={sort} onChange={(sort) => selectSort(sort)}> - - + + diff --git a/client/coral-admin/src/routes/Moderation/containers/Moderation.js b/client/coral-admin/src/routes/Moderation/containers/Moderation.js index d5ca5c840..ba8a80677 100644 --- a/client/coral-admin/src/routes/Moderation/containers/Moderation.js +++ b/client/coral-admin/src/routes/Moderation/containers/Moderation.js @@ -279,7 +279,7 @@ const COMMENT_REJECTED_SUBSCRIPTION = gql` `; const LOAD_MORE_QUERY = gql` - query CoralAdmin_Moderation_LoadMore($limit: Int = 10, $cursor: Date, $sort: SORT_ORDER, $asset_id: ID, $statuses:[COMMENT_STATUS!], $action_type: ACTION_TYPE) { + query CoralAdmin_Moderation_LoadMore($limit: Int = 10, $cursor: Cursor, $sort: SORT_ORDER, $asset_id: ID, $statuses:[COMMENT_STATUS!], $action_type: ACTION_TYPE) { comments(query: {limit: $limit, cursor: $cursor, asset_id: $asset_id, statuses: $statuses, sort: $sort, action_type: $action_type}) { nodes { ...${getDefinitionName(Comment.fragments.comment)} diff --git a/client/coral-admin/src/routes/Moderation/graphql.js b/client/coral-admin/src/routes/Moderation/graphql.js index 0d4991f72..e3dac8e8f 100644 --- a/client/coral-admin/src/routes/Moderation/graphql.js +++ b/client/coral-admin/src/routes/Moderation/graphql.js @@ -36,7 +36,7 @@ function shouldCommentBeAdded(root, queue, comment, sort) { return true; } const cursor = new Date(root[queue].endCursor); - return sort === 'CHRONOLOGICAL' + return sort === 'ASC' ? new Date(comment.created_at) <= cursor : new Date(comment.created_at) >= cursor; } @@ -46,7 +46,7 @@ function addCommentToQueue(root, queue, comment, sort) { return root; } - const sortAlgo = sort === 'CHRONOLOGICAL' ? ascending : descending; + const sortAlgo = sort === 'ASC' ? ascending : descending; const changes = { [`${queue}Count`]: {$set: root[`${queue}Count`] + 1}, }; diff --git a/client/coral-embed-stream/src/containers/Stream.js b/client/coral-embed-stream/src/containers/Stream.js index 451b115a9..de05f27b6 100644 --- a/client/coral-embed-stream/src/containers/Stream.js +++ b/client/coral-embed-stream/src/containers/Stream.js @@ -102,7 +102,7 @@ class StreamContainer extends React.Component { cursor: comment.replies.endCursor, parent_id, asset_id: this.props.root.asset.id, - sort: 'CHRONOLOGICAL', + sort: 'ASC', excludeIgnored: this.props.data.variables.excludeIgnored, }, updateQuery: (prev, {fetchMoreResult:{comments}}) => { @@ -119,7 +119,7 @@ class StreamContainer extends React.Component { cursor: this.props.root.asset.comments.endCursor, parent_id: null, asset_id: this.props.root.asset.id, - sort: 'REVERSE_CHRONOLOGICAL', + sort: 'DESC', excludeIgnored: this.props.data.variables.excludeIgnored, }, updateQuery: (prev, {fetchMoreResult:{comments}}) => { @@ -202,7 +202,7 @@ const COMMENTS_EDITED_SUBSCRIPTION = gql` `; const LOAD_MORE_QUERY = gql` - query CoralEmbedStream_LoadMoreComments($limit: Int = 5, $cursor: Date, $parent_id: ID, $asset_id: ID, $sort: SORT_ORDER, $excludeIgnored: Boolean) { + query CoralEmbedStream_LoadMoreComments($limit: Int = 5, $cursor: Cursor, $parent_id: ID, $asset_id: ID, $sort: SORT_ORDER, $excludeIgnored: Boolean) { comments(query: {limit: $limit, cursor: $cursor, parent_id: $parent_id, asset_id: $asset_id, sort: $sort, excludeIgnored: $excludeIgnored}) { nodes { id diff --git a/client/coral-framework/utils/index.js b/client/coral-framework/utils/index.js index 63dfd7dc4..84249667d 100644 --- a/client/coral-framework/utils/index.js +++ b/client/coral-framework/utils/index.js @@ -156,12 +156,12 @@ const ascending = (a, b) => { const descending = (a, b) => ascending(a, b) * -1; -export function insertCommentsSorted(nodes, comments, sortOrder = 'CHRONOLOGICAL') { +export function insertCommentsSorted(nodes, comments, sortOrder = 'ASC') { const added = nodes.concat(comments); - if (sortOrder === 'CHRONOLOGICAL') { + if (sortOrder === 'ASC') { return added.sort(ascending); } - if (sortOrder === 'REVERSE_CHRONOLOGICAL') { + if (sortOrder === 'DESC') { return added.sort(descending); } throw new Error(`Unknown sort order ${sortOrder}`); diff --git a/client/coral-settings/containers/ProfileContainer.js b/client/coral-settings/containers/ProfileContainer.js index e33c0b6cd..920f50e73 100644 --- a/client/coral-settings/containers/ProfileContainer.js +++ b/client/coral-settings/containers/ProfileContainer.js @@ -38,7 +38,7 @@ class ProfileContainer extends Component { me: { comments: { nodes: { - $apply: (nodes) => insertCommentsSorted(nodes, comments.nodes, 'REVERSE_CHRONOLOGICAL'), + $apply: (nodes) => insertCommentsSorted(nodes, comments.nodes, 'DESC'), }, hasNextPage: {$set: comments.hasNextPage}, endCursor: {$set: comments.endCursor}, @@ -112,7 +112,7 @@ const CommentFragment = gql` `; const LOAD_MORE_QUERY = gql` - query TalkSettings_LoadMoreComments($limit: Int, $cursor: Date) { + query TalkSettings_LoadMoreComments($limit: Int, $cursor: Cursor) { comments(query: {limit: $limit, cursor: $cursor}) { ...TalkSettings_CommentConnectionFragment } diff --git a/graph/loaders/comments.js b/graph/loaders/comments.js index 7a17cfabd..0df73e970 100644 --- a/graph/loaders/comments.js +++ b/graph/loaders/comments.js @@ -312,7 +312,7 @@ const getCommentsByQuery = async ({user}, {ids, statuses, asset_id, parent_id, a } if (cursor) { - if (sort === 'REVERSE_CHRONOLOGICAL') { + if (sort === 'DESC') { comments = comments.where({ created_at: { $lt: cursor @@ -328,7 +328,7 @@ const getCommentsByQuery = async ({user}, {ids, statuses, asset_id, parent_id, a } let query = comments - .sort({created_at: sort === 'REVERSE_CHRONOLOGICAL' ? -1 : 1}); + .sort({created_at: sort === 'DESC' ? -1 : 1}); if (limit) { query = query.limit(limit + 1); } @@ -363,7 +363,7 @@ const genRecentReplies = (context, ids) => { } }}, - // sort these by their created at timestamp, CHRONOLOGICAL'y as these are + // sort these by their created at timestamp, ASC'y as these are // replies {$sort: { created_at: 1 @@ -413,7 +413,7 @@ const genRecentComments = (_, ids) => { } }}, - // sort these by their created at timestamp, CHRONOLOGICAL'y as these are + // sort these by their created at timestamp, ASC'y as these are // replies {$sort: { created_at: 1 diff --git a/graph/loaders/users.js b/graph/loaders/users.js index c4850eaf0..fe7a6285d 100644 --- a/graph/loaders/users.js +++ b/graph/loaders/users.js @@ -36,7 +36,7 @@ const getUsersByQuery = ({user}, {ids, limit, cursor, statuses = null, sort}) => } if (cursor) { - if (sort === 'REVERSE_CHRONOLOGICAL') { + if (sort === 'DESC') { users = users.where({ created_at: { $lt: cursor @@ -52,7 +52,7 @@ const getUsersByQuery = ({user}, {ids, limit, cursor, statuses = null, sort}) => } return users - .sort({created_at: sort === 'REVERSE_CHRONOLOGICAL' ? -1 : 1}) + .sort({created_at: sort === 'DESC' ? -1 : 1}) .limit(limit); }; diff --git a/graph/resolvers/cursor.js b/graph/resolvers/cursor.js new file mode 100644 index 000000000..2e7fec605 --- /dev/null +++ b/graph/resolvers/cursor.js @@ -0,0 +1,35 @@ +const GraphQLScalarType = require('graphql').GraphQLScalarType; +const Kind = require('graphql/language').Kind; + +module.exports = new GraphQLScalarType({ + name: 'Cursor', + description: 'Cursor represents a paginating cursor.', + serialize(value) { + if (value instanceof Date) { + return value.toISOString(); + } + + return value; + }, + parseValue(value) { + if (typeof value === 'string') { + return new Date(value); + } + + return value; + }, + parseLiteral(ast) { + switch (ast.kind) { + case Kind.STRING: + + // This handles an empty string. + if (ast.value && ast.value.length === 0) { + return null; + } + + return new Date(ast.value); + default: + return ast.value; + } + } +}); diff --git a/graph/resolvers/index.js b/graph/resolvers/index.js index 850a2f15a..69ae9ca3e 100644 --- a/graph/resolvers/index.js +++ b/graph/resolvers/index.js @@ -5,8 +5,9 @@ const ActionSummary = require('./action_summary'); const Action = require('./action'); const AssetActionSummary = require('./asset_action_summary'); const Asset = require('./asset'); -const Comment = require('./comment'); const CommentStatusHistory = require('./comment_status_history'); +const Comment = require('./comment'); +const Cursor = require('./cursor'); const Date = require('./date'); const FlagActionSummary = require('./flag_action_summary'); const FlagAction = require('./flag_action'); @@ -31,8 +32,9 @@ let resolvers = { Action, AssetActionSummary, Asset, - Comment, CommentStatusHistory, + Comment, + Cursor, Date, FlagActionSummary, FlagAction, diff --git a/graph/typeDefs.graphql b/graph/typeDefs.graphql index d2c1ffe1f..505026389 100644 --- a/graph/typeDefs.graphql +++ b/graph/typeDefs.graphql @@ -5,6 +5,9 @@ # Date represented as an ISO8601 string. scalar Date +# Cursor represents a paginating cursor. +scalar Cursor + ################################################################################ ## Reliability ################################################################################ @@ -126,10 +129,10 @@ input UsersQuery { limit: Int = 10 # Skip results from the last created_at timestamp. - cursor: Date + cursor: Cursor # Sort the results by created_at. - sort: SORT_ORDER = REVERSE_CHRONOLOGICAL + sort: SORT_ORDER = DESC } # AssetsQuery allows teh ability to query assets by specific fields @@ -241,10 +244,10 @@ input CommentsQuery { limit: Int = 10 # Skip results from the last created_at timestamp. - cursor: Date + cursor: Cursor # Sort the results by created_at. - sort: SORT_ORDER = REVERSE_CHRONOLOGICAL + sort: SORT_ORDER = DESC # Filter by a specific tag name. tags: [String!] @@ -314,7 +317,7 @@ type Comment { recentReplies: [Comment!] # the replies that were made to the comment. - replies(sort: SORT_ORDER = CHRONOLOGICAL, limit: Int = 3, excludeIgnored: Boolean): CommentConnection! + replies(sort: SORT_ORDER = ASC, limit: Int = 3, excludeIgnored: Boolean): CommentConnection! # The count of replies on a comment. replyCount(excludeIgnored: Boolean): Int @@ -348,10 +351,10 @@ type CommentConnection { hasNextPage: Boolean! # Cursor of first comment in subset. - startCursor: Date + startCursor: Cursor # Cursor of last comment in subset. - endCursor: Date + endCursor: Cursor # Subset of comments. nodes: [Comment!]! @@ -573,7 +576,7 @@ type Asset { # If `deep` is true, it will return comments of all depths, # otherwise only top-level comments are returned. comments( - sort: SORT_ORDER = REVERSE_CHRONOLOGICAL, + sort: SORT_ORDER = DESC, limit: Int = 10, excludeIgnored: Boolean, tags: [String!] @@ -652,10 +655,10 @@ type ValidationUserError implements UserError { enum SORT_ORDER { # newest to oldest order. - REVERSE_CHRONOLOGICAL + DESC # oldest to newer order. - CHRONOLOGICAL + ASC } # All queries that can be executed. diff --git a/plugins/talk-plugin-featured-comments/client/containers/TabPane.js b/plugins/talk-plugin-featured-comments/client/containers/TabPane.js index 2195b0107..4c36c5c62 100644 --- a/plugins/talk-plugin-featured-comments/client/containers/TabPane.js +++ b/plugins/talk-plugin-featured-comments/client/containers/TabPane.js @@ -18,7 +18,7 @@ class TabPaneContainer extends React.Component { limit: 5, cursor: this.props.root.asset.featuredComments.endCursor, asset_id: this.props.root.asset.id, - sort: 'REVERSE_CHRONOLOGICAL', + sort: 'DESC', excludeIgnored: this.props.data.variables.excludeIgnored, }, updateQuery: (previous, {fetchMoreResult:{comments}}) => { @@ -26,7 +26,7 @@ class TabPaneContainer extends React.Component { asset: { featuredComments: { nodes: { - $apply: (nodes) => insertCommentsSorted(nodes, comments.nodes, 'REVERSE_CHRONOLOGICAL'), + $apply: (nodes) => insertCommentsSorted(nodes, comments.nodes, 'DESC'), }, hasNextPage: {$set: comments.hasNextPage}, endCursor: {$set: comments.endCursor}, @@ -47,7 +47,7 @@ class TabPaneContainer extends React.Component { } const LOAD_MORE_QUERY = gql` - query TalkFeaturedComments_LoadMoreComments($limit: Int = 5, $cursor: Date, $asset_id: ID, $sort: SORT_ORDER, $excludeIgnored: Boolean) { + query TalkFeaturedComments_LoadMoreComments($limit: Int = 5, $cursor: String, $asset_id: ID, $sort: SORT_ORDER, $excludeIgnored: Boolean) { comments(query: {limit: $limit, cursor: $cursor, tags: ["FEATURED"], asset_id: $asset_id, sort: $sort, excludeIgnored: $excludeIgnored}) { nodes { ...${getDefinitionName(Comment.fragments.comment)} diff --git a/plugins/talk-plugin-featured-comments/client/index.js b/plugins/talk-plugin-featured-comments/client/index.js index ad10f87ca..c796521e9 100644 --- a/plugins/talk-plugin-featured-comments/client/index.js +++ b/plugins/talk-plugin-featured-comments/client/index.js @@ -60,7 +60,7 @@ export default { asset: { featuredComments: { nodes: { - $apply: (nodes) => insertCommentsSorted(nodes, comment, 'REVERSE_CHRONOLOGICAL') + $apply: (nodes) => insertCommentsSorted(nodes, comment, 'DESC') } }, featuredCommentsCount: {