Просмотр исходного кода

Merge pull request #6445 from weseek/support/DeleteCommentModal-ccr

support: DeleteCommentModal client side rendering
Yohei Shiina 3 лет назад
Родитель
Сommit
abbf22e384

+ 7 - 4
packages/app/src/components/PageComment.tsx

@@ -17,13 +17,16 @@ import { useSWRxPageComment } from '../stores/comment';
 import { Comment } from './PageComment/Comment';
 import { CommentEditorProps } from './PageComment/CommentEditor';
 import { CommentEditorLazyRenderer } from './PageComment/CommentEditorLazyRenderer';
-import { DeleteCommentModal } from './PageComment/DeleteCommentModal';
+import { DeleteCommentModalProps } from './PageComment/DeleteCommentModal';
 import { ReplyComments } from './PageComment/ReplyComments';
 import { PageCommentSkelton } from './PageCommentSkelton';
 
 import styles from './PageComment.module.scss';
 
 const CommentEditor = dynamic<CommentEditorProps>(() => import('./PageComment/CommentEditor').then(mod => mod.CommentEditor), { ssr: false });
+const DeleteCommentModal = dynamic<DeleteCommentModalProps>(
+  () => import('./PageComment/DeleteCommentModal').then(mod => mod.DeleteCommentModal), { ssr: false },
+);
 
 
 type PageCommentProps = {
@@ -228,13 +231,13 @@ export const PageComment: FC<PageCommentProps> = memo((props:PageCommentProps):
           </div>
         </div>
       </div>
-      {(!isReadOnly && commentToBeDeleted != null) && (
+      {!isReadOnly && (
         <DeleteCommentModal
           isShown={isDeleteConfirmModalShown}
           comment={commentToBeDeleted}
           errorMessage={errorMessageOnDelete}
-          cancel={onCancelDeleteComment}
-          confirmedToDelete={onDeleteComment}
+          cancelToDelete={onCancelDeleteComment}
+          confirmToDelete={onDeleteComment}
         />
       )}
     </>

+ 59 - 32
packages/app/src/components/PageComment/DeleteCommentModal.tsx

@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useMemo } from 'react';
 
 import { UserPicture } from '@growi/ui';
 import { format } from 'date-fns';
@@ -12,55 +12,82 @@ import Username from '../User/Username';
 import styles from './DeleteCommentModal.module.scss';
 
 
-type DeleteCommentModalProps = {
+export type DeleteCommentModalProps = {
   isShown: boolean,
-  comment: ICommentHasId,
+  comment: ICommentHasId | null,
   errorMessage: string,
-  cancel: () => void, // for cancel evnet handling
-  confirmedToDelete: () => void, // for confirmed event handling
+  cancelToDelete: () => void,
+  confirmToDelete: () => void,
 }
 
 export const DeleteCommentModal = (props: DeleteCommentModalProps): JSX.Element => {
-
   const {
-    isShown, comment, errorMessage, cancel, confirmedToDelete,
+    isShown, comment, errorMessage, cancelToDelete, confirmToDelete,
   } = props;
 
-  /*
-   * the threshold for omitting body
-   */
-  const OMIT_BODY_THRES = 400;
+  const HeaderContent = useMemo(() => {
+    if (comment == null || isShown === false) {
+      return <></>;
+    }
+    return (
+      <span>
+        <i className="icon-fw icon-fire"></i>
+        Delete comment?
+      </span>
+    );
+  }, [comment, isShown]);
 
-  const commentDate = format(new Date(comment.createdAt), 'yyyy/MM/dd HH:mm');
+  const BodyContent = useMemo(() => {
+    if (comment == null || isShown === false) {
+      return <></>;
+    }
 
-  // generate body
-  let commentBody = comment.comment;
-  if (commentBody.length > OMIT_BODY_THRES) { // omit
-    commentBody = `${commentBody.substr(0, OMIT_BODY_THRES)}...`;
-  }
-  const commentBodyElement = <span style={{ whiteSpace: 'pre-wrap' }}>{commentBody}</span>;
+    // the threshold for omitting body
+    const OMIT_BODY_THRES = 400;
 
-  return (
-    <Modal isOpen={isShown} toggle={cancel} className={`${styles['page-comment-delete-modal']}`}>
-      <ModalHeader tag="h4" toggle={cancel} className="bg-danger text-light">
-        <span>
-          <i className="icon-fw icon-fire"></i>
-          Delete comment?
-        </span>
-      </ModalHeader>
-      <ModalBody>
+    const commentDate = format(new Date(comment.createdAt), 'yyyy/MM/dd HH:mm');
+
+    let commentBody = comment.comment;
+    if (commentBody.length > OMIT_BODY_THRES) { // omit
+      commentBody = `${commentBody.substr(0, OMIT_BODY_THRES)}...`;
+    }
+    const commentBodyElement = <span style={{ whiteSpace: 'pre-wrap' }}>{commentBody}</span>;
+
+    return (
+      <>
         <UserPicture user={comment.creator} size="xs" /> <strong><Username user={comment.creator}></Username></strong> wrote on {commentDate}:
         <p className="card well comment-body mt-2 p-2">{commentBodyElement}</p>
-      </ModalBody>
-      <ModalFooter>
+      </>
+    );
+  }, [comment, isShown]);
+
+  const FooterContent = useMemo(() => {
+    if (comment == null || isShown === false) {
+      return <></>;
+    }
+    return (
+      <>
         <span className="text-danger">{errorMessage}</span>&nbsp;
-        <Button onClick={cancel}>Cancel</Button>
-        <Button color="danger" onClick={confirmedToDelete}>
+        <Button onClick={cancelToDelete}>Cancel</Button>
+        <Button color="danger" onClick={confirmToDelete}>
           <i className="icon icon-fire"></i>
           Delete
         </Button>
+      </>
+    );
+  }, [cancelToDelete, comment, confirmToDelete, errorMessage, isShown]);
+
+  return (
+    <Modal isOpen={isShown} toggle={cancelToDelete} className={`${styles['page-comment-delete-modal']}`}>
+      <ModalHeader tag="h4" toggle={cancelToDelete} className="bg-danger text-light">
+        {HeaderContent}
+      </ModalHeader>
+      <ModalBody>
+        {BodyContent}
+      </ModalBody>
+      <ModalFooter>
+        {FooterContent}
       </ModalFooter>
     </Modal>
   );
-
 };