SubNavButtons.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import React, {
  2. FC, useCallback,
  3. } from 'react';
  4. import AppContainer from '../../client/services/AppContainer';
  5. import { withUnstatedContainers } from '../UnstatedUtils';
  6. import PageReactionButtons from '../PageReactionButtons';
  7. import PageManagement from '../Page/PageManagement';
  8. import { useSWRPageInfo } from '../../stores/page';
  9. import { useSWRBookmarkInfo } from '../../stores/bookmark';
  10. import { toastError } from '../../client/util/apiNotification';
  11. import { apiv3Put } from '../../client/util/apiv3-client';
  12. import { useSWRxLikerList } from '../../stores/user';
  13. import { useEditorMode } from '~/stores/ui';
  14. type SubNavButtonsProps= {
  15. appContainer: AppContainer,
  16. isCompactMode?: boolean,
  17. pageId: string,
  18. revisionId: string,
  19. path: string,
  20. willShowPageManagement: boolean,
  21. isDeletable: boolean,
  22. isAbleToDeleteCompletely: boolean,
  23. }
  24. const SubNavButtons: FC<SubNavButtonsProps> = (props: SubNavButtonsProps) => {
  25. const {
  26. appContainer, isCompactMode, pageId, revisionId, path, willShowPageManagement, isDeletable, isAbleToDeleteCompletely,
  27. } = props;
  28. const { data: editorMode } = useEditorMode();
  29. const isViewMode = editorMode === 'view';
  30. const { isGuestUser } = appContainer;
  31. const { data: pageInfo, error: pageInfoError, mutate: mutatePageInfo } = useSWRPageInfo(pageId);
  32. const { data: likers } = useSWRxLikerList(pageInfo?.likerIds);
  33. const { data: bookmarkInfo, error: bookmarkInfoError, mutate: mutateBookmarkInfo } = useSWRBookmarkInfo(pageId);
  34. const likeClickhandler = useCallback(async() => {
  35. const { isGuestUser } = appContainer;
  36. if (isGuestUser) {
  37. return;
  38. }
  39. try {
  40. // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  41. await apiv3Put('/page/likes', { pageId, bool: !pageInfo!.isLiked });
  42. mutatePageInfo();
  43. }
  44. catch (err) {
  45. toastError(err);
  46. }
  47. }, [pageInfo]);
  48. const bookmarkClickHandler = useCallback(async() => {
  49. if (isGuestUser) {
  50. return;
  51. }
  52. try {
  53. // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  54. await apiv3Put('/bookmarks', { pageId, bool: !bookmarkInfo!.isBookmarked });
  55. mutateBookmarkInfo();
  56. }
  57. catch (err) {
  58. toastError(err);
  59. }
  60. }, [bookmarkInfo]);
  61. if (pageInfoError != null || pageInfo == null) {
  62. return <></>;
  63. }
  64. if (bookmarkInfoError != null || bookmarkInfo == null) {
  65. return <></>;
  66. }
  67. const { sumOfLikers, isLiked } = pageInfo;
  68. const { sumOfBookmarks, isBookmarked } = bookmarkInfo;
  69. return (
  70. <>
  71. {isViewMode && (
  72. <PageReactionButtons
  73. sumOfLikers={sumOfLikers}
  74. isLiked={isLiked}
  75. likers={likers || []}
  76. onLikeClicked={likeClickhandler}
  77. sumOfBookmarks={sumOfBookmarks}
  78. isBookmarked={isBookmarked}
  79. onBookMarkClicked={bookmarkClickHandler}
  80. >
  81. </PageReactionButtons>
  82. )}
  83. {willShowPageManagement && (
  84. <PageManagement
  85. pageId={pageId}
  86. revisionId={revisionId}
  87. path={path}
  88. isCompactMode={isCompactMode}
  89. isDeletable={isDeletable}
  90. isAbleToDeleteCompletely={isAbleToDeleteCompletely}
  91. >
  92. </PageManagement>
  93. )}
  94. </>
  95. );
  96. };
  97. /**
  98. * Wrapper component for using unstated
  99. */
  100. const SubNavButtonsUnstatedWrapper = withUnstatedContainers(SubNavButtons, [AppContainer]);
  101. // wrapping tsx component returned by withUnstatedContainers to avoid type error when this component used in other tsx components.
  102. const SubNavButtonsWrapper = (props) => {
  103. return <SubNavButtonsUnstatedWrapper {...props}></SubNavButtonsUnstatedWrapper>;
  104. };
  105. export default SubNavButtonsWrapper;