social_stream 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. data/Rakefile +0 -12
  2. data/app/controllers/activities_controller.rb +17 -1
  3. data/app/controllers/api_controller.rb +2 -2
  4. data/app/controllers/avatars_controller.rb +44 -0
  5. data/app/controllers/contacts_controller.rb +13 -21
  6. data/app/controllers/conversations_controller.rb +107 -0
  7. data/app/controllers/groups_controller.rb +7 -11
  8. data/app/controllers/messages_controller.rb +21 -88
  9. data/app/controllers/profiles_controller.rb +3 -1
  10. data/app/controllers/pshb_controller.rb +37 -1
  11. data/app/controllers/ties_controller.rb +7 -8
  12. data/app/controllers/users_controller.rb +19 -43
  13. data/app/helpers/location_helper.rb +34 -0
  14. data/app/helpers/subjects_helper.rb +18 -1
  15. data/app/models/activity.rb +67 -27
  16. data/app/models/activity_verb.rb +1 -1
  17. data/app/models/actor.rb +85 -37
  18. data/app/models/avatar.rb +90 -0
  19. data/app/models/group.rb +2 -2
  20. data/app/models/profile.rb +8 -0
  21. data/app/models/tie.rb +20 -22
  22. data/app/models/user.rb +2 -8
  23. data/app/views/activities/_index.html.erb +22 -0
  24. data/app/views/activities/_options.html.erb +3 -1
  25. data/app/views/activities/_root.html.erb +4 -2
  26. data/app/views/activities/_walls.html.erb +34 -0
  27. data/app/views/activities/index.js.erb +1 -0
  28. data/app/views/avatars/_form.html.erb +23 -0
  29. data/app/views/{logos → avatars}/_precrop.html.erb +23 -15
  30. data/app/views/avatars/edit.html.erb +6 -0
  31. data/app/views/avatars/index.html.erb +42 -0
  32. data/app/views/{logos → avatars}/new.html.erb +7 -11
  33. data/app/views/avatars/show.html.erb +5 -0
  34. data/app/views/contacts/_index.html.erb +33 -0
  35. data/app/views/contacts/index.html.erb +35 -2
  36. data/app/views/contacts/index.js.erb +1 -0
  37. data/app/views/conversations/_conversation.html.erb +37 -0
  38. data/app/views/conversations/_conversation_full.html.erb +52 -0
  39. data/app/views/{messages → conversations}/_conversations.html.erb +2 -1
  40. data/app/views/conversations/_index.html.erb +23 -0
  41. data/app/views/{messages → conversations}/_menu_options.html.erb +2 -2
  42. data/app/views/conversations/_show.html.erb +21 -0
  43. data/app/views/{messages → conversations}/edit.html.erb +0 -0
  44. data/app/views/{messages → conversations}/index.html.erb +1 -3
  45. data/app/views/conversations/index.js.erb +7 -0
  46. data/app/views/conversations/show.html.erb +47 -0
  47. data/app/views/conversations/show.js.erb +39 -0
  48. data/app/views/frontpage/_header.html.erb +5 -1
  49. data/app/views/groups/_new.html.erb +50 -48
  50. data/app/views/groups/_sidebar_show.html.erb +1 -1
  51. data/app/views/groups/index.html.erb +1 -1
  52. data/app/views/groups/new.html.erb +6 -1
  53. data/app/views/groups/show.html.erb +1 -3
  54. data/app/views/home/_menu.html.erb +46 -0
  55. data/app/views/home/_sidebar.html.erb +12 -0
  56. data/app/views/home/index.html.erb +3 -3
  57. data/app/views/layouts/application.html.erb +1 -1
  58. data/app/views/layouts/test.html +58 -41
  59. data/app/views/location/_location.html.erb +3 -0
  60. data/app/views/messages/_form.html.erb +5 -52
  61. data/app/views/messages/_message.html.erb +31 -0
  62. data/app/views/messages/_new.html.erb +10 -16
  63. data/app/views/messages/new.html.erb +48 -3
  64. data/app/views/messages/new.js.erb +38 -1
  65. data/app/views/profiles/_profile.html.erb +194 -0
  66. data/app/views/profiles/edit.html.erb +168 -0
  67. data/app/views/profiles/show.html.erb +2 -175
  68. data/app/views/{users → profiles}/update.js.erb +12 -15
  69. data/app/views/subjects/_contacts.html.erb +2 -3
  70. data/app/views/subjects/_toolbar_home.html.erb +1 -1
  71. data/app/views/subjects/_toolbar_home_menu.html.erb +4 -1
  72. data/app/views/subjects/_toolbar_home_menu_options.html.erb +4 -7
  73. data/app/views/subjects/_toolbar_home_menu_options_subjects.html.erb +0 -3
  74. data/app/views/subjects/_toolbar_logo.html.erb +1 -1
  75. data/app/views/subjects/_toolbar_message_menu.html.erb +17 -0
  76. data/app/views/subjects/_toolbar_profile.html.erb +4 -12
  77. data/app/views/subjects/_toolbar_profile_menu.html.erb +9 -10
  78. data/app/views/subjects/_toolbar_profile_menu_basic_options.html.erb +6 -5
  79. data/app/views/subjects/_toolbar_profile_menu_tie_options.html.erb +13 -13
  80. data/app/views/ties/_new.html.erb +30 -25
  81. data/app/views/ties/_suggestions.html.erb +1 -0
  82. data/app/views/ties/new.js.erb +2 -0
  83. data/app/views/users/_index.html.erb +1 -1
  84. data/app/views/users/index.html.erb +1 -3
  85. data/app/views/users/show.html.erb +4 -3
  86. data/config/locales/en.yml +79 -24
  87. data/config/routes.rb +8 -2
  88. data/lib/generators/social_stream/install_generator.rb +1 -1
  89. data/lib/generators/social_stream/templates/migration.rb +17 -11
  90. data/lib/generators/social_stream/templates/public/images/btn/message_conversation.png +0 -0
  91. data/lib/generators/social_stream/templates/public/images/btn/message_inbox.png +0 -0
  92. data/lib/generators/social_stream/templates/public/images/btn/message_new.png +0 -0
  93. data/lib/generators/social_stream/templates/public/images/btn/message_sentbox.png +0 -0
  94. data/lib/generators/social_stream/templates/public/images/btn/message_trash.png +0 -0
  95. data/lib/generators/social_stream/templates/public/javascripts/ajax.paginate.js +1 -1
  96. data/lib/generators/social_stream/templates/public/javascripts/menu.js +9 -99
  97. data/lib/generators/social_stream/templates/public/stylesheets/default/base.css +14 -5
  98. data/lib/generators/social_stream/templates/public/stylesheets/default/home.css +1 -0
  99. data/lib/generators/social_stream/templates/public/stylesheets/default/jquery-ui.css +13 -10
  100. data/lib/generators/social_stream/templates/public/stylesheets/default/menu.css +5 -11
  101. data/lib/generators/social_stream/templates/public/stylesheets/default/messages.css +96 -20
  102. data/lib/generators/social_stream/templates/relations.yml +1 -0
  103. data/lib/paperclip/social_stream.rb +1 -1
  104. data/lib/social_stream/ability.rb +1 -0
  105. data/lib/social_stream/controllers/helpers.rb +20 -0
  106. data/lib/social_stream/models/subject.rb +13 -12
  107. data/lib/social_stream/rails.rb +4 -1
  108. data/lib/social_stream/version.rb +1 -1
  109. data/lib/tasks/db/populate.rake +14 -4
  110. data/social_stream.gemspec +31 -5
  111. data/spec/controllers/contacts_controller_spec.rb +6 -0
  112. data/spec/controllers/profiles_controller_spec.rb +3 -4
  113. data/spec/dummy/config/initializers/devise.rb +4 -1
  114. data/spec/dummy/config/relations.yml +1 -0
  115. data/spec/models/activity_spec.rb +24 -0
  116. metadata +91 -89
  117. data/app/controllers/logos_controller.rb +0 -37
  118. data/app/models/logo.rb +0 -88
  119. data/app/views/activities/_activities.html.erb +0 -46
  120. data/app/views/groups/_profile.html.erb +0 -142
  121. data/app/views/groups/edit.html.erb +0 -135
  122. data/app/views/groups/update.js.erb +0 -39
  123. data/app/views/logos/_form.html.erb +0 -33
  124. data/app/views/logos/edit.html.erb +0 -6
  125. data/app/views/logos/index.html.erb +0 -27
  126. data/app/views/logos/show.html.erb +0 -5
  127. data/app/views/menu/_group.html.erb +0 -15
  128. data/app/views/menu/_home_user.html.erb +0 -0
  129. data/app/views/menu/_optionsGroups.html.erb +0 -11
  130. data/app/views/menu/_optionsUser.html.erb +0 -11
  131. data/app/views/menu/_services.html.erb +0 -11
  132. data/app/views/menu/_tiesGroup.html.erb +0 -14
  133. data/app/views/menu/_tiesUser.html.erb +0 -11
  134. data/app/views/menu/_user.html.erb +0 -15
  135. data/app/views/messages/_conversation.html.erb +0 -34
  136. data/app/views/messages/_conversation_full.html.erb +0 -65
  137. data/app/views/messages/_index.html.erb +0 -19
  138. data/app/views/messages/_location.html.erb +0 -3
  139. data/app/views/messages/_show.html.erb +0 -22
  140. data/app/views/messages/index.js.erb +0 -1
  141. data/app/views/messages/show.html.erb +0 -10
  142. data/app/views/messages/show.js.erb +0 -1
  143. data/app/views/users/_profile.html.erb +0 -171
  144. data/app/views/users/_sidebar_show.html.erb +0 -1
  145. data/app/views/users/edit.html.erb +0 -194
@@ -1,17 +1,16 @@
1
1
  class TiesController < InheritedResources::Base
2
2
  respond_to :html, :xml, :js
3
3
 
4
- before_filter :authenticate_user!, :only => :suggestion
4
+ before_filter :authenticate_user!
5
+
6
+ def create
7
+ create! do |format|
8
+ format.html { redirect_to resource.receiver_subject }
9
+ end
10
+ end
5
11
 
6
12
  def suggestion
7
13
  @tie = current_subject.suggestion
8
14
  render :layout => false
9
15
  end
10
-
11
- def create
12
- super do |format|
13
- format.html { redirect_to resource.receiver_subject }
14
- end
15
- end
16
-
17
16
  end
@@ -1,51 +1,27 @@
1
- class UsersController < ApplicationController
1
+ class UsersController < InheritedResources::Base
2
+ respond_to :html, :xml, :js
3
+
2
4
  def index
3
- if params[:search]
4
- @users = User.search("%"+params[:search]+"%").paginate(:per_page => 10, :page => params[:page])
5
- else
6
- if params[:letter] && params[:letter]!="undefined"
7
- @users = User.search(params[:letter]+"%").paginate(:per_page => 10, :page => params[:page])
8
- else
9
- @users = User.alphabetic.paginate(:per_page => 10, :page => params[:page])
10
- end
5
+ @users = User.alphabetic.
6
+ letter(params[:letter]).
7
+ search(params[:search]).
8
+ paginate(:per_page => 10, :page => params[:page])
9
+
10
+ index! do |format|
11
+ format.html { render :layout => (user_signed_in? ? 'application' : 'frontpage') }
11
12
  end
12
13
  end
13
14
 
14
- def show
15
- @user = User.find_by_slug!(params[:id])
16
-
17
- respond_to do |format|
18
- format.html # show.html.erb
19
- format.xml # { render :xml => @user }
20
- end
21
- end
15
+ # Supported through devise
16
+ def new; end; def create; end
17
+ # Not supported yet
18
+ def destroy; end
22
19
 
23
- def edit
24
- @user = User.find_by_slug!(params[:id])
20
+ protected
25
21
 
26
- respond_to do |format|
27
- format.html # edit.html.erb
28
- format.xml { render :xml => @user }
29
- end
22
+ # Overwrite resource method to support slug
23
+ # See InheritedResources::BaseHelpers#resource
24
+ def resource
25
+ @user ||= end_of_association_chain.find_by_slug!(params[:id])
30
26
  end
31
-
32
- def update
33
-
34
- @user = User.find_by_slug!(params[:id])
35
-
36
- respond_to do |format|
37
- if @user.update_attributes(params[:user])
38
- #format.html { redirect_to(@user, :notice => 'User was successfully updated.') }
39
- #format.html { render :action => "edit", :notice => 'User was successfully updated.' }
40
- format.html { render :partial => "right_show", :notice => 'User was successfully updated.' }
41
- format.xml { head :ok }
42
- format.js
43
- else
44
- format.html { render :action => "edit" }
45
- format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
46
- format.js
47
- end
48
- end
49
- end
50
-
51
27
  end
@@ -0,0 +1,34 @@
1
+ module LocationHelper
2
+
3
+ # Renders the location stack for your view. You can add as many stack levels as you wish.
4
+ #
5
+ # Usage:
6
+ # <%= location(level1,leve2,level3,level4,....) %>
7
+ #
8
+ # Output:
9
+ # base > level1 > level2 > level3 > level 4
10
+ #
11
+ # Default configuration:
12
+ # base => "You are here" ("location.base" on config/locales)
13
+ # separator => ">" ("location.separator" on config/locales)
14
+ #
15
+ # Styles and HTML wrapping:
16
+ # partial => location/_location.html.erb
17
+ #
18
+ # Example:
19
+ # Render a location with a two leves depth:
20
+ #
21
+ # <%= location(link_to(leve1.name, level1.url),link_to(leve2.name, level2.url)) %>
22
+ #
23
+ def location(*stack)
24
+ location_body = t('location.base')
25
+ stack.collect {|level|
26
+ location_body << t('location.separator') + level
27
+ }
28
+
29
+ location_div = capture do
30
+ render :partial => "location/location", :locals=>{:location_body => location_body}
31
+ end
32
+ end
33
+
34
+ end
@@ -1,4 +1,9 @@
1
1
  module SubjectsHelper
2
+ # Return a link to this subject with the name
3
+ def link_name(subject, options = {})
4
+ link_to subject.name, subject, options
5
+ end
6
+
2
7
  # Define the toolbar content for your view. There are two typical cases, depending on the value of
3
8
  # options[:profile]
4
9
  # * If present, render the profile menu for the {SocialStream::Models::Subject subject}
@@ -29,13 +34,25 @@ module SubjectsHelper
29
34
  menu_options[options[:option]] = capture(&block)
30
35
  end
31
36
 
32
- content_for(:toolbar) do
37
+ content = capture do
33
38
  if options[:profile]
34
39
  render :partial => 'subjects/toolbar_profile', :locals => { :subject => options[:profile] }
35
40
  else
36
41
  render :partial => 'subjects/toolbar_home'
37
42
  end
38
43
  end
44
+
45
+ case request.format
46
+ when Mime::JS
47
+ <<-EOJ
48
+ $('#toolbar').html("#{ escape_javascript(content) }");
49
+ EOJ
50
+ else
51
+ content_for(:toolbar) do
52
+ content
53
+ end
54
+ end
55
+
39
56
  end
40
57
 
41
58
  # Cache menu options for toolbar
@@ -5,9 +5,17 @@
5
5
  # the relation in which the activity is transferred
6
6
  #
7
7
  # == Wall
8
- # The Activity.wall(ties) scope provides all the activities attached to a set of ties
8
+ # The Activity.wall(type, ties) scope provides all the activities attached to a set of ties
9
+ #
10
+ # There are two types of wall, :home and :profile. Check {Actor#wall} for more information
9
11
  #
10
12
  class Activity < ActiveRecord::Base
13
+ # The direction of the sender and receiver subjects compared with the attached tie
14
+ SUBJECT_DIRECTIONS = {
15
+ :direct => %w(follow make-friend),
16
+ :inverse => %w(like post update)
17
+ }
18
+
11
19
  has_ancestry
12
20
 
13
21
  belongs_to :activity_verb
@@ -28,21 +36,19 @@ class Activity < ActiveRecord::Base
28
36
 
29
37
  after_create :like_direct_object
30
38
 
31
- scope :home_wall, lambda { |ties|
32
- select("DISTINCT activities.*").
33
- roots.
34
- joins(:tie_activities).
35
- where('tie_activities.tie_id' => ties).
36
- order("created_at desc")
37
- }
39
+ scope :wall, lambda { |type, ties|
40
+ q = select("DISTINCT activities.*").
41
+ roots.
42
+ joins(:tie_activities).
43
+ where('tie_activities.tie_id' => ties).
44
+ order("created_at desc")
38
45
 
39
- scope :profile_wall, lambda { |ties|
40
- select("DISTINCT activities.*").
41
- roots.
42
- joins(:tie_activities).
43
- where('tie_activities.tie_id' => ties).
44
- where('tie_activities.original' => true).
45
- order("created_at desc")
46
+ # Profile wall is composed by original TieActivities. Not original are copies for followers
47
+ if type == :profile
48
+ q = q.where('tie_activities.original' => true)
49
+ end
50
+
51
+ q
46
52
  }
47
53
 
48
54
  # After an activity is created, it is associated to ties
@@ -59,32 +65,36 @@ class Activity < ActiveRecord::Base
59
65
  self.activity_verb = ActivityVerb[name]
60
66
  end
61
67
 
62
- # The author of the activity is the receiver of the tie
68
+ # The {Actor} author of this activity
63
69
  #
64
- # This method provides the actor. Use sender_subject for the subject (user, group, etc..)
70
+ # This method provides the {Actor}. Use {#sender_subject} for the {SocialStream::Models::Subject Subject}
71
+ # ({User}, {Group}, etc..)
65
72
  def sender
66
- tie.receiver
73
+ direct? ? tie.sender : tie.receiver
67
74
  end
68
75
 
69
- # The author of the activity is the receiver of the tie
76
+ # The {SocialStream::Models::Subject Subject} author of this activity
70
77
  #
71
- # This method provides the subject (user, group, etc...). Use sender for the actor.
78
+ # This method provides the {SocialStream::Models::Subject Subject} ({User}, {Group}, etc...).
79
+ # Use {#sender} for the {Actor}.
72
80
  def sender_subject
73
- tie.receiver_subject
81
+ direct? ? tie.sender_subject : tie.receiver_subject
74
82
  end
75
83
 
76
- # The wall where the activity is shown belongs to the sender of the tie
84
+ # The wall where the activity is shown belongs to receiver
77
85
  #
78
- # This method provides the actor. Use sender_subject for the subject (user, group, etc..)
86
+ # This method provides the {Actor}. Use {#receiver_subject} for the {SocialStream::Models::Subject Subject}
87
+ # ({User}, {Group}, etc..)
79
88
  def receiver
80
- tie.sender
89
+ direct? ? tie.receiver : tie.sender
81
90
  end
82
91
 
83
- # The wall where the activity is shown belongs to the sender of the tie
92
+ # The wall where the activity is shown belongs to the receiver
84
93
  #
85
- # This method provides the subject (user, group, etc...). Use sender for the actor.
94
+ # This method provides the {SocialStream::Models::Subject Subject} ({User}, {Group}, etc...).
95
+ # Use {#receiver} for the {Actor}.
86
96
  def receiver_subject
87
- tie.sender_subject
97
+ direct? ? tie.receiver_subject : tie.sender_subject
88
98
  end
89
99
 
90
100
  # The comments about this activity
@@ -123,6 +133,18 @@ class Activity < ActiveRecord::Base
123
133
  direct_activity_object.try(:object)
124
134
  end
125
135
 
136
+ # The title for this activity in the stream
137
+ def title view
138
+ case verb
139
+ when "follow", "make-friend"
140
+ I18n.t "activity.verb.#{ verb }.title",
141
+ :subject => view.link_name(sender_subject),
142
+ :contact => view.link_name(receiver_subject)
143
+ when "post"
144
+ view.link_name sender_subject
145
+ end.html_safe
146
+ end
147
+
126
148
  private
127
149
 
128
150
  # Assign to ties of followers
@@ -147,4 +169,22 @@ class Activity < ActiveRecord::Base
147
169
 
148
170
  activity_objects << parent.direct_activity_object
149
171
  end
172
+
173
+ private
174
+
175
+ # The {#sender} and the {#receiver} of the {Activity} depends on its {ActivityVerb}
176
+ #
177
+ # Contact activities such as make-friend or follow are direct. They have the same sender
178
+ # and receiver as their tie. On the other hand, post activities are inverse. The sender of
179
+ # the activity is the receiver of the tie and the receiver of the activity is the sender of
180
+ # the tie
181
+ def direct?
182
+ if SUBJECT_DIRECTIONS[:direct].include?(verb)
183
+ true
184
+ elsif SUBJECT_DIRECTIONS[:inverse].include?(verb)
185
+ false
186
+ else
187
+ raise "Unknown direction for verb #{ verb }"
188
+ end
189
+ end
150
190
  end
@@ -1,6 +1,6 @@
1
1
  class ActivityVerb < ActiveRecord::Base
2
2
  # Activity Strems verbs
3
- Available = %w( post update like make_friend)
3
+ Available = %w(follow like make-friend post update)
4
4
 
5
5
  validates_uniqueness_of :name
6
6
 
data/app/models/actor.rb CHANGED
@@ -19,14 +19,12 @@ class Actor < ActiveRecord::Base
19
19
  acts_as_messageable
20
20
  acts_as_url :name, :url_attribute => :slug
21
21
 
22
- has_attached_file :logo,
23
- :styles => { :tie => "30x30>",
24
- :actor => '35x35>',
25
- :profile => '94x94' },
26
- :default_url => "/images/:attachment/:style/:subtype_class.png"
27
-
28
22
  has_one :profile, :dependent => :destroy
29
-
23
+
24
+ has_many :avatars,
25
+ :validate => true,
26
+ :autosave => true
27
+
30
28
  has_many :sent_ties,
31
29
  :class_name => "Tie",
32
30
  :foreign_key => 'sender_id',
@@ -44,7 +42,31 @@ class Actor < ActiveRecord::Base
44
42
  has_many :receivers,
45
43
  :through => :sent_ties,
46
44
  :uniq => true
47
-
45
+
46
+ scope :alphabetic, order('actors.name')
47
+
48
+ scope :letter, lambda { |param|
49
+ if param.present?
50
+ where('actors.name LIKE ?', "#{ param }%")
51
+ end
52
+ }
53
+
54
+ scope :search, lambda { |param|
55
+ if param.present?
56
+ where('actors.name LIKE ?', "%#{ param }%")
57
+ end
58
+ }
59
+
60
+ scope :distinct_initials, select('DISTINCT SUBSTR(actors.name,1,1) as initial').order("initial ASC")
61
+
62
+ scope :contacted_to, lambda { |a|
63
+ joins(:sent_ties).merge(Tie.received_by(a))
64
+ }
65
+
66
+ scope :contacted_from, lambda { |a|
67
+ joins(:received_ties).merge(Tie.sent_by(a))
68
+ }
69
+
48
70
  after_create :initialize_ties
49
71
 
50
72
  after_create :create_profile
@@ -109,16 +131,16 @@ class Actor < ActiveRecord::Base
109
131
  relations.find_by_name(name)
110
132
  end
111
133
 
112
- # All the actors this one has relation with
134
+ # All the {Actor actors} this one has relation with
113
135
  #
114
136
  # Options:
115
- # * subject_type: Filter by the class of the subjects.
116
- # * direction: senders or receivers
137
+ # * type: Filter by the class of the contacts.
138
+ # * direction: sent or received
117
139
  # * relations: Restrict the relations of considered ties
118
140
  # * include_self: False by default, don't include this actor as subject even they have ties with themselves.
119
141
  #
120
- def actors(options = {})
121
- subject_types = Array(options[:subject_type] || self.class.subtypes)
142
+ def contact_actors(options = {})
143
+ subject_types = Array(options[:type] || self.class.subtypes)
122
144
  subject_classes = subject_types.map{ |s| s.to_s.classify }
123
145
 
124
146
  as = Actor.select("DISTINCT actors.*").
@@ -127,12 +149,12 @@ class Actor < ActiveRecord::Base
127
149
 
128
150
 
129
151
  case options[:direction]
130
- when :senders
131
- as = as.joins(:sent_ties).merge(Tie.received_by(self))
132
- when :receivers
133
- as = as.joins(:received_ties).merge(Tie.sent_by(self))
152
+ when :sent
153
+ as = as.contacted_from(self)
154
+ when :received
155
+ as = as.contacted_to(self)
134
156
  else
135
- raise "actors in both directions is not supported yet"
157
+ raise "contact actors in both directions are not supported yet"
136
158
  end
137
159
 
138
160
  if options[:include_self].blank?
@@ -140,20 +162,20 @@ class Actor < ActiveRecord::Base
140
162
  end
141
163
 
142
164
  if options[:relations].present?
143
- as &= Tie.related_by(options[:relations])
165
+ as = as.merge(Tie.related_by(options[:relations]))
144
166
  end
145
167
 
146
168
  as
147
169
  end
148
170
 
149
- # All the subject actors that send or receive at least one tie to this actor
171
+ # All the {SocialStream::Models::Subject subjects} that send or receive at least one {Tie} to this {Actor}
150
172
  #
151
- # When passing a block, it will be evaluated for the actors query, allowing to add
173
+ # When passing a block, it will be evaluated for building the actors query, allowing to add
152
174
  # options before the mapping to subjects
153
175
  #
154
- # See actors for options
155
- def subjects(options = {})
156
- as = actors(options)
176
+ # See #contact_actors for options
177
+ def contacts(options = {})
178
+ as = contact_actors(options)
157
179
 
158
180
  if block_given?
159
181
  as = yield(as)
@@ -189,7 +211,7 @@ class Actor < ActiveRecord::Base
189
211
  # Candidates are all the instance of "type" minus all the subjects
190
212
  # that are receiving any tie from this actor
191
213
  candidates = candidates_classes.inject([]) do |cs, klass|
192
- cs += klass.all - subjects(:subject_type => klass, :direction => :receivers)
214
+ cs += klass.all - contacts(:type => klass, :direction => :sent)
193
215
  cs -= Array(subject) if subject.is_a?(klass)
194
216
  cs
195
217
  end
@@ -210,6 +232,10 @@ class Actor < ActiveRecord::Base
210
232
  sent_ties.received_by(a)
211
233
  end
212
234
 
235
+ def ties_to?(a)
236
+ ties_to(a).present?
237
+ end
238
+
213
239
  # All the ties this actor has with subject that support permission
214
240
  def sent_ties_allowing(subject, action, objective)
215
241
  return [] if subject.blank?
@@ -235,21 +261,42 @@ class Actor < ActiveRecord::Base
235
261
  :receiver_id => i }
236
262
  end
237
263
 
238
- # The set of activities in the wall of this actor, includes all the activities
239
- # from the ties the actor has access to
264
+ # The set of {Activity activities} in the wall of this {Actor}.
240
265
  #
241
- def home_wall
242
- Activity.home_wall ties
266
+ # There are two types of walls:
267
+ # home:: includes all the {Activity activities} from this {Actor} and their followed {Actor actors}
268
+ # See {Permission permissions} for more information on the following support
269
+ # profile:: The set of activities in the wall profile of this {Actor}, it includes only the
270
+ # activities from the ties of this actor that can be read by the subject
271
+ #
272
+ # Options:
273
+ # :for:: the subject that is accessing the wall
274
+ # :relation:: show only activities that are attached at this relation level. For example,
275
+ # the wall for members of the group.
276
+ #
277
+ def wall(type, options = {})
278
+ ts = ties
279
+
280
+ if type == :profile
281
+ # FIXME: show public activities
282
+ return [] if options[:for].blank?
283
+
284
+ ts = ts.allowing(options[:for], 'read', 'activity')
285
+ end
286
+
287
+ if options[:relation].present?
288
+ ts = ts.related_by(Relation.normalize(options[:relation], :sender => self))
289
+ end
290
+
291
+ Activity.wall type, ts
243
292
  end
244
293
 
245
- # The set of activities in the wall profile of this actor, includes the activities
246
- # from the ties of this actor that can be read by user
247
- #
248
- def profile_wall(user)
249
- # FIXME: show public activities
250
- return [] if user.blank?
251
-
252
- Activity.profile_wall ties.allowing(user, 'read', 'activity')
294
+ def logo
295
+ avatar!.logo
296
+ end
297
+
298
+ def avatar!
299
+ avatars.active.first || avatars.build
253
300
  end
254
301
 
255
302
  private
@@ -260,4 +307,5 @@ class Actor < ActiveRecord::Base
260
307
  :relation => r
261
308
  end
262
309
  end
310
+
263
311
  end