SubNavButtons.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import React, { useCallback } from 'react';
  2. import { IPageInfo, isExistPageInfo } from '~/interfaces/page';
  3. import { useSWRxPageInfo } from '../../stores/page';
  4. import { useSWRBookmarkInfo } from '../../stores/bookmark';
  5. import { useSWRxUsersList } from '../../stores/user';
  6. import { useIsGuestUser } from '~/stores/context';
  7. import SubscribeButton from '../SubscribeButton';
  8. import LikeButtons from '../LikeButtons';
  9. import BookmarkButtons from '../BookmarkButtons';
  10. import SeenUserInfo from '../User/SeenUserInfo';
  11. import { toggleBookmark, toggleLike, toggleSubscribe } from '~/client/services/page-operation';
  12. type CommonProps = {
  13. isCompactMode?: boolean,
  14. disableSeenUserInfoPopover?: boolean,
  15. showPageControlDropdown?: boolean,
  16. }
  17. type SubNavButtonsSubstanceProps= CommonProps & {
  18. pageId: string,
  19. pageInfo: IPageInfo,
  20. }
  21. const SubNavButtonsSubstance = (props: SubNavButtonsSubstanceProps): JSX.Element => {
  22. const {
  23. pageInfo, pageId, isCompactMode, disableSeenUserInfoPopover, showPageControlDropdown,
  24. } = props;
  25. const { data: isGuestUser } = useIsGuestUser();
  26. const { mutate: mutatePageInfo } = useSWRxPageInfo(pageId);
  27. const { data: bookmarkInfo, mutate: mutateBookmarkInfo } = useSWRBookmarkInfo(pageId);
  28. const likerIds = pageInfo.likerIds != null ? pageInfo.likerIds.slice(0, 15) : [];
  29. const seenUserIds = pageInfo.seenUserIds != null ? pageInfo.seenUserIds.slice(0, 15) : [];
  30. // Put in a mixture of seenUserIds and likerIds data to make the cache work
  31. const { data: usersList } = useSWRxUsersList([...likerIds, ...seenUserIds]);
  32. const likers = usersList != null ? usersList.filter(({ _id }) => likerIds.includes(_id)).slice(0, 15) : [];
  33. const seenUsers = usersList != null ? usersList.filter(({ _id }) => seenUserIds.includes(_id)).slice(0, 15) : [];
  34. const subscribeClickhandler = useCallback(async() => {
  35. if (isGuestUser == null || isGuestUser) {
  36. return;
  37. }
  38. await toggleSubscribe(pageId, pageInfo.subscriptionStatus);
  39. mutatePageInfo();
  40. }, [isGuestUser, mutatePageInfo, pageId, pageInfo.subscriptionStatus]);
  41. const likeClickhandler = useCallback(async() => {
  42. if (isGuestUser == null || isGuestUser) {
  43. return;
  44. }
  45. await toggleLike(pageId, pageInfo.isLiked);
  46. mutatePageInfo();
  47. }, [isGuestUser, mutatePageInfo, pageId, pageInfo.isLiked]);
  48. const bookmarkClickHandler = useCallback(async() => {
  49. if (isGuestUser == null || isGuestUser) {
  50. return;
  51. }
  52. await toggleBookmark(pageId, pageInfo.isBookmarked);
  53. mutatePageInfo();
  54. mutateBookmarkInfo();
  55. }, [isGuestUser, mutateBookmarkInfo, mutatePageInfo, pageId, pageInfo.isBookmarked]);
  56. const {
  57. sumOfLikers, isLiked, bookmarkCount, isBookmarked,
  58. } = pageInfo;
  59. return (
  60. <div className="d-flex" style={{ gap: '2px' }}>
  61. <span>
  62. <SubscribeButton
  63. status={pageInfo.subscriptionStatus}
  64. onClick={subscribeClickhandler}
  65. />
  66. </span>
  67. <LikeButtons
  68. hideTotalNumber={isCompactMode}
  69. onLikeClicked={likeClickhandler}
  70. sumOfLikers={sumOfLikers}
  71. isLiked={isLiked}
  72. likers={likers}
  73. />
  74. <BookmarkButtons
  75. hideTotalNumber={isCompactMode}
  76. bookmarkCount={bookmarkCount}
  77. isBookmarked={isBookmarked}
  78. bookmarkedUsers={bookmarkInfo?.bookmarkedUsers}
  79. onBookMarkClicked={bookmarkClickHandler}
  80. />
  81. <SeenUserInfo seenUsers={seenUsers} disabled={disableSeenUserInfoPopover} />
  82. { showPageControlDropdown && (
  83. /*
  84. TODO:
  85. replace with PageItemControl
  86. */
  87. <></>
  88. // <PageManagement
  89. // pageId={pageId}
  90. // revisionId={revisionId}
  91. // path={path}
  92. // isCompactMode={isCompactMode}
  93. // isDeletable={isDeletable}
  94. // isAbleToDeleteCompletely={isAbleToDeleteCompletely}
  95. // >
  96. // </PageManagement>
  97. )}
  98. </div>
  99. );
  100. };
  101. type SubNavButtonsProps= CommonProps & {
  102. pageId?: string | null,
  103. };
  104. export const SubNavButtons = (props: SubNavButtonsProps): JSX.Element => {
  105. const { pageId, isCompactMode } = props;
  106. const { data: pageInfo, error } = useSWRxPageInfo(pageId ?? null);
  107. if (pageId == null || pageInfo == null || error != null) {
  108. return <></>;
  109. }
  110. if (!isExistPageInfo(pageInfo)) {
  111. return <></>;
  112. }
  113. return <SubNavButtonsSubstance pageInfo={pageInfo} pageId={pageId} isCompactMode={isCompactMode} />;
  114. };