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

re-impl SeenUserInfo and move to SubNavButtons

Yuki Takei 4 лет назад
Родитель
Сommit
62ff9dd759

+ 1 - 1
packages/app/src/components/BookmarkButtons.tsx

@@ -57,7 +57,7 @@ const BookmarkButtons: FC<Props> = (props: Props) => {
             {props.sumOfBookmarks}
             {props.sumOfBookmarks}
           </button>
           </button>
           <Popover placement="bottom" isOpen={isPopoverOpen} target="po-total-bookmarks" toggle={togglePopover} trigger="legacy">
           <Popover placement="bottom" isOpen={isPopoverOpen} target="po-total-bookmarks" toggle={togglePopover} trigger="legacy">
-            <PopoverBody className="seen-user-popover">
+            <PopoverBody className="user-list-popover">
               <div className="px-2 text-right user-list-content text-truncate text-muted">
               <div className="px-2 text-right user-list-content text-truncate text-muted">
                 {props.bookmarkedUsers.length ? <UserPictureList users={props.bookmarkedUsers} /> : t('No users have bookmarked yet')}
                 {props.bookmarkedUsers.length ? <UserPictureList users={props.bookmarkedUsers} /> : t('No users have bookmarked yet')}
               </div>
               </div>

+ 1 - 1
packages/app/src/components/LikeButtons.tsx

@@ -55,7 +55,7 @@ const LikeButtons: FC<LikeButtonsProps> = (props: LikeButtonsProps) => {
             {sumOfLikers}
             {sumOfLikers}
           </button>
           </button>
           <Popover placement="bottom" isOpen={isPopoverOpen} target="po-total-likes" toggle={togglePopover} trigger="legacy">
           <Popover placement="bottom" isOpen={isPopoverOpen} target="po-total-likes" toggle={togglePopover} trigger="legacy">
-            <PopoverBody className="seen-user-popover">
+            <PopoverBody className="user-list-popover">
               <div className="px-2 text-right user-list-content text-truncate text-muted">
               <div className="px-2 text-right user-list-content text-truncate text-muted">
                 {props.likers?.length ? <UserPictureList users={props.likers} /> : t('No users have liked this yet.')}
                 {props.likers?.length ? <UserPictureList users={props.likers} /> : t('No users have liked this yet.')}
               </div>
               </div>

+ 4 - 2
packages/app/src/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -9,7 +9,7 @@ import {
 } from '~/stores/ui';
 } from '~/stores/ui';
 import {
 import {
   useCurrentCreatedAt, useCurrentUpdatedAt, useCurrentPageId, useRevisionId, useCurrentPagePath,
   useCurrentCreatedAt, useCurrentUpdatedAt, useCurrentPageId, useRevisionId, useCurrentPagePath,
-  useCreator, useRevisionAuthor, useIsGuestUser,
+  useCreator, useRevisionAuthor, useIsGuestUser, useIsSharedUser,
 } from '~/stores/context';
 } from '~/stores/context';
 import { useSWRTagsInfo } from '~/stores/page';
 import { useSWRTagsInfo } from '~/stores/page';
 
 
@@ -33,6 +33,7 @@ const GrowiContextualSubNavigation = (props) => {
   const { data: creator } = useCreator();
   const { data: creator } = useCreator();
   const { data: revisionAuthor } = useRevisionAuthor();
   const { data: revisionAuthor } = useRevisionAuthor();
   const { data: isGuestUser } = useIsGuestUser();
   const { data: isGuestUser } = useIsGuestUser();
+  const { data: isSharedUser } = useIsSharedUser();
 
 
   const { data: isAbleToShowPageManagement } = useIsAbleToShowPageManagement();
   const { data: isAbleToShowPageManagement } = useIsAbleToShowPageManagement();
   const { data: isAbleToShowTagLabel } = useIsAbleToShowTagLabel();
   const { data: isAbleToShowTagLabel } = useIsAbleToShowTagLabel();
@@ -81,6 +82,7 @@ const GrowiContextualSubNavigation = (props) => {
             <SubNavButtons
             <SubNavButtons
               isCompactMode={isCompactMode}
               isCompactMode={isCompactMode}
               pageId={pageId}
               pageId={pageId}
+              disableSeenUserInfoPopover={isSharedUser}
               showPageControlDropdown={isAbleToShowPageManagement}
               showPageControlDropdown={isAbleToShowPageManagement}
             />
             />
           ) }
           ) }
@@ -100,7 +102,7 @@ const GrowiContextualSubNavigation = (props) => {
   }, [
   }, [
     pageId,
     pageId,
     editorMode, mutateEditorMode,
     editorMode, mutateEditorMode,
-    isCompactMode, isDeviceSmallerThanMd, isGuestUser,
+    isCompactMode, isDeviceSmallerThanMd, isGuestUser, isSharedUser,
     isViewMode, isAbleToShowPageEditorModeManager, isAbleToShowPageManagement,
     isViewMode, isAbleToShowPageEditorModeManager, isAbleToShowPageManagement,
   ]);
   ]);
 
 

+ 13 - 3
packages/app/src/components/Navbar/SubNavButtons.tsx

@@ -4,6 +4,7 @@ import { toastError } from '../../client/util/apiNotification';
 import { apiv3Put } from '../../client/util/apiv3-client';
 import { apiv3Put } from '../../client/util/apiv3-client';
 
 
 import { IPageInfo, isExistPageInfo } from '~/interfaces/page';
 import { IPageInfo, isExistPageInfo } from '~/interfaces/page';
+import { SubscriptionStatusType } from '~/interfaces/subscription';
 
 
 import { useSWRxPageInfo } from '../../stores/page';
 import { useSWRxPageInfo } from '../../stores/page';
 import { useSWRBookmarkInfo } from '../../stores/bookmark';
 import { useSWRBookmarkInfo } from '../../stores/bookmark';
@@ -13,11 +14,12 @@ import { useIsGuestUser } from '~/stores/context';
 import SubscribeButton from '../SubscribeButton';
 import SubscribeButton from '../SubscribeButton';
 import LikeButtons from '../LikeButtons';
 import LikeButtons from '../LikeButtons';
 import BookmarkButtons from '../BookmarkButtons';
 import BookmarkButtons from '../BookmarkButtons';
-import { SubscriptionStatusType } from '~/interfaces/subscription';
+import SeenUserInfo from '../User/SeenUserInfo';
 
 
 
 
 type CommonProps = {
 type CommonProps = {
   isCompactMode?: boolean,
   isCompactMode?: boolean,
+  disableSeenUserInfoPopover?: boolean,
   showPageControlDropdown?: boolean,
   showPageControlDropdown?: boolean,
 }
 }
 
 
@@ -28,16 +30,23 @@ type SubNavButtonsSubstanceProps= CommonProps & {
 
 
 const SubNavButtonsSubstance = (props: SubNavButtonsSubstanceProps): JSX.Element => {
 const SubNavButtonsSubstance = (props: SubNavButtonsSubstanceProps): JSX.Element => {
   const {
   const {
-    pageInfo, pageId, isCompactMode, showPageControlDropdown,
+    pageInfo, pageId, isCompactMode, disableSeenUserInfoPopover, showPageControlDropdown,
   } = props;
   } = props;
 
 
   const { data: isGuestUser } = useIsGuestUser();
   const { data: isGuestUser } = useIsGuestUser();
 
 
   const { mutate: mutatePageInfo } = useSWRxPageInfo(pageId);
   const { mutate: mutatePageInfo } = useSWRxPageInfo(pageId);
 
 
-  const { data: likers } = useSWRxUsersList(pageInfo.likerIds);
   const { data: bookmarkInfo, error: bookmarkInfoError, mutate: mutateBookmarkInfo } = useSWRBookmarkInfo(pageId, true);
   const { data: bookmarkInfo, error: bookmarkInfoError, mutate: mutateBookmarkInfo } = useSWRBookmarkInfo(pageId, true);
 
 
+  const likerIds = pageInfo.likerIds != null ? pageInfo.likerIds.slice(0, 15) : [];
+  const seenUserIds = pageInfo.seenUserIds != null ? pageInfo.seenUserIds.slice(0, 15) : [];
+
+  // Put in a mixture of seenUserIds and likerIds data to make the cache work
+  const { data: usersList } = useSWRxUsersList([...likerIds, ...seenUserIds]);
+  const likers = usersList != null ? usersList.filter(({ _id }) => likerIds.includes(_id)).slice(0, 15) : [];
+  const seenUsers = usersList != null ? usersList.filter(({ _id }) => seenUserIds.includes(_id)).slice(0, 15) : [];
+
   const subscribeClickhandler = useCallback(async() => {
   const subscribeClickhandler = useCallback(async() => {
     if (isGuestUser == null || isGuestUser) {
     if (isGuestUser == null || isGuestUser) {
       return;
       return;
@@ -113,6 +122,7 @@ const SubNavButtonsSubstance = (props: SubNavButtonsSubstanceProps): JSX.Element
         bookmarkedUsers={bookmarkedUsers}
         bookmarkedUsers={bookmarkedUsers}
         onBookMarkClicked={bookmarkClickHandler}
         onBookMarkClicked={bookmarkClickHandler}
       />
       />
+      <SeenUserInfo seenUsers={seenUsers} disabled={disableSeenUserInfoPopover} />
       { showPageControlDropdown && (
       { showPageControlDropdown && (
         /*
         /*
           TODO:
           TODO:

+ 0 - 5
packages/app/src/components/PageAccessoriesModalControl.jsx

@@ -11,7 +11,6 @@ import TimeLineIcon from './Icons/TimeLineIcon';
 import HistoryIcon from './Icons/HistoryIcon';
 import HistoryIcon from './Icons/HistoryIcon';
 import AttachmentIcon from './Icons/AttachmentIcon';
 import AttachmentIcon from './Icons/AttachmentIcon';
 import ShareLinkIcon from './Icons/ShareLinkIcon';
 import ShareLinkIcon from './Icons/ShareLinkIcon';
-import SeenUserInfo from './User/SeenUserInfo';
 
 
 import { withUnstatedContainers } from './UnstatedUtils';
 import { withUnstatedContainers } from './UnstatedUtils';
 
 
@@ -91,10 +90,6 @@ const PageAccessoriesModalControl = (props) => {
           </Fragment>
           </Fragment>
         );
         );
       })}
       })}
-      <div className="d-flex align-items-center">
-        <span className="border-left grw-border-vr">&nbsp;</span>
-        <SeenUserInfo disabled={isSharedUser} pageId={pageId} />
-      </div>
     </div>
     </div>
   );
   );
 };
 };

+ 8 - 16
packages/app/src/components/User/SeenUserInfo.tsx

@@ -3,40 +3,32 @@ import React, { FC, useState } from 'react';
 import { Button, Popover, PopoverBody } from 'reactstrap';
 import { Button, Popover, PopoverBody } from 'reactstrap';
 import { FootstampIcon } from '@growi/ui';
 import { FootstampIcon } from '@growi/ui';
 
 
+import { IUser } from '~/interfaces/user';
+
 import UserPictureList from './UserPictureList';
 import UserPictureList from './UserPictureList';
-import { useSWRxPageInfo } from '~/stores/page';
-import { useSWRxUsersList } from '~/stores/user';
 
 
 interface Props {
 interface Props {
-  pageId: string,
-  disabled: boolean
+  seenUsers: IUser[],
+  disabled?: boolean,
 }
 }
 
 
 const SeenUserInfo: FC<Props> = (props: Props) => {
 const SeenUserInfo: FC<Props> = (props: Props) => {
-  const { pageId, disabled } = props;
-
   const [isPopoverOpen, setIsPopoverOpen] = useState(false);
   const [isPopoverOpen, setIsPopoverOpen] = useState(false);
 
 
-  const { data: pageInfo } = useSWRxPageInfo(pageId);
-  const likerIds = pageInfo?.likerIds != null ? pageInfo.likerIds.slice(0, 15) : [];
-  const seenUserIds = pageInfo?.seenUserIds != null ? pageInfo.seenUserIds.slice(0, 15) : [];
-
-  // Put in a mixture of seenUserIds and likerIds data to make the cache work
-  const { data: usersList } = useSWRxUsersList([...likerIds, ...seenUserIds]);
-  const seenUsers = usersList != null ? usersList.filter(({ _id }) => seenUserIds.includes(_id)).slice(0, 15) : [];
+  const { seenUsers, disabled } = props;
 
 
   const togglePopover = () => setIsPopoverOpen(!isPopoverOpen);
   const togglePopover = () => setIsPopoverOpen(!isPopoverOpen);
 
 
   return (
   return (
     <div className="grw-seen-user-info">
     <div className="grw-seen-user-info">
-      <Button id="po-seen-user" color="link" className="px-2">
+      <Button id="btn-seen-user" color="link" className="btn-seen-user">
         <span className="mr-1 footstamp-icon">
         <span className="mr-1 footstamp-icon">
           <FootstampIcon />
           <FootstampIcon />
         </span>
         </span>
         <span className="seen-user-count">{seenUsers.length}</span>
         <span className="seen-user-count">{seenUsers.length}</span>
       </Button>
       </Button>
-      <Popover placement="bottom" isOpen={isPopoverOpen} target="po-seen-user" toggle={togglePopover} trigger="legacy" disabled={disabled}>
-        <PopoverBody className="seen-user-popover">
+      <Popover placement="bottom" isOpen={isPopoverOpen} target="btn-seen-user" toggle={togglePopover} trigger="legacy" disabled={disabled}>
+        <PopoverBody className="user-list-popover">
           <div className="px-2 text-right user-list-content text-truncate text-muted">
           <div className="px-2 text-right user-list-content text-truncate text-muted">
             <UserPictureList users={seenUsers} />
             <UserPictureList users={seenUsers} />
           </div>
           </div>

+ 0 - 27
packages/app/src/styles/_page-accessories-control.scss

@@ -15,31 +15,4 @@
     height: 25px;
     height: 25px;
     border-left: solid 1px transparent;
     border-left: solid 1px transparent;
   }
   }
-
-  .seen-user-count {
-    font-size: 12px;
-    font-weight: bolder;
-  }
-  .grw-seen-user-info {
-    .btn {
-      white-space: nowrap;
-    }
-  }
-
-  .seen-user-popover {
-    max-width: 200px;
-
-    .user-list-content {
-      direction: rtl;
-
-      .liker-user-count,
-      .seen-user-count {
-        font-size: 12px;
-        font-weight: bolder;
-      }
-    }
-    .cls-1 {
-      isolation: isolate;
-    }
-  }
 }
 }

+ 45 - 6
packages/app/src/styles/_subnav.scss

@@ -38,22 +38,44 @@
     }
     }
   }
   }
 
 
-  .btn-like,
-  .btn-bookmark,
   .btn-subscribe {
   .btn-subscribe {
     height: 40px;
     height: 40px;
     font-size: 20px;
     font-size: 20px;
   }
   }
-  .grw-btn-page-management {
+
+  .btn-like,
+  .btn-bookmark,
+  .btn-seen-user {
     height: 40px;
     height: 40px;
-    font-size: 16px;
+    padding-right: 6px;
+    padding-left: 8px;
+    font-size: 20px;
+    svg {
+      width: 20px;
+      height: 20px;
+    }
   }
   }
-
   .total-likes,
   .total-likes,
   .total-bookmarks {
   .total-bookmarks {
-    font-size: 17px;
+    display: flex;
+    align-items: end;
+    padding-right: 8px;
+    padding-left: 6px;
+    font-size: 14px;
     font-weight: $font-weight-bold;
     font-weight: $font-weight-bold;
   }
   }
+  .seen-user-count {
+    padding-right: 6px;
+    padding-left: 6px;
+    font-size: 14px;
+    font-weight: $font-weight-bold;
+    vertical-align: bottom;
+  }
+
+  .grw-btn-page-management {
+    height: 40px;
+    font-size: 16px;
+  }
 
 
   ul.authors {
   ul.authors {
     li {
     li {
@@ -133,3 +155,20 @@ $easeInOutCubic: cubic-bezier(0.65, 0, 0.35, 1);
     }
     }
   }
   }
 }
 }
+
+.user-list-popover {
+  max-width: 200px;
+
+  .user-list-content {
+    direction: rtl;
+
+    .liker-user-count,
+    .seen-user-count {
+      font-size: 12px;
+      font-weight: bolder;
+    }
+  }
+  .cls-1 {
+    isolation: isolate;
+  }
+}

+ 3 - 3
packages/app/src/styles/atoms/_buttons.scss

@@ -1,5 +1,5 @@
 .btn.btn-like {
 .btn.btn-like {
-  @include button-outline-variant($secondary, lighten($red, 15%), rgba(lighten($red, 10%), 0.15), rgba(lighten($red, 10%), 0.5));
+  @include button-outline-variant(rgba($secondary, 50%), lighten($red, 15%), rgba(lighten($red, 10%), 0.15), rgba(lighten($red, 10%), 0.5));
   &:not(:disabled):not(.disabled):active,
   &:not(:disabled):not(.disabled):active,
   &:not(:disabled):not(.disabled).active {
   &:not(:disabled):not(.disabled).active {
     color: lighten($red, 15%);
     color: lighten($red, 15%);
@@ -11,7 +11,7 @@
 }
 }
 
 
 .btn.btn-bookmark {
 .btn.btn-bookmark {
-  @include button-outline-variant($secondary, $orange, rgba(lighten($orange, 20%), 0.5), rgba(lighten($orange, 20%), 0.5));
+  @include button-outline-variant(rgba($secondary, 50%), $orange, rgba(lighten($orange, 20%), 0.5), rgba(lighten($orange, 20%), 0.5));
   &:not(:disabled):not(.disabled):active,
   &:not(:disabled):not(.disabled):active,
   &:not(:disabled):not(.disabled).active {
   &:not(:disabled):not(.disabled).active {
     color: $orange;
     color: $orange;
@@ -23,7 +23,7 @@
 }
 }
 
 
 .btn.btn-subscribe {
 .btn.btn-subscribe {
-  @include button-outline-variant($secondary, $success, rgba(lighten($success, 10%), 0.15), rgba(lighten($success, 10%), 0.5));
+  @include button-outline-variant(rgba($secondary, 50%), $success, rgba(lighten($success, 10%), 0.15), rgba(lighten($success, 10%), 0.5));
   &:not(:disabled):not(.disabled):active,
   &:not(:disabled):not(.disabled):active,
   &:not(:disabled):not(.disabled).active {
   &:not(:disabled):not(.disabled).active {
     color: lighten($success, 15%);
     color: lighten($success, 15%);

+ 0 - 2
packages/ui/src/components/SearchPage/FootstampIcon.jsx

@@ -3,8 +3,6 @@ import React from 'react';
 export const FootstampIcon = () => (
 export const FootstampIcon = () => (
   <svg
   <svg
     xmlns="http://www.w3.org/2000/svg"
     xmlns="http://www.w3.org/2000/svg"
-    width="16"
-    height="16"
     viewBox="0 0 16 16"
     viewBox="0 0 16 16"
   >
   >
     <path d="M7.34,8,3.31,9a1.83,1.83,0,0,1-1.24-.08A1.28,1.28,0,0,1,1.34,8a3.24,3.24,0,0,1,.2-1.82A6.06,6.06,0,0,1,2.6,4.35h0a2.56,
     <path d="M7.34,8,3.31,9a1.83,1.83,0,0,1-1.24-.08A1.28,1.28,0,0,1,1.34,8a3.24,3.24,0,0,1,.2-1.82A6.06,6.06,0,0,1,2.6,4.35h0a2.56,