okonomi 9 лет назад
Родитель
Сommit
35a8364e99
3 измененных файлов с 77 добавлено и 0 удалено
  1. 3 0
      lib/views/page.html
  2. 2 0
      resource/js/app.js
  3. 72 0
      resource/js/components/BookmarkButton.js

+ 3 - 0
lib/views/page.html

@@ -19,6 +19,9 @@
       <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>
       </div>
+      <div class="flex-item-action">
+        <span id="bookmark-button-react" data-csrftoken="{{ csrf() }}"></span>
+      </div>
       <div class="flex-item-action visible-xs visible-sm">
         <button
             data-csrftoken="{{ csrf() }}"

+ 2 - 0
resource/js/app.js

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

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

@@ -0,0 +1,72 @@
+import React from 'react';
+import $ from 'jquery';
+
+export default class BookmarkButton extends React.Component {
+
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      bookmarked: false,
+      pageId: null,
+      token: null,
+    };
+
+    this.handleClick = this.handleClick.bind(this);
+  }
+
+  componentWillMount() {
+    // FIXME(property?)
+    this.setState({
+      pageId: $('#content-main').data('page-id'),
+      token: $('#bookmark-button-react').data('csrftoken'),
+    });
+  }
+
+  componentDidMount() {
+    $.get('/_api/bookmarks.get', {page_id: this.state.pageId}, (res) => {
+      if (res.ok) {
+        if (res.bookmark) {
+          this.markBookmarked();
+        }
+      }
+    });
+  }
+
+  handleClick(event) {
+    event.preventDefault();
+
+    const token = this.state.token;
+    const pageId = this.state.pageId;
+
+    if (!this.state.bookmarked) {
+      $.post('/_api/bookmarks.add', {_csrf: token, page_id: pageId}, (res) => {
+        if (res.ok && res.bookmark) {
+          this.markBookmarked();
+        }
+      });
+    } else {
+      $.post('/_api/bookmarks.remove', {_csrf: token, page_id: pageId}, (res) => {
+        if (res.ok) {
+          this.markUnBookmarked();
+        }
+      });
+    }
+  }
+
+  markBookmarked() {
+    this.setState({bookmarked: true});
+  }
+
+  markUnBookmarked() {
+    this.setState({bookmarked: false});
+  }
+
+  render() {
+    const className = this.state.bookmarked ? 'fa fa-star' : 'fa fa-star-o';
+
+    return (
+      <a href="#" title="Bookmark" className="bookmark-link" onClick={this.handleClick}><i className={className}></i></a>
+    );
+  }
+}