PageListMeta.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import React, { FC } from 'react';
  2. import assert from 'assert';
  3. import { templateChecker, pagePathUtils, IPageHasId } from '@growi/core';
  4. import { FootstampIcon } from '../SearchPage/FootstampIcon';
  5. const { isTopPage } = pagePathUtils;
  6. const { checkTemplatePath } = templateChecker;
  7. const SEEN_USERS_HIDE_THRES__ACTIVE_USERS_COUNT = 5;
  8. const MAX_STRENGTH_LEVEL = 4;
  9. type SeenUsersCountProps = {
  10. count: number,
  11. basisViewersCount?: number,
  12. shouldSpaceOutIcon?: boolean,
  13. }
  14. const SeenUsersCount = (props: SeenUsersCountProps): JSX.Element => {
  15. const { count, shouldSpaceOutIcon, basisViewersCount } = props;
  16. if (count === 0) {
  17. return <></>;
  18. }
  19. if (basisViewersCount != null && basisViewersCount <= SEEN_USERS_HIDE_THRES__ACTIVE_USERS_COUNT) {
  20. return <></>;
  21. }
  22. const strengthLevel = Math.ceil(
  23. Math.min(0, Math.log(count / (basisViewersCount ?? count))) // Max: 0
  24. * 2 * -1,
  25. );
  26. if (strengthLevel > MAX_STRENGTH_LEVEL) {
  27. return <></>;
  28. }
  29. assert(strengthLevel >= 0 && strengthLevel <= MAX_STRENGTH_LEVEL); // [0, MAX_STRENGTH_LEVEL)
  30. const strengthClass = `strength-${strengthLevel}`; // strength-{0, 1, 2, 3, 4}
  31. return (
  32. <span className={`seen-users-count ${shouldSpaceOutIcon ? 'mr-3' : ''} ${strengthClass}`}>
  33. <i className="footstamp-icon"><FootstampIcon /></i>
  34. {count}
  35. </span>
  36. );
  37. };
  38. type PageListMetaProps = {
  39. page: IPageHasId,
  40. likerCount?: number,
  41. bookmarkCount?: number,
  42. shouldSpaceOutIcon?: boolean,
  43. basisViewersCount?: number,
  44. }
  45. export const PageListMeta: FC<PageListMetaProps> = (props: PageListMetaProps) => {
  46. const { page, shouldSpaceOutIcon, basisViewersCount } = props;
  47. // top check
  48. let topLabel;
  49. if (isTopPage(page.path)) {
  50. topLabel = <span className={`badge badge-info ${shouldSpaceOutIcon ? 'mr-3' : ''} top-label`}>TOP</span>;
  51. }
  52. // template check
  53. let templateLabel;
  54. if (checkTemplatePath(page.path)) {
  55. templateLabel = <span className={`badge badge-info ${shouldSpaceOutIcon ? 'mr-3' : ''}`}>TMPL</span>;
  56. }
  57. let commentCount;
  58. if (page.commentCount > 0) {
  59. commentCount = <span className={`${shouldSpaceOutIcon ? 'mr-3' : ''}`}><i className="icon-bubble" />{page.commentCount}</span>;
  60. }
  61. let likerCount;
  62. if (props.likerCount != null && props.likerCount > 0) {
  63. likerCount = <span className={`${shouldSpaceOutIcon ? 'mr-3' : ''}`}><i className="fa fa-heart-o" />{props.likerCount}</span>;
  64. }
  65. let locked;
  66. if (page.grant !== 1) {
  67. locked = <span className={`${shouldSpaceOutIcon ? 'mr-3' : ''}`}><i className="icon-lock" /></span>;
  68. }
  69. let bookmarkCount;
  70. if (props.bookmarkCount != null && props.bookmarkCount > 0) {
  71. bookmarkCount = <span className={`${shouldSpaceOutIcon ? 'mr-3' : ''}`}><i className="fa fa-bookmark-o" />{props.bookmarkCount}</span>;
  72. }
  73. return (
  74. <span className="page-list-meta">
  75. {topLabel}
  76. {templateLabel}
  77. <SeenUsersCount count={page.seenUsers.length} basisViewersCount={basisViewersCount} />
  78. {commentCount}
  79. {likerCount}
  80. {locked}
  81. {bookmarkCount}
  82. </span>
  83. );
  84. };