Browse Source

WIP: Fixes likes

Sotaro KARASAWA 10 years ago
parent
commit
24d91552ad
5 changed files with 130 additions and 80 deletions
  1. 47 35
      lib/models/page.js
  2. 3 3
      lib/routes/index.js
  3. 31 20
      lib/routes/page.js
  4. 6 15
      lib/views/widget/page_side_header.html
  5. 43 7
      resource/js/crowi.js

+ 47 - 35
lib/models/page.js

@@ -24,10 +24,10 @@ module.exports = function(crowi) {
       pageData.populate([
       pageData.populate([
         {path: 'creator', model: 'User', select: USER_PUBLIC_FIELDS},
         {path: 'creator', model: 'User', select: USER_PUBLIC_FIELDS},
         {path: 'revision', model: 'Revision'},
         {path: 'revision', model: 'Revision'},
-        {path: 'liker', options: { limit: 11 }},
-        {path: 'seenUsers', options: { limit: 11 }},
+        //{path: 'liker', options: { limit: 11 }},
+        //{path: 'seenUsers', options: { limit: 11 }},
       ], function (err, pageData) {
       ], function (err, pageData) {
-        Page.populate(pageData, {path: 'revision.author', model: 'User'}, function(err, data) {
+        Page.populate(pageData, {path: 'revision.author', model: 'User', select: USER_PUBLIC_FIELDS}, function(err, data) {
           if (err) {
           if (err) {
             return reject(err);
             return reject(err);
           }
           }
@@ -108,48 +108,60 @@ module.exports = function(crowi) {
   };
   };
 
 
   pageSchema.methods.isLiked = function(userData) {
   pageSchema.methods.isLiked = function(userData) {
-    if (undefined === this.populated('liker')) {
-      if (this.liker.indexOf(userData._id.toString()) != -1) {
-        return true;
-      }
-      return true;
-    } else {
-      return this.liker.some(function(likedUser) {
-        return likedUser._id.equals(userData._id);
-      });
-    }
+    //if (undefined === this.populated('liker')) {
+    //  if (this.liker.indexOf(userData._id.toString()) != -1) {
+    //    return true;
+    //  }
+    //  return true;
+    //} else {
+    return this.liker.some(function(likedUser) {
+      return likedUser == userData._id.toString();
+    });
+    //}
   };
   };
 
 
-  pageSchema.methods.like = function(userData, callback) {
+  pageSchema.methods.like = function(userData) {
     var self = this,
     var self = this,
       Page = self;
       Page = self;
 
 
-    var added = this.liker.addToSet(userData._id);
-    if (added.length > 0) {
-      this.save(function(err, data) {
-        debug('liker updated!', added);
-        return callback(err, data);
-      });
-    } else {
-      debug('liker not updated');
-      return callback(null, this);
-    }
+    return new Promise(function(resolve, reject) {
+      var added = self.liker.addToSet(userData._id);
+      if (added.length > 0) {
+        self.save(function(err, data) {
+          if (err) {
+            return reject(err);
+          }
+          debug('liker updated!', added);
+          return resolve(data);
+        });
+      } else {
+        debug('liker not updated');
+        return reject(self);
+      }
+    });
+
   };
   };
 
 
   pageSchema.methods.unlike = function(userData, callback) {
   pageSchema.methods.unlike = function(userData, callback) {
     var self = this,
     var self = this,
       Page = self;
       Page = self;
 
 
-    var removed = this.liker.pull(userData._id);
-    if (removed.length > 0) {
-      this.save(function(err, data) {
-        debug('unlike updated!', removed);
-        return callback(err, data);
-      });
-    } else {
-      debug('unlike not updated');
-      callback(null, this);
-    }
+    return new Promise(function(resolve, reject) {
+      var removed = self.liker.pull(userData._id);
+      if (removed.length > 0) {
+        self.save(function(err, data) {
+          if (err) {
+            return reject(err);
+          }
+          debug('unlike updated!', removed);
+          return resolve(data);
+        });
+      } else {
+        debug('unlike not updated');
+        return reject(self);
+      }
+    });
+
   };
   };
 
 
   pageSchema.methods.isSeenUser = function(userData) {
   pageSchema.methods.isSeenUser = function(userData) {
@@ -157,7 +169,7 @@ module.exports = function(crowi) {
       Page = self;
       Page = self;
 
 
     return this.seenUsers.some(function(seenUser) {
     return this.seenUsers.some(function(seenUser) {
-      return seenUser._id.equals(userData._id);
+      return seenUser.equals(userData._id);
     });
     });
   };
   };
 
 

+ 3 - 3
lib/routes/index.js

@@ -72,8 +72,6 @@ module.exports = function(crowi, app) {
   app.get( '/_api/attachment/page/:pageId', loginRequired(crowi, app) , attachment.api.list);
   app.get( '/_api/attachment/page/:pageId', loginRequired(crowi, app) , attachment.api.list);
   app.post('/_api/attachment/page/:pageId', loginRequired(crowi, app) , attachment.api.add);
   app.post('/_api/attachment/page/:pageId', loginRequired(crowi, app) , attachment.api.add);
   app.post('/_api/attachment/:id/remove',loginRequired(crowi, app), attachment.api.remove);
   app.post('/_api/attachment/:id/remove',loginRequired(crowi, app), attachment.api.remove);
-  app.post('/_api/page/:id/like'      , loginRequired(crowi, app) , page.api.like);
-  app.post('/_api/page/:id/unlike'    , loginRequired(crowi, app) , page.api.unlike);
 
 
   // HTTP RPC Styled API (に徐々に移行していいこうと思う)
   // HTTP RPC Styled API (に徐々に移行していいこうと思う)
   app.get('/_api/pages.get'           , accessTokenParser(crowi, app) , loginRequired(crowi, app) , page.api.get);
   app.get('/_api/pages.get'           , accessTokenParser(crowi, app) , loginRequired(crowi, app) , page.api.get);
@@ -82,7 +80,9 @@ module.exports = function(crowi, app) {
   app.post('/_api/comments.add'       , form.comment, accessTokenParser(crowi, app) , loginRequired(crowi, app) , comment.api.add);
   app.post('/_api/comments.add'       , form.comment, accessTokenParser(crowi, app) , loginRequired(crowi, app) , comment.api.add);
   app.get( '/_api/bookmarks.get'      , accessTokenParser(crowi, app) , loginRequired(crowi, app) , bookmark.api.get);
   app.get( '/_api/bookmarks.get'      , accessTokenParser(crowi, app) , loginRequired(crowi, app) , bookmark.api.get);
   app.post('/_api/bookmarks.add'      , accessTokenParser(crowi, app) , loginRequired(crowi, app) , bookmark.api.add);
   app.post('/_api/bookmarks.add'      , accessTokenParser(crowi, app) , loginRequired(crowi, app) , bookmark.api.add);
-  app.post('/_api/bookmarks.remove'   , accessTokenParser(crowi, app) , loginRequired(crowi, app) , bookmark.api.remove);
+  app.post('/_api/likes.add'          , accessTokenParser(crowi, app) , loginRequired(crowi, app) , page.api.like);
+  app.post('/_api/likes.remove'       , accessTokenParser(crowi, app) , loginRequired(crowi, app) , page.api.unlike);
+
   //app.get('/_api/revision/:id'     , user.useUserData()         , revision.api.get);
   //app.get('/_api/revision/:id'     , user.useUserData()         , revision.api.get);
   //app.get('/_api/r/:revisionId'    , user.useUserData()         , page.api.get);
   //app.get('/_api/r/:revisionId'    , user.useUserData()         , page.api.get);
 
 

+ 31 - 20
lib/routes/page.js

@@ -269,35 +269,46 @@ module.exports = function(crowi, app) {
   };
   };
 
 
   /**
   /**
-   * page like
+   * @api {post} /likes.add Like page
+   * @apiName LikePage
+   * @apiGroup Page
+   *
+   * @apiParam {String} page_id Page Id.
    */
    */
   api.like = function(req, res){
   api.like = function(req, res){
-    var id = req.params.id;
-    Page.findPageByIdAndGrantedUser(id, req.user, function(err, pageData) {
-      if (pageData) {
-        pageData.like(req.user, function(err, data) {
-          return res.json({status: true});
-        });
-      } else {
-        return res.json({status: false});
-      }
+    var id = req.body.page_id;
+
+    Page.findPageByIdAndGrantedUser(id, req.user)
+    .then(function(pageData) {
+      return pageData.like(req.user);
+    }).then(function(data) {
+      var result = {page: data};
+      return res.json(ApiResponse.success(result));
+    }).catch(function(err) {
+      debug('Like failed', err);
+      return res.json(ApiResponse.error({}));
     });
     });
   };
   };
 
 
   /**
   /**
-   * page like
+   * @api {post} /likes.remove Unlike page
+   * @apiName UnlikePage
+   * @apiGroup Page
+   *
+   * @apiParam {String} page_id Page Id.
    */
    */
   api.unlike = function(req, res){
   api.unlike = function(req, res){
-    var id = req.params.id;
+    var id = req.body.page_id;
 
 
-    Page.findPageByIdAndGrantedUser(id, req.user, function(err, pageData) {
-      if (pageData) {
-        pageData.unlike(req.user, function(err, data) {
-          return res.json({status: true});
-        });
-      } else {
-        return res.json({status: false});
-      }
+    Page.findPageByIdAndGrantedUser(id, req.user)
+    .then(function(pageData) {
+      return pageData.unlike(req.user);
+    }).then(function(data) {
+      var result = {page: data};
+      return res.json(ApiResponse.success(result));
+    }).catch(function(err) {
+      debug('Unlike failed', err);
+      return res.json(ApiResponse.error({}));
     });
     });
   };
   };
 
 

+ 6 - 15
lib/views/widget/page_side_header.html

@@ -23,20 +23,18 @@
       </dt>
       </dt>
       <dd>
       <dd>
         <p class="liker-count">
         <p class="liker-count">
-        {{ page.liker.length }}
-          {% if page.isLiked(user) %}
-            <button data-liked="1" class="btn btn-default btn-sm active" id="pageLikeButton"><i class="fa fa-thumbs-up"></i> いいね!</button>
-          {% else %}
-            <button data-liked="0" class="btn btn-default btn-sm" id="pageLikeButton"><i class="fa fa-thumbs-o-up"></i> いいね!</button>
-          {% endif %}
+        <span id="like-count">{{ page.liker.length }}</span>
+        <button data-liked="{% if page.isLiked(user) %}1{% else %}0{% endif %}" class="btn btn-default btn-sm" id="like-button"><i class="fa fa-thumbs-o-up"></i> いいね!</button>
         </p>
         </p>
         <p class="liker-list">
         <p class="liker-list">
+        {#
           {% for liker in page.liker %}
           {% for liker in page.liker %}
             <a href="{{ user_page_root(liker) }}" title="{{ liker.name }}"><img alt="{{ liker.name }}" src="{{ liker|picture }}" class="picture picture-xs picture-rounded"></a>
             <a href="{{ user_page_root(liker) }}" title="{{ liker.name }}"><img alt="{{ liker.name }}" src="{{ liker|picture }}" class="picture picture-xs picture-rounded"></a>
           {% endfor %}
           {% endfor %}
           {% if page.liker.length > 10 %}
           {% if page.liker.length > 10 %}
             (...)
             (...)
           {% endif %}
           {% endif %}
+          #}
         </p>
         </p>
       </dd>
       </dd>
 
 
@@ -46,24 +44,17 @@
           {{ page.seenUsers.length }}
           {{ page.seenUsers.length }}
         </p>
         </p>
         <p class="seen-user-list">
         <p class="seen-user-list">
+        {#
           {% for seenUser in page.seenUsers %}
           {% for seenUser in page.seenUsers %}
           <a href="{{ user_page_root(seenUser) }}" title="{{ seenUser.name }}"><img alt="{{ seenUser.name }}" src="{{ seenUser|picture }}" class="picture picture-xs picture-rounded"></a>
           <a href="{{ user_page_root(seenUser) }}" title="{{ seenUser.name }}"><img alt="{{ seenUser.name }}" src="{{ seenUser|picture }}" class="picture picture-xs picture-rounded"></a>
           {% endfor %}
           {% endfor %}
           {% if page.seenUsers.length > 10 %}
           {% if page.seenUsers.length > 10 %}
             (...)
             (...)
           {% endif %}
           {% endif %}
+        #}
         </p>
         </p>
       </dd>
       </dd>
     </dl>
     </dl>
   </div>
   </div>
-<script>
-$(function() {
-  $('#pageLikeButton').click(function() {
-    var pageId = {{page._id|json|safe}};
-    $.post('/_api/page/{{ page._id.toString() }}/like', function(data) {
-    });
-  });
-});
-</script>
 </div>
 </div>
 {% endif %} {# if page }}} #}
 {% endif %} {# if page }}} #}

+ 43 - 7
resource/js/crowi.js

@@ -448,16 +448,52 @@ $(function() {
         .addClass('fa-star-o');
         .addClass('fa-star-o');
       $bookmarkButton.data('bookmarked', 0);
       $bookmarkButton.data('bookmarked', 0);
     }
     }
-  }
 
 
-  if (!isSeen) {
-    $.post('/_api/pages.seen', {page_id: pageId}, function(res) {
-      // ignore unless response has error
-      console.log(pageId, res);
-      if (res.ok && res.seenUser) {
-        $('#content-main').data('page-is-seen', 1);
+    // Like
+    var $likeButton = $('#like-button');
+    var $likeCount = $('#like-count');
+    $likeButton.click(function() {
+      var liked = $likeButton.data('liked');
+      if (!liked) {
+        $.post('/_api/likes.add', {page_id: pageId}, function(res) {
+          if (res.ok) {
+            MarkLiked();
+          }
+        });
+      } else {
+        $.post('/_api/likes.remove', {page_id: pageId}, function(res) {
+          if (res.ok) {
+            MarkUnLiked();
+          }
+        });
       }
       }
+
+      return false;
     });
     });
+
+    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);
+    }
+
+    if (!isSeen) {
+      $.post('/_api/pages.seen', {page_id: pageId}, function(res) {
+        // ignore unless response has error
+        console.log(pageId, res);
+        if (res.ok && res.seenUser) {
+          $('#content-main').data('page-is-seen', 1);
+        }
+      });
+    }
   }
   }
 });
 });