From 203707124c87b36d5d4595d5e4c830ab23f24a38 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Fri, 4 Aug 2017 16:55:02 +0700 Subject: [PATCH 01/15] More css classes --- client/coral-embed-stream/src/components/Toggleable.js | 10 +++++----- .../coral-embed-stream/src/components/TopRightMenu.js | 2 +- .../talk-plugin-auth/client/components/SignInButton.js | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/coral-embed-stream/src/components/Toggleable.js b/client/coral-embed-stream/src/components/Toggleable.js index 1c70f2468..49f2a701b 100644 --- a/client/coral-embed-stream/src/components/Toggleable.js +++ b/client/coral-embed-stream/src/components/Toggleable.js @@ -1,10 +1,10 @@ import React from 'react'; import ClickOutside from 'coral-framework/components/ClickOutside'; import styles from './Toggleable.css'; -import classnames from 'classnames'; +import cn from 'classnames'; -const upArrow = ; -const downArrow = ; +const upArrow = ; +const downArrow = ; export default class Toggleable extends React.Component { constructor(props) { @@ -23,11 +23,11 @@ export default class Toggleable extends React.Component { } render() { - const {children} = this.props; + const {children, className, ...rest} = this.props; const {isOpen} = this.state; return ( - + {isOpen ? children : null} diff --git a/client/coral-embed-stream/src/components/TopRightMenu.js b/client/coral-embed-stream/src/components/TopRightMenu.js index 4cd544379..64acb2290 100644 --- a/client/coral-embed-stream/src/components/TopRightMenu.js +++ b/client/coral-embed-stream/src/components/TopRightMenu.js @@ -45,7 +45,7 @@ export class TopRightMenu extends React.Component { } }; return ( - +
( -
+
{!loggedIn ?
diff --git a/client/coral-ui/components/Drawer.css b/client/coral-ui/components/Drawer.css index d6a7e6871..88c30425f 100644 --- a/client/coral-ui/components/Drawer.css +++ b/client/coral-ui/components/Drawer.css @@ -3,7 +3,7 @@ min-width: 550px; position: fixed; top: 0; - right: -17px; + right: 0px; bottom: 0; background-color: white; transition: transform 500ms ease-in-out; From 567f8bf94eba5f02db08c83a0e269f4e5d9b0b5f Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 7 Aug 2017 14:54:11 +1000 Subject: [PATCH 05/15] adjusted wrapResponse function --- graph/helpers/response.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/graph/helpers/response.js b/graph/helpers/response.js index f5e7a54f4..1db1e9b89 100644 --- a/graph/helpers/response.js +++ b/graph/helpers/response.js @@ -6,15 +6,17 @@ const {Error: {ValidationError}} = require('mongoose'); * keyed at `key` or an error caught at `errors`. */ -const wrapResponse = (key) => (promiseOrValue) => { - return Promise.resolve(promiseOrValue).then((value) => { +const wrapResponse = (key) => async (promise) => { + try { + let value = await promise; + let res = {}; if (key) { res[key] = value; } + return res; - }) - .catch((err) => { + } catch (err) { if (err instanceof errors.APIError) { return { errors: [err] @@ -26,7 +28,7 @@ const wrapResponse = (key) => (promiseOrValue) => { } throw err; - }); + } }; module.exports = wrapResponse; From c2f8f41e596e8b8b89f977b9e109de0efd01d30c Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 7 Aug 2017 18:12:07 +0700 Subject: [PATCH 06/15] Support rendering system flags --- client/coral-admin/src/components/FlagBox.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/coral-admin/src/components/FlagBox.js b/client/coral-admin/src/components/FlagBox.js index 38af61c5c..240d52078 100644 --- a/client/coral-admin/src/components/FlagBox.js +++ b/client/coral-admin/src/components/FlagBox.js @@ -61,9 +61,11 @@ class FlagBox extends Component {
    {actionList.map((action, j) =>
  • - viewUserDetail(action.user.id)}> - {action.user.username} - + {action.user && + viewUserDetail(action.user.id)}> + {action.user.username} + + } {action.message}
  • )} From 1d5f1e676f85d99ecf73986eaaf3068f14b86e42 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 7 Aug 2017 18:12:25 +0700 Subject: [PATCH 07/15] Sort aggregation --- services/actions.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/actions.js b/services/actions.js index c59b3a3f9..197c0513e 100644 --- a/services/actions.js +++ b/services/actions.js @@ -173,7 +173,8 @@ module.exports = class ActionsService { return ActionModel.aggregate([ {$match}, {$group}, - {$project} + {$project}, + {$sort: {count: -1, action_type: 1, group_id: 1}}, ]); } From 10936d9f41cff5c960675c9fb43f2969c43ad832 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 7 Aug 2017 18:23:44 +0700 Subject: [PATCH 08/15] Sort not by count --- services/actions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/actions.js b/services/actions.js index 197c0513e..74c3bdad3 100644 --- a/services/actions.js +++ b/services/actions.js @@ -174,7 +174,7 @@ module.exports = class ActionsService { {$match}, {$group}, {$project}, - {$sort: {count: -1, action_type: 1, group_id: 1}}, + {$sort: {action_type: 1, group_id: 1}}, ]); } From a22d0f7536a67219b654ed8d385f1e692e943151 Mon Sep 17 00:00:00 2001 From: Erik Reyna Date: Mon, 7 Aug 2017 14:00:53 -0400 Subject: [PATCH 09/15] expose talk-stream-comment-container class --- client/coral-embed-stream/src/components/Comment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/coral-embed-stream/src/components/Comment.js b/client/coral-embed-stream/src/components/Comment.js index 34f672d8a..ed30e2e32 100644 --- a/client/coral-embed-stream/src/components/Comment.js +++ b/client/coral-embed-stream/src/components/Comment.js @@ -406,7 +406,7 @@ export default class Comment extends React.Component { inline /> -
    +
    From 1e8d2ce3a665f5cd065e991dc3a537f015ebb83a Mon Sep 17 00:00:00 2001 From: Erik Reyna Date: Mon, 7 Aug 2017 14:11:51 -0400 Subject: [PATCH 10/15] expose talk-stream-comment-avatar class --- client/coral-embed-stream/src/components/Comment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/coral-embed-stream/src/components/Comment.js b/client/coral-embed-stream/src/components/Comment.js index 34f672d8a..1c57e2d1e 100644 --- a/client/coral-embed-stream/src/components/Comment.js +++ b/client/coral-embed-stream/src/components/Comment.js @@ -400,7 +400,7 @@ export default class Comment extends React.Component {
    Date: Tue, 8 Aug 2017 19:50:59 +0700 Subject: [PATCH 11/15] Pass config to plugins --- client/coral-framework/helpers/plugins.js | 4 ++-- plugin-api/beta/client/hocs/withReaction.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/coral-framework/helpers/plugins.js b/client/coral-framework/helpers/plugins.js index 1af2a9a59..5e5a8c0c0 100644 --- a/client/coral-framework/helpers/plugins.js +++ b/client/coral-framework/helpers/plugins.js @@ -10,7 +10,7 @@ import camelize from './camelize'; import plugins from 'pluginsConfig'; export function getSlotComponents(slot, reduxState, props = {}) { - const pluginConfig = reduxState.config.pluginConfig || {}; + const pluginConfig = reduxState.config.plugin_config || {}; return flatten(plugins // Filter out components that have slots and have been disabled in `plugin_config` @@ -39,7 +39,7 @@ export function isSlotEmpty(slot, reduxState, props) { * Returns React Elements for given slot. */ export function getSlotElements(slot, reduxState, props = {}) { - const pluginConfig = reduxState.config.pluginConfig || {}; + const pluginConfig = reduxState.config.plugin_config || {}; return getSlotComponents(slot, reduxState, props) .map((component, i) => React.createElement(component, {key: i, ...props, config: pluginConfig})); } diff --git a/plugin-api/beta/client/hocs/withReaction.js b/plugin-api/beta/client/hocs/withReaction.js index 40ee6e14c..7f43cc5b2 100644 --- a/plugin-api/beta/client/hocs/withReaction.js +++ b/plugin-api/beta/client/hocs/withReaction.js @@ -271,6 +271,7 @@ export default (reaction) => (WrappedComponent) => { alreadyReacted={alreadyReacted} postReaction={this.postReaction} deleteReaction={this.deleteReaction} + config={this.props.config} />; } } From c4a91d225e57657cdf56d4861373413dea374348 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 8 Aug 2017 19:57:23 +0700 Subject: [PATCH 12/15] Pass config also to withTags --- plugin-api/beta/client/hocs/withTags.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugin-api/beta/client/hocs/withTags.js b/plugin-api/beta/client/hocs/withTags.js index 75d434bef..e9b5bdff0 100644 --- a/plugin-api/beta/client/hocs/withTags.js +++ b/plugin-api/beta/client/hocs/withTags.js @@ -68,16 +68,17 @@ export default (tag) => (WrappedComponent) => { } render() { - const {comment} = this.props; + const {comment, user, config} = this.props; const alreadyTagged = isTagged(comment.tags, TAG); return ; } } From 7bdd28cb9c192ef8aa4e3a83e430f32aaf237d6f Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 8 Aug 2017 20:47:21 +0700 Subject: [PATCH 13/15] Emit `ui.AllCommentsPane.viewNewComments` and `ui.Comment.showMoreReplies` --- client/coral-embed-stream/src/components/AllCommentsPane.js | 3 +++ client/coral-embed-stream/src/components/Comment.js | 1 + client/coral-embed-stream/src/components/Stream.js | 1 + client/coral-embed-stream/src/containers/Stream.js | 3 ++- plugin-api/beta/client/hocs/index.js | 1 + 5 files changed, 8 insertions(+), 1 deletion(-) diff --git a/client/coral-embed-stream/src/components/AllCommentsPane.js b/client/coral-embed-stream/src/components/AllCommentsPane.js index 7166aa6e9..6c5d6bb23 100644 --- a/client/coral-embed-stream/src/components/AllCommentsPane.js +++ b/client/coral-embed-stream/src/components/AllCommentsPane.js @@ -93,6 +93,7 @@ class AllCommentsPane extends React.Component { viewNewComments = () => { this.setState(resetCursors); + this.props.emit('ui.AllCommentsPane.viewNewComments'); }; // getVisibileComments returns a list containing comments @@ -142,6 +143,7 @@ class AllCommentsPane extends React.Component { charCountEnable, maxCharCount, editComment, + emit, } = this.props; const {loadingState} = this.state; @@ -181,6 +183,7 @@ class AllCommentsPane extends React.Component { charCountEnable={charCountEnable} maxCharCount={maxCharCount} editComment={editComment} + emit={emit} />; })} diff --git a/client/coral-embed-stream/src/components/Comment.js b/client/coral-embed-stream/src/components/Comment.js index 34f672d8a..a8bba1ca3 100644 --- a/client/coral-embed-stream/src/components/Comment.js +++ b/client/coral-embed-stream/src/components/Comment.js @@ -224,6 +224,7 @@ export default class Comment extends React.Component { return; } this.setState(resetCursors); + this.props.emit('ui.Comment.showMoreReplies'); }; showReplyBox = () => { diff --git a/client/coral-embed-stream/src/components/Stream.js b/client/coral-embed-stream/src/components/Stream.js index 1e0ff7ea9..7b9e5f566 100644 --- a/client/coral-embed-stream/src/components/Stream.js +++ b/client/coral-embed-stream/src/components/Stream.js @@ -292,6 +292,7 @@ class Stream extends React.Component { charCountEnable={asset.settings.charCountEnable} maxCharCount={asset.settings.charCount} editComment={editComment} + emit={this.props.emit} /> diff --git a/client/coral-embed-stream/src/containers/Stream.js b/client/coral-embed-stream/src/containers/Stream.js index fcedbcb0b..73676713c 100644 --- a/client/coral-embed-stream/src/containers/Stream.js +++ b/client/coral-embed-stream/src/containers/Stream.js @@ -14,7 +14,7 @@ import {editName} from 'coral-framework/actions/user'; import {setActiveReplyBox, setActiveTab, viewAllComments} from '../actions/stream'; import Stream from '../components/Stream'; import Comment from './Comment'; -import {withFragments} from 'coral-framework/hocs'; +import {withFragments, withEmit} from 'coral-framework/hocs'; import {getDefinitionName, getSlotFragmentSpreads} from 'coral-framework/utils'; import {Spinner} from 'coral-ui'; import { @@ -326,6 +326,7 @@ const mapDispatchToProps = (dispatch) => export default compose( withFragments(fragments), + withEmit, connect(mapStateToProps, mapDispatchToProps), withPostComment, withPostFlag, diff --git a/plugin-api/beta/client/hocs/index.js b/plugin-api/beta/client/hocs/index.js index 68547692d..60b118522 100644 --- a/plugin-api/beta/client/hocs/index.js +++ b/plugin-api/beta/client/hocs/index.js @@ -3,3 +3,4 @@ export {default as withTags} from './withTags'; export {default as withFragments} from 'coral-framework/hocs/withFragments'; export {default as excludeIf} from 'coral-framework/hocs/excludeIf'; export {default as connect} from 'coral-framework/hocs/connect'; +export {default as withEmit} from 'coral-framework/hocs/withEmit'; From 976bd1e9add953de3599a1dc0afab5adf7336761 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 8 Aug 2017 22:39:24 +0700 Subject: [PATCH 14/15] Paginate my comments in profile tab --- .../containers/ProfileContainer.js | 94 +++++++++++++------ client/talk-plugin-history/CommentHistory.js | 57 ++++++++--- client/talk-plugin-history/LoadMore.js | 30 ++++++ graph/resolvers/user.js | 4 +- .../client/components/TabPane.js | 2 +- 5 files changed, 138 insertions(+), 49 deletions(-) create mode 100644 client/talk-plugin-history/LoadMore.js diff --git a/client/coral-settings/containers/ProfileContainer.js b/client/coral-settings/containers/ProfileContainer.js index 91de923b2..0090847f7 100644 --- a/client/coral-settings/containers/ProfileContainer.js +++ b/client/coral-settings/containers/ProfileContainer.js @@ -1,7 +1,8 @@ import {connect} from 'react-redux'; -import {compose, graphql, gql} from 'react-apollo'; +import {compose, gql} from 'react-apollo'; import React, {Component} from 'react'; import {bindActionCreators} from 'redux'; +import {withQuery} from 'coral-framework/hocs'; import {withStopIgnoringUser} from 'coral-framework/graphql/mutations'; @@ -11,18 +12,12 @@ import IgnoredUsers from '../components/IgnoredUsers'; import {Spinner} from 'coral-ui'; import CommentHistory from 'talk-plugin-history/CommentHistory'; import {showSignInDialog, checkLogin} from 'coral-framework/actions/auth'; +import {insertCommentsSorted} from 'plugin-api/beta/client/utils'; +import update from 'immutability-helper'; import t from 'coral-framework/services/i18n'; class ProfileContainer extends Component { - constructor() { - super(); - - this.state = { - activeTab: 0 - }; - } - componentWillReceiveProps(nextProps) { if (!this.props.auth.loggedIn && nextProps.auth.loggedIn) { @@ -31,21 +26,40 @@ class ProfileContainer extends Component { } } - handleTabChange = (tab) => { - this.setState({ - activeTab: tab + loadMore = () => { + return this.props.data.fetchMore({ + query: LOAD_MORE_QUERY, + variables: { + limit: 5, + cursor: this.props.root.me.comments.endCursor, + }, + updateQuery: (previous, {fetchMoreResult:{comments}}) => { + const updated = update(previous, { + me: { + comments: { + nodes: { + $apply: (nodes) => insertCommentsSorted(nodes, comments.nodes, 'REVERSE_CHRONOLOGICAL'), + }, + hasNextPage: {$set: comments.hasNextPage}, + endCursor: {$set: comments.endCursor}, + }, + } + }); + return updated; + }, }); }; render() { - const {auth, asset, data, showSignInDialog, stopIgnoringUser} = this.props; - const {me} = this.props.data; + const {auth, asset, showSignInDialog, stopIgnoringUser} = this.props; + const {me} = this.props.root; + const loading = [1, 2, 4].indexOf(this.props.data.networkStatus) >= 0; if (!auth.loggedIn) { return ; } - if (!me || data.loading) { + if (loading) { return ; } @@ -73,14 +87,40 @@ class ProfileContainer extends Component {

    {t('framework.my_comments')}

    {me.comments.nodes.length - ? + ? :

    {t('user_no_comment')}

    }
    ); } } -const withQuery = graphql( +const CommentFragment = gql` + fragment TalkSettings_CommentConnectionFragment on CommentConnection { + nodes { + id + body + asset { + id + title + url + } + created_at + } + endCursor + hasNextPage + } +`; + +const LOAD_MORE_QUERY = gql` + query TalkSettings_LoadMoreComments($limit: Int, $cursor: Date) { + comments(query: {limit: $limit, cursor: $cursor}) { + ...TalkSettings_CommentConnectionFragment + } + } + ${CommentFragment} +`; + +const withProfileQuery = withQuery( gql` query CoralEmbedStream_Profile { me { @@ -89,21 +129,13 @@ const withQuery = graphql( id, username, } - comments { - nodes { - id - body - asset { - id - title - url - } - created_at - } + comments(query: {limit: 10}) { + ...TalkSettings_CommentConnectionFragment } } - }` -); + } + ${CommentFragment} +`); const mapStateToProps = (state) => ({ user: state.user.toJS(), @@ -117,5 +149,5 @@ const mapDispatchToProps = (dispatch) => export default compose( connect(mapStateToProps, mapDispatchToProps), withStopIgnoringUser, - withQuery + withProfileQuery )(ProfileContainer); diff --git a/client/talk-plugin-history/CommentHistory.js b/client/talk-plugin-history/CommentHistory.js index 72c4de982..d584d6a0a 100644 --- a/client/talk-plugin-history/CommentHistory.js +++ b/client/talk-plugin-history/CommentHistory.js @@ -1,25 +1,52 @@ import React, {PropTypes} from 'react'; import Comment from './Comment'; import styles from './CommentHistory.css'; +import LoadMore from './LoadMore'; +import {forEachError} from 'plugin-api/beta/client/utils'; -const CommentHistory = (props) => { - return ( -
    -
    - {props.comments.map((comment, i) => { - return ; - })} +class CommentHistory extends React.Component { + state = { + loadingState: '', + }; + + loadMore = () => { + this.setState({loadingState: 'loading'}); + this.props.loadMore() + .then(() => { + this.setState({loadingState: 'success'}); + }) + .catch((error) => { + this.setState({loadingState: 'error'}); + forEachError(error, ({msg}) => {this.props.addNotification('error', msg);}); + }); + } + + render() { + const {link, comments} = this.props; + return ( +
    +
    + {comments.nodes.map((comment, i) => { + return ; + })} +
    + {comments.hasNextPage && + + }
    -
    - ); -}; + ); + } +} CommentHistory.propTypes = { - comments: PropTypes.array.isRequired + comments: PropTypes.object.isRequired }; export default CommentHistory; diff --git a/client/talk-plugin-history/LoadMore.js b/client/talk-plugin-history/LoadMore.js new file mode 100644 index 000000000..a168ed43a --- /dev/null +++ b/client/talk-plugin-history/LoadMore.js @@ -0,0 +1,30 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {Button} from 'coral-ui'; +import t from 'coral-framework/services/i18n'; +import cn from 'classnames'; + +class LoadMore extends React.Component { + render () { + const {loadingState, loadMore} = this.props; + const disabled = loadingState === 'loading'; + return ( +
    + +
    + ); + } +} + +LoadMore.propTypes = { + loadMore: PropTypes.func.isRequired, + loadingState: PropTypes.oneOf(['', 'loading', 'success', 'error']), +}; + +export default LoadMore; diff --git a/graph/resolvers/user.js b/graph/resolvers/user.js index 2878d6561..5a851233a 100644 --- a/graph/resolvers/user.js +++ b/graph/resolvers/user.js @@ -29,12 +29,12 @@ const User = { return null; }, - comments({id}, _, {loaders: {Comments}, user}) { + comments({id}, {query}, {loaders: {Comments}, user}) { // If the user is not an admin, only return comment list for the owner of // the comments. if (user && (user.can(SEARCH_OTHERS_COMMENTS) || user.id === id)) { - return Comments.getByQuery({author_id: id, sort: 'REVERSE_CHRONOLOGICAL'}); + return Comments.getByQuery(Object.assign({}, query, {author_id: id})); } return null; diff --git a/plugins/talk-plugin-featured-comments/client/components/TabPane.js b/plugins/talk-plugin-featured-comments/client/components/TabPane.js index 3cf8b2cfd..2f5d0c7c2 100644 --- a/plugins/talk-plugin-featured-comments/client/components/TabPane.js +++ b/plugins/talk-plugin-featured-comments/client/components/TabPane.js @@ -36,7 +36,7 @@ class TabPane extends React.Component { {featuredComments.hasNextPage && }
    From 6913fe05ae48d5e9d399b2b8ff854547381bde33 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Wed, 9 Aug 2017 09:38:09 +1000 Subject: [PATCH 15/15] fixes #841 --- docs/_docs/05-01-development-tools.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_docs/05-01-development-tools.md b/docs/_docs/05-01-development-tools.md index 609d3ef48..fc19a077c 100644 --- a/docs/_docs/05-01-development-tools.md +++ b/docs/_docs/05-01-development-tools.md @@ -1,6 +1,6 @@ --- title: Development Tooling -permalink: /docs/development/tools +permalink: /docs/development/tools/ --- ## Debugging