Yuki Takei 7 лет назад
Родитель
Сommit
e17f2849d7

+ 12 - 0
src/client/js/app.js

@@ -29,6 +29,7 @@ import SeenUserList     from './components/SeenUserList';
 import RevisionPath     from './components/Page/RevisionPath';
 import RevisionPath     from './components/Page/RevisionPath';
 import RevisionUrl      from './components/Page/RevisionUrl';
 import RevisionUrl      from './components/Page/RevisionUrl';
 import BookmarkButton   from './components/BookmarkButton';
 import BookmarkButton   from './components/BookmarkButton';
+import LikeButton       from './components/LikeButton';
 import PagePathAutoComplete from './components/PagePathAutoComplete';
 import PagePathAutoComplete from './components/PagePathAutoComplete';
 import RecentCreated from './components/RecentCreated/RecentCreated';
 import RecentCreated from './components/RecentCreated/RecentCreated';
 
 
@@ -309,6 +310,17 @@ if (componentInstances['page'] != null) {
   crowi.setPage(componentInstances['page']);
   crowi.setPage(componentInstances['page']);
 }
 }
 
 
+// render LikeButton
+const likeButtonElem = document.getElementById('like-button');
+if (likeButtonElem) {
+  const isLiked = likeButtonElem.dataset.liked === 'true';
+  ReactDOM.render(
+    <LikeButton crowi={crowi} pageId={pageId} isLiked={isLiked} />,
+    likeButtonElem
+  );
+  componentInstances.likeButtonElem = likeButtonElem;
+}
+
 // render SavePageControls
 // render SavePageControls
 let savePageControls = null;
 let savePageControls = null;
 const savePageControlsElem = document.getElementById('save-page-controls');
 const savePageControlsElem = document.getElementById('save-page-controls');

+ 66 - 0
src/client/js/components/LikeButton.jsx

@@ -0,0 +1,66 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+export default class LikeButton extends React.Component {
+
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      isLiked: !!props.isLiked,
+    };
+
+    this.handleClick = this.handleClick.bind(this);
+  }
+
+  handleClick(event) {
+    event.preventDefault();
+
+    const pageId = this.props.pageId;
+
+    if (!this.state.isLiked) {
+      this.props.crowi.apiPost('/likes.add', {page_id: pageId})
+      .then(res => {
+        this.setState({isLiked: true});
+      });
+    }
+    else {
+      this.props.crowi.apiPost('/likes.remove', {page_id: pageId})
+      .then(res => {
+        this.setState({isLiked: false});
+      });
+    }
+  }
+
+  isUserLoggedIn() {
+    return this.props.crowi.me !== '';
+  }
+
+  render() {
+    // if guest user
+    if (!this.isUserLoggedIn()) {
+      return <div></div>;
+    }
+
+    const btnSizeClassName = this.props.size ? `btn-${this.props.size}` : 'btn-md';
+    const addedClassNames = [
+      this.state.isLiked ? 'active' : '',
+      btnSizeClassName,
+    ];
+    const addedClassName = addedClassNames.join(' ');
+
+    return (
+      <button href="#" title="Like" onClick={this.handleClick}
+          className={`btn-like btn btn-default btn-circle btn-outline ${addedClassName}`}>
+        <i className="icon-like"></i>
+      </button>
+    );
+  }
+}
+
+LikeButton.propTypes = {
+  crowi: PropTypes.object.isRequired,
+  pageId: PropTypes.string,
+  isLiked: PropTypes.bool,
+  size: PropTypes.string,
+};

+ 0 - 35
src/client/js/legacy/crowi.js

@@ -581,29 +581,6 @@ $(function() {
       top.location.href = `${path}#edit`;
       top.location.href = `${path}#edit`;
     });
     });
 
 
-    // Like
-    const $likeButton = $('.like-button');
-    const $likeCount = $('#like-count');
-    $likeButton.click(function() {
-      const liked = $likeButton.data('liked');
-      const token = $likeButton.data('csrftoken');
-      if (!liked) {
-        $.post('/_api/likes.add', {_csrf: token, page_id: pageId}, function(res) {
-          if (res.ok) {
-            MarkLiked();
-          }
-        });
-      }
-      else {
-        $.post('/_api/likes.remove', {_csrf: token, page_id: pageId}, function(res) {
-          if (res.ok) {
-            MarkUnLiked();
-          }
-        });
-      }
-
-      return false;
-    });
     const $likerList = $('#liker-list');
     const $likerList = $('#liker-list');
     const likers = $likerList.data('likers');
     const likers = $likerList.data('likers');
     if (likers && likers.length > 0) {
     if (likers && likers.length > 0) {
@@ -620,18 +597,6 @@ $(function() {
       });
       });
     }
     }
 
 
-    function MarkLiked() {
-      $likeButton.addClass('active');
-      $likeButton.data('liked', 1);
-      $likeCount.text(parseInt($likeCount.text()) + 1);
-    }
-
-    function MarkUnLiked() {
-      $likeButton.removeClass('active');
-      $likeButton.data('liked', 0);
-      $likeCount.text(parseInt($likeCount.text()) - 1);
-    }
-
     function CreateUserLinkWithPicture(user) {
     function CreateUserLinkWithPicture(user) {
       const $userHtml = $('<a>');
       const $userHtml = $('<a>');
       $userHtml.data('user-id', user._id);
       $userHtml.data('user-id', user._id);

+ 1 - 1
src/client/styles/scss/_on-edit.scss

@@ -40,7 +40,7 @@ body.on-edit {
   .portal-form-button,
   .portal-form-button,
   .alert-info.alert-moved,
   .alert-info.alert-moved,
   .alert-info.alert-unlinked,
   .alert-info.alert-unlinked,
-  .like-button, .bookmark-link, .btn-edit,
+  .btn-like, .btn-bookmark, .btn-edit,
   .authors,
   .authors,
   footer {
   footer {
     display: none !important;
     display: none !important;

+ 3 - 3
src/client/styles/scss/_page.scss

@@ -28,7 +28,7 @@
       }
       }
     }
     }
 
 
-    .like-button, .bookmark-link {
+    .btn-like, .btn-bookmark {
       border: none;
       border: none;
       font-size: 1.2em;
       font-size: 1.2em;
       line-height: 0.8em;
       line-height: 0.8em;
@@ -36,12 +36,12 @@
         background-color: transparent;
         background-color: transparent;
       }
       }
     }
     }
-    .like-button {
+    .btn-like {
       &.active {
       &.active {
         @extend .btn-info;
         @extend .btn-info;
       }
       }
     }
     }
-    .bookmark-link {
+    .btn-bookmark {
       &.active {
       &.active {
         @extend .btn-warning;
         @extend .btn-warning;
       }
       }

+ 1 - 1
src/client/styles/scss/_user.scss

@@ -38,7 +38,7 @@
       }
       }
     }
     }
 
 
-    .like-button, .bookmark-link {
+    .btn-like, .btn-bookmark {
       &.btn-lg {
       &.btn-lg {
         font-size: 1.5em;
         font-size: 1.5em;
         padding: 8px;
         padding: 8px;

+ 1 - 8
src/server/views/layout-crowi/widget/page_side_header.html

@@ -25,14 +25,7 @@
       </dt>
       </dt>
       <dd>
       <dd>
         <p class="liker-count">
         <p class="liker-count">
-        <span id="like-count">{{ page.liker.length }}</span>
-        {% if user %}
-        <button
-          data-csrftoken="{{ csrf() }}"
-          data-liked="{% if page.isLiked(user) %}1{% else %}0{% endif %}"
-          class="like-button btn btn-xs btn-default btn-outline btn-rounded {% if page.isLiked(user) %}active btn-info{% endif %}"
-          ><i class="icon-like"></i> {{ t('Like!') }}</button>
-        {% endif %}
+          <span id="like-count">{{ page.liker.length }}</span>
         </p>
         </p>
         <p id="liker-list" class="liker-list" data-likers="{{ page.liker|default([])|join(',') }}">
         <p id="liker-list" class="liker-list" data-likers="{{ page.liker|default([])|join(',') }}">
         </p>
         </p>

+ 6 - 7
src/server/views/widget/header-button-like.html

@@ -1,7 +1,6 @@
-<button
-    data-csrftoken="{{ csrf() }}"
-    data-liked="{% if page.isLiked(user) %}1{% else %}0{% endif %}"
-    class="like-button btn btn-default btn-outline btn-circle
-          {% if not size == null %}btn-{{size}}{% endif %}
-          {% if page.isLiked(user) %}active{% endif %}"
-><i class="icon-like"></i></button>
+{# This widget will be rendered by React #}
+{% if not size == null %}
+  <span id="like-button-{{size}}" data-liked="{% if page.isLiked(user) %}true{% else %}false{% endif %}"></span>
+{% else %}
+  <span id="like-button" data-liked="{% if page.isLiked(user) %}true{% else %}false{% endif %}"></span>
+{% endif %}