Skip to content

Instantly share code, notes, and snippets.

@Polyrhythm
Last active September 25, 2015 19:41
Show Gist options
  • Save Polyrhythm/10b76ed44ddd51b82a89 to your computer and use it in GitHub Desktop.
Save Polyrhythm/10b76ed44ddd51b82a89 to your computer and use it in GitHub Desktop.
import React from 'react';
import { Link } from 'react-router';
import copy from 'shared/constants/copy';
import PostComments from 'shared/components/PostComments';
import PostCommentControls from 'shared/components/PostCommentControls';
import FluxComponent from 'flummox/component';
export default class PostComment extends React.Component {
constructor(props) {
super(props);
this.state = {
expanded: false,
controls: false
};
}
shouldComponentUpdate(nextProps, nextState) {
const props = [
'comment',
'author',
'points',
'replies',
'parentLevel',
'postId',
'nestingColor',
'commentId',
'activeComment'
];
if (
this.state.expanded !== nextState.expanded ||
this.state.controls !== nextState.controls
) {
return true;
}
for (let i = 0; i < props.length; i++) {
if (this.props[props[i]] !== nextProps[props[i]]) {
return true;
}
}
return false;
}
_commentReplyCount() {
return (
<span className="PostComment-replyCount">
{`${this.props.replies.size} ${copy('commentReplies')}`}
</span>
);
}
_commentReplies() {
return (
<PostComments
topLevel={false}
level={this.props.parentLevel + 1}
comments={this.props.replies}/>
);
}
_levelIndicator() {
return (
<span
className="PostComment PostComment-levelIndicator"
style={{ backgroundColor: this.props.nestingColor }}>
</span>
);
}
_separator() {
return (
<span
className="PostComment PostComment-levelIndicatorSeparator"
style={{ backgroundColor: this.props.nestingColor }}>
</span>
);
}
async handleCommentClick(e) {
e.stopPropagation();
const postStore = this.context.flux.getStore('post');
const commentActions = this.context.flux.getActions('comment');
this.context.flux.getActions('comment').toggleReply(false);
// only load comments if the click happened on a top-level comment
// and comments are not currently loaded
if (this.props.parentLevel === 0 && postStore.getComments().size === 0) {
await commentActions.getComments(this.props.postId);
}
if (
this.state.controls &&
this.state.expanded &&
postStore.getActiveComment() !== this.props.commentId
) {
commentActions.setActiveComment(this.props.commentId);
return;
}
// notify all other comments via PostStore that this comment
// is now active
commentActions.setActiveComment(this.props.commentId);
this.setState({
expanded: !this.state.expanded,
controls: !this.state.controls
});
}
render() {
const replyCount = this.props.replies.size ?
this._commentReplyCount() :
<span></span>;
const replies = this.props.replies.size && this.state.expanded ?
this._commentReplies() :
<span></span>;
const controls = (this.props.activeComment === this.props.commentId) && this.state.controls ?
// this component subscribes to replyActive
// so that it knows to have its reply textarea
// expanded or not
<FluxComponent connectToStores={{
post: (store) => ({
replyActive: store.getReplyActive()
})
}}>
<PostCommentControls
commentId={this.props.commentId.toString()}
vote={this.props.vote}/>
</FluxComponent> :
<span></span>;
const levelIndicator = this.props.parentLevel ?
this._levelIndicator() :
<span></span>;
const separator = this.props.parentLevel ?
this._separator() :
<span></span>;
return (
<div className="PostComment"
onClick={this.handleCommentClick.bind(this)}>
{separator}
<hr className="PostComments-separator"/>
<div className="PostComment-contentContainer">
<div className="PostComment-metaContainer">
{levelIndicator}
<a
className="PostComment-author"
href={`/user/${this.props.author}`}>
{this.props.author}
</a>
<span className="PostComment-points">
{`${this.props.points} ${copy('postPoints')}`}
</span>
{replyCount}
</div>
<p className="PostComment-commentText">{this.props.comment}</p>
{controls}
</div>
{replies}
</div>
);
}
}
PostComment.contextTypes = {
flux: React.PropTypes.object
};
PostComment.propTypes = {
comment: React.PropTypes.string,
author: React.PropTypes.string,
points: React.PropTypes.number,
replies: React.PropTypes.object, // Immutable list
parentLevel: React.PropTypes.number,
postId: React.PropTypes.string,
nestingColor: React.PropTypes.string,
commentId: React.PropTypes.number,
vote: React.PropTypes.string
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment