Commit ca5ebf95375cd5dbb80a047dc79f4c31e36df899
1 parent
04962ef3
Exists in
master
and in
29 other branches
Pagination of comments and replies on profile wall.
The comments and replies are fetched only after the View all and More links are clicked.
Showing
10 changed files
with
153 additions
and
29 deletions
Show diff stats
app/controllers/public/profile_controller.rb
... | ... | @@ -210,6 +210,48 @@ class ProfileController < PublicController |
210 | 210 | render :partial => 'profile_network_activities', :locals => {:network_activities => @activities} |
211 | 211 | end |
212 | 212 | |
213 | + def more_comments | |
214 | + activity_id = params[:activity].to_i | |
215 | + activity = ActionTracker::Record.find(:first, :conditions => {:id => activity_id, :user_id => @profile.id}) | |
216 | + comments_count = activity.comments.count | |
217 | + comment_page = (params[:comment_page] || 1).to_i | |
218 | + comments_per_page = 5 | |
219 | + no_more_pages = comments_count <= comment_page * comments_per_page | |
220 | + | |
221 | + render :update do |page| | |
222 | + page.insert_html :bottom, 'profile-wall-activities-comments-'+params[:activity], | |
223 | + :partial => 'comment', :collection => activity.comments.paginate(:per_page => comments_per_page, :page => comment_page) | |
224 | + | |
225 | + if no_more_pages | |
226 | + page.remove 'profile-wall-activities-comments-more-'+params[:activity] | |
227 | + else | |
228 | + page.replace_html 'profile-wall-activities-comments-more-'+params[:activity], | |
229 | + :partial => 'more_comments', :locals => {:activity => activity, :comment_page => comment_page} | |
230 | + end | |
231 | + end | |
232 | + end | |
233 | + | |
234 | + def more_replies | |
235 | + activity_id = params[:activity].to_i | |
236 | + activity = Scrap.find(:first, :conditions => {:id => activity_id, :receiver_id => @profile.id, :scrap_id => nil}) | |
237 | + comments_count = activity.replies.count | |
238 | + comment_page = (params[:comment_page] || 1).to_i | |
239 | + comments_per_page = 5 | |
240 | + no_more_pages = comments_count <= comment_page * comments_per_page | |
241 | + | |
242 | + render :update do |page| | |
243 | + page.insert_html :bottom, 'profile-wall-activities-comments-'+params[:activity], | |
244 | + :partial => 'profile_scrap', :collection => activity.replies.paginate(:per_page => comments_per_page, :page => comment_page), :as => :scrap | |
245 | + | |
246 | + if no_more_pages | |
247 | + page.remove 'profile-wall-activities-comments-more-'+params[:activity] | |
248 | + else | |
249 | + page.replace_html 'profile-wall-activities-comments-more-'+params[:activity], | |
250 | + :partial => 'more_replies', :locals => {:activity => activity, :comment_page => comment_page} | |
251 | + end | |
252 | + end | |
253 | + end | |
254 | + | |
213 | 255 | def remove_scrap |
214 | 256 | begin |
215 | 257 | scrap = current_user.person.scraps(params[:scrap_id]) |
... | ... | @@ -343,6 +385,7 @@ class ProfileController < PublicController |
343 | 385 | end |
344 | 386 | end |
345 | 387 | |
388 | + | |
346 | 389 | protected |
347 | 390 | |
348 | 391 | def check_access_to_profile |
... | ... | @@ -393,4 +436,5 @@ class ProfileController < PublicController |
393 | 436 | def relations_to_include |
394 | 437 | [:image, :domains, :preferred_domain, :environment] |
395 | 438 | end |
439 | + | |
396 | 440 | end | ... | ... |
app/views/profile/_profile_activities_list.rhtml
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | <% if activity.kind_of?(ActionTracker::Record) %> |
5 | 5 | <%= render :partial => 'profile_activity', :locals => { :activity => activity, :tab_action => 'wall' } if activity.visible? %> |
6 | 6 | <% else %> |
7 | - <%= render :partial => 'profile_scrap', :locals => {:scrap => activity } %> | |
7 | + <%= render :partial => 'profile_scraps', :locals => { :activity => activity, :scrap => activity } %> | |
8 | 8 | <% end %> |
9 | 9 | <% end %> |
10 | 10 | <% end %> | ... | ... |
app/views/profile/_profile_comments.rhtml
1 | 1 | <hr /> |
2 | 2 | |
3 | -<% if activity.comments_count > 2 %> | |
3 | +<ul id="profile-wall-activities-comments-<%= activity.id %>" class="profile-wall-activities-comments" > | |
4 | +</ul> | |
5 | +<% if activity.comments_count > 0 %> | |
6 | +<div id="profile-wall-activities-comments-more-<%= activity.id %>" class="profile-wall-activities-comments" > | |
4 | 7 | <div class='view-all-comments icon-chat'> |
5 | - <%= link_to(_("View all %s comments") % activity.comments_count, '#') %> | |
8 | + <%= link_to_remote(_("View all %s comments") % activity.comments_count, :url => { :profile => profile.identifier, :controller => 'profile', :action => 'more_comments', :activity => activity, :comment_page => (1)}) %> | |
6 | 9 | </div> |
10 | +</div> | |
7 | 11 | <% end %> |
8 | - | |
9 | -<ul class="profile-wall-activities-comments" style="<%= 'display:none;' if (activity.comments_count > 2) %>" > | |
10 | - <%= render :partial => 'comment', :collection => activity.comments_as_thread %> | |
11 | -</ul> | |
12 | - | |
13 | 12 | <%= render :partial => 'profile_comment_form', :locals => { :activity => activity, :tab_action => tab_action } %> | ... | ... |
app/views/profile/_profile_scrap.rhtml
... | ... | @@ -16,13 +16,7 @@ |
16 | 16 | </div> |
17 | 17 | </div> |
18 | 18 | |
19 | - <% if scrap.replies.count > 2 %> | |
20 | - <div class='view-all-comments icon-chat'> | |
21 | - <%= link_to(_("View all %s comments") % scrap.replies.count, '#') %> | |
22 | - </div> | |
23 | - <% end %> | |
24 | - | |
25 | - <ul class="profile-wall-activities-comments scrap-replies" style="width: auto; <%= 'display:none;' if (scrap.replies.count > 2) %>" > | |
19 | + <ul class="profile-wall-activities-comments scrap-replies" style="width: auto;" > | |
26 | 20 | <% scrap.replies.map do |reply| %> |
27 | 21 | <%= render :partial => 'profile_scrap', :locals => {:scrap => reply} %> |
28 | 22 | <% end %> | ... | ... |
app/views/profile/_profile_scraps.rhtml
1 | -NÃO DEVE APARECER | |
1 | +<li class='profile-activity-item' id='profile-activity-item-<%= scrap.id %>'> | |
2 | + <div class='profile-activity-image'> | |
3 | + <%= link_to(profile_image(scrap.sender, :minor), scrap.sender.url) %> | |
4 | + </div> | |
5 | + <div class='profile-activity-description'> | |
6 | + <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p> | |
7 | + <p class='profile-activity-text'><%= txt2html scrap.content %></p> | |
8 | + <p class='profile-activity-time'><%= time_ago_as_sentence(scrap.created_at) %></p> | |
9 | + <div class='profile-wall-actions'> | |
10 | + <% if logged_in? && current_person.follows?(scrap.sender) %> | |
11 | + <span class='profile-activity-send-reply'> | |
12 | + <%= link_to_function s_('profile|Comment'), "hide_and_show(['#profile-wall-message-response-#{scrap.id}'],['#profile-wall-reply-#{scrap.id}', '#profile-wall-reply-form-#{scrap.id}']);$('reply_content_#{scrap.id}').value='';$('reply_content_#{scrap.id}').focus();return false", :class => "profile-send-reply" %> | |
13 | + </span> | |
14 | + <% end %> | |
15 | + <%= link_to_function(_('Remove'), 'remove_item_wall(this, %s, %s, %s); return false ;' % ["'.profile-activity-item'", url_for(:profile => params[:profile], :action => :remove_scrap, :scrap_id => scrap.id, :view => params[:view]).to_json, _('Are you sure you want to remove this scrap and all its replies?').to_json]) if logged_in? && user.can_control_scrap?(scrap) %> | |
16 | + </div> | |
17 | + </div> | |
18 | + | |
19 | + | |
20 | + <ul id="profile-wall-activities-comments-<%= activity.id %>" class="profile-wall-activities-comments scrap-replies" style="width: auto;" > | |
21 | + </ul> | |
22 | + | |
23 | + <% if scrap.replies.count > 0 %> | |
24 | + <div id="profile-wall-activities-comments-more-<%= activity.id %>" class="profile-wall-activities-comments"> | |
25 | + <div class='view-all-comments icon-chat'> | |
26 | + <%= link_to_remote(_("View all %s comments") % scrap.replies.count, :url => { :profile => profile.identifier, :controller => 'profile', :action => 'more_replies', :activity => activity, :comment_page => (1)}) %> | |
27 | + </div> | |
28 | + </div> | |
29 | + <% end %> | |
30 | + <%= render :partial => 'profile_scrap_reply_form', :locals => { :scrap => scrap } %> | |
31 | + <hr /> | |
32 | +</li> | |
2 | 33 | \ No newline at end of file | ... | ... |
public/stylesheets/application.css
... | ... | @@ -5681,6 +5681,13 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { |
5681 | 5681 | padding-left: 20px; |
5682 | 5682 | } |
5683 | 5683 | |
5684 | +.view-more-comments, .view-more-replies { | |
5685 | + border-bottom: 1px solid #d2d2d2 !important; | |
5686 | + border-top: 1px solid #fff; | |
5687 | + margin-bottom: 0; | |
5688 | + text-align: center; | |
5689 | +} | |
5690 | + | |
5684 | 5691 | /* Profile activity relative dimensions */ |
5685 | 5692 | |
5686 | 5693 | #leave_scrap { | ... | ... |
test/functional/profile_controller_test.rb
... | ... | @@ -1170,6 +1170,58 @@ class ProfileControllerTest < ActionController::TestCase |
1170 | 1170 | assert_redirected_to :controller => 'account', :action => 'login' |
1171 | 1171 | end |
1172 | 1172 | |
1173 | + should "not index display activities comments" do | |
1174 | + login_as(profile.identifier) | |
1175 | + article = TinyMceArticle.create!(:profile => profile, :name => 'An Article about Free Software') | |
1176 | + ActionTracker::Record.destroy_all | |
1177 | + activity = ActionTracker::Record.create!(:user_id => profile.id, :user_type => 'Profile', :verb => 'create_article', :target_id => article.id, :target_type => 'Article', :params => {'name' => article.name, 'url' => article.url, 'lead' => article.lead, 'first_image' => article.first_image}) | |
1178 | + 20.times {comment = fast_create(Comment, :source_id => article, :title => 'a comment', :body => 'lalala', :created_at => Time.now)} | |
1179 | + article.reload | |
1180 | + get :index, :profile => profile.identifier | |
1181 | + assert_tag 'ul', :attributes => {:class => 'profile-wall-activities-comments'}, :children => {:count => 0 } | |
1182 | + end | |
1183 | + | |
1184 | + should "view more comments paginated" do | |
1185 | + login_as(profile.identifier) | |
1186 | + article = TinyMceArticle.create!(:profile => profile, :name => 'An Article about Free Software') | |
1187 | + ActionTracker::Record.destroy_all | |
1188 | + activity = ActionTracker::Record.create!(:user_id => profile.id, :user_type => 'Profile', :verb => 'create_article', :target_id => article.id, :target_type => 'Article', :params => {'name' => article.name, 'url' => article.url, 'lead' => article.lead, 'first_image' => article.first_image}) | |
1189 | + 20.times {comment = fast_create(Comment, :source_id => article, :title => 'a comment', :body => 'lalala', :created_at => Time.now)} | |
1190 | + article.reload | |
1191 | + assert_equal 20, article.comments.count | |
1192 | + get :more_comments, :activity => activity.id, :comment_page => 2 | |
1193 | + assert_response :success | |
1194 | + assert_template '_comment' | |
1195 | + assert_select_rjs :insert_html do | |
1196 | + assert_select 'li', 5 # 5 comments per page | |
1197 | + end | |
1198 | + end | |
1199 | + | |
1200 | + should "not index display scraps replies" do | |
1201 | + login_as(profile.identifier) | |
1202 | + Scrap.destroy_all | |
1203 | + scrap = fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id) | |
1204 | + 20.times {fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id, :scrap_id => scrap.id)} | |
1205 | + profile.reload | |
1206 | + get :index, :profile => profile.identifier | |
1207 | + assert_tag 'ul', :attributes => {:class => 'profile-wall-activities-comments scrap-replies'}, :children => {:count => 0 } | |
1208 | + end | |
1209 | + | |
1210 | + should "view more replies paginated" do | |
1211 | + login_as(profile.identifier) | |
1212 | + Scrap.destroy_all | |
1213 | + scrap = fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id) | |
1214 | + 20.times {fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id, :scrap_id => scrap.id)} | |
1215 | + profile.reload | |
1216 | + assert_equal 20, scrap.replies.count | |
1217 | + get :more_replies, :activity => scrap.id, :comment_page => 2 | |
1218 | + assert_response :success | |
1219 | + assert_template '_profile_scrap' | |
1220 | + assert_select_rjs :insert_html do | |
1221 | + assert_select 'li', 5 # 5 replies per page | |
1222 | + end | |
1223 | + end | |
1224 | + | |
1173 | 1225 | should 'render empty response for not logged in users in check_membership' do |
1174 | 1226 | get :check_membership |
1175 | 1227 | assert_equal '', @response.body | ... | ... |
vendor/plugins/action_tracker_has_comments/init.rb
... | ... | @@ -3,22 +3,13 @@ |
3 | 3 | Rails.configuration.to_prepare do |
4 | 4 | ActionTracker::Record.module_eval do |
5 | 5 | |
6 | - has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :finder_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments} ORDER BY created_at ASC', :counter_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments}' | |
6 | + has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, | |
7 | + :finder_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments} ORDER BY created_at ASC', | |
8 | + :counter_sql => 'SELECT COUNT(*) FROM comments WHERE #{conditions_for_comments}' | |
7 | 9 | |
8 | 10 | def conditions_for_comments |
9 | 11 | type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id]) |
10 | - "source_type = '#{type}' AND source_id = '#{id}'" | |
11 | - end | |
12 | - | |
13 | - def comments_as_thread | |
14 | - result = {} | |
15 | - root = [] | |
16 | - self.comments.each do |c| | |
17 | - c.replies = [] | |
18 | - result[c.id] ||= c | |
19 | - c.reply_of_id.nil? ? root << c : result[c.reply_of_id].replies << c | |
20 | - end | |
21 | - root | |
12 | + "source_type = '#{type}' AND source_id = '#{id}' AND reply_of_id IS NULL" | |
22 | 13 | end |
23 | 14 | |
24 | 15 | end | ... | ... |