mirror of
https://github.com/wassname/talk.git
synced 2026-08-20 12:50:41 +08:00
merge remote. can reply to a comment
This commit is contained in:
@@ -11,103 +11,157 @@ import PermalinkButton from 'coral-plugin-permalinks/PermalinkButton';
|
||||
// import AuthorName from '../../coral-plugin-author-name/AuthorName';
|
||||
import Content from '../../coral-plugin-commentcontent/CommentContent';
|
||||
import PubDate from '../../coral-plugin-pubdate/PubDate';
|
||||
// import {ReplyBox, ReplyButton} from '../../coral-plugin-replies';
|
||||
import {ReplyBox, ReplyButton} from 'coral-plugin-replies';
|
||||
import FlagComment from '../../coral-plugin-flags/FlagComment';
|
||||
import LikeButton from '../../coral-plugin-likes/LikeButton';
|
||||
|
||||
const getAction = (type, comment) => comment.actions.filter((a) => a.type === type)[0];
|
||||
|
||||
const Comment = ({comment, currentUser, asset, depth, showSignInDialog, postAction, deleteAction}) => {
|
||||
const like = getAction('LIKE', comment);
|
||||
const flag = getAction('FLAG', comment);
|
||||
return (
|
||||
<div
|
||||
className="comment"
|
||||
id={`c_${comment.id}`}
|
||||
style={{marginLeft: depth * 30}}>
|
||||
<hr aria-hidden={true} />
|
||||
{/* <AuthorName
|
||||
author={comment.user}
|
||||
addNotification={this.props.addNotification}
|
||||
id={comment.id}
|
||||
author_id={comment.user.id}
|
||||
postAction={this.props.postAction}
|
||||
showSignInDialog={this.props.showSignInDialog}
|
||||
deleteAction={this.props.deleteAction}
|
||||
addItem={this.props.addItem}
|
||||
updateItem={this.props.updateItem}
|
||||
currentUser={currentUser}/>*/}
|
||||
<PubDate created_at={comment.created_at} />
|
||||
<Content body={comment.body} />
|
||||
<div className="commentActionsLeft">
|
||||
{/*
|
||||
<ReplyButton/>
|
||||
*/}
|
||||
<LikeButton
|
||||
like={like}
|
||||
id={comment.id}
|
||||
postAction={postAction}
|
||||
deleteAction={deleteAction}
|
||||
showSignInDialog={showSignInDialog}
|
||||
currentUser={currentUser}
|
||||
/>
|
||||
</div>
|
||||
<div className="commentActionsRight">
|
||||
<FlagComment
|
||||
flag={flag}
|
||||
class Comment extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {replyBoxVisible: false};
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
showSignInDialog: PropTypes.func.isRequired,
|
||||
postAction: PropTypes.func.isRequired,
|
||||
deleteAction: PropTypes.func.isRequired,
|
||||
parentId: PropTypes.string,
|
||||
addNotification: PropTypes.func.isRequired,
|
||||
postItem: PropTypes.func.isRequired,
|
||||
depth: PropTypes.number.isRequired,
|
||||
asset: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
url: PropTypes.string
|
||||
}).isRequired,
|
||||
currentUser: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired
|
||||
}),
|
||||
comment: PropTypes.shape({
|
||||
depth: PropTypes.number,
|
||||
actions: PropTypes.array.isRequired,
|
||||
body: PropTypes.string.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
replies: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
body: PropTypes.string.isRequired,
|
||||
id: PropTypes.string.isRequired
|
||||
})
|
||||
),
|
||||
user: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired
|
||||
}).isRequired
|
||||
}).isRequired
|
||||
}
|
||||
|
||||
render () {
|
||||
const {
|
||||
comment,
|
||||
currentUser,
|
||||
asset,
|
||||
depth,
|
||||
postItem,
|
||||
addNotification,
|
||||
showSignInDialog,
|
||||
postAction,
|
||||
deleteAction
|
||||
} = this.props;
|
||||
|
||||
const like = getAction('LIKE', comment);
|
||||
const flag = getAction('FLAG', comment);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="comment"
|
||||
id={`c_${comment.id}`}
|
||||
style={{marginLeft: depth * 30}}>
|
||||
<hr aria-hidden={true} />
|
||||
{/* <AuthorName
|
||||
author={comment.user}
|
||||
addNotification={this.props.addNotification}
|
||||
id={comment.id}
|
||||
author_id={comment.user.id}
|
||||
postAction={postAction}
|
||||
deleteAction={deleteAction}
|
||||
showSignInDialog={showSignInDialog}
|
||||
currentUser={currentUser}
|
||||
/>
|
||||
<PermalinkButton articleURL={asset.url} commentId={comment.id} />
|
||||
</div>
|
||||
{
|
||||
comment.replies &&
|
||||
comment.replies.map(reply => {
|
||||
return <Comment
|
||||
depth={depth + 1}
|
||||
asset={asset}
|
||||
currentUser={currentUser}
|
||||
currentUser={currentUser}
|
||||
postAction={this.props.postAction}
|
||||
showSignInDialog={this.props.showSignInDialog}
|
||||
deleteAction={this.props.deleteAction}
|
||||
addItem={this.props.addItem}
|
||||
updateItem={this.props.updateItem}
|
||||
currentUser={currentUser}/>*/}
|
||||
<PubDate created_at={comment.created_at} />
|
||||
<Content body={comment.body} />
|
||||
|
||||
{
|
||||
currentUser
|
||||
? <div className="commentActionsLeft">
|
||||
<ReplyButton
|
||||
onClick={() => {
|
||||
console.log('reply button click');
|
||||
this.setState({replyBoxVisible: !this.state.replyBoxVisible});
|
||||
}}
|
||||
parentCommentId={comment.id}
|
||||
currentUserId={currentUser.id}
|
||||
banned={false} />
|
||||
<LikeButton
|
||||
like={like}
|
||||
id={comment.id}
|
||||
postAction={postAction}
|
||||
deleteAction={deleteAction}
|
||||
showSignInDialog={showSignInDialog}
|
||||
currentUser={currentUser} />
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
<div className="commentActionsRight">
|
||||
{
|
||||
currentUser
|
||||
? <FlagComment
|
||||
flag={flag}
|
||||
id={comment.id}
|
||||
author_id={comment.user.id}
|
||||
postAction={postAction}
|
||||
deleteAction={deleteAction}
|
||||
showSignInDialog={showSignInDialog}
|
||||
key={reply.id}
|
||||
comment={reply} />;
|
||||
})
|
||||
}
|
||||
currentUser={currentUser} />
|
||||
: null
|
||||
}
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
<PermalinkButton articleURL={asset.url} commentId={comment.id} />
|
||||
</div>
|
||||
{
|
||||
this.state.replyBoxVisible
|
||||
? <ReplyBox
|
||||
parentId={comment.id}
|
||||
addNotification={addNotification}
|
||||
authorId={currentUser.id}
|
||||
postItem={postItem}
|
||||
assetId={asset.id} />
|
||||
: null
|
||||
}
|
||||
{
|
||||
comment.replies &&
|
||||
comment.replies.map(reply => {
|
||||
return <Comment
|
||||
addNotification={addNotification}
|
||||
parentId={comment.id}
|
||||
postItem={postItem}
|
||||
depth={depth + 1}
|
||||
asset={asset}
|
||||
currentUser={currentUser}
|
||||
postAction={postAction}
|
||||
deleteAction={deleteAction}
|
||||
showSignInDialog={showSignInDialog}
|
||||
key={reply.id}
|
||||
comment={reply} />;
|
||||
})
|
||||
}
|
||||
|
||||
Comment.propTypes = {
|
||||
depth: PropTypes.number.isRequired,
|
||||
asset: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
url: PropTypes.string
|
||||
}).isRequired,
|
||||
currentUser: PropTypes.object,
|
||||
comment: PropTypes.shape({
|
||||
depth: PropTypes.number,
|
||||
actions: PropTypes.array.isRequired,
|
||||
body: PropTypes.string.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
replies: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
body: PropTypes.string.isRequired,
|
||||
id: PropTypes.string.isRequired
|
||||
})
|
||||
),
|
||||
user: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired
|
||||
}).isRequired
|
||||
}).isRequired
|
||||
};
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Comment;
|
||||
|
||||
@@ -102,7 +102,7 @@ class Embed extends Component {
|
||||
|
||||
// const banned = (this.props.userData.status === 'banned');
|
||||
|
||||
const {loading, asset} = this.props.data;
|
||||
const {loading, asset, refetch} = this.props.data;
|
||||
|
||||
// const {status, moderation, closedMessage, charCount, charCountEnable} = asset.settings;
|
||||
|
||||
@@ -129,24 +129,31 @@ class Embed extends Component {
|
||||
enable={asset.settings.infoBoxEnable}
|
||||
/>
|
||||
<RestrictedContent restricted={false} restrictedComp={<SuspendedAccount />}>
|
||||
<CommentBox
|
||||
addNotification={this.props.addNotification}
|
||||
postItem={this.props.postItem}
|
||||
appendItemArray={this.props.appendItemArray}
|
||||
updateItem={this.props.updateItem}
|
||||
id={asset.id}
|
||||
premod={asset.settings.moderation}
|
||||
reply={false}
|
||||
currentUser={this.props.auth.user}
|
||||
banned={false}
|
||||
author={user}
|
||||
charCount={asset.settings.charCountEnable && asset.settings.charCount}/>
|
||||
{
|
||||
user
|
||||
? <CommentBox
|
||||
addNotification={this.props.addNotification}
|
||||
postItem={this.props.postItem}
|
||||
appendItemArray={this.props.appendItemArray}
|
||||
updateItem={this.props.updateItem}
|
||||
assetId={asset.id}
|
||||
premod={asset.settings.moderation}
|
||||
isReply={false}
|
||||
currentUser={this.props.auth.user}
|
||||
banned={false}
|
||||
authorId={user.id}
|
||||
charCount={asset.settings.charCountEnable && asset.settings.charCount} />
|
||||
: null
|
||||
}
|
||||
</RestrictedContent>
|
||||
</div>
|
||||
: <p>{asset.settings.closedMessage}</p>
|
||||
}
|
||||
{!loggedIn && <SignInContainer offset={signInOffset}/>}
|
||||
<Stream
|
||||
refetch={refetch}
|
||||
addNotification={this.props.addNotification}
|
||||
postItem={this.props.postItem}
|
||||
asset={asset}
|
||||
currentUser={user}
|
||||
postAction={this.props.postAction}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import React, {PropTypes} from 'react';
|
||||
import Comment from './Comment';
|
||||
|
||||
const Stream = ({comments, currentUser, asset, postAction, deleteAction, showSignInDialog}) => {
|
||||
const Stream = ({comments, currentUser, asset, postItem, addNotification, postAction, deleteAction, showSignInDialog}) => {
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
comments.map(comment => {
|
||||
return <Comment
|
||||
addNotification={addNotification}
|
||||
depth={0}
|
||||
postItem={postItem}
|
||||
asset={asset}
|
||||
currentUser={currentUser}
|
||||
postAction={postAction}
|
||||
@@ -22,6 +24,8 @@ const Stream = ({comments, currentUser, asset, postAction, deleteAction, showSig
|
||||
};
|
||||
|
||||
Stream.propTypes = {
|
||||
addNotification: PropTypes.func.isRequired,
|
||||
postItem: PropTypes.func.isRequired,
|
||||
asset: PropTypes.object.isRequired,
|
||||
comments: PropTypes.array.isRequired,
|
||||
currentUser: PropTypes.shape({
|
||||
|
||||
@@ -5,12 +5,12 @@ import DELETE_ACTION from './deleteAction.graphql';
|
||||
|
||||
export const postComment = graphql(POST_COMMENT, {
|
||||
props: ({mutate}) => ({
|
||||
postItem: ({asset_id, body}) => {
|
||||
postItem: ({asset_id, body, parent_id} /*, type */) => {
|
||||
return mutate({
|
||||
variables: {
|
||||
asset_id,
|
||||
body,
|
||||
parent_id: null
|
||||
parent_id
|
||||
}
|
||||
});
|
||||
}}),
|
||||
|
||||
@@ -8,11 +8,13 @@ const name = 'coral-plugin-commentbox';
|
||||
class CommentBox extends Component {
|
||||
|
||||
static propTypes = {
|
||||
postItem: PropTypes.func,
|
||||
updateItem: PropTypes.func,
|
||||
id: PropTypes.string,
|
||||
comments: PropTypes.array,
|
||||
reply: PropTypes.bool,
|
||||
postItem: PropTypes.func.isRequired,
|
||||
// updateItem: PropTypes.func,
|
||||
assetId: PropTypes.string.isRequired,
|
||||
parentId: PropTypes.string,
|
||||
authorId: PropTypes.string.isRequired,
|
||||
// comments: PropTypes.array,
|
||||
isReply: PropTypes.bool.isRequired,
|
||||
canPost: PropTypes.bool,
|
||||
currentUser: PropTypes.object
|
||||
}
|
||||
@@ -25,33 +27,36 @@ class CommentBox extends Component {
|
||||
postComment = () => {
|
||||
const {
|
||||
postItem,
|
||||
updateItem,
|
||||
id,
|
||||
parent_id,
|
||||
child_id,
|
||||
// updateItem,
|
||||
assetId,
|
||||
parentId,
|
||||
// child_id,
|
||||
addNotification,
|
||||
appendItemArray,
|
||||
author
|
||||
// appendItemArray,
|
||||
authorId
|
||||
} = this.props;
|
||||
|
||||
let comment = {
|
||||
body: this.state.body,
|
||||
asset_id: id,
|
||||
author_id: author.id
|
||||
asset_id: assetId,
|
||||
author_id: authorId,
|
||||
parent_id: parentId
|
||||
};
|
||||
let related;
|
||||
let parent_type;
|
||||
if (parent_id) {
|
||||
comment.parent_id = parent_id;
|
||||
related = 'children';
|
||||
parent_type = 'comments';
|
||||
} else {
|
||||
related = 'comments';
|
||||
parent_type = 'assets';
|
||||
}
|
||||
if (child_id || parent_id) {
|
||||
updateItem(child_id || parent_id, 'showReply', false, 'comments');
|
||||
}
|
||||
|
||||
console.log('CommentBox.parentId', parentId);
|
||||
// let related;
|
||||
// let parent_type;
|
||||
// if (parent_id) {
|
||||
// comment.parent_id = parent_id;
|
||||
// related = 'children';
|
||||
// parent_type = 'comments';
|
||||
// } else {
|
||||
// related = 'comments';
|
||||
// parent_type = 'assets';
|
||||
// }
|
||||
// if (child_id || parent_id) {
|
||||
// updateItem(child_id || parent_id, 'showReply', false, 'comments');
|
||||
// }
|
||||
|
||||
if (this.props.charCount && this.state.body.length > this.props.charCount) {
|
||||
return;
|
||||
@@ -59,13 +64,13 @@ class CommentBox extends Component {
|
||||
postItem(comment, 'comments')
|
||||
.then(({data}) => {
|
||||
const postedComment = data.createComment;
|
||||
const commentId = postedComment.id;
|
||||
// const commentId = postedComment.id;
|
||||
if (postedComment.status === 'rejected') {
|
||||
addNotification('error', lang.t('comment-post-banned-word'));
|
||||
} else if (postedComment.status === 'PREMOD') {
|
||||
addNotification('success', lang.t('comment-post-notif-premod'));
|
||||
} else {
|
||||
appendItemArray(parent_id || id, related, commentId, !parent_id, parent_type);
|
||||
// appendItemArray(parent_id || id, related, commentId, !parent_id, parent_type);
|
||||
addNotification('success', 'Your comment has been posted.');
|
||||
}
|
||||
})
|
||||
@@ -74,23 +79,23 @@ class CommentBox extends Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const {styles, reply, author, charCount} = this.props;
|
||||
const {styles, isReply, authorId, charCount} = this.props;
|
||||
const length = this.state.body.length;
|
||||
return <div>
|
||||
<div
|
||||
className={`${name}-container`}>
|
||||
<label
|
||||
htmlFor={ reply ? 'replyText' : 'commentText'}
|
||||
htmlFor={ isReply ? 'replyText' : 'commentText'}
|
||||
className="screen-reader-text"
|
||||
aria-hidden={true}>
|
||||
{reply ? lang.t('reply') : lang.t('comment')}
|
||||
{isReply ? lang.t('reply') : lang.t('comment')}
|
||||
</label>
|
||||
<textarea
|
||||
className={`${name}-textarea`}
|
||||
style={styles && styles.textarea}
|
||||
value={this.state.body}
|
||||
placeholder={lang.t('comment')}
|
||||
id={reply ? 'replyText' : 'commentText'}
|
||||
id={isReply ? 'replyText' : 'commentText'}
|
||||
onChange={(e) => this.setState({body: e.target.value})}
|
||||
rows={3}/>
|
||||
</div>
|
||||
@@ -101,7 +106,7 @@ class CommentBox extends Component {
|
||||
}
|
||||
</div>
|
||||
<div className={`${name}-button-container`}>
|
||||
{ author && (
|
||||
{ authorId && (
|
||||
<Button
|
||||
cStyle={!length || (charCount && length > charCount) ? 'lightGrey' : 'darkGrey'}
|
||||
className={`${name}-button`}
|
||||
|
||||
@@ -115,7 +115,7 @@ class FlagButton extends Component {
|
||||
{
|
||||
flagged
|
||||
? <span className={`${name}-button-text`}>{lang.t('reported')}</span>
|
||||
: <span className={`${name}-button-text`}>{lang.t('report')}</span>
|
||||
: <span className={`${name}-button-text`}>{lang.t('report')}</span>
|
||||
}
|
||||
<i className={`${name}-icon material-icons ${flagged && 'flaggedIcon'}`}
|
||||
style={flagged ? styles.flaggedIcon : {}}
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
import React from 'react';
|
||||
import React, {PropTypes} from 'react';
|
||||
import CommentBox from '../coral-plugin-commentbox/CommentBox';
|
||||
|
||||
const name = 'coral-plugin-replies';
|
||||
|
||||
const ReplyBox = (props) => <div
|
||||
className={`${name}-textarea`}
|
||||
style={props.styles && props.styles.container}>
|
||||
{
|
||||
props.showReply && <CommentBox
|
||||
{...props}
|
||||
comments = {props.child}
|
||||
reply = {true}/>
|
||||
}
|
||||
</div>;
|
||||
const ReplyBox = ({styles, postItem, assetId, authorId, addNotification, parentId}) => (
|
||||
<div className={`${name}-textarea`} style={styles && styles.container}>
|
||||
<CommentBox
|
||||
parentId={parentId}
|
||||
addNotification={addNotification}
|
||||
authorId={authorId}
|
||||
assetId={assetId}
|
||||
postItem={postItem}
|
||||
isReply={true} />
|
||||
</div>
|
||||
);
|
||||
|
||||
ReplyBox.propTypes = {
|
||||
parentId: PropTypes.string,
|
||||
addNotification: PropTypes.func.isRequired,
|
||||
authorId: PropTypes.string.isRequired,
|
||||
postItem: PropTypes.func.isRequired,
|
||||
assetId: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
export default ReplyBox;
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
import React from 'react';
|
||||
import React, {PropTypes} from 'react';
|
||||
import {I18n} from '../coral-framework';
|
||||
import translations from './translations.json';
|
||||
|
||||
const name = 'coral-plugin-replies';
|
||||
|
||||
const ReplyButton = (props) => <button
|
||||
className={`${name}-reply-button`}
|
||||
onClick={() => {
|
||||
if (props.banned) {
|
||||
return;
|
||||
}
|
||||
props.updateItem(props.id, 'showReply', !props.showReply, 'comments');
|
||||
}}>
|
||||
{lang.t('reply')}
|
||||
<i className={`${name}-icon material-icons`}
|
||||
aria-hidden={true}>reply</i>
|
||||
</button>;
|
||||
const ReplyButton = ({banned, parentCommentId, currentUserId, onClick}) => {
|
||||
return (
|
||||
<button
|
||||
className={`${name}-reply-button`}
|
||||
onClick={onClick}>
|
||||
{lang.t('reply')}
|
||||
<i className={`${name}-icon material-icons`}
|
||||
aria-hidden={true}>{banned ? 'BANNED' : 'reply'}</i>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
ReplyButton.propTypes = {
|
||||
onClick: PropTypes.func.isRequired,
|
||||
banned: PropTypes.bool.isRequired,
|
||||
parentCommentId: PropTypes.string.isRequired,
|
||||
currentUserId: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
export default ReplyButton;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user