mirror of
https://github.com/wassname/talk.git
synced 2026-07-04 22:47:38 +08:00
Merge pull request #842 from coralproject/paginate-my-comments
Paginate my comments in profile tab
This commit is contained in:
@@ -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 <NotLoggedIn showSignInDialog={showSignInDialog} />;
|
||||
}
|
||||
|
||||
if (!me || data.loading) {
|
||||
if (loading) {
|
||||
return <Spinner />;
|
||||
}
|
||||
|
||||
@@ -73,14 +87,40 @@ class ProfileContainer extends Component {
|
||||
|
||||
<h3>{t('framework.my_comments')}</h3>
|
||||
{me.comments.nodes.length
|
||||
? <CommentHistory comments={me.comments.nodes} asset={asset} link={link} />
|
||||
? <CommentHistory comments={me.comments} asset={asset} link={link} loadMore={this.loadMore}/>
|
||||
: <p>{t('user_no_comment')}</p>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -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 (
|
||||
<div className={`${styles.header} commentHistory`}>
|
||||
<div className="commentHistory__list">
|
||||
{props.comments.map((comment, i) => {
|
||||
return <Comment
|
||||
key={i}
|
||||
comment={comment}
|
||||
link={props.link}
|
||||
asset={comment.asset} />;
|
||||
})}
|
||||
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 (
|
||||
<div className={`${styles.header} commentHistory`}>
|
||||
<div className="commentHistory__list">
|
||||
{comments.nodes.map((comment, i) => {
|
||||
return <Comment
|
||||
key={i}
|
||||
comment={comment}
|
||||
link={link}
|
||||
asset={comment.asset} />;
|
||||
})}
|
||||
</div>
|
||||
{comments.hasNextPage &&
|
||||
<LoadMore
|
||||
loadMore={this.loadMore}
|
||||
loadingState={this.state.loadingState}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CommentHistory.propTypes = {
|
||||
comments: PropTypes.array.isRequired
|
||||
comments: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default CommentHistory;
|
||||
|
||||
@@ -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 (
|
||||
<div className='talk-load-more'>
|
||||
<Button
|
||||
onClick={loadMore}
|
||||
className={cn('talk-load-more-button', {[`talk-load-more-button-${loadingState}`]: loadingState})}
|
||||
disabled={disabled}
|
||||
>
|
||||
{t('framework.view_more_comments')}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
LoadMore.propTypes = {
|
||||
loadMore: PropTypes.func.isRequired,
|
||||
loadingState: PropTypes.oneOf(['', 'loading', 'success', 'error']),
|
||||
};
|
||||
|
||||
export default LoadMore;
|
||||
@@ -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;
|
||||
|
||||
@@ -36,7 +36,7 @@ class TabPane extends React.Component {
|
||||
{featuredComments.hasNextPage &&
|
||||
<LoadMore
|
||||
loadMore={this.loadMore}
|
||||
loadingState={this.loadingState}
|
||||
loadingState={this.state.loadingState}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user