|
@@ -2,6 +2,7 @@
|
|
|
/* eslint-disable react/no-access-state-in-setstate */
|
|
/* eslint-disable react/no-access-state-in-setstate */
|
|
|
import React from 'react';
|
|
import React from 'react';
|
|
|
import PropTypes from 'prop-types';
|
|
import PropTypes from 'prop-types';
|
|
|
|
|
+import Button from 'react-bootstrap/es/Button';
|
|
|
|
|
|
|
|
import { Subscribe } from 'unstated';
|
|
import { Subscribe } from 'unstated';
|
|
|
|
|
|
|
@@ -47,6 +48,7 @@ class PageComments extends React.Component {
|
|
|
this.showDeleteConfirmModal = this.showDeleteConfirmModal.bind(this);
|
|
this.showDeleteConfirmModal = this.showDeleteConfirmModal.bind(this);
|
|
|
this.closeDeleteConfirmModal = this.closeDeleteConfirmModal.bind(this);
|
|
this.closeDeleteConfirmModal = this.closeDeleteConfirmModal.bind(this);
|
|
|
this.replyButtonClickedHandler = this.replyButtonClickedHandler.bind(this);
|
|
this.replyButtonClickedHandler = this.replyButtonClickedHandler.bind(this);
|
|
|
|
|
+ this.commentButtonClickedHandler = this.commentButtonClickedHandler.bind(this);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
componentWillMount() {
|
|
componentWillMount() {
|
|
@@ -98,19 +100,24 @@ class PageComments extends React.Component {
|
|
|
this.setState({ showEditorIds: ids });
|
|
this.setState({ showEditorIds: ids });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // inserts reply after each corresponding comment
|
|
|
|
|
- reorderBasedOnReplies(comments, replies) {
|
|
|
|
|
- // const connections = this.findConnections(comments, replies);
|
|
|
|
|
- // const replyConnections = this.findConnectionsWithinReplies(replies);
|
|
|
|
|
- const repliesReversed = replies.slice().reverse();
|
|
|
|
|
- for (let i = 0; i < comments.length; i++) {
|
|
|
|
|
- for (let j = 0; j < repliesReversed.length; j++) {
|
|
|
|
|
- if (repliesReversed[j].replyTo === comments[i]._id) {
|
|
|
|
|
- comments.splice(i + 1, 0, repliesReversed[j]);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ commentButtonClickedHandler(commentId) {
|
|
|
|
|
+ this.setState((prevState) => {
|
|
|
|
|
+ prevState.showEditorIds.delete(commentId);
|
|
|
|
|
+ return {
|
|
|
|
|
+ showEditorIds: prevState.showEditorIds,
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // adds replies to specific comment object
|
|
|
|
|
+ addRepliesToComments(comment, replies) {
|
|
|
|
|
+ const replyList = [];
|
|
|
|
|
+ replies.forEach((reply) => {
|
|
|
|
|
+ if (reply.replyTo === comment._id) {
|
|
|
|
|
+ replyList.push(reply);
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- return comments;
|
|
|
|
|
|
|
+ });
|
|
|
|
|
+ return replyList;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -121,11 +128,14 @@ class PageComments extends React.Component {
|
|
|
* @memberOf PageComments
|
|
* @memberOf PageComments
|
|
|
*/
|
|
*/
|
|
|
generateCommentElements(comments, replies) {
|
|
generateCommentElements(comments, replies) {
|
|
|
- const commentsWithReplies = this.reorderBasedOnReplies(comments, replies);
|
|
|
|
|
- return commentsWithReplies.map((comment) => {
|
|
|
|
|
|
|
+ return comments.map((comment) => {
|
|
|
|
|
|
|
|
const commentId = comment._id;
|
|
const commentId = comment._id;
|
|
|
const showEditor = this.state.showEditorIds.has(commentId);
|
|
const showEditor = this.state.showEditorIds.has(commentId);
|
|
|
|
|
+ const crowi = this.props.crowi;
|
|
|
|
|
+ const username = crowi.me;
|
|
|
|
|
+
|
|
|
|
|
+ const replyList = this.addRepliesToComments(comment, replies);
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<div key={commentId}>
|
|
<div key={commentId}>
|
|
@@ -133,18 +143,45 @@ class PageComments extends React.Component {
|
|
|
comment={comment}
|
|
comment={comment}
|
|
|
deleteBtnClicked={this.confirmToDeleteComment}
|
|
deleteBtnClicked={this.confirmToDeleteComment}
|
|
|
crowiRenderer={this.growiRenderer}
|
|
crowiRenderer={this.growiRenderer}
|
|
|
- onReplyButtonClicked={() => { this.replyButtonClickedHandler(commentId) }}
|
|
|
|
|
crowi={this.props.crowi}
|
|
crowi={this.props.crowi}
|
|
|
|
|
+ replyList={replyList}
|
|
|
|
|
+ revisionCreatedAt={this.props.revisionCreatedAt}
|
|
|
|
|
+ revisionId={this.props.revisionId}
|
|
|
/>
|
|
/>
|
|
|
- { showEditor && (
|
|
|
|
|
- <CommentEditor
|
|
|
|
|
- crowi={this.props.crowi}
|
|
|
|
|
- crowiOriginRenderer={this.props.crowiOriginRenderer}
|
|
|
|
|
- editorOptions={this.props.editorOptions}
|
|
|
|
|
- slackChannels={this.props.slackChannels}
|
|
|
|
|
- replyTo={commentId}
|
|
|
|
|
- />
|
|
|
|
|
- )}
|
|
|
|
|
|
|
+ <div className="container-fluid">
|
|
|
|
|
+ <div className="row">
|
|
|
|
|
+ <div className="col-xs-offset-1 col-xs-11 col-sm-offset-1 col-sm-11 col-md-offset-1 col-md-11 col-lg-offset-1 col-lg-11">
|
|
|
|
|
+ { !showEditor && (
|
|
|
|
|
+ <div>
|
|
|
|
|
+ { username
|
|
|
|
|
+ && (
|
|
|
|
|
+ <div className="col-xs-offset-6 col-sm-offset-6 col-md-offset-6 col-lg-offset-6">
|
|
|
|
|
+ <Button
|
|
|
|
|
+ bsStyle="primary"
|
|
|
|
|
+ className="fcbtn btn btn-sm btn-primary btn-outline btn-rounded btn-1b"
|
|
|
|
|
+ onClick={() => { return this.replyButtonClickedHandler(commentId) }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <i className="icon-bubble"></i> Reply
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
|
|
+ { showEditor && (
|
|
|
|
|
+ <CommentEditor
|
|
|
|
|
+ crowi={this.props.crowi}
|
|
|
|
|
+ crowiOriginRenderer={this.props.crowiOriginRenderer}
|
|
|
|
|
+ editorOptions={this.props.editorOptions}
|
|
|
|
|
+ slackChannels={this.props.slackChannels}
|
|
|
|
|
+ replyTo={commentId}
|
|
|
|
|
+ commentButtonClickedHandler={this.commentButtonClickedHandler}
|
|
|
|
|
+ />
|
|
|
|
|
+ )}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <br />
|
|
|
</div>
|
|
</div>
|
|
|
);
|
|
);
|
|
|
});
|
|
});
|
|
@@ -152,11 +189,7 @@ class PageComments extends React.Component {
|
|
|
|
|
|
|
|
render() {
|
|
render() {
|
|
|
const currentComments = [];
|
|
const currentComments = [];
|
|
|
- const newerComments = [];
|
|
|
|
|
- const olderComments = [];
|
|
|
|
|
const currentReplies = [];
|
|
const currentReplies = [];
|
|
|
- const newerReplies = [];
|
|
|
|
|
- const olderReplies = [];
|
|
|
|
|
|
|
|
|
|
let comments = this.props.commentContainer.state.comments;
|
|
let comments = this.props.commentContainer.state.comments;
|
|
|
if (this.state.isLayoutTypeGrowi) {
|
|
if (this.state.isLayoutTypeGrowi) {
|
|
@@ -164,100 +197,29 @@ class PageComments extends React.Component {
|
|
|
comments = comments.slice().reverse(); // non-destructive reverse
|
|
comments = comments.slice().reverse(); // non-destructive reverse
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // divide by revisionId and createdAt
|
|
|
|
|
- const revisionId = this.props.revisionId;
|
|
|
|
|
- const revisionCreatedAt = this.props.revisionCreatedAt;
|
|
|
|
|
comments.forEach((comment) => {
|
|
comments.forEach((comment) => {
|
|
|
- // comparing ObjectId
|
|
|
|
|
- // eslint-disable-next-line eqeqeq
|
|
|
|
|
if (comment.replyTo === undefined) {
|
|
if (comment.replyTo === undefined) {
|
|
|
- // comment is not a reply
|
|
|
|
|
- if (comment.revision === revisionId) {
|
|
|
|
|
- currentComments.push(comment);
|
|
|
|
|
- }
|
|
|
|
|
- else if (Date.parse(comment.createdAt) / 1000 > revisionCreatedAt) {
|
|
|
|
|
- newerComments.push(comment);
|
|
|
|
|
- }
|
|
|
|
|
- else {
|
|
|
|
|
- olderComments.push(comment);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // comment is not a reply
|
|
|
|
|
+ currentComments.push(comment);
|
|
|
}
|
|
}
|
|
|
- else
|
|
|
|
|
|
|
+ else {
|
|
|
// comment is a reply
|
|
// comment is a reply
|
|
|
- if (comment.revision === revisionId) {
|
|
|
|
|
currentReplies.push(comment);
|
|
currentReplies.push(comment);
|
|
|
}
|
|
}
|
|
|
- else if (Date.parse(comment.createdAt) / 1000 > revisionCreatedAt) {
|
|
|
|
|
- newerReplies.push(comment);
|
|
|
|
|
- }
|
|
|
|
|
- else {
|
|
|
|
|
- olderReplies.push(comment);
|
|
|
|
|
- }
|
|
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
// generate elements
|
|
// generate elements
|
|
|
const currentElements = this.generateCommentElements(currentComments, currentReplies);
|
|
const currentElements = this.generateCommentElements(currentComments, currentReplies);
|
|
|
- const newerElements = this.generateCommentElements(newerComments, newerReplies);
|
|
|
|
|
- const olderElements = this.generateCommentElements(olderComments, olderReplies);
|
|
|
|
|
|
|
+
|
|
|
// generate blocks
|
|
// generate blocks
|
|
|
const currentBlock = (
|
|
const currentBlock = (
|
|
|
<div className="page-comments-list-current" id="page-comments-list-current">
|
|
<div className="page-comments-list-current" id="page-comments-list-current">
|
|
|
{currentElements}
|
|
{currentElements}
|
|
|
</div>
|
|
</div>
|
|
|
);
|
|
);
|
|
|
- const newerBlock = (
|
|
|
|
|
- <div className="page-comments-list-newer collapse in" id="page-comments-list-newer">
|
|
|
|
|
- {newerElements}
|
|
|
|
|
- </div>
|
|
|
|
|
- );
|
|
|
|
|
- const olderBlock = (
|
|
|
|
|
- <div className="page-comments-list-older collapse in" id="page-comments-list-older">
|
|
|
|
|
- {olderElements}
|
|
|
|
|
- </div>
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- // generate toggle elements
|
|
|
|
|
- const iconForNewer = (this.state.isLayoutTypeGrowi)
|
|
|
|
|
- ? <i className="fa fa-angle-double-down"></i>
|
|
|
|
|
- : <i className="fa fa-angle-double-up"></i>;
|
|
|
|
|
- const toggleNewer = (newerElements.length === 0)
|
|
|
|
|
- ? <div></div>
|
|
|
|
|
- : (
|
|
|
|
|
- <a className="page-comments-list-toggle-newer text-center" data-toggle="collapse" href="#page-comments-list-newer">
|
|
|
|
|
- {iconForNewer} Comments for Newer Revision {iconForNewer}
|
|
|
|
|
- </a>
|
|
|
|
|
- );
|
|
|
|
|
- const iconForOlder = (this.state.isLayoutTypeGrowi)
|
|
|
|
|
- ? <i className="fa fa-angle-double-up"></i>
|
|
|
|
|
- : <i className="fa fa-angle-double-down"></i>;
|
|
|
|
|
- const toggleOlder = (olderElements.length === 0)
|
|
|
|
|
- ? <div></div>
|
|
|
|
|
- : (
|
|
|
|
|
- <a className="page-comments-list-toggle-older text-center" data-toggle="collapse" href="#page-comments-list-older">
|
|
|
|
|
- {iconForOlder} Comments for Older Revision {iconForOlder}
|
|
|
|
|
- </a>
|
|
|
|
|
- );
|
|
|
|
|
|
|
|
|
|
// layout blocks
|
|
// layout blocks
|
|
|
- const commentsElements = (this.state.isLayoutTypeGrowi)
|
|
|
|
|
- ? (
|
|
|
|
|
- <div>
|
|
|
|
|
- {olderBlock}
|
|
|
|
|
- {toggleOlder}
|
|
|
|
|
- {currentBlock}
|
|
|
|
|
- {toggleNewer}
|
|
|
|
|
- {newerBlock}
|
|
|
|
|
- </div>
|
|
|
|
|
- )
|
|
|
|
|
- : (
|
|
|
|
|
- <div>
|
|
|
|
|
- {newerBlock}
|
|
|
|
|
- {toggleNewer}
|
|
|
|
|
- {currentBlock}
|
|
|
|
|
- {toggleOlder}
|
|
|
|
|
- {olderBlock}
|
|
|
|
|
- </div>
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ const commentsElements = (<div>{currentBlock}</div>);
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<div>
|
|
<div>
|