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

show createdAt/updatedAt with date distance format

Yuki Takei 6 лет назад
Родитель
Сommit
bf5e2a6996

+ 47 - 35
src/client/js/components/PageComment/Comment.jsx

@@ -1,8 +1,12 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 
+import { distanceInWordsStrict } from 'date-fns';
 import dateFnsFormat from 'date-fns/format';
 
+import Tooltip from 'react-bootstrap/es/Tooltip';
+import OverlayTrigger from 'react-bootstrap/es/OverlayTrigger';
+
 import AppContainer from '../../services/AppContainer';
 import PageContainer from '../../services/PageContainer';
 
@@ -65,9 +69,25 @@ class Comment extends React.Component {
     return this.props.comment.revision === this.props.pageContainer.state.revisionId;
   }
 
-  getRootClassName() {
-    return `page-comment ${
-      this.isCurrentUserEqualsToAuthor() ? 'page-comment-me ' : ''}`;
+  getRootClassName(comment) {
+    let className = 'page-comment';
+
+    const { revisionId, revisionCreatedAt } = this.props.pageContainer.state;
+    if (comment.revision === revisionId) {
+      className += ' page-comment-current';
+    }
+    else if (Date.parse(comment.createdAt) / 1000 > revisionCreatedAt) {
+      className += ' page-comment-newer';
+    }
+    else {
+      className += ' page-comment-older';
+    }
+
+    if (this.isCurrentUserEqualsToAuthor()) {
+      className += ' page-comment-me';
+    }
+
+    return className;
   }
 
   getRevisionLabelClassName() {
@@ -202,46 +222,38 @@ class Comment extends React.Component {
     const creator = comment.creator;
     const isMarkdown = comment.isMarkdown;
 
-    const rootClassName = this.getRootClassName();
-    const commentDate = dateFnsFormat(comment.createdAt, 'YYYY/MM/DD HH:mm');
+    const rootClassName = this.getRootClassName(comment);
+    const commentDate = distanceInWordsStrict(comment.createdAt, new Date());
     const commentBody = isMarkdown ? this.renderRevisionBody() : this.renderText(comment.comment);
     const revHref = `?revision=${comment.revision}`;
     const revFirst8Letters = comment.revision.substr(-8);
     const revisionLavelClassName = this.getRevisionLabelClassName();
 
-    const { revisionId, revisionCreatedAt } = this.props.pageContainer.state;
-
-    let isNewer;
-    if (comment.revision === revisionId) {
-      isNewer = 'page-comments-list-current';
-    }
-    else if (Date.parse(comment.createdAt) / 1000 > revisionCreatedAt) {
-      isNewer = 'page-comments-list-newer';
-    }
-    else {
-      isNewer = 'page-comments-list-older';
-    }
-
+    const commentDateTooltip = (
+      <Tooltip id={`commentDateTooltip-${comment._id}`}>
+        {dateFnsFormat(comment.createdAt, 'YYYY/MM/DD HH:mm')}
+      </Tooltip>
+    );
 
     return (
       <div>
-        <div className={isNewer}>
-          <div className={rootClassName}>
-            <UserPicture user={creator} />
-            <div className="page-comment-main">
-              <div className="page-comment-creator">
-                <Username user={creator} />
-              </div>
-              <div className="page-comment-body">{commentBody}</div>
-              <div className="page-comment-meta">
-                {commentDate}&nbsp;
-                <a className={revisionLavelClassName} href={revHref}>{revFirst8Letters}</a>
-              </div>
-              <div className="page-comment-control">
-                <button type="button" className="btn btn-link" onClick={this.deleteBtnClickedHandler}>
-                  <i className="ti-close"></i>
-                </button>
-              </div>
+        <div className={rootClassName}>
+          <UserPicture user={creator} />
+          <div className="page-comment-main">
+            <div className="page-comment-creator">
+              <Username user={creator} />
+            </div>
+            <div className="page-comment-body">{commentBody}</div>
+            <div className="page-comment-meta">
+              <OverlayTrigger overlay={commentDateTooltip} placement="bottom">
+                <span>{commentDate}</span>
+              </OverlayTrigger>
+              <span className="ml-2"><a className={revisionLavelClassName} href={revHref}>{revFirst8Letters}</a></span>
+            </div>
+            <div className="page-comment-control">
+              <button type="button" className="btn btn-link" onClick={this.deleteBtnClickedHandler}>
+                <i className="ti-close"></i>
+              </button>
             </div>
           </div>
         </div>

+ 10 - 8
src/client/styles/scss/_comment.scss

@@ -31,15 +31,17 @@
       text-align: center;
     }
 
-    // older comments
-    .page-comments-list-older .page-comment {
-    }
-    // newer comments
-    .page-comments-list-newer .page-comment {
-      opacity: 0.7;
+    .page-comment {
+      // older comments
+      &.page-comment-older {
+      }
+      // newer comments
+      &.page-comment-newer {
+        opacity: 0.7;
 
-      &:hover {
-        opacity: 1;
+        &:hover {
+          opacity: 1;
+        }
       }
     }
   }

+ 3 - 5
src/client/styles/scss/_comment_growi.scss

@@ -77,13 +77,11 @@
     }
 
     .page-comment-meta {
+      display: flex;
+      justify-content: flex-end;
+
       font-size: 0.9em;
       color: #999;
-      text-align: right;
-
-      * {
-        vertical-align: 25%;
-      }
     }
   }
 

+ 4 - 5
src/client/styles/scss/_comment_kibela.scss

@@ -65,12 +65,11 @@
       word-wrap: break-word;
     }
     .page-comment-meta {
+      display: flex;
+      justify-content: flex-end;
+
       font-size: 0.9em;
-      color: #e5ecf1;
-      text-align: right;
-      * {
-        vertical-align: 25%;
-      }
+      color: #999;
     }
   } // show when hover
   .page-comment-main:hover > .page-comment-control {

+ 5 - 0
src/server/util/middlewares.js

@@ -1,5 +1,6 @@
 const debug = require('debug')('growi:lib:middlewares');
 const logger = require('@alias/logger')('growi:lib:middlewares');
+const { distanceInWordsStrict } = require('date-fns');
 const pathUtils = require('growi-commons').pathUtils;
 const md5 = require('md5');
 const entities = require('entities');
@@ -119,6 +120,10 @@ module.exports = (crowi, app) => {
         return swigFilters.date(input, format, app.get('tzoffset'));
       });
 
+      swig.setFilter('dateDistance', (input) => {
+        return distanceInWordsStrict(input, new Date());
+      });
+
       swig.setFilter('nl2br', (string) => {
         return string
           .replace(/\n/g, '<br>');

+ 6 - 6
src/server/views/layout-growi/widget/header.html

@@ -21,9 +21,9 @@
             <a class="m-r-5" href="{{ userPageRoot(page.creator) }}" data-toggle="tooltip" data-placement="bottom" title="{{ page.creator.name|default(author.name) }}">
               <img src="{{ page.creator|default(author)|picture }}" class="picture img-circle">
             </a>
-            <div>
+            <div class="d-flex align-items-end flex-column">
               <div>Created by <a href="{{ userPageRoot(page.creator) }}">{{ page.creator.name|default(author.name) }}</a></div>
-              <div class="text-muted">{{ page.createdAt|datetz('Y/m/d H:i:s') }}</div>
+              <div class="text-muted" data-toggle="tooltip" data-placement="bottom" title="{{ page.createdAt|datetz('Y/m/d H:i:s') }}">{{ page.createdAt|dateDistance }}</div>
             </div>
           </div>
           <div class="d-flex align-items-center only-affix">
@@ -31,7 +31,7 @@
               <img src="{{ page.creator|default(author)|picture }}" class="picture picture-xs img-circle">
             </a>
             <div class="ml-auto">
-              <div>Created at <span class="text-muted">{{ page.createdAt|datetz('y/m/d H:i') }}</span></div>
+              <div>Created in <span class="text-muted" data-toggle="tooltip" data-placement="bottom" title="{{ page.createdAt|datetz('Y/m/d H:i:s') }}">{{ page.createdAt|dateDistance }}</span></div>
             </div>
           </div>
         </li>
@@ -40,9 +40,9 @@
             <a class="m-r-5" href="{{ userPageRoot(author) }}" data-toggle="tooltip" data-placement="bottom" title="{{ author.name }}">
               <img src="{{ author|picture }}" class="picture img-circle">
             </a>
-            <div>
+            <div class="d-flex align-items-end flex-column">
               <div>Updated by <a href="{{ userPageRoot(page.revision.author) }}">{{ author.name }}</a></div>
-              <div class="text-muted">{{ page.updatedAt|datetz('Y/m/d H:i:s') }}</div>
+              <div class="text-muted" data-toggle="tooltip" data-placement="bottom" title="{{ page.updatedAt|datetz('Y/m/d H:i:s') }}">{{ page.updatedAt|dateDistance }}</div>
             </div>
           </div>
           <div class="d-flex align-items-center only-affix">
@@ -50,7 +50,7 @@
               <img src="{{ author|picture }}" class="picture picture-xs img-circle">
             </a>
             <div class="ml-auto">
-              <div>Updated at <span class="text-muted">{{ page.updatedAt|datetz('y/m/d H:i') }}</span></div>
+              <div>Updated in <span class="text-muted"  data-toggle="tooltip" data-placement="bottom" title="{{ page.updatedAt|datetz('Y/m/d H:i:s') }}">{{ page.updatedAt|dateDistance }}</span></div>
             </div>
           </div>
         </li>

+ 7 - 7
src/server/views/layout-kibela/widget/header.html

@@ -19,24 +19,24 @@
           <a class="m-r-5" href="{{ userPageRoot(page.creator) }}">
             <img src="{{ page.creator|default(author)|picture }}" class="picture img-circle">
           </a>
-          <div>
+          <div class="d-flex align-items-end flex-column">
             <div>Created by
               <a href="{{ userPageRoot(page.creator) }}">{{ page.creator.name|default(author.name) }}</a>
             </div>
-            <div class="text-muted">{{ page.createdAt|datetz('Y/m/d H:i:s') }}</div>
+            <div class="text-muted" data-toggle="tooltip" data-placement="bottom" title="{{ page.createdAt|datetz('Y/m/d H:i:s') }}">{{ page.createdAt|dateDistance }}</div>
           </div>
         </div>
       </li>
       <li class="m-t-5">
         <div class="d-flex align-items-center">
-          <a class="m-r-5" href="{{ userPageRoot(page.revision.author) }}">
-            <img src="{{ page.revision.author|default(author)|picture }}" class="picture img-circle">
+          <a class="m-r-5" href="{{ userPageRoot(author) }}">
+            <img src="{{ author|picture }}" class="picture img-circle">
           </a>
-          <div>
+          <div class="d-flex align-items-end flex-column">
             <div>Updated by
-              <a href="{{ userPageRoot(page.revision.author) }}">{{ page.revision.author.name|default(author.name) }}</a>
+              <a href="{{ userPageRoot(author) }}">{{ author.name }}</a>
             </div>
-            <div class="text-muted">{{ page.updatedAt|datetz('Y/m/d H:i:s') }}</div>
+            <div class="text-muted" data-toggle="tooltip" data-placement="bottom" title="{{ page.updatedAt|datetz('Y/m/d H:i:s') }}">{{ page.updatedAt|dateDistance }}</div>
           </div>
         </div>
       </li>