Ajax in likes in stream

This commit is contained in:
Raphael Sofaer 2011-07-04 21:40:29 -07:00
parent 1cd9c4bd0f
commit 4f056dca8e
18 changed files with 114 additions and 38 deletions

View file

@ -38,7 +38,7 @@ class AspectsController < ApplicationController
:type => ['StatusMessage','ActivityStreams::Photo'],
:order => session[:sort_order] + ' DESC',
:max_time => params[:max_time].to_i
).includes(:likes, {:comments => {:author => :profile}}, {:mentions => {:person => :profile}})
).includes({:comments => {:author => :profile}}, {:mentions => {:person => :profile}})
@posts = PostsFake.new(posts)
if params[:only_posts]

View file

@ -9,7 +9,7 @@ class LikesController < ApplicationController
respond_to :html, :mobile, :json
def create
target = current_user.find_visible_post_by_id params[:post_id]
target = current_user.find_visible_post_by_id params[:status_message_id]
positive = (params[:positive] == 'true') ? true : false
if target
@like = current_user.build_like(:positive => positive, :post => target)
@ -32,7 +32,7 @@ class LikesController < ApplicationController
end
def destroy
if @like = Like.where(:id => params[:id], :author_id => current_user.person.id).first
if @like = Like.where(:id => params[:id], :author_id => current_user.person.id, :post_id => params[:status_message_id]).first
current_user.retract(@like)
else
respond_to do |format|
@ -41,4 +41,13 @@ class LikesController < ApplicationController
end
end
end
def index
if target = current_user.find_visible_post_by_id(params[:status_message_id])
@likes = target.likes.includes(:author => :profile)
render :layout => false
else
render :nothing => true, :status => 404
end
end
end

View file

@ -10,9 +10,9 @@ module LikesHelper
def like_action(post, current_user=current_user)
if current_user.liked?(post)
link_to t('shared.stream_element.unlike'), like_path(current_user.like_for(post)), :method => :delete, :class => 'unlike', :remote => true
link_to t('shared.stream_element.unlike'), status_message_like_path(post, current_user.like_for(post)), :method => :delete, :class => 'unlike', :remote => true
else
link_to t('shared.stream_element.like'), likes_path(:positive => 'true', :post_id => post.id ), :method => :post, :class => 'like', :remote => true
link_to t('shared.stream_element.like'), status_message_likes_path(post, :positive => 'true'), :method => :post, :class => 'like', :remote => true
end
end
end

View file

@ -15,7 +15,7 @@ class Like < ActiveRecord::Base
xml_attr :positive
xml_attr :diaspora_handle
belongs_to :post
belongs_to :post, :counter_cache => true
belongs_to :author, :class_name => 'Person'
validates_uniqueness_of :post_id, :scope => :author_id

View file

@ -182,10 +182,14 @@ class User < ActiveRecord::Base
# Check whether the user has liked a post. Extremely inefficient if the post's likes are not loaded.
# @param [Post] post
def liked?(post)
if self.like_for(post)
return true
if post.likes.loaded?
if self.like_for(post)
return true
else
return false
end
else
return false
Like.exists?(:author_id => self.person.id, :post_id => post.id)
end
end
@ -193,10 +197,11 @@ class User < ActiveRecord::Base
# @param [Post] post
# @return [Like]
def like_for(post)
post.likes.each do |like|
return like if like.author_id == self.person.id
if post.likes.loaded?
return post.likes.detect{ |like| like.author_id == self.person.id }
else
return Like.where(:author_id => self.person.id, :post_id => post.id).first
end
return nil
end
######### Mailer #######################

View file

@ -2,11 +2,5 @@
-# licensed under the Affero General Public License version 3 or later. See
-# the COPYRIGHT file.
- if likes.size > 0
.likes_container
.likes
= image_tag('icons/heart.svg')
= link_to t('.people_like_this', :count => likes.length), "#", :class => "expand_likes"
%span.hidden.likes_list
= notification_people_link(nil, likes.map{|x| x.author})
= notification_people_link(nil, likes.map{|x| x.author})

View file

@ -0,0 +1,12 @@
-# Copyright (c) 2010, Diaspora Inc. This file is
-# licensed under the Affero General Public License version 3 or later. See
-# the COPYRIGHT file.
- if likes_count > 0
.likes_container
.likes
= image_tag('icons/heart.svg')
= link_to t('likes.likes.people_like_this', :count => likes_count), status_message_likes_path(post_id), :class => "expand_likes"
%span.hidden.likes_list
/= render 'likes/likes', :likes => likes

View file

@ -1,4 +1,4 @@
$(".like_action", ".stream_element[data-guid=<%=@like.post_id%>]").html("<%= escape_javascript(like_action(@like.post))%>");
WebSocketReceiver.processLike("<%=@like.post_id%>", "<%= escape_javascript(render("likes/likes", :post_id => @like.post_id, :likes => @like.post.likes)) %>");
WebSocketReceiver.processLike("<%=@like.post_id%>", "<%= escape_javascript(render("likes/likes_container", :post_id => @like.post_id, :likes_count => @like.post.likes.count)) %>");

View file

@ -1,3 +1,3 @@
$(".like_action", ".stream_element[data-guid=<%=@like.post_id%>]").html("<%= escape_javascript(like_action(@like.post))%>");
WebSocketReceiver.processLike("<%=@like.post_id%>", "<%= escape_javascript(render("likes/likes", :post_id => @like.post_id, :likes => @like.post.likes)) %>");
WebSocketReceiver.processLike("<%=@like.post_id%>", "<%= escape_javascript(render("likes/likes_container", :post_id => @like.post_id, :likes_count => @like.post.likes.count)) %>");

View file

@ -0,0 +1 @@
= render 'likes', :likes => @likes

View file

@ -65,5 +65,5 @@
#photo_stream.stream.show
%div{:data=>{:guid=>parent.id}}
.likes_container
= render "likes/likes", :post_id => parent.id, :likes => parent.likes
= render "likes/likes_container", :post_id => parent.id, :likes_count => parent.likes_count
= render "comments/comments", :post => parent, :comments => parent.comments, :always_expanded => true

View file

@ -51,7 +51,7 @@
= link_to t('comments.new_comment.comment'), '#', :class => 'focus_comment_textarea'
.likes
- if post.likes.size > 0
= render "likes/likes", :post_id => post.id, :likes => post.likes, :current_user => current_user
- if post.likes_count > 0
= render "likes/likes_container", :post_id => post.id, :likes_count => post.likes_count, :current_user => current_user
= render "comments/comments", :post => post, :comments => post.comments, :current_user => current_user, :condensed => true, :commenting_disabled => (defined?(@commenting_disabled) && @commenting_disabled)

View file

@ -10,7 +10,10 @@ Diaspora::Application.routes.draw do
put 'toggle_contact_visibility' => :toggle_contact_visibility
end
resources :status_messages, :only => [:new, :create, :destroy, :show]
resources :status_messages, :only => [:new, :create, :destroy, :show] do
resources :likes, :only => [:create, :destroy, :index]
end
get 'bookmarklet' => 'status_messages#bookmarklet'
get 'p/:id' => 'posts#show', :as => 'post'
@ -20,7 +23,6 @@ Diaspora::Application.routes.draw do
resources :comments, :only => [:create, :destroy]
resources :likes, :only => [:create, :destroy]
resources :conversations do
resources :messages, :only => [:create, :show]

View file

@ -0,0 +1,9 @@
class CounterCacheOnPostLikes < ActiveRecord::Migration
def self.up
add_column :posts, :likes_count, :integer, :default => 0
end
def self.down
remove_column :posts, :likes_count
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20110623210918) do
ActiveRecord::Schema.define(:version => 20110705003445) do
create_table "aspect_memberships", :force => true do |t|
t.integer "aspect_id", :null => false
@ -266,6 +266,7 @@ ActiveRecord::Schema.define(:version => 20110623210918) do
t.string "actor_url"
t.integer "objectId"
t.string "status_message_guid"
t.integer "likes_count", :default => 0
end
add_index "posts", ["author_id"], :name => "index_posts_on_person_id"

View file

@ -20,11 +20,7 @@
};
this.setUpLikes = function() {
$(this.expandLikesSelector).live("click", function(evt) {
evt.preventDefault();
$(this).siblings(".likes_list")
.fadeToggle("fast");
});
$(this.expandLikesSelector).live("click", this.expandLikes);
var likeIt = $(this.likesSelector);
@ -37,7 +33,24 @@
$(this).parent().fadeIn("fast");
});
};
this.expandLikes = function(evt){
evt.preventDefault();
var likesList = $(this).siblings(".likes_list");
if(likesList.children().length == 0){
likesList.append("<img alt='loading' src='/images/ajax-loader.gif' />");
$.ajax({
url: this.href,
success: function(data){
likesList.html(data);
likesList.fadeToggle("fast");
}
});
}else {
likesList
.fadeToggle("fast");
}
};
};
Diaspora.widgets.add("post", Post);
})();
})();

View file

@ -12,18 +12,17 @@ describe LikesController do
@aspect1 = @user1.aspects.first
@aspect2 = @user2.aspects.first
@controller.stub(:current_user).and_return(alice)
sign_in :user, @user1
end
describe '#create' do
let(:like_hash) {
{:positive => 1,
:post_id => "#{@post.id}"}
:status_message_id => "#{@post.id}"}
}
let(:dislike_hash) {
{:positive => 0,
:post_id => "#{@post.id}"}
:status_message_id => "#{@post.id}"}
}
context "on my own post" do
@ -72,6 +71,29 @@ describe LikesController do
end
end
describe '#index' do
before do
@message = alice.post(:status_message, :text => "hey", :to => @aspect1.id)
end
it 'returns a 404 for a post not visible to the user' do
sign_in eve
get :index, :status_message_id => @message.id
end
it 'returns an array of likes for a post' do
like = bob.build_like(:positive => true, :post => @message)
like.save!
get :index, :status_message_id => @message.id
assigns[:likes].map(&:id).should == @message.likes.map(&:id)
end
it 'returns an empty array for a post with no likes' do
get :index, :status_message_id => @message.id
assigns[:likes].should == []
end
end
describe '#destroy' do
before do
@message = bob.post(:status_message, :text => "hey", :to => @aspect1.id)
@ -81,7 +103,7 @@ describe LikesController do
it 'lets a user destroy their like' do
expect {
delete :destroy, :format => "js", :post_id => @like.post_id, :id => @like.id
delete :destroy, :format => "js", :status_message_id => @like.post_id, :id => @like.id
}.should change(Like, :count).by(-1)
response.status.should == 200
end
@ -91,7 +113,7 @@ describe LikesController do
like2.save
expect {
delete :destroy, :format => "js", :post_id => like2.post_id, :id => like2.id
delete :destroy, :format => "js", :status_message_id => like2.post_id, :id => like2.id
}.should_not change(Like, :count)
response.status.should == 403

View file

@ -56,6 +56,14 @@ describe Like do
end
end
describe 'counter cache' do
it 'increments the counter cache on its post' do
lambda {
@alice.like(1, :post => @status)
}.should change{ @status.reload.likes_count }.by(1)
end
end
describe 'xml' do
before do
@liker = Factory.create(:user)