Browse Source

Merge pull request #5101 from weseek/imprv/85804-add-bookmark-from-pagetree

Imprv/85804 add bookmark from pagetree
cao 4 years ago
parent
commit
bd942dd265

+ 2 - 1
packages/app/resource/locales/en_US/translation.json

@@ -155,7 +155,8 @@
   "Sign out": "Logout",
   "Disassociate": "Disassociate",
   "No bookmarks yet": "No bookmarks yet",
-  "Add to bookmark": "Add to bookmark",
+  "add_bookmark": "Add to Bookmarks",
+  "remove_bookmark": "Remove from Bookmarks",
   "Recent Created": "Recent Created",
   "Recent Changes": "Recent Changes",
   "Page Tree": "Page Tree",

+ 2 - 1
packages/app/resource/locales/ja_JP/translation.json

@@ -157,7 +157,8 @@
   "Sidebar mode": "サイドバーモード",
   "Sidebar mode on Editor": "サイドバーモード(編集時)",
   "No bookmarks yet": "No bookmarks yet",
-  "Add to bookmark": "ブックマークに追加",
+  "add_bookmark": "ブックマークに追加",
+  "remove_bookmark": "ブックマークから削除",
   "Recent Created": "最新の作成",
   "Recent Changes": "最新の変更",
   "Page Tree": "ページツリー",

+ 2 - 1
packages/app/resource/locales/zh_CN/translation.json

@@ -163,7 +163,8 @@
 	"Sign out": "退出",
   "Disassociate": "解除关联",
   "No bookmarks yet": "暂无书签",
-  "Add to bookmark": "添加到书签",
+  "add_bookmark": "添加到书签",
+  "remove_bookmark": "从书签中删除",
 	"Recent Created": "最新创建",
   "Recent Changes": "最新修改",
   "Page Tree": "页面树",

+ 37 - 6
packages/app/src/components/Common/Dropdown/PageItemControl.tsx

@@ -1,12 +1,15 @@
-import React, { FC } from 'react';
+import React, { FC, useState } from 'react';
 import {
-  UncontrolledDropdown, DropdownMenu, DropdownToggle, DropdownItem,
+  Dropdown, DropdownMenu, DropdownToggle, DropdownItem,
 } from 'reactstrap';
 
 import toastr from 'toastr';
 import { useTranslation } from 'react-i18next';
 
 import { IPageHasId } from '~/interfaces/page';
+import { apiv3Put } from '~/client/util/apiv3-client';
+import { toastError } from '~/client/util/apiNotification';
+import { useSWRBookmarkInfo } from '~/stores/bookmark';
 
 type PageItemControlProps = {
   page: Partial<IPageHasId>
@@ -21,14 +24,42 @@ const PageItemControl: FC<PageItemControlProps> = (props: PageItemControlProps)
     page, isEnableActions, onClickDeleteButton, isDeletable,
   } = props;
   const { t } = useTranslation('');
+  const [isOpen, setIsOpen] = useState(false);
+  const { data: bookmarkInfo, error: bookmarkInfoError, mutate: mutateBookmarkInfo } = useSWRBookmarkInfo(page._id, isOpen);
 
   const deleteButtonHandler = () => {
     if (onClickDeleteButton != null && page._id != null) {
       onClickDeleteButton(page._id);
     }
   };
+
+
+  const bookmarkToggleHandler = (async() => {
+    try {
+      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+      await apiv3Put('/bookmarks', { pageId: page._id, bool: !bookmarkInfo!.isBookmarked });
+      mutateBookmarkInfo();
+    }
+    catch (err) {
+      toastError(err);
+    }
+  });
+
+  const renderBookmarkText = () => {
+    if (bookmarkInfoError != null || bookmarkInfo == null) {
+      return '';
+    }
+    return bookmarkInfo.isBookmarked ? t('remove_bookmark') : t('add_bookmark');
+  };
+
+
+  const dropdownToggle = () => {
+    setIsOpen(!isOpen);
+  };
+
+
   return (
-    <UncontrolledDropdown>
+    <Dropdown isOpen={isOpen} toggle={dropdownToggle}>
       <DropdownToggle color="transparent" className="btn-link border-0 rounded grw-btn-page-management p-0">
         <i className="icon-options fa fa-rotate-90 text-muted p-1"></i>
       </DropdownToggle>
@@ -62,9 +93,9 @@ const PageItemControl: FC<PageItemControlProps> = (props: PageItemControlProps)
           </DropdownItem>
         )}
         {isEnableActions && (
-          <DropdownItem onClick={() => toastr.warning(t('search_result.currently_not_implemented'))}>
+          <DropdownItem onClick={bookmarkToggleHandler}>
             <i className="fa fa-fw fa-bookmark-o"></i>
-            {t('Add to bookmark')}
+            {renderBookmarkText()}
           </DropdownItem>
         )}
         {isEnableActions && (
@@ -91,7 +122,7 @@ const PageItemControl: FC<PageItemControlProps> = (props: PageItemControlProps)
       </DropdownMenu>
 
 
-    </UncontrolledDropdown>
+    </Dropdown>
   );
 
 };

+ 1 - 1
packages/app/src/components/Navbar/SubNavButtons.tsx

@@ -34,7 +34,7 @@ const SubNavButtons: FC<SubNavButtonsProps> = (props: SubNavButtonsProps) => {
 
   const { data: pageInfo, error: pageInfoError, mutate: mutatePageInfo } = useSWRPageInfo(pageId);
   const { data: likers } = useSWRxLikerList(pageInfo?.likerIds);
-  const { data: bookmarkInfo, error: bookmarkInfoError, mutate: mutateBookmarkInfo } = useSWRBookmarkInfo(pageId);
+  const { data: bookmarkInfo, error: bookmarkInfoError, mutate: mutateBookmarkInfo } = useSWRBookmarkInfo(pageId, true);
 
   const likeClickhandler = useCallback(async() => {
     if (isGuestUser == null || isGuestUser) {

+ 11 - 9
packages/app/src/stores/bookmark.ts

@@ -3,13 +3,15 @@ import { apiv3Get } from '../client/util/apiv3-client';
 import { IBookmarkInfo } from '../interfaces/bookmark-info';
 
 
-export const useSWRBookmarkInfo = (pageId: string | null): SWRResponse<IBookmarkInfo, Error> => {
-  return useSWR(pageId != null
-    ? `/bookmarks/info?pageId=${pageId}` : null,
-  endpoint => apiv3Get(endpoint).then((response) => {
-    return {
-      sumOfBookmarks: response.data.sumOfBookmarks,
-      isBookmarked: response.data.isBookmarked,
-    };
-  }));
+export const useSWRBookmarkInfo = (pageId: string | null | undefined, isOpen = false): SWRResponse<IBookmarkInfo, Error> => {
+  return useSWR(
+    pageId != null && isOpen
+      ? `/bookmarks/info?pageId=${pageId}` : null,
+    endpoint => apiv3Get(endpoint).then((response) => {
+      return {
+        sumOfBookmarks: response.data.sumOfBookmarks,
+        isBookmarked: response.data.isBookmarked,
+      };
+    }),
+  );
 };