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
# the COPYRIGHT file.
require File.join(Rails.root, "lib", "aspect_stream")
class AspectsController < ApplicationController
before_filter :authenticate_user!
before_filter :save_sort_order, :only => :index
@ -11,38 +13,18 @@ class AspectsController < ApplicationController
respond_to :json, :only => [:show, :create]
helper_method :tags, :tag_followings
helper_method :all_aspects_selected?
helper_method :selected_people
def index
@aspects = current_user.aspects
@aspects = @aspects.where(:id => params[:a_ids]) if params[:a_ids]
@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)
@stream = AspectStream.new(current_user, params[:a_ids],
:order => session[:sort_order],
:max_time => params[:max_time])
if params[:only_posts]
render :partial => 'shared/stream', :locals => {:posts => @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)
render :partial => 'shared/stream', :locals => {:posts => @stream.posts}
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
@aspect = current_user.aspects.create(params[:aspect])
@ -156,10 +138,6 @@ class AspectsController < ApplicationController
params[:max_time] ||= Time.now + 1
end
def all_aspects_selected?
@aspect == :all
end
def tag_followings
if current_user
if @tag_followings == nil

View file

@ -11,7 +11,7 @@ module StreamHelper
elsif controller.instance_of?(PeopleController)
person_path(@person, :max_time => @posts.last.created_at.to_i)
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
raise 'in order to use pagination for this new controller, update next_page_path in stream helper'
end

View file

@ -6,24 +6,24 @@
#sort_by
= t('.recently')
%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
- if all_aspects_selected?
- if stream.for_all_aspects?
= t('.stream')
- 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'
- if current_user.contacts.size < 2
= render 'aspects/no_contacts_message'
#main_stream.stream{:data => {:guids => aspect_ids.join(',')}}
- if posts.length > 0
= render 'shared/stream', :posts => posts
#main_stream.stream{:data => {:guids => stream.aspect_ids.join(',')}}
- if stream.posts.length > 0
= render 'shared/stream', :posts => stream.posts
#pagination
=link_to(t('more'), next_page_path, :class => 'paginate')

View file

@ -1,22 +1,22 @@
#selected_aspect_contacts.section
.title.no_icon
%h5
- if all_aspects_selected? || !@aspect || @aspect_ids.size > 1
- if @stream.for_all_aspects? || @stream.aspect_ids.size > 1
= "#{t('_contacts')}"
- else
= @aspect.name
= "(#{count})"
= @stream.aspect.name
= "(#{@stream.people.size})"
.content
- if people.size > 0
- for person in people
= person_image_link person
- if @stream.people.size > 0
- for person in @stream.people
= 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"
- 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
= t('.no_contacts')

View file

@ -26,12 +26,9 @@
.span-13.append-1
#aspect_stream_container.stream_container
= render 'aspect_stream',
:aspect => @aspect,
:aspect_ids => @aspect_ids,
:posts => @posts
= render 'aspect_stream', :stream => @stream
.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'

View file

@ -1,3 +1,3 @@
$('#aspect_stream_container').html("<%= escape_javascript(render('aspects/aspect_stream', :aspect => @aspect, :aspect_ids => @aspect_ids, :posts => @posts)) %>");
$('#selected_aspect_contacts').html("<%= escape_javascript(render('aspects/selected_contacts', :people => @selected_people.sample(20), :count => @contact_count )) %>");
$('#aspect_stream_container').html("<%= escape_javascript(render('aspects/aspect_stream', :stream => @stream)) %>");
$('#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();

View file

@ -3,18 +3,18 @@
-# the COPYRIGHT file.
#aspect_header
- if @aspect == :all
- if @stream.for_all_aspects?
= t('all_aspects')
- else
= @aspect
= @stream.aspect
= link_to t('.post_a_message'), '#publisher_page', :id => 'publisher_button'
#main_stream.stream
= render 'shared/stream', :posts => @posts
-if @posts.length > 0
= render 'shared/stream', :posts => @stream.posts
-if @stream.posts.length > 0
#pagination
%a.more-link.paginate{:href => next_page_path}
%h2= t("more")
- 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
%span#publisher_service_icons
= 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)
= image_tag "icons/globe.png", :title => t('javascripts.publisher.limited'), :class => 'public_icon dim', :width => 16, :height => 16
- if current_user.services

View file

@ -25,12 +25,12 @@
= 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
%fieldset
- unless params[:a_ids]
- unless aspect_ids
%input{:type => 'checkbox', :name => 'status_message[public]', :id => 'public', :class => 'custom', :value => 'true'}
%label{:for => '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
describe "#index" do
it "generates a jasmine fixture", :fixture => true do
get :index
save_fixture(html_for("body"), "aspects_index")
end
context 'jasmine fixtures' do
it "generates a jasmine fixture", :fixture => true do
get :index
save_fixture(html_for("body"), "aspects_index")
end
it "generates a jasmine fixture with a prefill", :fixture => true do
get :index, :prefill => "reshare things"
save_fixture(html_for("body"), "aspects_index_prefill")
end
it "generates a jasmine fixture with a prefill", :fixture => true do
get :index, :prefill => "reshare things"
save_fixture(html_for("body"), "aspects_index_prefill")
end
it 'generates a jasmine fixture with services', :fixture => true do
alice.services << Services::Facebook.create(:user_id => alice.id)
alice.services << Services::Twitter.create(:user_id => alice.id)
get :index, :prefill => "reshare things"
save_fixture(html_for("body"), "aspects_index_services")
end
it 'generates a jasmine fixture with services', :fixture => true do
alice.services << Services::Facebook.create(:user_id => alice.id)
alice.services << Services::Twitter.create(:user_id => alice.id)
get :index, :prefill => "reshare things"
save_fixture(html_for("body"), "aspects_index_services")
end
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)
message = alice.post(:status_message, :text => "hello "*800, :to => @alices_aspect_2.id)
5.times { bob.comment("what", :post => message) }
get :index
save_fixture(html_for("body"), "aspects_index_with_posts")
end
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)
message = alice.post(:status_message, :text => "hello "*800, :to => @alices_aspect_2.id)
5.times { bob.comment("what", :post => message) }
get :index
save_fixture(html_for("body"), "aspects_index_with_posts")
end
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)
5.times { bob.comment("what", :post => message) }
get :index
save_fixture(html_for("body"), "aspects_index_post_with_comments")
end
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)
5.times { bob.comment("what", :post => message) }
get :index
save_fixture(html_for("body"), "aspects_index_post_with_comments")
end
it 'generates a jasmine fixture with a followed tag', :fixture => true do
@tag = ActsAsTaggableOn::Tag.create!(:name => "partytimeexcellent")
TagFollowing.create!(:tag => @tag, :user => alice)
get :index
save_fixture(html_for("body"), "aspects_index_with_one_followed_tag")
end
it 'generates a jasmine fixture with a followed tag', :fixture => true do
@tag = ActsAsTaggableOn::Tag.create!(:name => "partytimeexcellent")
TagFollowing.create!(:tag => @tag, :user => alice)
get :index
save_fixture(html_for("body"), "aspects_index_with_one_followed_tag")
end
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").
with(:headers => {'Accept'=>'*/*'}).
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)
get :index
save_fixture(html_for("body"), "aspects_index_with_video_post")
end
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").
with(:headers => {'Accept'=>'*/*'}).
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)
get :index
save_fixture(html_for("body"), "aspects_index_with_video_post")
end
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)
alice.build_like(:positive => true, :target => message).save
bob.build_like(:positive => true, :target => message).save
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)
alice.build_like(:positive => true, :target => message).save
bob.build_like(:positive => true, :target => message).save
get :index
save_fixture(html_for("body"), "aspects_index_with_a_post_with_likes")
get :index
save_fixture(html_for("body"), "aspects_index_with_a_post_with_likes")
end
end
context "mobile" do
@ -135,25 +137,9 @@ describe AspectsController do
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
before do
pending 'this spec needs to be moved into AspectStream spec'
@posts = []
2.times do |n|
user = Factory(:user)
@ -179,6 +165,7 @@ describe AspectsController do
get :index
assigns[:posts].include?(@status).should be_true
end
it "does not pull back hidden posts" do
@vis.update_attributes(:hidden => true)
get :index