mirror of
https://github.com/wassname/talk.git
synced 2026-07-01 09:11:35 +08:00
Merge branch 'master' into update-my-comments
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
.loadMoreContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.loadMore {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
color: #FFF;
|
||||
max-width: 660px;
|
||||
margin-bottom: 30px;
|
||||
background-color: #2376D8;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.loadMore:hover {
|
||||
background-color: #4399FF;
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -1,9 +1,10 @@
|
||||
import React, {PropTypes} from 'react';
|
||||
import {Button} from 'coral-ui';
|
||||
import styles from './styles.css';
|
||||
import styles from './LoadMore.css';
|
||||
import cn from 'classnames';
|
||||
|
||||
const LoadMore = ({loadMore, showLoadMore}) =>
|
||||
<div className={styles.loadMoreContainer}>
|
||||
const LoadMore = ({loadMore, showLoadMore, className, ...rest}) =>
|
||||
<div {...rest} className={cn(className, styles.loadMoreContainer)}>
|
||||
{
|
||||
showLoadMore && <Button
|
||||
className={styles.loadMore}
|
||||
@@ -79,3 +79,12 @@
|
||||
margin-left: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
.loadMore > button {
|
||||
background-color: #696969;
|
||||
|
||||
&:hover {
|
||||
background-color: #404040;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {Slot} from 'coral-framework/components';
|
||||
import ButtonCopyToClipboard from './ButtonCopyToClipboard';
|
||||
import {actionsMap} from '../utils/moderationQueueActionsMap';
|
||||
import ClickOutside from 'coral-framework/components/ClickOutside';
|
||||
import LoadMore from '../components/LoadMore';
|
||||
|
||||
export default class UserDetail extends React.Component {
|
||||
|
||||
@@ -59,7 +60,7 @@ export default class UserDetail extends React.Component {
|
||||
user,
|
||||
totalComments,
|
||||
rejectedComments,
|
||||
comments: {nodes}
|
||||
comments: {nodes, hasNextPage}
|
||||
},
|
||||
activeTab,
|
||||
selectedCommentIds,
|
||||
@@ -70,6 +71,7 @@ export default class UserDetail extends React.Component {
|
||||
bulkReject,
|
||||
hideUserDetail,
|
||||
viewUserDetail,
|
||||
loadMore,
|
||||
} = this.props;
|
||||
|
||||
const localProfile = user.profiles.find((p) => p.provider === 'local');
|
||||
@@ -167,6 +169,11 @@ export default class UserDetail extends React.Component {
|
||||
})
|
||||
}
|
||||
</div>
|
||||
<LoadMore
|
||||
className={styles.loadMore}
|
||||
loadMore={loadMore}
|
||||
showLoadMore={hasNextPage}
|
||||
/>
|
||||
</Drawer>
|
||||
</ClickOutside>
|
||||
);
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.root:last-child {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.rootSelected {
|
||||
background-color: #ecf4ff;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
} from 'coral-admin/src/actions/userDetail';
|
||||
import {withSetCommentStatus} from 'coral-framework/graphql/mutations';
|
||||
import UserDetailComment from './UserDetailComment';
|
||||
import update from 'immutability-helper';
|
||||
|
||||
const commentConnectionFragment = gql`
|
||||
fragment CoralAdmin_Moderation_CommentConnection on CommentConnection {
|
||||
@@ -32,6 +33,7 @@ const slots = [
|
||||
];
|
||||
|
||||
class UserDetailContainer extends React.Component {
|
||||
isLoadingMore = false;
|
||||
|
||||
// status can be 'ACCEPTED' or 'REJECTED'
|
||||
bulkSetCommentStatus = (status) => {
|
||||
@@ -40,7 +42,6 @@ class UserDetailContainer extends React.Component {
|
||||
});
|
||||
|
||||
Promise.all(changes).then(() => {
|
||||
this.props.data.refetch(); // some comments may have moved out of this tab
|
||||
this.props.clearUserDetailSelections(); // un-select everything
|
||||
});
|
||||
}
|
||||
@@ -61,12 +62,53 @@ class UserDetailContainer extends React.Component {
|
||||
return this.props.setCommentStatus({commentId, status: 'REJECTED'});
|
||||
}
|
||||
|
||||
loadMore = () => {
|
||||
if (this.isLoadingMore) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isLoadingMore = true;
|
||||
const variables = {
|
||||
limit: 10,
|
||||
cursor: this.props.root.comments.endCursor,
|
||||
author_id: this.props.data.variables.author_id,
|
||||
statuses: this.props.data.variables.statuses,
|
||||
};
|
||||
this.props.data.fetchMore({
|
||||
query: LOAD_MORE_QUERY,
|
||||
variables,
|
||||
updateQuery: (prev, {fetchMoreResult:{comments}}) => {
|
||||
return update(prev, {
|
||||
comments: {
|
||||
nodes: {$push: comments.nodes},
|
||||
hasNextPage: {$set: comments.hasNextPage},
|
||||
startCursor: {$set: comments.startCursor},
|
||||
endCursor: {$set: comments.endCursor},
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
this.isLoadingMore = false;
|
||||
})
|
||||
.catch((err) => {
|
||||
this.isLoadingMore = false;
|
||||
throw err;
|
||||
});
|
||||
};
|
||||
|
||||
componentWillReceiveProps(next) {
|
||||
if (this.props.userId === null && next.userId) {
|
||||
next.data.refetch();
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
if (!this.props.userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const loading = !('user' in this.props.root) || this.props.root.user.id !== this.props.userId;
|
||||
const loading = [1, 2, 4].indexOf(this.props.data.networkStatus) >= 0;
|
||||
|
||||
return <UserDetail
|
||||
bulkReject={this.bulkReject}
|
||||
@@ -76,10 +118,20 @@ class UserDetailContainer extends React.Component {
|
||||
acceptComment={this.acceptComment}
|
||||
rejectComment={this.rejectComment}
|
||||
loading={loading}
|
||||
loadMore={this.loadMore}
|
||||
{...this.props} />;
|
||||
}
|
||||
}
|
||||
|
||||
const LOAD_MORE_QUERY = gql`
|
||||
query CoralAdmin_Moderation_LoadMore($limit: Int = 10, $cursor: Date, $author_id: ID!, $statuses: [COMMENT_STATUS!]) {
|
||||
comments(query: {limit: $limit, cursor: $cursor, author_id: $author_id, statuses: $statuses}) {
|
||||
...CoralAdmin_Moderation_CommentConnection
|
||||
}
|
||||
}
|
||||
${commentConnectionFragment}
|
||||
`;
|
||||
|
||||
export const withUserDetailQuery = withQuery(gql`
|
||||
query CoralAdmin_UserDetail($author_id: ID!, $statuses: [COMMENT_STATUS!]) {
|
||||
user(id: $author_id) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import Comment from '../containers/Comment';
|
||||
import styles from './styles.css';
|
||||
import EmptyCard from '../../../components/EmptyCard';
|
||||
import {actionsMap} from '../../../utils/moderationQueueActionsMap';
|
||||
import LoadMore from './LoadMore';
|
||||
import LoadMore from '../../../components/LoadMore';
|
||||
import t from 'coral-framework/services/i18n';
|
||||
import {CSSTransitionGroup} from 'react-transition-group';
|
||||
|
||||
|
||||
@@ -397,26 +397,6 @@ span {
|
||||
}
|
||||
}
|
||||
|
||||
.loadMoreContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
};
|
||||
|
||||
.loadMore {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
color: #FFF;
|
||||
max-width: 660px;
|
||||
margin-bottom: 30px;
|
||||
background-color: #2376D8;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.loadMore:hover {
|
||||
background-color: #4399FF;
|
||||
}
|
||||
|
||||
.tabIcon {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
@@ -499,4 +479,4 @@ span {
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,7 +400,7 @@ export default class Comment extends React.Component {
|
||||
<div className={commentClassName}>
|
||||
|
||||
<Slot
|
||||
className={styles.commentAvatar}
|
||||
className={`${styles.commentAvatar} talk-stream-comment-avatar`}
|
||||
fill="commentAvatar"
|
||||
{...slotProps}
|
||||
inline
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -2,18 +2,21 @@ const errors = require('../../errors');
|
||||
const {Error: {ValidationError}} = require('mongoose');
|
||||
|
||||
/**
|
||||
* Wraps up a promise to return an object with the resolution of the promise
|
||||
* Wraps up a promise or value to return an object with the resolution of the promise
|
||||
* keyed at `key` or an error caught at `errors`.
|
||||
*/
|
||||
|
||||
const wrapResponse = (key) => (promise) => {
|
||||
return promise.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]
|
||||
@@ -25,7 +28,7 @@ const wrapResponse = (key) => (promise) => {
|
||||
}
|
||||
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = wrapResponse;
|
||||
|
||||
Reference in New Issue
Block a user