Răsfoiți Sursa

Merge pull request #6967 from weseek/feat/update-footer-comment-skeleton

feat: Update Footer and Comment Skeleton
Yuki Takei 3 ani în urmă
părinte
comite
2829974f50

+ 5 - 5
packages/app/src/components/Comments.tsx

@@ -3,7 +3,7 @@ import React from 'react';
 import { IRevisionHasId } from '@growi/core';
 import { IRevisionHasId } from '@growi/core';
 import dynamic from 'next/dynamic';
 import dynamic from 'next/dynamic';
 
 
-import { PageComment } from '~/components/PageComment';
+import { PageCommentProps } from '~/components/PageComment';
 import { useSWRxPageComment } from '~/stores/comment';
 import { useSWRxPageComment } from '~/stores/comment';
 import { useIsTrashPage } from '~/stores/page';
 import { useIsTrashPage } from '~/stores/page';
 
 
@@ -11,18 +11,18 @@ import { useCurrentUser } from '../stores/context';
 
 
 import { CommentEditorProps } from './PageComment/CommentEditor';
 import { CommentEditorProps } from './PageComment/CommentEditor';
 
 
-
+const PageComment = dynamic<PageCommentProps>(() => import('~/components/PageComment').then(mod => mod.PageComment), { ssr: false });
 const CommentEditor = dynamic<CommentEditorProps>(() => import('./PageComment/CommentEditor').then(mod => mod.CommentEditor), { ssr: false });
 const CommentEditor = dynamic<CommentEditorProps>(() => import('./PageComment/CommentEditor').then(mod => mod.CommentEditor), { ssr: false });
 
 
-
 type CommentsProps = {
 type CommentsProps = {
   pageId: string,
   pageId: string,
+  pagePath: string,
   revision: IRevisionHasId,
   revision: IRevisionHasId,
 }
 }
 
 
 export const Comments = (props: CommentsProps): JSX.Element => {
 export const Comments = (props: CommentsProps): JSX.Element => {
 
 
-  const { pageId, revision } = props;
+  const { pageId, pagePath, revision } = props;
 
 
   const { mutate } = useSWRxPageComment(pageId);
   const { mutate } = useSWRxPageComment(pageId);
   const { data: isDeleted } = useIsTrashPage();
   const { data: isDeleted } = useIsTrashPage();
@@ -33,13 +33,13 @@ export const Comments = (props: CommentsProps): JSX.Element => {
   }
   }
 
 
   return (
   return (
-    // TODO: Check and refactor CSS import
     <div className="page-comments-row mt-5 py-4 d-edit-none d-print-none">
     <div className="page-comments-row mt-5 py-4 d-edit-none d-print-none">
       <div className="container-lg">
       <div className="container-lg">
         <div className="page-comments">
         <div className="page-comments">
           <div id="page-comments-list" className="page-comments-list">
           <div id="page-comments-list" className="page-comments-list">
             <PageComment
             <PageComment
               pageId={pageId}
               pageId={pageId}
+              pagePath={pagePath}
               revision={revision}
               revision={revision}
               currentUser={currentUser}
               currentUser={currentUser}
               isReadOnly={false}
               isReadOnly={false}

+ 9 - 11
packages/app/src/components/PageComment.tsx

@@ -3,7 +3,6 @@ import React, {
 } from 'react';
 } from 'react';
 
 
 import { IRevisionHasId, isPopulated, getIdForRef } from '@growi/core';
 import { IRevisionHasId, isPopulated, getIdForRef } from '@growi/core';
-import dynamic from 'next/dynamic';
 import { Button } from 'reactstrap';
 import { Button } from 'reactstrap';
 
 
 import { toastError } from '~/client/util/apiNotification';
 import { toastError } from '~/client/util/apiNotification';
@@ -15,18 +14,12 @@ import { ICommentHasId, ICommentHasIdList } from '../interfaces/comment';
 import { useSWRxPageComment } from '../stores/comment';
 import { useSWRxPageComment } from '../stores/comment';
 
 
 import { Comment } from './PageComment/Comment';
 import { Comment } from './PageComment/Comment';
-import { CommentEditorProps } from './PageComment/CommentEditor';
-import { DeleteCommentModalProps } from './PageComment/DeleteCommentModal';
+import { CommentEditor } from './PageComment/CommentEditor';
+import { DeleteCommentModal } from './PageComment/DeleteCommentModal';
 import { ReplyComments } from './PageComment/ReplyComments';
 import { ReplyComments } from './PageComment/ReplyComments';
-import { PageCommentSkeleton } from './PageCommentSkeleton';
 
 
 import styles from './PageComment.module.scss';
 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 },
-);
-
 export const ROOT_ELEM_ID = 'page-comments' as const;
 export const ROOT_ELEM_ID = 'page-comments' as const;
 
 
 // Always render '#page-comments' for MutationObserver of SearchResultContent
 // Always render '#page-comments' for MutationObserver of SearchResultContent
@@ -38,6 +31,7 @@ const PageCommentRoot = (props: React.HTMLAttributes<HTMLDivElement>): JSX.Eleme
 export type PageCommentProps = {
 export type PageCommentProps = {
   rendererOptions?: RendererOptions,
   rendererOptions?: RendererOptions,
   pageId: string,
   pageId: string,
+  pagePath: string,
   revision: string | IRevisionHasId,
   revision: string | IRevisionHasId,
   currentUser: any,
   currentUser: any,
   isReadOnly: boolean,
   isReadOnly: boolean,
@@ -49,7 +43,7 @@ export const PageComment: FC<PageCommentProps> = memo((props:PageCommentProps):
 
 
   const {
   const {
     rendererOptions: rendererOptionsByProps,
     rendererOptions: rendererOptionsByProps,
-    pageId, revision, currentUser, isReadOnly, titleAlign, hideIfEmpty,
+    pageId, pagePath, revision, currentUser, isReadOnly, titleAlign, hideIfEmpty,
   } = props;
   } = props;
 
 
   const { data: comments, mutate } = useSWRxPageComment(pageId);
   const { data: comments, mutate } = useSWRxPageComment(pageId);
@@ -123,7 +117,7 @@ export const PageComment: FC<PageCommentProps> = memo((props:PageCommentProps):
       return <PageCommentRoot />;
       return <PageCommentRoot />;
     }
     }
     return (
     return (
-      <PageCommentSkeleton commentTitleClasses={commentTitleClasses}/>
+      <></>
     );
     );
   }
   }
 
 
@@ -138,6 +132,8 @@ export const PageComment: FC<PageCommentProps> = memo((props:PageCommentProps):
       revisionCreatedAt={revisionCreatedAt as Date}
       revisionCreatedAt={revisionCreatedAt as Date}
       currentUser={currentUser}
       currentUser={currentUser}
       isReadOnly={isReadOnly}
       isReadOnly={isReadOnly}
+      pageId={pageId}
+      pagePath={pagePath}
       deleteBtnClicked={onClickDeleteButton}
       deleteBtnClicked={onClickDeleteButton}
       onComment={mutate}
       onComment={mutate}
     />
     />
@@ -151,6 +147,8 @@ export const PageComment: FC<PageCommentProps> = memo((props:PageCommentProps):
       revisionCreatedAt={revisionCreatedAt as Date}
       revisionCreatedAt={revisionCreatedAt as Date}
       currentUser={currentUser}
       currentUser={currentUser}
       replyList={replyComments}
       replyList={replyComments}
+      pageId={pageId}
+      pagePath={pagePath}
       deleteBtnClicked={onClickDeleteButton}
       deleteBtnClicked={onClickDeleteButton}
       onComment={mutate}
       onComment={mutate}
     />
     />

+ 19 - 12
packages/app/src/components/PageComment/Comment.tsx

@@ -1,11 +1,12 @@
 import React, { useEffect, useMemo, useState } from 'react';
 import React, { useEffect, useMemo, useState } from 'react';
 
 
-import { IUser } from '@growi/core';
+import { IUser, pathUtils } from '@growi/core';
 import { UserPicture } from '@growi/ui';
 import { UserPicture } from '@growi/ui';
 import { format } from 'date-fns';
 import { format } from 'date-fns';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
-import dynamic from 'next/dynamic';
+import Link from 'next/link';
 import { UncontrolledTooltip } from 'reactstrap';
 import { UncontrolledTooltip } from 'reactstrap';
+import urljoin from 'url-join';
 
 
 import { RendererOptions } from '~/services/renderer/renderer';
 import { RendererOptions } from '~/services/renderer/renderer';
 
 
@@ -16,12 +17,10 @@ import RevisionRenderer from '../Page/RevisionRenderer';
 import { Username } from '../User/Username';
 import { Username } from '../User/Username';
 
 
 import { CommentControl } from './CommentControl';
 import { CommentControl } from './CommentControl';
-import { CommentEditorProps } from './CommentEditor';
+import { CommentEditor } from './CommentEditor';
 
 
 import styles from './Comment.module.scss';
 import styles from './Comment.module.scss';
 
 
-const CommentEditor = dynamic<CommentEditorProps>(() => import('./CommentEditor').then(mod => mod.CommentEditor), { ssr: false });
-
 type CommentProps = {
 type CommentProps = {
   comment: ICommentHasId,
   comment: ICommentHasId,
   rendererOptions: RendererOptions,
   rendererOptions: RendererOptions,
@@ -29,6 +28,8 @@ type CommentProps = {
   revisionCreatedAt: Date,
   revisionCreatedAt: Date,
   currentUser: IUser,
   currentUser: IUser,
   isReadOnly: boolean,
   isReadOnly: boolean,
+  pageId: string,
+  pagePath: string,
   deleteBtnClicked: (comment: ICommentHasId) => void,
   deleteBtnClicked: (comment: ICommentHasId) => void,
   onComment: () => void,
   onComment: () => void,
 }
 }
@@ -37,9 +38,11 @@ export const Comment = (props: CommentProps): JSX.Element => {
 
 
   const {
   const {
     comment, rendererOptions, revisionId, revisionCreatedAt, currentUser, isReadOnly,
     comment, rendererOptions, revisionId, revisionCreatedAt, currentUser, isReadOnly,
-    deleteBtnClicked, onComment,
+    pageId, pagePath, deleteBtnClicked, onComment,
   } = props;
   } = props;
 
 
+  const { returnPathForURL } = pathUtils;
+
   const { t } = useTranslation();
   const { t } = useTranslation();
 
 
   const [markdown, setMarkdown] = useState('');
   const [markdown, setMarkdown] = useState('');
@@ -151,9 +154,11 @@ export const Comment = (props: CommentProps): JSX.Element => {
             </div>
             </div>
             <div className="page-comment-body">{commentBody}</div>
             <div className="page-comment-body">{commentBody}</div>
             <div className="page-comment-meta">
             <div className="page-comment-meta">
-              <a href={`#${commentId}`}>
-                <FormattedDistanceDate id={commentId} date={comment.createdAt} />
-              </a>
+              <Link href={`#${commentId}`} prefetch={false}>
+                <a>
+                  <FormattedDistanceDate id={commentId} date={comment.createdAt} />
+                </a>
+              </Link>
               { isEdited && (
               { isEdited && (
                 <>
                 <>
                   <span id={editedDateId}>&nbsp;(edited)</span>
                   <span id={editedDateId}>&nbsp;(edited)</span>
@@ -161,9 +166,11 @@ export const Comment = (props: CommentProps): JSX.Element => {
                 </>
                 </>
               ) }
               ) }
               <span className="ml-2">
               <span className="ml-2">
-                <a id={`page-comment-revision-${commentId}`} className="page-comment-revision" href={revHref}>
-                  <HistoryIcon />
-                </a>
+                <Link href={urljoin(returnPathForURL(pagePath, pageId), revHref)} prefetch={false}>
+                  <a id={`page-comment-revision-${commentId}`} className="page-comment-revision">
+                    <HistoryIcon />
+                  </a>
+                </Link>
                 <UncontrolledTooltip placement="bottom" fade={false} target={`page-comment-revision-${commentId}`}>
                 <UncontrolledTooltip placement="bottom" fade={false} target={`page-comment-revision-${commentId}`}>
                   {t('page_comment.display_the_page_when_posting_this_comment')}
                   {t('page_comment.display_the_page_when_posting_this_comment')}
                 </UncontrolledTooltip>
                 </UncontrolledTooltip>

+ 5 - 1
packages/app/src/components/PageComment/ReplyComments.tsx

@@ -21,6 +21,8 @@ type ReplycommentsProps = {
   revisionCreatedAt: Date,
   revisionCreatedAt: Date,
   currentUser: IUser,
   currentUser: IUser,
   replyList: ICommentHasIdList,
   replyList: ICommentHasIdList,
+  pageId: string,
+  pagePath: string,
   deleteBtnClicked: (comment: ICommentHasId) => void,
   deleteBtnClicked: (comment: ICommentHasId) => void,
   onComment: () => void,
   onComment: () => void,
 }
 }
@@ -29,7 +31,7 @@ export const ReplyComments = (props: ReplycommentsProps): JSX.Element => {
 
 
   const {
   const {
     rendererOptions, isReadOnly, revisionId, revisionCreatedAt, currentUser, replyList,
     rendererOptions, isReadOnly, revisionId, revisionCreatedAt, currentUser, replyList,
-    deleteBtnClicked, onComment,
+    pageId, pagePath, deleteBtnClicked, onComment,
   } = props;
   } = props;
 
 
   const { data: isAllReplyShown } = useIsAllReplyShown();
   const { data: isAllReplyShown } = useIsAllReplyShown();
@@ -46,6 +48,8 @@ export const ReplyComments = (props: ReplycommentsProps): JSX.Element => {
           revisionCreatedAt={revisionCreatedAt}
           revisionCreatedAt={revisionCreatedAt}
           currentUser={currentUser}
           currentUser={currentUser}
           isReadOnly={isReadOnly}
           isReadOnly={isReadOnly}
+          pageId={pageId}
+          pagePath={pagePath}
           deleteBtnClicked={deleteBtnClicked}
           deleteBtnClicked={deleteBtnClicked}
           onComment={onComment}
           onComment={onComment}
         />
         />

+ 0 - 58
packages/app/src/components/PageCommentSkeleton.tsx

@@ -1,58 +0,0 @@
-import React from 'react';
-
-import { Skeleton } from './Skeleton';
-
-import styles from './PageComment.module.scss';
-import CommentStyles from './PageComment/Comment.module.scss';
-import CommentEditorStyles from './PageComment/CommentEditor.module.scss';
-
-type PageCommentSkeletonProps = {
-  commentTitleClasses?: string,
-  roundedPill?: boolean,
-}
-
-export const PageCommentSkeleton = (props: PageCommentSkeletonProps): JSX.Element => {
-  const {
-    commentTitleClasses,
-  } = props;
-
-  return (
-    <>
-      {/* TODO: Check the comment.html CSS */}
-      <div className={`${styles['page-comment-styles']} page-comments-row comment-list`}>
-        <div className="container-lg">
-          <div className="page-comments">
-            <h2 className={commentTitleClasses}><i className="icon-fw icon-bubbles"></i>Comments</h2>
-            <div className="page-comments-list" id="page-comments-list">
-              <div className={`${CommentStyles['comment-styles']} page-comment-thread pb-5  page-comment-thread-no-replies`}>
-                <div className='page-comment flex-column'>
-                  <div className='page-commnet-writer'>
-                    <Skeleton additionalClass='rounded-circle picture' roundedPill />
-                  </div>
-                  <Skeleton additionalClass="page-comment-comment-body-skeleton grw-skeleton" />
-                </div>
-                <div className='page-comment flex-column ml-4 ml-sm-5 mr-3'>
-                  <div className='page-commnet-writer mt-3'>
-                    <Skeleton additionalClass='rounded-circle picture' roundedPill />
-                  </div>
-                  <Skeleton additionalClass="page-comment-comment-body-skeleton grw-skeleton mt-3" />
-                </div>
-                <div className="text-right">
-                  <Skeleton additionalClass="page-comment-button-skeleton btn btn-outline-secondary btn-sm grw-skeleton" />
-                </div>
-              </div>
-            </div>
-            <div className={`${CommentEditorStyles['comment-editor-styles']} form page-comment-form`}>
-              <div className='comment-form'>
-                <div className='comment-form-user'>
-                  <Skeleton additionalClass='rounded-circle picture' roundedPill />
-                </div>
-                <Skeleton additionalClass="page-comment-commenteditorlazyrenderer-body-skeleton grw-skeleton" />
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </>
-  );
-};

+ 1 - 5
packages/app/src/components/PageContentFooter.tsx

@@ -6,14 +6,10 @@ import dynamic from 'next/dynamic';
 import { useSWRxCurrentPage } from '~/stores/page';
 import { useSWRxCurrentPage } from '~/stores/page';
 
 
 import type { AuthorInfoProps } from './Navbar/AuthorInfo';
 import type { AuthorInfoProps } from './Navbar/AuthorInfo';
-import { Skeleton } from './Skeleton';
 
 
 import styles from './PageContentFooter.module.scss';
 import styles from './PageContentFooter.module.scss';
 
 
-const AuthorInfo = dynamic<AuthorInfoProps>(() => import('./Navbar/AuthorInfo').then(mod => mod.AuthorInfo), {
-  ssr: false,
-  loading: () => <Skeleton additionalClass={`${styles['page-content-footer-skeleton']} mb-3`} />,
-});
+const AuthorInfo = dynamic<AuthorInfoProps>(() => import('./Navbar/AuthorInfo').then(mod => mod.AuthorInfo), { ssr: false });
 
 
 export type PageContentFooterProps = {
 export type PageContentFooterProps = {
   page: IPage,
   page: IPage,

+ 1 - 0
packages/app/src/components/SearchPage/SearchResultContent.tsx

@@ -262,6 +262,7 @@ export const SearchResultContent: FC<Props> = (props: Props) => {
         <PageComment
         <PageComment
           rendererOptions={rendererOptions}
           rendererOptions={rendererOptions}
           pageId={page._id}
           pageId={page._id}
+          pagePath={page.path}
           revision={page.revision}
           revision={page.revision}
           currentUser={currentUser}
           currentUser={currentUser}
           isReadOnly
           isReadOnly

+ 3 - 1
packages/app/src/pages/[[...path]].page.tsx

@@ -337,7 +337,9 @@ const GrowiPage: NextPage<Props> = (props: Props) => {
           </div>
           </div>
           { !props.isIdenticalPathPage && !props.isNotFound && (
           { !props.isIdenticalPathPage && !props.isNotFound && (
             <footer className="footer d-edit-none">
             <footer className="footer d-edit-none">
-              { pageWithMeta != null && !isTopPagePath && (<Comments pageId={pageId} revision={pageWithMeta.data.revision} />) }
+              { pageWithMeta != null && pagePath != null && !isTopPagePath && (
+                <Comments pageId={pageId} pagePath={pagePath} revision={pageWithMeta.data.revision} />
+              ) }
               { pageWithMeta != null && isUsersHomePage(pageWithMeta.data.path) && (
               { pageWithMeta != null && isUsersHomePage(pageWithMeta.data.path) && (
                 <UsersHomePageFooter creatorId={pageWithMeta.data.creator._id}/>
                 <UsersHomePageFooter creatorId={pageWithMeta.data.creator._id}/>
               ) }
               ) }