Make comments index ajaxy

This commit is contained in:
Raphael Sofaer 2011-07-11 12:32:08 -07:00
parent 3f555eefc4
commit 39ff51a9d7
14 changed files with 145 additions and 133 deletions

View file

@ -28,7 +28,7 @@ class AspectsController < ApplicationController
redirect_to getting_started_path redirect_to getting_started_path
return return
end end
# redirect to aspects creation # redirect to aspects creation
if @aspects.blank? if @aspects.blank?
redirect_to new_aspect_path redirect_to new_aspect_path
@ -47,7 +47,7 @@ class AspectsController < ApplicationController
:type => ['StatusMessage','ActivityStreams::Photo'], :type => ['StatusMessage','ActivityStreams::Photo'],
:order => session[:sort_order] + ' DESC', :order => session[:sort_order] + ' DESC',
:max_time => params[:max_time].to_i :max_time => params[:max_time].to_i
).includes({:comments => {:author => :profile}}, {:mentions => {:person => :profile}}) ).includes(:mentions => {:person => :profile})
@posts = PostsFake.new(posts) @posts = PostsFake.new(posts)
if params[:only_posts] if params[:only_posts]

View file

@ -57,7 +57,8 @@ class CommentsController < ApplicationController
def index def index
@post = current_user.find_visible_post_by_id(params[:post_id]) @post = current_user.find_visible_post_by_id(params[:post_id])
if @post if @post
@comments = @post.comments @comments = @post.comments.includes(:author => :profile)
render :layout => false
else else
raise ActiveRecord::RecordNotFound.new raise ActiveRecord::RecordNotFound.new
end end

View file

@ -4,11 +4,11 @@
module CommentsHelper module CommentsHelper
GSUB_THIS = "FIUSDHVIUSHDVIUBAIUHAPOIUXJM" GSUB_THIS = "FIUSDHVIUSHDVIUBAIUHAPOIUXJM"
def comment_toggle(count, commenting_disabled=false) def comment_toggle(post, commenting_disabled=false)
if count <= 3 if post.comments.size <= 3
str = link_to "#{t('stream_helper.hide_comments')}", '#', :class => "show_post_comments" str = link_to "#{t('stream_helper.hide_comments')}", post_comments_path(post.id), :class => "toggle_post_comments"
else else
str = link_to "#{t('stream_helper.show_more_comments', :number => count-3)}", '#', :class => "show_post_comments" str = link_to "#{t('stream_helper.show_more_comments', :number => post.comments.size - 3)}", post_comments_path(post.id), :class => "toggle_post_comments"
end end
str str
end end

View file

@ -13,7 +13,7 @@ class Post < ActiveRecord::Base
xml_attr :public xml_attr :public
xml_attr :created_at xml_attr :created_at
has_many :comments, :order => 'created_at ASC', :dependent => :destroy has_many :comments, :dependent => :destroy
has_many :likes, :conditions => {:positive => true}, :dependent => :delete_all has_many :likes, :conditions => {:positive => true}, :dependent => :delete_all
has_many :dislikes, :conditions => {:positive => false}, :class_name => 'Like', :dependent => :delete_all has_many :dislikes, :conditions => {:positive => false}, :class_name => 'Like', :dependent => :delete_all
@ -111,5 +111,10 @@ class Post < ActiveRecord::Base
def activity_streams? def activity_streams?
false false
end end
# @return [Array<Comment>]
def last_three_comments
self.comments.order('created_at DESC').limit(3).includes(:author => :profile).reverse
end
end end

View file

@ -3,18 +3,16 @@
-# the COPYRIGHT file. -# the COPYRIGHT file.
- unless comments_expanded - unless comments_expanded
%ul.show_comments{:class => ("hidden" if post.comments.count <= 3)} %ul.show_comments{:class => ("hidden" if post.comments.size <= 3)}
%li %li
%b= comment_toggle( post.comments.count ) %b= comment_toggle( post)
%ul.comments{:id => post.id, :class => ("hidden" if comments.size == 0 && !comments_expanded)} %ul.comments{:id => post.id, :class => ('loaded' if post.comments.size <= 3)}
-if comments.size > 3 -if post.comments.size > 3 && !comments_expanded
.older_comments{:class => ("hidden inactive" unless comments_expanded)} = render :partial => 'comments/comment', :collection => post.last_three_comments, :locals => {:post => post}
= render :partial => 'comments/comment', :collection => comments[0..-4], :locals => {:post => post}
= render :partial => 'comments/comment', :collection => comments[-3, 3], :locals => {:post => post}
-else -else
= render :partial => 'comments/comment', :collection => comments, :locals => {:post => post} = render :partial => 'comments/comment', :collection => post.comments, :locals => {:post => post}
- unless @commenting_disabled - unless @commenting_disabled
%li.comment.show .new_comment_form_wrapper{:class => ( 'hidden' if post.comments.size == 0)}
= new_comment_form(post.id, current_user) = new_comment_form(post.id, current_user)

View file

@ -0,0 +1 @@
= render :partial => 'comments/comment', :collection => @comments, :locals => {:post => @post}

View file

@ -1,2 +0,0 @@
var html = <%= render :partial => 'comments/comment', :collection => @comments, :locals => {:post => @post} %>
$('.comments', '.stream_element[data-guid="<%= @post.id %>"]').html(html);

View file

@ -59,4 +59,4 @@
- if post.likes_count > 0 - if post.likes_count > 0
= render "likes/likes_container", :post_id => post.id, :likes_count => post.likes_count, :current_user => current_user = 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, :commenting_disabled => (defined?(@commenting_disabled) && @commenting_disabled) = render "comments/comments", :post => post, :current_user => current_user, :commenting_disabled => (defined?(@commenting_disabled) && @commenting_disabled)

View file

@ -7,11 +7,9 @@ When /^I open the comment box$/ do
end end
Then /^the first comment field should be open/ do Then /^the first comment field should be open/ do
css_query = "$('#main_stream .stream_element:first ul.comments:visible')" find("#main_stream .stream_element .new_comment").should be_visible
page.evaluate_script("#{css_query}.length").should == 1
end end
Then /^the first comment field should be closed$/ do Then /^the first comment field should be closed$/ do
css_query = "$('#main_stream .stream_element:first ul.comments:hidden')" find("#main_stream .stream_element .new_comment").should_not be_visible
page.evaluate_script("#{css_query}.length").should == 1
end end

View file

@ -6,9 +6,6 @@ class PostsFake
author_ids = [] author_ids = []
posts.each do |p| posts.each do |p|
author_ids << p.author_id author_ids << p.author_id
p.comments.each do |c|
author_ids << c.author_id
end
end end
people = Person.where(:id => author_ids).includes(:profile) people = Person.where(:id => author_ids).includes(:profile)
@ -17,9 +14,6 @@ class PostsFake
@post_fakes = posts.map do |post| @post_fakes = posts.map do |post|
f = Fake.new(post, self) f = Fake.new(post, self)
f.comments = post.comments.map do |comment|
Fake.new(comment, self)
end
f f
end end
end end
@ -29,7 +23,6 @@ class PostsFake
end end
class Fake class Fake
attr_accessor :comments
attr_reader :model attr_reader :model
def initialize(model, fakes_collection) def initialize(model, fakes_collection)
@fakes_collection = fakes_collection @fakes_collection = fakes_collection

View file

@ -52,7 +52,7 @@ var Stream = {
}, },
setUpComments: function(){ setUpComments: function(){
$("a.show_post_comments:not(.show)", this.selector).live('click', Stream.toggleComments); $("a.toggle_post_comments:not(.show)", this.selector).live('click', Stream.toggleComments);
// comment link form focus // comment link form focus
$(".focus_comment_textarea", this.selector).live('click', function(evt) { $(".focus_comment_textarea", this.selector).live('click', function(evt) {
Stream.focusNewComment($(this), evt); Stream.focusNewComment($(this), evt);
@ -66,7 +66,7 @@ var Stream = {
var element = $(this), var element = $(this),
target = element.parents(".comment"), target = element.parents(".comment"),
post = element.closest(".stream_element"), post = element.closest(".stream_element"),
toggler = post.find(".show_post_comments"); toggler = post.find(".toggle_post_comments");
target.hide("blind", { direction: "vertical" }, 300, function() { target.hide("blind", { direction: "vertical" }, 300, function() {
$(this).remove(); $(this).remove();
@ -126,42 +126,58 @@ var Stream = {
toggleComments: function(evt) { toggleComments: function(evt) {
evt.preventDefault(); evt.preventDefault();
var $this = $(this),
showUl = $(this).closest("li"),
commentBlock = $this.closest(".stream_element").find("ul.comments", ".content"),
commentBlockMore = $this.closest(".stream_element").find(".older_comments", ".content")
if( commentBlockMore.hasClass("inactive") ) { var $toggler = $(this),
commentBlockMore.fadeIn(150, function() { comments = $toggler.closest('.stream_element').find('ul.comments');
commentBlockMore.removeClass("inactive");
commentBlockMore.removeClass("hidden"); if (comments.hasClass('loaded') && !comments.hasClass('hidden')){
}); Stream.hideComments.apply($toggler);
$this.html(Diaspora.widgets.i18n.t("comments.hide")); }else {
} else { Stream.showComments.apply($toggler);
if(commentBlock.hasClass("hidden")) {
commentBlock.removeClass("hidden");
showUl.css("margin-bottom","-1em");
$this.html(Diaspora.widgets.i18n.t("comments.hide"));
}else{
commentBlock.addClass("hidden");
showUl.css("margin-bottom","1em");
$this.html(Diaspora.widgets.i18n.t("comments.show"));
}
} }
}, },
showComments: function(){
var commentList = this.closest('.stream_element').find('ul.comments'),
toggle = this;
if( commentList.hasClass('loaded') ){
toggle.html(Diaspora.widgets.i18n.t("comments.hide"));
commentList.removeClass('hidden');
}
else {
toggle.append("<img alt='loading' src='/images/ajax-loader.gif' />");
$.ajax({
url: this.attr('href'),
success: function(data){
toggle.html(Diaspora.widgets.i18n.t("comments.hide"));
commentList.html(data)
.addClass('loaded');
Diaspora.widgets.publish("stream/scrolled")
}
});
}
},
hideComments: function(){
var commentList = this.closest('.stream_element').find('ul.comments');
commentList.addClass('hidden');
this.html(Diaspora.widgets.i18n.t("comments.show"));
},
focusNewComment: function(toggle, evt) { focusNewComment: function(toggle, evt) {
evt.preventDefault(); evt.preventDefault();
var commentBlock = toggle.closest(".stream_element").find("ul.comments", ".content"); var post = toggle.closest(".stream_element");
var commentBlock = post.find(".new_comment_form_wrapper");
var textarea = post.find(".new_comment textarea");
if(commentBlock.hasClass("hidden")) { if(commentBlock.hasClass("hidden")) {
commentBlock.removeClass("hidden"); commentBlock.removeClass("hidden");
commentBlock.find("textarea").focus(); textarea.focus();
} else { } else {
if(commentBlock.children().length <= 1) { if(commentBlock.children().length <= 1) {
commentBlock.addClass("hidden"); commentBlock.addClass("hidden");
} else { } else {
commentBlock.find("textarea").focus(); textarea.focus();
} }
} }
} }

View file

@ -97,16 +97,16 @@ var WebSocketReceiver = {
$(html).fadeIn("fast", function(){}) $(html).fadeIn("fast", function(){})
); );
} else { } else {
$('.comments li:last', post).before( $('.comments', post).append(
$(html).fadeIn("fast", function(){}) $(html).fadeIn("fast", function(){})
); );
} }
var toggler = $('.show_post_comments', post).parent(); var toggler = $('.toggle_post_comments', post).parent();
if(toggler.length > 0){ if(toggler.length > 0){
toggler.html( toggler.html(
toggler.html().replace(/\d+/,$('.comments', post).find('li').length -1) toggler.html().replace(/\d+/,$('.comments', post).find('li').length)
); );
if( !$(".comments", post).is(':visible') ) { if( !$(".comments", post).is(':visible') ) {

View file

@ -472,11 +472,6 @@ ul.dropdown
:font :font
:size 1em :size 1em
.comments
:padding
:bottom 6px
> li:last-child
:border-bottom none
.comment_box .comment_box
:width 475px :width 475px
:margin :margin
@ -543,23 +538,6 @@ ul.dropdown
:background none :background none
:border none :border none
.stream ul.comments
:padding
:bottom 6px
> li:last-child
:border-bottom none
.avatar
:width 30px
:height 30px
.comment_box
:margin
:bottom 5px
.submit_button .submit_button
:text :text
:align right :align right
@ -567,8 +545,12 @@ ul.dropdown
ul.comments, ul.comments,
ul.show_comments, ul.show_comments,
.likes_container .likes_container
.avatar
:width 30px
:height 30px
:margin 0 :margin 0
:top 0.5em
:padding 0 :padding 0
:font :font
@ -578,14 +560,6 @@ ul.show_comments,
:position relative :position relative
form
textarea
:width 365px
:height 21px
input
:display none
li li
:list :list
:style none :style none
@ -594,12 +568,6 @@ ul.show_comments,
:border :border
:bottom 1px dotted #aaa :bottom 1px dotted #aaa
.new_comment
:min-height 35px
p
:margin
:bottom 0
.from .from
:font :font
:size 1em :size 1em
@ -618,7 +586,7 @@ ul.show_comments,
:padding :padding
:left 36px :left 36px
:right 10px :right 10px
p p
:margin :margin
:bottom 0 :bottom 0
@ -627,41 +595,68 @@ ul.show_comments,
.right .right
:right 4px :right 4px
form
:margin
:top -5px
:bottom -4px
:font
:size 1em
.submit_button
input
:margin
:right 0
textarea
:font
:size 1em
:margin
:bottom -3px
p
:position relative
:left 35px
.avatar .avatar
:position absolute :position absolute
:display inline :display inline
form.open ul.show_comments
.submit_button :padding
:display block :bottom 6px
:margin :margin
:top 5px :top 6px
:bottom 2px
:right 2px form.new_comment
input :padding 8px 5px
:display inline-block .avatar
:position absolute
:display inline
:width 30px
:height 30px
:min-height 35px
input
:display none
:margin
:bottom -4px
:font
:size 1em
.submit_button
input
:margin
:right 0
textarea
:width 365px
:height 21px
:font
:size 1em
:margin
:top 0
:bottom -3px
p
:margin
:bottom 0
:top -10px
:position relative
:left 35px
&.open
.submit_button
:display block
:margin
:top 5px
:bottom 2px
:right 2px
input
:display inline-block
.comments .comments
.timeago .timeago
@ -2200,8 +2195,6 @@ h3,h4
ul.show_comments ul.show_comments
:margin
:bottom -0.5em
:border :border
:top 1px dotted #aaa :top 1px dotted #aaa

View file

@ -51,6 +51,15 @@ describe Post do
end end
end end
describe '#receive' do describe '#last_three_comments' do
it 'returns the last three comments of a post' do
post = bob.post :status_message, :text => "hello", :to => 'all'
created_at = Time.now - 100
comments = [alice, eve, bob, alice].map do |u|
created_at = created_at + 10
u.comment("hey", :post => post, :created_at => created_at)
end
post.last_three_comments.map{|c| c.id}.should == comments[1,3].map{|c| c.id}
end
end end
end end