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

Merge pull request #212 from crowi/react-bookmark-button

React bookmark button
Sotaro KARASAWA 9 лет назад
Родитель
Сommit
fab6f9beb1

+ 10 - 2
lib/views/page.html

@@ -17,7 +17,11 @@
       <h1 class="title flex-item-title" id="revision-path">{{ path|insertSpaceToEachSlashes }}</h1>
       {% if page %}
       <div class="flex-item-action">
-        <a href="#" title="Bookmark" class="bookmark-link" id="bookmark-button" data-csrftoken="{{ csrf() }}" data-bookmarked="0"><i class="fa fa-star-o"></i></a>
+        <span id="bookmark-button">
+          <p class="bookmark-link">
+            <i class="fa fa-star-o"></i>
+          </p>
+        </span>
       </div>
       <div class="flex-item-action visible-xs visible-sm">
         <button
@@ -35,7 +39,11 @@
     <div class="flex-title-line">
       <h1 class="title flex-item-title">{{ path|insertSpaceToEachSlashes }}</h1>
       <div class="flex-item-action">
-        <a href="#" title="Bookmark" class="bookmark-link" id="bookmark-button" data-csrftoken="{{ csrf() }}" data-bookmarked="0"><i class="fa fa-star-o"></i></a>
+        <span id="bookmark-button">
+          <p class="bookmark-link">
+            <i class="fa fa-star-o"></i>
+          </a>
+        </span>
       </div>
     </div>
   </header>

+ 1 - 1
lib/views/page_list.html

@@ -31,7 +31,7 @@
       </h1>
       {% if page %}
       <div class="flex-item-action">
-        <a href="#" title="Bookmark" class="bookmark-link" id="bookmark-button" data-csrftoken="{{ csrf() }}" data-bookmarked="0"><i class="fa fa-star-o"></i></a>
+        <span id="bookmark-button" data-csrftoken="{{ csrf() }}"></span>
       </div>
       <div class="flex-item-action visible-xs visible-sm">
         <button

+ 1 - 1
lib/views/user_page.html

@@ -10,7 +10,7 @@
   <h1 class="title" id="revision-path">{{ path|insertSpaceToEachSlashes }}</h1>
   <div class="user-page-header">
   {% if page %}
-    <a href="#" title="Bookmark" class="bookmark-link" id="bookmark-button" data-bookmarked="0"><i class="fa fa-star-o"></i></a>
+    <span id="bookmark-button" data-csrftoken="{{ csrf() }}"></span>
   {% endif %}
     <div class="pull-left user-page-picture">
       <img src="{{ pageUser|picture }}" class="picture picture-rounded">

+ 2 - 0
resource/js/app.js

@@ -10,6 +10,7 @@ import PageListSearch   from './components/PageListSearch';
 import PageHistory      from './components/PageHistory';
 import PageAttachment   from './components/PageAttachment';
 import SeenUserList     from './components/SeenUserList';
+import BookmarkButton   from './components/BookmarkButton';
 //import PageComment  from './components/PageComment';
 
 if (!window) {
@@ -48,6 +49,7 @@ const componentMappings = {
   //'revision-history': <PageHistory pageId={pageId} />,
   //'page-comment': <PageComment />,
   'seen-user-list': <SeenUserList />,
+  'bookmark-button': <BookmarkButton pageId={pageId} crowi={crowi} />,
 };
 
 Object.keys(componentMappings).forEach((key) => {

+ 67 - 0
resource/js/components/BookmarkButton.js

@@ -0,0 +1,67 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import Icon from './Common/Icon'
+
+export default class BookmarkButton extends React.Component {
+
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      bookmarked: false,
+    };
+
+    this.handleClick = this.handleClick.bind(this);
+  }
+
+  componentDidMount() {
+    this.props.crowi.apiGet('/bookmarks.get', {page_id: this.props.pageId})
+    .then(res => {
+      if (res.bookmark) {
+        this.markBookmarked();
+      }
+    });
+  }
+
+  handleClick(event) {
+    event.preventDefault();
+
+    const pageId = this.props.pageId;
+
+    if (!this.state.bookmarked) {
+      this.props.crowi.apiPost('/bookmarks.add', {page_id: pageId})
+      .then(res => {
+        this.markBookmarked();
+      });
+    } else {
+      this.props.crowi.apiPost('/bookmarks.remove', {page_id: pageId})
+      .then(res => {
+        this.markUnBookmarked();
+      });
+    }
+  }
+
+  markBookmarked() {
+    this.setState({bookmarked: true});
+  }
+
+  markUnBookmarked() {
+    this.setState({bookmarked: false});
+  }
+
+  render() {
+    const iconName = this.state.bookmarked ? 'star' : 'star-o';
+
+    return (
+      <a href="#" title="Bookmark" className="bookmark-link" onClick={this.handleClick}>
+        <Icon name={iconName} />
+      </a>
+    );
+  }
+}
+
+BookmarkButton.propTypes = {
+  pageId: PropTypes.string,
+  crowi: PropTypes.object.isRequired,
+};

+ 0 - 46
resource/js/crowi.js

@@ -558,52 +558,6 @@ $(function() {
       return false;
     });
 
-    // bookmark
-    var $bookmarkButton = $('#bookmark-button');
-    $.get('/_api/bookmarks.get', {page_id: pageId}, function(res) {
-      if (res.ok) {
-        if (res.bookmark) {
-          MarkBookmarked();
-        }
-      }
-    });
-
-    $bookmarkButton.click(function() {
-      var bookmarked = $bookmarkButton.data('bookmarked');
-      var token = $bookmarkButton.data('csrftoken');
-      if (!bookmarked) {
-        $.post('/_api/bookmarks.add', {_csrf: token, page_id: pageId}, function(res) {
-          if (res.ok && res.bookmark) {
-            MarkBookmarked();
-          }
-        });
-      } else {
-        $.post('/_api/bookmarks.remove', {_csrf: token, page_id: pageId}, function(res) {
-          if (res.ok) {
-            MarkUnBookmarked();
-          }
-        });
-      }
-
-      return false;
-    });
-
-    function MarkBookmarked()
-    {
-      $('i', $bookmarkButton)
-        .removeClass('fa-star-o')
-        .addClass('fa-star');
-      $bookmarkButton.data('bookmarked', 1);
-    }
-
-    function MarkUnBookmarked()
-    {
-      $('i', $bookmarkButton)
-        .removeClass('fa-star')
-        .addClass('fa-star-o');
-      $bookmarkButton.data('bookmarked', 0);
-    }
-
     // Like
     var $likeButton = $('.like-button');
     var $likeCount = $('#like-count');