Created AspectStream; removed all logic from AspectsController#index

This commit is contained in:
danielgrippi 2011-09-10 11:18:21 -07:00
parent 96fc057974
commit ec4dc7a905
11 changed files with 145 additions and 124 deletions

View file

@ -2,6 +2,8 @@
# licensed under the Affero General Public License version 3 or later. See # licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file. # the COPYRIGHT file.
require File.join(Rails.root, "lib", "aspect_stream")
class AspectsController < ApplicationController class AspectsController < ApplicationController
before_filter :authenticate_user! before_filter :authenticate_user!
before_filter :save_sort_order, :only => :index before_filter :save_sort_order, :only => :index
@ -11,38 +13,18 @@ class AspectsController < ApplicationController
respond_to :json, :only => [:show, :create] respond_to :json, :only => [:show, :create]
helper_method :tags, :tag_followings helper_method :tags, :tag_followings
helper_method :all_aspects_selected?
helper_method :selected_people helper_method :selected_people
def index def index
@aspects = current_user.aspects @stream = AspectStream.new(current_user, params[:a_ids],
@aspects = @aspects.where(:id => params[:a_ids]) if params[:a_ids] :order => session[:sort_order],
:max_time => params[:max_time])
@aspect_ids = @aspects.map { |a| a.id }
@posts = current_user.visible_posts(:by_members_of => @aspect_ids,
:type => ['StatusMessage','Reshare', 'ActivityStreams::Photo'],
:order => session[:sort_order] + ' DESC',
:max_time => params[:max_time].to_i
).includes(:mentions => {:person => :profile}, :author => :profile)
if params[:only_posts] if params[:only_posts]
render :partial => 'shared/stream', :locals => {:posts => @posts} render :partial => 'shared/stream', :locals => {:posts => @stream.posts}
else
@contact_count = selected_people(@aspect_ids).count
# aspects.first is used for mobile
# the :all is currently used for view switching logic
@aspect = (params[:a_ids] ? @aspects.first : :all)
end end
end end
def selected_people(aspect_ids)
@selected_people ||= Person.joins(:contacts => :aspect_memberships).
where(:contacts => {:user_id => current_user.id},
:aspect_memberships => {:aspect_id => @aspect_ids}).
select("DISTINCT people.*").includes(:profile)
end
def create def create
@aspect = current_user.aspects.create(params[:aspect]) @aspect = current_user.aspects.create(params[:aspect])
@ -156,10 +138,6 @@ class AspectsController < ApplicationController
params[:max_time] ||= Time.now + 1 params[:max_time] ||= Time.now + 1
end end
def all_aspects_selected?
@aspect == :all
end
def tag_followings def tag_followings
if current_user if current_user
if @tag_followings == nil if @tag_followings == nil

View file

@ -11,7 +11,7 @@ module StreamHelper
elsif controller.instance_of?(PeopleController) elsif controller.instance_of?(PeopleController)
person_path(@person, :max_time => @posts.last.created_at.to_i) person_path(@person, :max_time => @posts.last.created_at.to_i)
elsif controller.instance_of?(AspectsController) elsif controller.instance_of?(AspectsController)
aspects_path(:max_time => @posts.last.send(session[:sort_order].to_sym).to_i, :a_ids => params[:a_ids]) aspects_path(:max_time => @stream.posts.last.send(@stream.order.to_sym).to_i, :a_ids => @stream.aspect_ids)
else else
raise 'in order to use pagination for this new controller, update next_page_path in stream helper' raise 'in order to use pagination for this new controller, update next_page_path in stream helper'
end end

View file

@ -6,24 +6,24 @@
#sort_by #sort_by
= t('.recently') = t('.recently')
%span.controls %span.controls
= link_to_if(session[:sort_order] == 'created_at', t('.commented_on'), aspects_path(:a_ids => params[:a_ids], :sort_order => 'updated_at')) = link_to_if(session[:sort_order] == 'created_at', t('.commented_on'), aspects_path(:a_ids => stream.aspect_ids, :sort_order => 'updated_at'))
· ·
= link_to_if(session[:sort_order] == 'updated_at', t('.posted'), aspects_path(:a_ids => params[:a_ids], :sort_order => 'created_at' )) = link_to_if(session[:sort_order] == 'updated_at', t('.posted'), aspects_path(:a_ids => stream.aspect_ids, :sort_order => 'created_at' ))
%h3 %h3
- if all_aspects_selected? - if stream.for_all_aspects?
= t('.stream') = t('.stream')
- else - else
= @aspects.to_sentence = stream.aspects.to_sentence
= render 'shared/publisher', :selected_aspects => @aspects, :aspect_ids => aspect_ids, :aspect => @aspect = render 'shared/publisher', :selected_aspects => stream.aspects, :aspect_ids => stream.aspect_ids, :for_all_aspects => stream.for_all_aspects?, :aspect => stream.aspect
= render 'aspects/no_posts_message' = render 'aspects/no_posts_message'
- if current_user.contacts.size < 2 - if current_user.contacts.size < 2
= render 'aspects/no_contacts_message' = render 'aspects/no_contacts_message'
#main_stream.stream{:data => {:guids => aspect_ids.join(',')}} #main_stream.stream{:data => {:guids => stream.aspect_ids.join(',')}}
- if posts.length > 0 - if stream.posts.length > 0
= render 'shared/stream', :posts => posts = render 'shared/stream', :posts => stream.posts
#pagination #pagination
=link_to(t('more'), next_page_path, :class => 'paginate') =link_to(t('more'), next_page_path, :class => 'paginate')

View file

@ -1,22 +1,22 @@
#selected_aspect_contacts.section #selected_aspect_contacts.section
.title.no_icon .title.no_icon
%h5 %h5
- if all_aspects_selected? || !@aspect || @aspect_ids.size > 1 - if @stream.for_all_aspects? || @stream.aspect_ids.size > 1
= "#{t('_contacts')}" = "#{t('_contacts')}"
- else - else
= @aspect.name = @stream.aspect.name
= "(#{count})" = "(#{@stream.people.size})"
.content .content
- if people.size > 0 - if @stream.people.size > 0
- for person in people - for person in @stream.people
= person_image_link person = person_image_link(person)
- if all_aspects_selected? || @aspect_ids.size > 1 - if @stream.for_all_aspects? || @stream.aspect_ids.size > 1
= link_to t('.view_all_contacts'), contacts_link, :id => "view_all_contacts_link" = link_to t('.view_all_contacts'), contacts_link, :id => "view_all_contacts_link"
- else - else
= link_to t('.view_all_contacts'), contacts_path(:a_id => @aspect.id), :id => "view_all_contacts_link" = link_to t('.view_all_contacts'), contacts_path(:a_id => @stream.aspect.id), :id => "view_all_contacts_link"
- else - else
= t('.no_contacts') = t('.no_contacts')

View file

@ -26,12 +26,9 @@
.span-13.append-1 .span-13.append-1
#aspect_stream_container.stream_container #aspect_stream_container.stream_container
= render 'aspect_stream', = render 'aspect_stream', :stream => @stream
:aspect => @aspect,
:aspect_ids => @aspect_ids,
:posts => @posts
.span-5.rightBar.last .span-5.rightBar.last
= render 'selected_contacts', :people => selected_people(@aspect_ids).sample(20), :count => @contact_count = render 'selected_contacts', :stream => @stream
= render 'shared/right_sections' = render 'shared/right_sections'

View file

@ -1,3 +1,3 @@
$('#aspect_stream_container').html("<%= escape_javascript(render('aspects/aspect_stream', :aspect => @aspect, :aspect_ids => @aspect_ids, :posts => @posts)) %>"); $('#aspect_stream_container').html("<%= escape_javascript(render('aspects/aspect_stream', :stream => @stream)) %>");
$('#selected_aspect_contacts').html("<%= escape_javascript(render('aspects/selected_contacts', :people => @selected_people.sample(20), :count => @contact_count )) %>"); $('#selected_aspect_contacts').html("<%= escape_javascript(render('aspects/selected_contacts', :people => @stream.people.sample(20), :count => @stream.people.size)) %>");
$('#aspect_stream_container a[rel*=facebox]').facebox(); $('#aspect_stream_container a[rel*=facebox]').facebox();

View file

@ -3,18 +3,18 @@
-# the COPYRIGHT file. -# the COPYRIGHT file.
#aspect_header #aspect_header
- if @aspect == :all - if @stream.for_all_aspects?
= t('all_aspects') = t('all_aspects')
- else - else
= @aspect = @stream.aspect
= link_to t('.post_a_message'), '#publisher_page', :id => 'publisher_button' = link_to t('.post_a_message'), '#publisher_page', :id => 'publisher_button'
#main_stream.stream #main_stream.stream
= render 'shared/stream', :posts => @posts = render 'shared/stream', :posts => @stream.posts
-if @posts.length > 0 -if @stream.posts.length > 0
#pagination #pagination
%a.more-link.paginate{:href => next_page_path} %a.more-link.paginate{:href => next_page_path}
%h2= t("more") %h2= t("more")
- content_for :subpages do - content_for :subpages do
= render 'shared/publisher', :aspect_ids => @aspect_ids, :selected_aspects => @aspects, :aspect => @aspect = render 'shared/publisher', :aspect_ids => @stream.aspect_ids, :selected_aspects => @stream.aspects, :aspect => @stream.aspect

View file

@ -32,7 +32,7 @@
.public_toggle .public_toggle
%span#publisher_service_icons %span#publisher_service_icons
= t("shared.publisher.click_to_share_with") = t("shared.publisher.click_to_share_with")
- if aspect == :all || aspect == :profile - if((defined?(for_all_aspects) && for_all_aspects) || aspect == :profile)
= status.hidden_field(:public) = status.hidden_field(:public)
= image_tag "icons/globe.png", :title => t('javascripts.publisher.limited'), :class => 'public_icon dim', :width => 16, :height => 16 = image_tag "icons/globe.png", :title => t('javascripts.publisher.limited'), :class => 'public_icon dim', :width => 16, :height => 16
- if current_user.services - if current_user.services

View file

@ -25,12 +25,12 @@
= status.text_area :text = status.text_area :text
- for aspect_id in @aspect_ids - for aspect_id in aspect_ids
= hidden_field_tag 'aspect_ids[]', aspect_id.to_s = hidden_field_tag 'aspect_ids[]', aspect_id.to_s
%fieldset %fieldset
- unless params[:a_ids] - unless aspect_ids
%input{:type => 'checkbox', :name => 'status_message[public]', :id => 'public', :class => 'custom', :value => 'true'} %input{:type => 'checkbox', :name => 'status_message[public]', :id => 'public', :class => 'custom', :value => 'true'}
%label{:for => 'public'} %label{:for => 'public'}
= t('.make_public') = t('.make_public')

59
lib/aspect_stream.rb Normal file
View file

@ -0,0 +1,59 @@
# Copyright (c) 2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
class AspectStream
attr_reader :aspects, :aspect_ids, :max_time, :order
# @param user [User]
# @param aspect_ids [Array<Integer>] Aspects this stream is responsible for
def initialize(user, aspect_ids, opts={})
@user = user
@aspects = user.aspects
@aspects = @aspects.where(:id => aspect_ids) if aspect_ids.present?
@aspect_ids = self.aspect_ids
# ugly hack for now
@max_time = opts[:max_time].to_i
@order = opts[:order]
end
# @return [Array<Integer>]
def aspect_ids
@aspect_ids ||= @aspects.map { |a| a.id }
end
# @return [ActiveRecord::Association<Post>] AR association of posts
def posts
@posts ||= @user.visible_posts(:by_members_of => @aspect_ids,
:type => ['StatusMessage','Reshare', 'ActivityStreams::Photo'],
:order => @order + ' DESC',
:max_time => @max_time
).includes(:mentions => {:person => :profile}, :author => :profile)
end
# @return [ActiveRecord::Association<Person>] AR association of people within stream's given aspects
def people
@people ||= Person.joins(:contacts => :aspect_memberships).
where(:contacts => {:user_id => @user.id},
:aspect_memberships => {:aspect_id => @aspect_ids}).
select("DISTINCT people.*").includes(:profile)
end
# @note aspects.first is used for mobile.
# The :all is currently used for view switching logic
# @return [Aspect,Symbol]
def aspect
for_all_aspects? ? :all : @aspects.first
end
# Determine whether or not the stream is displaying across
# all of the user's aspects.
#
# @return [Boolean]
def for_all_aspects?
@aspect_ids.length == @aspects.length
end
end

View file

@ -66,61 +66,63 @@ describe AspectsController do
end end
describe "#index" do describe "#index" do
it "generates a jasmine fixture", :fixture => true do context 'jasmine fixtures' do
get :index it "generates a jasmine fixture", :fixture => true do
save_fixture(html_for("body"), "aspects_index") get :index
end save_fixture(html_for("body"), "aspects_index")
end
it "generates a jasmine fixture with a prefill", :fixture => true do it "generates a jasmine fixture with a prefill", :fixture => true do
get :index, :prefill => "reshare things" get :index, :prefill => "reshare things"
save_fixture(html_for("body"), "aspects_index_prefill") save_fixture(html_for("body"), "aspects_index_prefill")
end end
it 'generates a jasmine fixture with services', :fixture => true do it 'generates a jasmine fixture with services', :fixture => true do
alice.services << Services::Facebook.create(:user_id => alice.id) alice.services << Services::Facebook.create(:user_id => alice.id)
alice.services << Services::Twitter.create(:user_id => alice.id) alice.services << Services::Twitter.create(:user_id => alice.id)
get :index, :prefill => "reshare things" get :index, :prefill => "reshare things"
save_fixture(html_for("body"), "aspects_index_services") save_fixture(html_for("body"), "aspects_index_services")
end end
it 'generates a jasmine fixture with posts', :fixture => true do it 'generates a jasmine fixture with posts', :fixture => true do
bob.post(:status_message, :text => "Is anyone out there?", :to => @bob.aspects.where(:name => "generic").first.id) bob.post(:status_message, :text => "Is anyone out there?", :to => @bob.aspects.where(:name => "generic").first.id)
message = alice.post(:status_message, :text => "hello "*800, :to => @alices_aspect_2.id) message = alice.post(:status_message, :text => "hello "*800, :to => @alices_aspect_2.id)
5.times { bob.comment("what", :post => message) } 5.times { bob.comment("what", :post => message) }
get :index get :index
save_fixture(html_for("body"), "aspects_index_with_posts") save_fixture(html_for("body"), "aspects_index_with_posts")
end end
it "generates a jasmine fixture with a post with comments", :fixture => true do it "generates a jasmine fixture with a post with comments", :fixture => true do
message = bob.post(:status_message, :text => "HALO WHIRLED", :to => @bob.aspects.where(:name => "generic").first.id) message = bob.post(:status_message, :text => "HALO WHIRLED", :to => @bob.aspects.where(:name => "generic").first.id)
5.times { bob.comment("what", :post => message) } 5.times { bob.comment("what", :post => message) }
get :index get :index
save_fixture(html_for("body"), "aspects_index_post_with_comments") save_fixture(html_for("body"), "aspects_index_post_with_comments")
end end
it 'generates a jasmine fixture with a followed tag', :fixture => true do it 'generates a jasmine fixture with a followed tag', :fixture => true do
@tag = ActsAsTaggableOn::Tag.create!(:name => "partytimeexcellent") @tag = ActsAsTaggableOn::Tag.create!(:name => "partytimeexcellent")
TagFollowing.create!(:tag => @tag, :user => alice) TagFollowing.create!(:tag => @tag, :user => alice)
get :index get :index
save_fixture(html_for("body"), "aspects_index_with_one_followed_tag") save_fixture(html_for("body"), "aspects_index_with_one_followed_tag")
end end
it "generates a jasmine fixture with a post containing a video", :fixture => true do it "generates a jasmine fixture with a post containing a video", :fixture => true do
stub_request(:get, "http://gdata.youtube.com/feeds/api/videos/UYrkQL1bX4A?v=2"). stub_request(:get, "http://gdata.youtube.com/feeds/api/videos/UYrkQL1bX4A?v=2").
with(:headers => {'Accept'=>'*/*'}). with(:headers => {'Accept'=>'*/*'}).
to_return(:status => 200, :body => "<title>LazyTown song - Cooking By The Book</title>", :headers => {}) to_return(:status => 200, :body => "<title>LazyTown song - Cooking By The Book</title>", :headers => {})
alice.post(:status_message, :text => "http://www.youtube.com/watch?v=UYrkQL1bX4A", :to => @alices_aspect_2.id) alice.post(:status_message, :text => "http://www.youtube.com/watch?v=UYrkQL1bX4A", :to => @alices_aspect_2.id)
get :index get :index
save_fixture(html_for("body"), "aspects_index_with_video_post") save_fixture(html_for("body"), "aspects_index_with_video_post")
end end
it "generates a jasmine fixture with a post that has been liked", :fixture => true do it "generates a jasmine fixture with a post that has been liked", :fixture => true do
message = alice.post(:status_message, :text => "hello "*800, :to => @alices_aspect_2.id) message = alice.post(:status_message, :text => "hello "*800, :to => @alices_aspect_2.id)
alice.build_like(:positive => true, :target => message).save alice.build_like(:positive => true, :target => message).save
bob.build_like(:positive => true, :target => message).save bob.build_like(:positive => true, :target => message).save
get :index get :index
save_fixture(html_for("body"), "aspects_index_with_a_post_with_likes") save_fixture(html_for("body"), "aspects_index_with_a_post_with_likes")
end
end end
context "mobile" do context "mobile" do
@ -135,25 +137,9 @@ describe AspectsController do
end end
end end
context 'with getting_started = true' do
before do
alice.getting_started = true
alice.save
end
it 'does not redirect mobile users to getting_started' do
get :index, :format => :mobile
response.should_not be_redirect
end
it 'does not redirect ajax to getting_started' do
get :index, :format => :js
response.should_not be_redirect
end
end
context 'with posts in multiple aspects' do context 'with posts in multiple aspects' do
before do before do
pending 'this spec needs to be moved into AspectStream spec'
@posts = [] @posts = []
2.times do |n| 2.times do |n|
user = Factory(:user) user = Factory(:user)
@ -179,6 +165,7 @@ describe AspectsController do
get :index get :index
assigns[:posts].include?(@status).should be_true assigns[:posts].include?(@status).should be_true
end end
it "does not pull back hidden posts" do it "does not pull back hidden posts" do
@vis.update_attributes(:hidden => true) @vis.update_attributes(:hidden => true)
get :index get :index