Просмотр исходного кода

Merge pull request #5727 from weseek/fix/too-many-footstamps

fix: Too many footstamps icons are shown by lsx output
Yuki Takei 4 лет назад
Родитель
Сommit
c42ecb44de

+ 12 - 0
packages/app/src/styles/_page_list.scss

@@ -48,6 +48,18 @@ body .page-list {
       i {
         margin-right: 2px;
       }
+
+      .seen-users-count {
+        &.strength-1 {
+          font-weight: bold;
+        }
+        &.strength-2 {
+          font-weight: normal;
+        }
+        &.strength-3 {
+          opacity: 0.6;
+        }
+      }
     }
 
     // after second level indent

+ 4 - 1
packages/plugin-lsx/src/client/js/components/Lsx.jsx

@@ -1,9 +1,10 @@
 
+import React from 'react';
+
 import * as url from 'url';
 
 import { pathUtils } from '@growi/core';
 import PropTypes from 'prop-types';
-import React from 'react';
 
 // eslint-disable-next-line no-unused-vars
 import styles from '../../css/index.css';
@@ -59,6 +60,8 @@ export class Lsx extends React.Component {
     try {
       const res = await this.props.appContainer.apiGet('/plugins/lsx', { pagePath, options: lsxContext.options });
 
+      lsxContext.activeUsersCount = res.activeUsersCount;
+
       if (res.ok) {
         const nodeTree = this.generatePageNodeTree(pagePath, res.pages);
         this.setState({ nodeTree });

+ 3 - 2
packages/plugin-lsx/src/client/js/components/LsxPageList/LsxPage.jsx

@@ -1,8 +1,8 @@
+import React from 'react';
 
 import { pathUtils } from '@growi/core';
 import { PageListMeta } from '@growi/ui';
 import PropTypes from 'prop-types';
-import React from 'react';
 
 import { LsxContext } from '../../util/LsxContext';
 import { PageNode } from '../PageNode';
@@ -79,6 +79,7 @@ export class LsxPage extends React.Component {
 
   render() {
     const pageNode = this.props.pageNode;
+    const { activeUsersCount } = this.props.lsxContext;
 
     // create PagePath element
     let pagePathNode = <PagePathWrapper pagePath={pageNode.pagePath} isExists={this.state.isExists} />;
@@ -87,7 +88,7 @@ export class LsxPage extends React.Component {
     }
 
     // create PageListMeta element
-    const pageListMeta = (this.state.isExists) ? <PageListMeta page={pageNode.page} /> : '';
+    const pageListMeta = (this.state.isExists) ? <PageListMeta page={pageNode.page} activeUsersCount={activeUsersCount} /> : '';
 
     return (
       <li className="page-list-li">

+ 11 - 1
packages/plugin-lsx/src/server/routes/lsx.js

@@ -162,6 +162,7 @@ class Lsx {
 
 module.exports = (crowi, app) => {
   const Page = crowi.model('Page');
+  const User = crowi.model('User');
   const ApiResponse = crowi.require('../util/apiResponse');
   const actions = {};
 
@@ -207,6 +208,15 @@ module.exports = (crowi, app) => {
 
     const builder = await generateBaseQueryBuilder(pagePath, user);
 
+    // count active users
+    let activeUsersCount;
+    try {
+      activeUsersCount = await User.countListByStatus(User.STATUS_ACTIVE);
+    }
+    catch (error) {
+      return res.json(ApiResponse.error(error));
+    }
+
     let query = builder.query;
     try {
       // depth
@@ -227,7 +237,7 @@ module.exports = (crowi, app) => {
       query = Lsx.addSortCondition(query, pagePath, options.sort, options.reverse);
 
       const pages = await query.exec();
-      res.json(ApiResponse.success({ pages }));
+      res.json(ApiResponse.success({ pages, activeUsersCount }));
     }
     catch (error) {
       return res.json(ApiResponse.error(error));

+ 50 - 12
packages/ui/src/components/PagePath/PageListMeta.tsx

@@ -1,5 +1,7 @@
 import React, { FC } from 'react';
 
+import assert from 'assert';
+
 import { IPageHasId } from '@growi/app/src/interfaces/page';
 import { templateChecker, pagePathUtils } from '@growi/core';
 
@@ -8,16 +10,62 @@ import { FootstampIcon } from '../SearchPage/FootstampIcon';
 const { isTopPage } = pagePathUtils;
 const { checkTemplatePath } = templateChecker;
 
+
+const SEEN_USERS_HIDE_THRES__ACTIVE_USERS_COUNT = 5;
+const MIN_STRENGTH_LEVEL = -3;
+
+type SeenUsersCountProps = {
+  count: number,
+  activeUsersCount?: number,
+  shouldSpaceOutIcon?: boolean,
+}
+
+const SeenUsersCount = (props: SeenUsersCountProps): JSX.Element => {
+
+  const { count, shouldSpaceOutIcon, activeUsersCount } = props;
+
+  if (count === 0) {
+    return <></>;
+  }
+
+  if (activeUsersCount != null && activeUsersCount <= SEEN_USERS_HIDE_THRES__ACTIVE_USERS_COUNT) {
+    return <></>;
+  }
+
+  const strengthLevel = Math.log(count / (activeUsersCount ?? count)); // Max: 0
+
+  if (strengthLevel <= MIN_STRENGTH_LEVEL) {
+    return <></>;
+  }
+
+  assert(strengthLevel > MIN_STRENGTH_LEVEL); // [0, MIN_STRENGTH_LEVEL)
+
+  let strengthClass = '';
+  if (strengthLevel < 0) {
+    strengthClass = `strength-${Math.ceil(strengthLevel * -1)}`; // strength-{0, 1, 2, 3}
+  }
+
+  return (
+    <span className={`seen-users-count ${shouldSpaceOutIcon ? 'mr-3' : ''} ${strengthClass}`}>
+      <i className="footstamp-icon"><FootstampIcon /></i>
+      {count}
+    </span>
+  );
+
+};
+
+
 type PageListMetaProps = {
   page: IPageHasId,
   likerCount?: number,
   bookmarkCount?: number,
   shouldSpaceOutIcon?: boolean,
+  activeUsersCount?: number,
 }
 
 export const PageListMeta: FC<PageListMetaProps> = (props: PageListMetaProps) => {
 
-  const { page, shouldSpaceOutIcon } = props;
+  const { page, shouldSpaceOutIcon, activeUsersCount } = props;
 
   // top check
   let topLabel;
@@ -46,16 +94,6 @@ export const PageListMeta: FC<PageListMetaProps> = (props: PageListMetaProps) =>
     locked = <span className={`${shouldSpaceOutIcon ? 'mr-3' : ''}`}><i className="icon-lock" /></span>;
   }
 
-  let seenUserCount;
-  if (page.seenUsers.length > 0) {
-    seenUserCount = (
-      <span className={`${shouldSpaceOutIcon ? 'mr-3' : ''}`}>
-        <i className="footstamp-icon"><FootstampIcon /></i>
-        {page.seenUsers.length}
-      </span>
-    );
-  }
-
   let bookmarkCount;
   if (props.bookmarkCount != null && props.bookmarkCount > 0) {
     bookmarkCount = <span className={`${shouldSpaceOutIcon ? 'mr-3' : ''}`}><i className="fa fa-bookmark-o" />{props.bookmarkCount}</span>;
@@ -65,7 +103,7 @@ export const PageListMeta: FC<PageListMetaProps> = (props: PageListMetaProps) =>
     <span className="page-list-meta">
       {topLabel}
       {templateLabel}
-      {seenUserCount}
+      <SeenUsersCount count={page.seenUsers.length} activeUsersCount={activeUsersCount} />
       {commentCount}
       {likerCount}
       {locked}