ReplyComments.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import React, { useState } from 'react';
  2. import type { IUser } from '@growi/core';
  3. import { Collapse } from 'reactstrap';
  4. import type { RendererOptions } from '~/interfaces/renderer-options';
  5. import type { ICommentHasId, ICommentHasIdList } from '../../interfaces/comment';
  6. import { useIsAllReplyShown } from '../../stores/context';
  7. import { Comment } from './Comment';
  8. import styles from './ReplyComments.module.scss';
  9. type ReplycommentsProps = {
  10. rendererOptions: RendererOptions,
  11. isReadOnly: boolean,
  12. revisionId: string,
  13. revisionCreatedAt: Date,
  14. currentUser: IUser,
  15. replyList: ICommentHasIdList,
  16. pageId: string,
  17. pagePath: string,
  18. deleteBtnClicked: (comment: ICommentHasId) => void,
  19. onComment: () => void,
  20. }
  21. export const ReplyComments = (props: ReplycommentsProps): JSX.Element => {
  22. const {
  23. rendererOptions, isReadOnly, revisionId, revisionCreatedAt, currentUser, replyList,
  24. pageId, pagePath, deleteBtnClicked, onComment,
  25. } = props;
  26. const { data: isAllReplyShown } = useIsAllReplyShown();
  27. const [isOlderRepliesShown, setIsOlderRepliesShown] = useState(false);
  28. const renderReply = (reply: ICommentHasId) => {
  29. return (
  30. <div key={reply._id} className={`${styles['page-comment-reply']} ms-4 ms-sm-5 me-3`}>
  31. <Comment
  32. rendererOptions={rendererOptions}
  33. comment={reply}
  34. revisionId={revisionId}
  35. revisionCreatedAt={revisionCreatedAt}
  36. currentUser={currentUser}
  37. isReadOnly={isReadOnly}
  38. pageId={pageId}
  39. pagePath={pagePath}
  40. deleteBtnClicked={deleteBtnClicked}
  41. onComment={onComment}
  42. />
  43. </div>
  44. );
  45. };
  46. if (isAllReplyShown) {
  47. return (
  48. <>
  49. {replyList.map((reply) => {
  50. return renderReply(reply);
  51. })}
  52. </>
  53. );
  54. }
  55. const areThereHiddenReplies = (replyList.length > 2);
  56. const toggleButtonIconName = isOlderRepliesShown ? 'expand_less' : 'more_vert';
  57. const toggleButtonIcon = <span className="material-icons-outlined me-1">{toggleButtonIconName}</span>;
  58. const toggleButtonLabel = isOlderRepliesShown ? '' : 'more';
  59. const shownReplies = replyList.slice(replyList.length - 2, replyList.length);
  60. const hiddenReplies = replyList.slice(0, replyList.length - 2);
  61. const hiddenElements = hiddenReplies.map((reply) => {
  62. return renderReply(reply);
  63. });
  64. const shownElements = shownReplies.map((reply) => {
  65. return renderReply(reply);
  66. });
  67. return (
  68. <>
  69. {areThereHiddenReplies && (
  70. <div className={`${styles['page-comments-hidden-replies']}`}>
  71. <Collapse isOpen={isOlderRepliesShown}>
  72. <div>{hiddenElements}</div>
  73. </Collapse>
  74. <div className="text-center">
  75. <button
  76. type="button"
  77. className="btn btn-link"
  78. onClick={() => setIsOlderRepliesShown(!isOlderRepliesShown)}
  79. >
  80. {toggleButtonIcon} {toggleButtonLabel}
  81. </button>
  82. </div>
  83. </div>
  84. )}
  85. {shownElements}
  86. </>
  87. );
  88. };