mirror of
https://github.com/wassname/talk.git
synced 2026-07-02 21:57:13 +08:00
Merge pull request #812 from coralproject/view-context-non-public
Allow admins / mods to view context of rejected and premod comments
This commit is contained in:
@@ -169,5 +169,5 @@
|
||||
}
|
||||
|
||||
.footer {
|
||||
|
||||
min-height: 10px;
|
||||
}
|
||||
|
||||
@@ -317,6 +317,7 @@ export default class Comment extends React.Component {
|
||||
} = this.props;
|
||||
|
||||
const view = this.getVisibileReplies();
|
||||
const isActive = ['NONE', 'ACCEPTED'].indexOf(comment.status) >= 0;
|
||||
const {loadingState} = this.state;
|
||||
const isPending = comment.id.indexOf('pending') >= 0;
|
||||
const isHighlighted = highlighted === comment.id;
|
||||
@@ -422,7 +423,7 @@ export default class Comment extends React.Component {
|
||||
{...slotProps}
|
||||
/>
|
||||
|
||||
{ (currentUser && (comment.user.id === currentUser.id)) &&
|
||||
{ isActive && (currentUser && (comment.user.id === currentUser.id)) &&
|
||||
|
||||
/* User can edit/delete their own comment for a short window after posting */
|
||||
<span className={cn(styles.topRight)}>
|
||||
@@ -467,44 +468,48 @@ export default class Comment extends React.Component {
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div className={styles.footer}>
|
||||
<div className="commentActionsLeft comment__action-container">
|
||||
<Slot
|
||||
fill="commentReactions"
|
||||
{...slotProps}
|
||||
inline
|
||||
/>
|
||||
{!disableReply &&
|
||||
<ActionButton>
|
||||
<ReplyButton
|
||||
onClick={this.showReplyBox}
|
||||
parentCommentId={parentId || comment.id}
|
||||
currentUserId={currentUser && currentUser.id}
|
||||
<div className={cn(styles.footer, 'talk-stream-comment-footer')}>
|
||||
{isActive &&
|
||||
<div className={'talk-stream-comment-actions-container'}>
|
||||
<div className="commentActionsLeft comment__action-container">
|
||||
<Slot
|
||||
fill="commentReactions"
|
||||
{...slotProps}
|
||||
inline
|
||||
/>
|
||||
</ActionButton>}
|
||||
</div>
|
||||
<div className="commentActionsRight comment__action-container">
|
||||
<Slot
|
||||
fill="commentActions"
|
||||
wrapperComponent={ActionButton}
|
||||
{...slotProps}
|
||||
inline
|
||||
/>
|
||||
<ActionButton>
|
||||
<FlagComment
|
||||
flaggedByCurrentUser={!!myFlag}
|
||||
flag={myFlag}
|
||||
id={comment.id}
|
||||
author_id={comment.user.id}
|
||||
postFlag={postFlag}
|
||||
addNotification={addNotification}
|
||||
postDontAgree={postDontAgree}
|
||||
deleteAction={deleteAction}
|
||||
showSignInDialog={showSignInDialog}
|
||||
currentUser={currentUser}
|
||||
/>
|
||||
</ActionButton>
|
||||
</div>
|
||||
{!disableReply &&
|
||||
<ActionButton>
|
||||
<ReplyButton
|
||||
onClick={this.showReplyBox}
|
||||
parentCommentId={parentId || comment.id}
|
||||
currentUserId={currentUser && currentUser.id}
|
||||
/>
|
||||
</ActionButton>}
|
||||
</div>
|
||||
<div className="commentActionsRight comment__action-container">
|
||||
<Slot
|
||||
fill="commentActions"
|
||||
wrapperComponent={ActionButton}
|
||||
{...slotProps}
|
||||
inline
|
||||
/>
|
||||
<ActionButton>
|
||||
<FlagComment
|
||||
flaggedByCurrentUser={!!myFlag}
|
||||
flag={myFlag}
|
||||
id={comment.id}
|
||||
author_id={comment.user.id}
|
||||
postFlag={postFlag}
|
||||
addNotification={addNotification}
|
||||
postDontAgree={postDontAgree}
|
||||
deleteAction={deleteAction}
|
||||
showSignInDialog={showSignInDialog}
|
||||
currentUser={currentUser}
|
||||
/>
|
||||
</ActionButton>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,7 +16,7 @@ import QuestionBox from 'talk-plugin-questionbox/QuestionBox';
|
||||
import {Button, TabBar, Tab, TabCount, TabContent, TabPane} from 'coral-ui';
|
||||
import cn from 'classnames';
|
||||
|
||||
import {getTopLevelParent} from '../graphql/utils';
|
||||
import {getTopLevelParent, attachCommentToParent} from '../graphql/utils';
|
||||
import AllCommentsPane from './AllCommentsPane';
|
||||
|
||||
import styles from './Stream.css';
|
||||
@@ -103,7 +103,16 @@ class Stream extends React.Component {
|
||||
const open = asset.closedAt === null;
|
||||
|
||||
// even though the permalinked comment is the highlighted one, we're displaying its parent + replies
|
||||
const highlightedComment = comment && getTopLevelParent(comment);
|
||||
let highlightedComment = comment && getTopLevelParent(comment);
|
||||
if (highlightedComment) {
|
||||
const isInactive = ['NONE', 'ACCEPTED'].indexOf(comment.status) === -1;
|
||||
if (comment.parent && isInactive) {
|
||||
|
||||
// the highlighted comment is not active and as such not in the replies, so we
|
||||
// attach it to the right parent.
|
||||
highlightedComment = attachCommentToParent(highlightedComment, comment);
|
||||
}
|
||||
}
|
||||
|
||||
const banned = user && user.status === 'BANNED';
|
||||
const temporarilySuspended =
|
||||
|
||||
@@ -185,6 +185,32 @@ export function insertFetchedCommentsIntoEmbedQuery(root, comments, parent_id) {
|
||||
return applyToCommentsOrigin(root, (origin) => findAndInsertFetchedComments(origin, comments, parent_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* attachCommentToParent recurses through the comment tree starting at `topLevelComment`
|
||||
* to find the parent of `comment` and attach it to the replies.
|
||||
*/
|
||||
export function attachCommentToParent(topLevelComment, comment) {
|
||||
if (topLevelComment.id === comment.parent.id) {
|
||||
return update(topLevelComment, {
|
||||
replies: {
|
||||
nodes: {
|
||||
$apply: (nodes) => insertCommentsSorted(nodes, comment),
|
||||
},
|
||||
},
|
||||
replyCount: {
|
||||
$set: (count) => count + 1,
|
||||
}
|
||||
});
|
||||
}
|
||||
return update(topLevelComment, {
|
||||
replies: {
|
||||
nodes: {
|
||||
$apply: (nodes) => nodes.map((node) => attachCommentToParent(node, comment)),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Nest a string in itself repeatly until `level` has been reached.
|
||||
*
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
const {decorateWithTags} = require('./util');
|
||||
const {
|
||||
SEARCH_NON_NULL_OR_ACCEPTED_COMMENTS,
|
||||
} = require('../../perms/constants');
|
||||
|
||||
const Asset = {
|
||||
recentComments({id}, _, {loaders: {Comments}}) {
|
||||
return Comments.genRecentComments.load(id);
|
||||
},
|
||||
async comment({id}, {id: commentId}, {loaders: {Comments}}) {
|
||||
async comment({id}, {id: commentId}, {loaders: {Comments}, user}) {
|
||||
const statuses = user && user.can(SEARCH_NON_NULL_OR_ACCEPTED_COMMENTS)
|
||||
? ['NONE', 'ACCEPTED', 'PREMOD', 'REJECTED']
|
||||
: ['NONE', 'ACCEPTED'];
|
||||
|
||||
const comments = await Comments.getByQuery({
|
||||
asset_id: id,
|
||||
ids: commentId
|
||||
ids: commentId,
|
||||
statuses,
|
||||
});
|
||||
|
||||
return comments.nodes[0];
|
||||
|
||||
Reference in New Issue
Block a user