Przeglądaj źródła

Merge pull request #1646 from weseek/fix/do-not-open-the-reoly-collapse

Fix/do not open the reply collapse
itizawa 6 lat temu
rodzic
commit
c76819cb3d

+ 0 - 81
src/client/js/components/PageComment/Comment.jsx

@@ -3,10 +3,8 @@ import PropTypes from 'prop-types';
 
 import { format, formatDistanceStrict } from 'date-fns';
 
-import Button from 'react-bootstrap/es/Button';
 import Tooltip from 'react-bootstrap/es/Tooltip';
 import OverlayTrigger from 'react-bootstrap/es/OverlayTrigger';
-import Collapse from 'react-bootstrap/es/Collapse';
 
 import AppContainer from '../../services/AppContainer';
 import PageContainer from '../../services/PageContainer';
@@ -33,7 +31,6 @@ class Comment extends React.PureComponent {
 
     this.state = {
       html: '',
-      isOlderRepliesShown: false,
       isReEdit: false,
     };
 
@@ -145,14 +142,6 @@ class Comment extends React.PureComponent {
     );
   }
 
-  toggleOlderReplies() {
-    this.setState((prevState) => {
-      return {
-        showOlderReplies: !prevState.showOlderReplies,
-      };
-    });
-  }
-
   async renderHtml() {
 
     const { growiRenderer, appContainer } = this.props;
@@ -172,71 +161,6 @@ class Comment extends React.PureComponent {
     await interceptorManager.process('postRenderCommentHtml', context);
   }
 
-  renderReply(reply) {
-    return (
-      <div key={reply._id} className="page-comment-reply">
-        <CommentWrapper
-          comment={reply}
-          deleteBtnClicked={this.props.deleteBtnClicked}
-          growiRenderer={this.props.growiRenderer}
-        />
-      </div>
-    );
-  }
-
-  renderReplies() {
-    const layoutType = this.props.appContainer.getConfig().layoutType;
-    const isBaloonStyle = layoutType.match(/crowi-plus|growi|kibela/);
-
-    let replyList = this.props.replyList;
-    if (!isBaloonStyle) {
-      replyList = replyList.slice().reverse();
-    }
-
-    const areThereHiddenReplies = replyList.length > 2;
-
-    const { isOlderRepliesShown } = this.state;
-    const toggleButtonIconName = isOlderRepliesShown ? 'icon-arrow-up' : 'icon-options-vertical';
-    const toggleButtonIcon = <i className={`icon-fw ${toggleButtonIconName}`}></i>;
-    const toggleButtonLabel = isOlderRepliesShown ? '' : 'more';
-    const toggleButton = (
-      <Button
-        bsStyle="link"
-        className="page-comments-list-toggle-older"
-        onClick={() => { this.setState({ isOlderRepliesShown: !isOlderRepliesShown }) }}
-      >
-        {toggleButtonIcon} {toggleButtonLabel}
-      </Button>
-    );
-
-    const shownReplies = replyList.slice(replyList.length - 2, replyList.length);
-    const hiddenReplies = replyList.slice(0, replyList.length - 2);
-
-    const hiddenElements = hiddenReplies.map((reply) => {
-      return this.renderReply(reply);
-    });
-
-    const shownElements = shownReplies.map((reply) => {
-      return this.renderReply(reply);
-    });
-
-    return (
-      <React.Fragment>
-        {areThereHiddenReplies && (
-          <div className="page-comments-hidden-replies">
-            <Collapse in={this.state.isOlderRepliesShown}>
-              <div>{hiddenElements}</div>
-            </Collapse>
-            <div className="text-center">{toggleButton}</div>
-          </div>
-        )}
-
-        {shownElements}
-      </React.Fragment>
-    );
-  }
-
-
   render() {
     const comment = this.props.comment;
     const commentId = comment._id;
@@ -303,7 +227,6 @@ class Comment extends React.PureComponent {
           </div>
           )
         }
-        {this.renderReplies()}
 
       </React.Fragment>
     );
@@ -325,10 +248,6 @@ Comment.propTypes = {
   comment: PropTypes.object.isRequired,
   growiRenderer: PropTypes.object.isRequired,
   deleteBtnClicked: PropTypes.func.isRequired,
-  replyList: PropTypes.array,
-};
-Comment.defaultProps = {
-  replyList: [],
 };
 
 export default CommentWrapper;

+ 125 - 0
src/client/js/components/PageComment/ReplayComments.jsx

@@ -0,0 +1,125 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import Button from 'react-bootstrap/es/Button';
+import Collapse from 'react-bootstrap/es/Collapse';
+
+import AppContainer from '../../services/AppContainer';
+import PageContainer from '../../services/PageContainer';
+
+import Comment from './Comment';
+
+import { createSubscribedElement } from '../UnstatedUtils';
+
+class ReplayComments extends React.PureComponent {
+
+  constructor() {
+    super();
+
+    this.state = {
+      isOlderRepliesShown: false,
+    };
+
+    this.toggleIsOlderRepliesShown = this.toggleIsOlderRepliesShown.bind(this);
+  }
+
+  toggleIsOlderRepliesShown() {
+    this.setState({ isOlderRepliesShown: !this.state.isOlderRepliesShown });
+  }
+
+  renderReply(reply) {
+    return (
+      <div key={reply._id} className="page-comment-reply">
+        <Comment
+          comment={reply}
+          deleteBtnClicked={this.props.deleteBtnClicked}
+          growiRenderer={this.props.growiRenderer}
+        />
+      </div>
+    );
+  }
+
+  render() {
+
+    const layoutType = this.props.appContainer.getConfig().layoutType;
+    const isBaloonStyle = layoutType.match(/crowi-plus|growi|kibela/);
+
+    // TODO GW-1143 Switchable in admin page
+    const isAllReplyShown = this.props.appContainer.getConfig().isAllReplyShown || false;
+
+    let replyList = this.props.replyList;
+    if (!isBaloonStyle) {
+      replyList = replyList.slice().reverse();
+    }
+
+    if (isAllReplyShown) {
+      return (
+        <React.Fragment>
+          {replyList.map((reply) => {
+            return this.renderReply(reply);
+          })}
+        </React.Fragment>
+      );
+    }
+
+    const areThereHiddenReplies = (replyList.length > 2);
+
+    const { isOlderRepliesShown } = this.state;
+    const toggleButtonIconName = isOlderRepliesShown ? 'icon-arrow-up' : 'icon-options-vertical';
+    const toggleButtonIcon = <i className={`icon-fw ${toggleButtonIconName}`}></i>;
+    const toggleButtonLabel = isOlderRepliesShown ? '' : 'more';
+
+    const shownReplies = replyList.slice(replyList.length - 2, replyList.length);
+    const hiddenReplies = replyList.slice(0, replyList.length - 2);
+
+    const hiddenElements = hiddenReplies.map((reply) => {
+      return this.renderReply(reply);
+    });
+
+    const shownElements = shownReplies.map((reply) => {
+      return this.renderReply(reply);
+    });
+
+    return (
+      <React.Fragment>
+        {areThereHiddenReplies && (
+          <div className="page-comments-hidden-replies">
+            <Collapse in={this.state.isOlderRepliesShown}>
+              <div>{hiddenElements}</div>
+            </Collapse>
+            <div className="text-center">
+              <Button
+                bsStyle="link"
+                className="page-comments-list-toggle-older"
+                onClick={this.toggleIsOlderRepliesShown}
+              >
+                {toggleButtonIcon} {toggleButtonLabel}
+              </Button>
+            </div>
+          </div>
+        )}
+        {shownElements}
+
+      </React.Fragment>
+    );
+  }
+
+}
+
+/**
+ * Wrapper component for using unstated
+ */
+const ReplayCommentsWrapper = (props) => {
+  return createSubscribedElement(ReplayComments, props, [AppContainer, PageContainer]);
+};
+
+ReplayComments.propTypes = {
+  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+  pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
+
+  growiRenderer: PropTypes.object.isRequired,
+  deleteBtnClicked: PropTypes.func.isRequired,
+  replyList: PropTypes.array,
+};
+
+export default ReplayCommentsWrapper;

+ 7 - 1
src/client/js/components/PageComments.jsx

@@ -14,6 +14,7 @@ import { createSubscribedElement } from './UnstatedUtils';
 import CommentEditor from './PageComment/CommentEditor';
 import Comment from './PageComment/Comment';
 import DeleteCommentModal from './PageComment/DeleteCommentModal';
+import ReplayComments from './PageComment/ReplayComments';
 
 
 /**
@@ -138,11 +139,16 @@ class PageComments extends React.Component {
       <div key={commentId} className={`mb-5 ${rootClassNames}`}>
         <Comment
           comment={comment}
-          editBtnClicked={this.confirmToEditComment}
           deleteBtnClicked={this.confirmToDeleteComment}
           growiRenderer={this.growiRenderer}
+        />
+        {replies.length !== 0 && (
+        <ReplayComments
           replyList={replies}
+          deleteBtnClicked={this.confirmToDeleteComment}
+          growiRenderer={this.growiRenderer}
         />
+        )}
         { !showEditor && isLoggedIn && (
           <div className="text-right">
             <Button

+ 8 - 1
src/client/styles/scss/_comment.scss

@@ -1,11 +1,17 @@
 .main-container {
   .page-comment-main {
+    pointer-events: auto;
+
     // delete button
     .page-comment-control {
       position: absolute;
       top: 0;
       right: 0;
-      display: none; // default hidden
+      visibility: hidden;
+    }
+
+    &:hover > .page-comment-control {
+      visibility: visible;
     }
   }
 
@@ -24,6 +30,7 @@
 .page-comment {
   padding-top: 50px;
   margin-top: -50px;
+  pointer-events: none;
 }
 
 .main-container {

+ 0 - 5
src/client/styles/scss/_comment_growi.scss

@@ -103,11 +103,6 @@
     border-left: none;
   }
 
-  // show when hover
-  .page-comment-main:hover > .page-comment-control {
-    display: block;
-  }
-
   // display cheatsheet for comment form only
   .comment-form {
     .editor-cheatsheet {

+ 0 - 5
src/client/styles/scss/_comment_kibela.scss

@@ -105,11 +105,6 @@
     border-left: none;
   }
 
-  // show when hover
-  .page-comment-main:hover > .page-comment-control {
-    display: block;
-  }
-
   // display cheatsheet for comment form only
   .comment-form {
     .editor-cheatsheet {

+ 0 - 5
src/client/styles/scss/_layout_crowi_sidebar.scss

@@ -144,11 +144,6 @@
               display: none; // default hidden
             }
           }
-
-          // show controls when hover
-          .page-comment-main:hover > .page-comment-control {
-            display: block;
-          }
         }
       }
     }