Mao 4 лет назад
Родитель
Сommit
0f34278231

+ 7 - 20
packages/app/src/components/LikeButtons.jsx

@@ -32,31 +32,17 @@ class LikeButtons extends React.Component {
     }));
   }
 
-  async handleClick() {
-    const {
-      appContainer, pageId, isLiked, onChangeInvoked,
-    } = this.props;
-    const { isGuestUser } = appContainer;
 
-    if (isGuestUser) {
+  handleClick() {
+    if (this.props.onLikeClicked == null) {
       return;
     }
-
-    try {
-      const toggleLike = !isLiked;
-      await apiv3Put('/page/likes', { pageId, bool: toggleLike });
-      if (onChangeInvoked !== null) {
-        await onChangeInvoked();
-      }
-    }
-    catch (err) {
-      toastError(err);
-    }
+    this.props.onLikeClicked();
   }
 
   render() {
     const {
-      appContainer, likers, sumOfLikers, isLiked, t,
+      appContainer, likerIds, sumOfLikers, isLiked, t,
     } = this.props;
     const { isGuestUser } = appContainer;
 
@@ -83,7 +69,7 @@ class LikeButtons extends React.Component {
         <Popover placement="bottom" isOpen={this.state.isPopoverOpen} target="po-total-likes" toggle={this.togglePopover} trigger="legacy">
           <PopoverBody className="seen-user-popover">
             <div className="px-2 text-right user-list-content text-truncate text-muted">
-              {likers.length ? <UserPictureList users={likers} /> : t('No users have liked this yet.')}
+              {likerIds.length ? <UserPictureList users={likerIds} /> : t('No users have liked this yet.')}
             </div>
           </PopoverBody>
         </Popover>
@@ -102,9 +88,10 @@ LikeButtons.propTypes = {
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   onChangeInvoked: PropTypes.func,
   pageId: PropTypes.string.isRequired,
-  likers: PropTypes.arrayOf(PropTypes.object).isRequired,
+  likerIds: PropTypes.arrayOf(PropTypes.object).isRequired,
   sumOfLikers: PropTypes.number.isRequired,
   isLiked: PropTypes.bool.isRequired,
+  onLikeClicked: PropTypes.func,
   t: PropTypes.func.isRequired,
 };
 

+ 1 - 1
packages/app/src/components/Navbar/GrowiSubNavigation.jsx

@@ -59,7 +59,7 @@ const GrowiSubNavigation = (props) => {
 
         <div className="d-flex flex-column align-items-end">
           <div className="d-flex">
-            <SubnavButtons isCompactMode={isCompactMode} />
+            <SubnavButtons isCompactMode={isCompactMode} pageId={pageId} />
           </div>
           <div className="mt-2">
             {pageContainer.isAbleToShowPageEditorModeManager && (

+ 0 - 54
packages/app/src/components/Navbar/SubNavButtons.jsx

@@ -1,54 +0,0 @@
-import React, { useEffect } from 'react';
-import PropTypes from 'prop-types';
-import AppContainer from '~/client/services/AppContainer';
-import NavigationContainer from '~/client/services/NavigationContainer';
-import PageContainer from '~/client/services/PageContainer';
-import { withUnstatedContainers } from '../UnstatedUtils';
-
-import PageReactionButtons from '../PageReactionButtons';
-import PageManagement from '../Page/PageManagement';
-
-
-const SubnavButtons = (props) => {
-  const {
-    appContainer, navigationContainer, pageContainer, isCompactMode,
-  } = props;
-
-  const { pageId } = pageContainer.state;
-  const { editorMode } = navigationContainer.state;
-  const isViewMode = editorMode === 'view';
-  const { sumOfLikers, likerIds, isLiked } = pageContainer.state;
-  return (
-    <>
-      {isViewMode && (
-        <>
-          {pageContainer.isAbleToShowPageReactionButtons && (
-            <PageReactionButtons
-              pageId={pageId}
-              currentUserId={appContainer.state.currentUserId}
-              likerSum={sumOfLikers}
-              likerIds={likerIds}
-              isAlreadyLiked={isLiked}
-            />
-          )}
-          {pageContainer.isAbleToShowPageManagement && <PageManagement isCompactMode={isCompactMode} />}
-        </>
-      )}
-    </>
-  );
-};
-
-/**
- * Wrapper component for using unstated
- */
-const SubnavButtonsWrapper = withUnstatedContainers(SubnavButtons, [AppContainer, NavigationContainer, PageContainer]);
-
-SubnavButtons.propTypes = {
-  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
-  navigationContainer: PropTypes.instanceOf(NavigationContainer).isRequired,
-  pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
-
-  isCompactMode: PropTypes.bool,
-};
-
-export default SubnavButtonsWrapper;

+ 80 - 0
packages/app/src/components/Navbar/SubNavButtons.tsx

@@ -0,0 +1,80 @@
+import React, {
+  FC, useCallback,
+} from 'react';
+import AppContainer from '../../client/services/AppContainer';
+import NavigationContainer from '../../client/services/NavigationContainer';
+import { withUnstatedContainers } from '../UnstatedUtils';
+
+import PageReactionButtons from '../PageReactionButtons';
+import PageManagement from '../Page/PageManagement';
+import { useSWRPageInfo } from '../../stores/page';
+import { toastError } from '../../client/util/apiNotification';
+import { apiv3Put } from '../../client/util/apiv3-client';
+
+
+type SubNavButtonsProps= {
+  appContainer: AppContainer,
+  navigationContainer: NavigationContainer,
+  isCompactMode?: boolean,
+  pageId: string,
+}
+const SubNavButtons: FC<SubNavButtonsProps> = (props: SubNavButtonsProps) => {
+  const {
+    appContainer, navigationContainer, isCompactMode, pageId,
+  } = props;
+  const { editorMode } = navigationContainer.state;
+  const isViewMode = editorMode === 'view';
+  const { data: pageInfo, error: pageInfoError, mutate: mutatePageInfo } = useSWRPageInfo(pageId);
+
+  const onLikeClicked = useCallback(async(isLiked) => {
+    const { isGuestUser } = appContainer;
+
+    if (isGuestUser) {
+      return;
+    }
+
+    try {
+      await apiv3Put('/page/likes', { pageId, bool: !isLiked });
+      mutatePageInfo();
+    }
+    catch (err) {
+      toastError(err);
+    }
+  }, []);
+
+
+  if (pageInfoError != null || pageInfo == null) {
+    return <></>;
+  }
+  const { sumOfLikers, likerIds, isLiked } = pageInfo;
+
+  return (
+    <>
+      {isViewMode && (
+        <PageReactionButtons
+          pageId={pageId}
+          sumOfLikers={sumOfLikers}
+          likerIds={likerIds}
+          isLiked={isLiked}
+          onLikeClicked={() => {
+            onLikeClicked(isLiked);
+          }}
+        >
+        </PageReactionButtons>
+      )}
+      {/*
+        TODO :
+        once 80335 is done, merge 77543 branch(parent of 80335) into 77524.
+        (pageContainer dependencies in bookmark, delete modal, rename etc are removed)
+        then place PageManagement here.
+        TASK: https://estoc.weseek.co.jp/redmine/issues/81076
+        CONDITION :isAbleToShowPageManagement = !isNotFoundPage && !isTrashPage && !isSharedUser
+      */}
+      {/* if (CONDITION) then <PageManagement isCompactMode> */}
+    </>
+  );
+};
+
+const SubNavButtonsWrapper = withUnstatedContainers(SubNavButtons, [AppContainer, NavigationContainer]);
+
+export default SubNavButtonsWrapper;

+ 5 - 21
packages/app/src/components/PageReactionButtons.tsx

@@ -1,14 +1,13 @@
 import React, { FC, useState, useEffect } from 'react';
 import LikeButtons from './LikeButtons';
-import { apiv3Get } from '../client/util/apiv3-client';
 
 
 type Props = {
   pageId: string,
-  currentUserId: string,
-  likerSum: number,
+  sumOfLikers: number,
   likerIds: string[],
-  isAlreadyLiked: boolean,
+  isLiked: boolean,
+  onLikeClicked: (isLiked : boolean)=>void,
 }
 
 const LikeButtonsWrapper = (props) => {
@@ -17,29 +16,14 @@ const LikeButtonsWrapper = (props) => {
 
 const PageReactionButtons : FC<Props> = (props: Props) => {
   const {
-    pageId, currentUserId, likerSum, likerIds, isAlreadyLiked,
+    pageId, sumOfLikers, likerIds, isLiked, onLikeClicked,
   } = props;
-  const [sumOflikers, setSumOfLikers] = useState(likerSum);
-  const [likers, setLikers] = useState<string[]>(likerIds);
-  const [isLiked, setIsLiked] = useState(isAlreadyLiked);
 
-  useEffect(() => {
-    setSumOfLikers(likerSum);
-    setLikers(likerIds);
-    setIsLiked(isAlreadyLiked);
-  }, [props]);
-
-
-  const likeInvoked = async() => {
-    setSumOfLikers(sumOflikers => (isLiked ? sumOflikers - 1 : sumOflikers + 1));
-    setLikers(likerIds => (isLiked ? likerIds.filter(id => id !== currentUserId) : [...likerIds, currentUserId]));
-    setIsLiked(isLiked => !isLiked);
-  };
 
   return (
     <>
       <span>
-        <LikeButtonsWrapper onChangeInvoked={likeInvoked} pageId={pageId} likers={likers} sumOfLikers={sumOflikers} isLiked={isLiked}></LikeButtonsWrapper>
+        <LikeButtonsWrapper onLikeClicked={onLikeClicked} pageId={pageId} likerIds={likerIds} sumOfLikers={sumOfLikers} isLiked={isLiked}></LikeButtonsWrapper>
       </span>
       <span>
         {/*

+ 4 - 4
packages/app/src/components/SearchPage/SearchResultContentSubNavigation.tsx

@@ -2,7 +2,7 @@ import React, { FC } from 'react';
 import PagePathNav from '../PagePathNav';
 import { withUnstatedContainers } from '../UnstatedUtils';
 import AppContainer from '../../client/services/AppContainer';
-import SearchResultSubNavButton from './SearchResultSubNavButton';
+import SubNavButtons from '../Navbar/SubNavButtons';
 
 type Props = {
   appContainer:AppContainer
@@ -12,8 +12,8 @@ type Props = {
   isCompactMode?: boolean,
 }
 
-const SearchResultSubNavButtonWrapper = (props) => {
-  return <SearchResultSubNavButton {...props}></SearchResultSubNavButton>;
+const SubNavButtonsWrapper = (props) => {
+  return <SubNavButtons {...props}></SubNavButtons>;
 };
 
 const SearchResultContentSubNavigation: FC<Props> = (props : Props) => {
@@ -39,7 +39,7 @@ const SearchResultContentSubNavigation: FC<Props> = (props : Props) => {
       </div>
       {/* Right side */}
       <div className="d-flex">
-        <SearchResultSubNavButtonWrapper pageId={pageId} isCompactMode={isCompactMode}></SearchResultSubNavButtonWrapper>
+        <SubNavButtonsWrapper isCompactMode={isCompactMode} pageId={pageId}></SubNavButtonsWrapper>
       </div>
     </div>
   );

+ 0 - 48
packages/app/src/components/SearchPage/SearchResultSubNavButton.tsx

@@ -1,48 +0,0 @@
-import React, {
-  FC,
-} from 'react';
-import AppContainer from '../../client/services/AppContainer';
-import { withUnstatedContainers } from '../UnstatedUtils';
-
-import PageReactionButtons from '../PageReactionButtons';
-import PageManagement from '../Page/PageManagement';
-import { useSWRPageInfo } from '../../stores/page';
-
-
-type SearchResultSubNavButtonProps = {
-  appContainer: AppContainer,
-  isCompactMode: boolean,
-
-  pageId: string,
-}
-const SearchResultSubNavButton: FC<SearchResultSubNavButtonProps> = (props: SearchResultSubNavButtonProps) => {
-  const { appContainer, isCompactMode, pageId } = props;
-  const { data: pageInfo, error: pageInfoError } = useSWRPageInfo(pageId);
-  return (
-    <>
-      {pageInfo != null && (
-        <PageReactionButtons
-          pageId={pageId}
-          currentUserId={appContainer.currentUserId}
-          likerSum={pageInfo.sumOfLikers}
-          likerIds={pageInfo.likerIds}
-          isAlreadyLiked={pageInfo.isLiked}
-        >
-        </PageReactionButtons>
-      )}
-      {/*
-        TODO :
-        once 80335 is done, merge 77543 branch(parent of 80335) into 77524.
-        (pageContainer dependencies in bookmark, delete modal, rename etc are removed)
-        then place PageManagement here.
-        TASK: https://estoc.weseek.co.jp/redmine/issues/81076
-        CONDITION :isAbleToShowPageManagement = !isNotFoundPage && !isTrashPage && !isSharedUser
-      */}
-      {/* if (CONDITION) then <PageManagement isCompactMode> */}
-    </>
-  );
-};
-
-const SearchResultSubNavButtonWrapper = withUnstatedContainers(SearchResultSubNavButton, [AppContainer]);
-
-export default SearchResultSubNavButtonWrapper;

+ 1 - 1
packages/app/src/interfaces/page-info.ts

@@ -1,4 +1,4 @@
-export type IpageInfo = {
+export type IPageInfo = {
   sumOfLikers: number;
   likerIds: string[];
   seenUserIds: string[];

+ 6 - 7
packages/app/src/stores/page.tsx

@@ -1,11 +1,10 @@
 import useSWR, { SWRResponse } from 'swr';
 
-import { apiv3Get } from '~/client/util/apiv3-client';
-
-import { IPage } from '~/interfaces/page';
-import { IPagingResult } from '~/interfaces/paging-result';
-import { IpageInfo } from '~/interfaces/page-info';
+import { apiv3Get } from '../client/util/apiv3-client';
 
+import { IPage } from '../interfaces/page';
+import { IPagingResult } from '../interfaces/paging-result';
+import { IPageInfo } from '../interfaces/page-info';
 
 // eslint-disable-next-line @typescript-eslint/no-unused-vars
 export const useSWRxRecentlyUpdated = <Data, Error>(): SWRResponse<IPage[], Error> => {
@@ -34,8 +33,8 @@ export const useSWRxPageList = (
 };
 
 
-export const useSWRPageInfo = (pageId: string): SWRResponse<IpageInfo, Error> => {
-  return useSWR(`page/info?pageId=${pageId}`, endpoint => apiv3Get(endpoint).then((response) => {
+export const useSWRPageInfo = (pageId: string): SWRResponse<IPageInfo, Error> => {
+  return useSWR(`/page/info?pageId=${pageId}`, endpoint => apiv3Get(endpoint).then((response) => {
     return {
       sumOfLikers: response.data.sumOfLikers,
       likerIds: response.data.likerIds,