Advertisement
Guest User

Untitled

a guest
Aug 24th, 2016
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.56 KB | None | 0 0
  1. class CommentBox extends React.Component {
  2. constructor() {
  3. super();
  4.  
  5. this.state = {
  6. showComments: false,
  7. comments: []
  8. };
  9. }
  10.  
  11. componentWillMount() {
  12. this._fetchComments();
  13. }
  14.  
  15. render() {
  16. const comments = this._getComments();
  17. return(
  18. <div className="comment-box">
  19. <CommentForm addComment={this._addComment.bind(this)} />
  20. <CommentAvatarList avatars={this._getAvatars()} />
  21. {this._getPopularMessage(comments.length)}
  22. <h3 className="comment-count">{this._getCommentsTitle(comments.length)}</h3>
  23. <div className="comment-list">
  24. {comments}
  25. </div>
  26. </div>
  27. );
  28. }
  29.  
  30. _getAvatars() {
  31. return this.state.comments.map(comment => comment.avatarUrl);
  32. }
  33.  
  34. _getPopularMessage(commentCount) {
  35. const POPULAR_COUNT = 10;
  36. if (commentCount > POPULAR_COUNT) {
  37. return (
  38. <div>This post is getting really popular, don't miss out!</div>
  39. );
  40. }
  41. }
  42.  
  43. _getComments() {
  44. return this.state.comments.map((comment) => {
  45. return (<Comment
  46. id={comment.id}
  47. author={comment.author}
  48. body={comment.body}
  49. avatarUrl={comment.avatarUrl}
  50. onDelete={this._deleteComment.bind(this)}
  51. key={comment.id} />);
  52. });
  53. }
  54.  
  55. _getCommentsTitle(commentCount) {
  56. if (commentCount === 0) {
  57. return 'No comments yet';
  58. } else if (commentCount === 1) {
  59. return '1 comment';
  60. } else {
  61. return `${commentCount} comments`;
  62. }
  63. }
  64.  
  65. _addComment(commentAuthor, commentBody) {
  66. let comment = {
  67. id: Math.floor(Math.random() * (9999 - this.state.comments.length + 1)) + this.state.comments.length,
  68. author: commentAuthor,
  69. body: commentBody,
  70. avatarUrl: 'images/default-avatar.png'
  71. };
  72.  
  73. this.setState({
  74. comments: this.state.comments.concat([comment])
  75. });
  76. }
  77.  
  78. _fetchComments() {
  79. $.ajax({
  80. method: 'GET',
  81. url: 'comments.json',
  82. success: (comments) => {
  83. this.setState({ comments });
  84. }
  85. });
  86. }
  87.  
  88. _deleteComment(commentID) {
  89. const comments = this.state.comments.filter(
  90. comment => comment.id !== commentID
  91. );
  92.  
  93. this.setState({ comments });
  94. }
  95. }
  96.  
  97. class CommentForm extends React.Component {
  98. constructor() {
  99. super();
  100. this.state = {
  101. characters: 0
  102. };
  103. }
  104.  
  105. render() {
  106. return (
  107. <form className="comment-form" onSubmit={this._handleSubmit.bind(this)}>
  108. <label>New comment</label>
  109. <div className="comment-form-fields">
  110. <input placeholder="Name:" ref={c => this._author = c} />
  111. <textarea placeholder="Comment:" ref={c => this._body = c} onChange={this._getCharacterCount.bind(this)}></textarea>
  112. </div>
  113. <p>{this.state.characters} characters</p>
  114. <div className="comment-form-actions">
  115. <button type="submit">
  116. Post comment
  117. </button>
  118. </div>
  119. </form>
  120. );
  121. }
  122.  
  123. _getCharacterCount(e) {
  124. this.setState({
  125. characters: this._body.value.length
  126. });
  127. }
  128.  
  129. _handleSubmit(event) {
  130. event.preventDefault();
  131.  
  132. if (!this._author.value || !this._body.value) {
  133. alert('Please enter your name and comment.');
  134. return;
  135. }
  136.  
  137. this.props.addComment(this._author.value, this._body.value);
  138.  
  139. this._author.value = '';
  140. this._body.value = '';
  141.  
  142. this.setState({ characters: 0 });
  143. }
  144. }
  145.  
  146. class CommentAvatarList extends React.Component {
  147. render() {
  148. const { avatars = [] } = this.props;
  149. return (
  150. <div className="comment-avatars">
  151. <h4>Authors</h4>
  152. <ul>
  153. {avatars.map((avatarUrl, i) => (
  154. <li key={i}>
  155. <img src={avatarUrl} />
  156. </li>
  157. ))}
  158. </ul>
  159. </div>
  160. );
  161. }
  162. }
  163.  
  164. class Comment extends React.Component {
  165. constructor() {
  166. super();
  167.  
  168. this.state = {
  169. isAbusive: false
  170. };
  171. }
  172.  
  173. render() {
  174. let commentBody;
  175. if (!this.state.isAbusive) {
  176. commentBody = this.props.body;
  177. } else {
  178. commentBody = <em>Content marked as abusive</em>;
  179. }
  180. return(
  181. <div className="comment">
  182. <img src={this.props.avatarUrl} alt={`${this.props.author}'s picture`} />
  183. <p className="comment-header">{this.props.author}</p>
  184. <p className="comment-body">{commentBody}</p>
  185. <div className="comment-actions">
  186. <RemoveCommentConfirmation onDelete={this._handleDelete.bind(this)} />
  187. <a href="#" onClick={this._toggleAbuse.bind(this)}>Report as Abuse</a>
  188. </div>
  189. </div>
  190. );
  191. }
  192.  
  193. _toggleAbuse(event) {
  194. event.preventDefault();
  195.  
  196. this.setState({
  197. isAbusive: !this.state.isAbusive
  198. });
  199. }
  200.  
  201. _handleDelete() {
  202. this.props.onDelete(this.props.id);
  203. }
  204. }
  205.  
  206. class RemoveCommentConfirmation extends React.Component {
  207. constructor() {
  208. super();
  209.  
  210. this.state = {
  211.  
  212. showConfirm: false
  213.  
  214. };
  215. }
  216.  
  217. render() {
  218. let confirmNode;
  219. if (this.state.showConfirm) {
  220. return (
  221. <span>
  222. <a href="" onClick={this._confirmDelete.bind(this)}>Yes </a> - or - <a href="" onClick={this._toggleConfirmMessage.bind(this)}> No</a>
  223. </span>
  224. );
  225. } else {
  226. confirmNode = <a href="" onClick={this._toggleConfirmMessage.bind(this)}>Delete comment?</a>;
  227. }
  228. return (
  229. <span>{confirmNode}</span>
  230. );
  231. }
  232.  
  233. _toggleConfirmMessage(e) {
  234. e.preventDefault();
  235.  
  236. this.setState({
  237. showConfirm: !this.state.showConfirm
  238. });
  239. }
  240.  
  241. _confirmDelete(e) {
  242. e.preventDefault();
  243.  
  244. this.props.onDelete()
  245.  
  246. }
  247. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement