social_stream-base 0.19.2 → 0.20.0
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.
- data/app/assets/javascripts/social_stream.follow.js +23 -0
- data/app/assets/javascripts/social_stream.wall.js.erb +3 -3
- data/app/controllers/search_controller.rb +30 -16
- data/app/helpers/location_helper.rb +1 -44
- data/app/helpers/search_helper.rb +7 -7
- data/app/models/activity.rb +0 -21
- data/app/models/activity_action.rb +8 -0
- data/app/models/activity_object.rb +55 -25
- data/app/models/activity_object_audience.rb +8 -0
- data/app/models/actor.rb +9 -0
- data/app/models/comment.rb +1 -3
- data/app/models/group.rb +3 -0
- data/app/models/post.rb +1 -3
- data/app/models/relation.rb +5 -0
- data/app/models/relation/follow.rb +6 -7
- data/app/models/relation/public.rb +5 -0
- data/app/models/relation/single.rb +11 -1
- data/app/views/activities/_new.html.erb +1 -1
- data/app/views/contacts/_link_follow.html.erb +8 -4
- data/app/views/followers/update.js.erb +2 -0
- data/app/views/layouts/_search.html.erb +2 -2
- data/app/views/search/_extended_search.html.erb +17 -17
- data/app/views/search/_form.html.erb +4 -4
- data/app/views/search/_header_search.html.erb +2 -2
- data/app/views/search/index.html.erb +1 -1
- data/app/views/search/index.js.erb +4 -4
- data/db/migrate/20120403175913_create_activity_object_audiences.rb +34 -0
- data/db/migrate/20120411132550_add_visit_count_to_activity_object.rb +9 -0
- data/db/migrate/20120411151413_relation_public_permissions.rb +8 -0
- data/lib/generators/social_stream/base/templates/initializer.rb +3 -0
- data/lib/social_stream-base.rb +2 -1
- data/lib/social_stream/ability/base.rb +14 -8
- data/lib/social_stream/base/dependencies.rb +1 -0
- data/lib/social_stream/base/thinking-sphinx.rb +18 -0
- data/lib/social_stream/base/version.rb +1 -1
- data/lib/social_stream/controllers/objects.rb +6 -0
- data/lib/social_stream/test_helpers/controllers.rb +1 -1
- data/lib/social_stream/views/location.rb +48 -0
- data/lib/tasks/db/populate.rake +1 -1
- data/lib/thinking-sphinx/social_stream.rb +3 -0
- data/spec/controllers/groups_controller_spec.rb +6 -6
- data/spec/controllers/posts_controller_spec.rb +6 -6
- data/spec/controllers/users_controller_spec.rb +4 -4
- data/spec/dummy/config/initializers/social_stream.rb +3 -0
- data/spec/factories/activity.rb +24 -1
- data/spec/factories/post.rb +1 -1
- data/spec/models/activity_authorization_spec.rb +1 -1
- data/spec/models/post_spec.rb +0 -4
- data/spec/models/relation_follow_spec.rb +8 -0
- metadata +73 -64
data/app/models/group.rb
CHANGED
@@ -34,6 +34,8 @@ class Group < ActiveRecord::Base
|
|
34
34
|
|
35
35
|
# Creates the ties from the founder to the group
|
36
36
|
def create_ties_from_founder
|
37
|
+
=begin
|
38
|
+
# FIXME: need to define a proper relation for this case. Maybe a system defined relation
|
37
39
|
author.sent_contacts.create! :receiver_id => actor_id,
|
38
40
|
:relation_ids => _relation_ids
|
39
41
|
|
@@ -41,6 +43,7 @@ class Group < ActiveRecord::Base
|
|
41
43
|
user_author.sent_contacts.create! :receiver_id => actor_id,
|
42
44
|
:relation_ids => _relation_ids
|
43
45
|
end
|
46
|
+
=end
|
44
47
|
end
|
45
48
|
|
46
49
|
# Creates the ties from the group to the participants
|
data/app/models/post.rb
CHANGED
data/app/models/relation.rb
CHANGED
@@ -67,6 +67,11 @@ class Relation < ActiveRecord::Base
|
|
67
67
|
where(:type => positive_names)
|
68
68
|
}
|
69
69
|
|
70
|
+
scope :allowing, lambda { |action, object|
|
71
|
+
joins(:permissions).
|
72
|
+
merge(Permission.where(:action => action).where(:object => object))
|
73
|
+
}
|
74
|
+
|
70
75
|
before_create :initialize_sender_type
|
71
76
|
|
72
77
|
class << self
|
@@ -4,11 +4,10 @@
|
|
4
4
|
# Use this model setting <tt>config.relation_model = :follow</tt> in your
|
5
5
|
# <tt>config/initializers/social_stream.rb</tt>
|
6
6
|
class Relation::Follow < Relation::Single
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
PERMISSIONS =
|
8
|
+
[
|
9
|
+
[ 'create', 'activity' ],
|
10
|
+
[ 'read', 'activity' ],
|
11
|
+
[ 'follow', nil ]
|
12
|
+
]
|
13
13
|
end
|
14
|
-
|
@@ -4,11 +4,21 @@
|
|
4
4
|
# these {Relation relations}.
|
5
5
|
#
|
6
6
|
class Relation::Single < Relation
|
7
|
+
PERMISSIONS = []
|
8
|
+
|
7
9
|
class << self
|
8
10
|
def instance
|
9
11
|
@instance ||=
|
10
|
-
first ||
|
12
|
+
first ||
|
13
|
+
create!(:permissions => permissions)
|
14
|
+
end
|
15
|
+
|
16
|
+
def permissions
|
17
|
+
self::PERMISSIONS.map{ |p|
|
18
|
+
Permission.find_or_create_by_action_and_object p.first, p.last
|
19
|
+
}
|
11
20
|
end
|
21
|
+
|
12
22
|
end
|
13
23
|
|
14
24
|
# The name of public relation
|
@@ -32,7 +32,7 @@
|
|
32
32
|
}
|
33
33
|
//For security with check "var default_security_width = '100px';" in activities.js.erb
|
34
34
|
<% end %>
|
35
|
-
<%= select_tag :
|
35
|
+
<%= select_tag :relation_ids, options_for_select(current_subject.activity_relations(receiver).sort.map{ |r| [ r.name, r.id ] }), :id => 'security', :multiple => true, :title => t("activity.privacy.myself.contacts.#{ receiver.class.to_s.underscore }") %>
|
36
36
|
<% else %>
|
37
37
|
<div id="security_chzn" class="chzn-container chzn-container-multi">
|
38
38
|
<ul class="chzn-choices">
|
@@ -1,9 +1,13 @@
|
|
1
1
|
<div class="<%= follow_link_class contact %>">
|
2
2
|
<% if contact.sent? %>
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
<div class="following-button">
|
4
|
+
<%= t 'contact.following' %>
|
5
|
+
</div>
|
6
|
+
<div class="unfollow-button">
|
7
|
+
<%= form_tag follower_path(contact), :method => :delete, :remote => true do |f| %>
|
8
|
+
<%= submit_tag t('contact.unfollow') %>
|
9
|
+
<% end %>
|
10
|
+
</div>
|
7
11
|
<% else %>
|
8
12
|
<%= form_tag follower_path(contact), :method => :put, :remote => true do |f| %>
|
9
13
|
<%= submit_tag t('contact.follow') %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div id="header_search">
|
2
2
|
<form action="<%=search_path%>" method="get" id="header_search_form">
|
3
|
-
<%= text_field_tag :
|
3
|
+
<%= text_field_tag :q, nil,:autocomplete => :off, :id => :header_search_input %>
|
4
4
|
</form>
|
5
5
|
<div id="header_search_display">
|
6
6
|
<ul><li class="loading"><%= image_tag('loading.gif', :class => :loading) %></li></ul>
|
@@ -44,7 +44,7 @@ $(document).ready(function() {
|
|
44
44
|
$("#header_search_display").html("<ul><li class=\"loading\"><%= escape_javascript(image_tag('loading.gif', :class => :loading)) %></li></ul>").show();
|
45
45
|
$.ajax({
|
46
46
|
type : "GET",
|
47
|
-
url : "<%= search_url %>?
|
47
|
+
url : "<%= search_url %>?q=" + searchstring + "&mode=header_search",
|
48
48
|
success : function(html) {
|
49
49
|
if ($("#header_search_input").val()==searchstring){ //Only show if input value is still the same
|
50
50
|
$("#header_search_display").html(html);
|
@@ -1,19 +1,19 @@
|
|
1
1
|
<% if @search_result.empty? %>
|
2
|
-
<div class="model_with_details">
|
3
|
-
|
4
|
-
</div>
|
2
|
+
<div class="model_with_details">
|
3
|
+
<%= I18n.t('search.nothing') %>
|
4
|
+
</div>
|
5
5
|
<% else %>
|
6
|
-
<% @search_result.each do |model|%>
|
7
|
-
<% if @search_class_sym.nil? %>
|
8
|
-
<div class="subject_search_results block left">
|
9
|
-
|
10
|
-
</div>
|
11
|
-
<% else %>
|
12
|
-
<div class="subject_search_results block left <%= model.class.name.downcase %>">
|
13
|
-
|
14
|
-
</div>
|
15
|
-
<% end %>
|
16
|
-
<% end %>
|
17
|
-
<br class="clearfloat">
|
18
|
-
<%= paginate @search_result %>
|
19
|
-
<% end %>
|
6
|
+
<% @search_result.each do |model|%>
|
7
|
+
<% if @search_class_sym.nil? %>
|
8
|
+
<div class="subject_search_results block left">
|
9
|
+
<%= render_global_search_for model %>
|
10
|
+
</div>
|
11
|
+
<% else %>
|
12
|
+
<div class="subject_search_results block left <%= model.class.name.downcase %>">
|
13
|
+
<%= render_focus_search_for model %>
|
14
|
+
</div>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
<br class="clearfloat">
|
18
|
+
<%= paginate @search_result %>
|
19
|
+
<% end %>
|
@@ -1,20 +1,20 @@
|
|
1
1
|
<%= form_tag search_path, :method => :get,
|
2
2
|
:remote => true,
|
3
3
|
:id => "search_form" do %>
|
4
|
-
<%= hidden_field_tag :
|
4
|
+
<%= hidden_field_tag :type, params[:type] %>
|
5
5
|
<div class="block">
|
6
6
|
<div class="error" id="too_short_error" <%= 'style=display:block;' if too_short_query? %>><%= t('search.at_least') %></div>
|
7
7
|
|
8
8
|
<div class="form_row search_row">
|
9
|
-
<%= text_field_tag :
|
9
|
+
<%= text_field_tag :q, params[:q], :autocomplete => :off, :id => :global_search_input %>
|
10
10
|
</div>
|
11
11
|
|
12
12
|
<div id="focus_options" class="form_row search_row">
|
13
13
|
<ul class="menu_plain_list">
|
14
14
|
<li><%= link_to content_tag(:span,
|
15
15
|
t('search.show_all'),
|
16
|
-
:class => "global #{ params[:
|
17
|
-
search_path(:
|
16
|
+
:class => "global #{ params[:type].blank? && 'selected' }"),
|
17
|
+
search_path(:q => params[:q]),
|
18
18
|
:remote => true %></li>
|
19
19
|
<% SocialStream.extended_search_models.each do |model_sym| %>
|
20
20
|
<li>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<%= link_to raw('<li class="more">' +
|
11
11
|
t("search.global.first_result.#{ total == 1 ? 'one' : 'more' }", :count => total) +
|
12
12
|
'<br>' +
|
13
|
-
t('search.global.query', :query => truncate(h(params[:
|
13
|
+
t('search.global.query', :query => truncate(h(params[:q]),:length => 20)) +
|
14
14
|
'</li>'),
|
15
|
-
search_path(:
|
15
|
+
search_path(:q => params[:q]) %>
|
16
16
|
</ul>
|
@@ -3,13 +3,13 @@
|
|
3
3
|
|
4
4
|
$('#focus_options ul li a span').removeClass('selected');
|
5
5
|
|
6
|
-
<% if params[:
|
7
|
-
$('#focus_options ul li a span.<%= params[:
|
6
|
+
<% if params[:type].present? %>
|
7
|
+
$('#focus_options ul li a span.<%= params[:type].pluralize.downcase %>').addClass('selected');
|
8
8
|
<% else %>
|
9
9
|
$('#focus_options ul li a span.global').addClass('selected');
|
10
10
|
<% end %>
|
11
11
|
|
12
|
-
$('title').text('<%= t('search.name')%> <%= escape_javascript(params[:
|
12
|
+
$('title').text('<%= t('search.name')%> <%= escape_javascript(params[:q].present? ? ": #{params[:q]}" : "")%>');
|
13
13
|
|
14
14
|
<% if too_short_query? %>
|
15
15
|
$('#too_short_error').show();
|
@@ -19,4 +19,4 @@
|
|
19
19
|
|
20
20
|
$('#global_search_input').removeClass("searching");
|
21
21
|
|
22
|
-
setActivityPrivacyTooltips();
|
22
|
+
setActivityPrivacyTooltips();
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# This migration comes from social_stream_base_engine (originally 20120403175913)
|
2
|
+
class CreateActivityObjectAudiences < ActiveRecord::Migration
|
3
|
+
def change
|
4
|
+
create_table :activity_object_audiences do |t|
|
5
|
+
t.references :activity_object
|
6
|
+
t.references :relation
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_foreign_key :activity_object_audiences, :activity_objects, :name => 'activity_object_audiences_on_activity_object_id'
|
12
|
+
add_foreign_key :activity_object_audiences, :relations, :name => 'activity_object_audiences_on_relation_id'
|
13
|
+
|
14
|
+
|
15
|
+
ActivityObject.all.each do |ao|
|
16
|
+
post_activity = ao.post_activity
|
17
|
+
next if post_activity.blank?
|
18
|
+
|
19
|
+
ao.relation_ids = post_activity.relation_ids
|
20
|
+
end
|
21
|
+
|
22
|
+
ActivityObjectAudience.record_timestamps = false
|
23
|
+
|
24
|
+
ActivityObject.all.each do |ao|
|
25
|
+
ao.activity_object_audiences.each do |aud|
|
26
|
+
aud.created_at = aud.updated_at = ao.created_at
|
27
|
+
aud.save!
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
ActivityObjectAudience.record_timestamps = true
|
32
|
+
ActivityObject.reset_column_information
|
33
|
+
end
|
34
|
+
end
|
@@ -41,3 +41,6 @@ SocialStream.setup do |config|
|
|
41
41
|
# Cleditor controls. It is used in new message editor, for example
|
42
42
|
# config.cleditor_controls = "bold italic underline strikethrough subscript superscript | size style | bullets | image link unlink"
|
43
43
|
end
|
44
|
+
|
45
|
+
# You can customize toolbar, sidebar and location bar from here
|
46
|
+
# See https://github.com/ging/social_stream/wiki/How-to-customize-the-toolbar,-sidebar-and-location
|
data/lib/social_stream-base.rb
CHANGED
@@ -35,7 +35,8 @@ module SocialStream
|
|
35
35
|
end
|
36
36
|
|
37
37
|
module Views
|
38
|
-
autoload :List,
|
38
|
+
autoload :List, 'social_stream/views/list'
|
39
|
+
autoload :Location, 'social_stream/views/location'
|
39
40
|
|
40
41
|
module Settings
|
41
42
|
autoload :Base, 'social_stream/views/settings/base'
|
@@ -13,20 +13,26 @@ module SocialStream
|
|
13
13
|
(SocialStream.objects - [ :actor, :comment ]).map{ |obj|
|
14
14
|
obj.to_s.classify.constantize
|
15
15
|
}.each do |klass|
|
16
|
-
can :create, klass do |
|
17
|
-
|
16
|
+
can :create, klass do |object| # can :create, Post do |post|
|
17
|
+
object.author.present? &&
|
18
|
+
object.owner.present? &&
|
19
|
+
object.author == Actor.normalize(subject) &&
|
20
|
+
( object.author == object.owner ||
|
21
|
+
object.owner.allow?(subject, 'create', 'activity') )
|
18
22
|
end
|
19
23
|
|
20
|
-
can :read, klass do |
|
21
|
-
|
24
|
+
can :read, klass do |object| # can :read, Post do |post|
|
25
|
+
object.authored_or_owned_by?(subject) ||
|
26
|
+
object.relation_ids.include?(Relation::Public.instance.id) ||
|
27
|
+
subject.present? && (object.relation_ids & subject.received_relation_ids).any?
|
22
28
|
end
|
23
29
|
|
24
|
-
can :update, klass do |
|
25
|
-
|
30
|
+
can :update, klass do |object| # can :update, Post do |post|
|
31
|
+
object.authored_or_owned_by?(subject)
|
26
32
|
end
|
27
33
|
|
28
|
-
can :destroy, klass do |
|
29
|
-
|
34
|
+
can :destroy, klass do |object| # can :destroy, Post do |post|
|
35
|
+
object.authored_or_owned_by?(subject)
|
30
36
|
end
|
31
37
|
end
|
32
38
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SocialStream
|
2
|
+
module Base
|
3
|
+
module ThinkingSphinx
|
4
|
+
module Index
|
5
|
+
module Builder
|
6
|
+
def activity_object_index
|
7
|
+
indexes activity_object.title, :as => :title
|
8
|
+
indexes activity_object.description, :as => :description
|
9
|
+
indexes activity_object.tags.name, :as => :tags
|
10
|
+
|
11
|
+
has created_at
|
12
|
+
has activity_object.author_action(:actor_id), :as => :author_id
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -8,6 +8,8 @@ module SocialStream
|
|
8
8
|
|
9
9
|
before_filter :set_author_ids, :only => [ :new, :create, :update ]
|
10
10
|
|
11
|
+
after_filter :increment_visit_count, :only => :show
|
12
|
+
|
11
13
|
load_and_authorize_resource :except => :index
|
12
14
|
|
13
15
|
respond_to :html, :js
|
@@ -27,6 +29,10 @@ module SocialStream
|
|
27
29
|
|
28
30
|
protected
|
29
31
|
|
32
|
+
def increment_visit_count
|
33
|
+
resource.activity_object.increment!(:visit_count) if request.format == 'html'
|
34
|
+
end
|
35
|
+
|
30
36
|
def set_author_ids
|
31
37
|
resource_params.first[:author_id] = current_subject.try(:actor_id)
|
32
38
|
resource_params.first[:user_author_id] = current_user.try(:actor_id)
|
@@ -34,7 +34,7 @@ module SocialStream
|
|
34
34
|
|
35
35
|
def model_assigned_to contact, relation_ids
|
36
36
|
model_attributes[:owner_id] = contact.receiver.id
|
37
|
-
model_attributes[:
|
37
|
+
model_attributes[:relation_ids] = Array(relation_ids).map(&:id)
|
38
38
|
end
|
39
39
|
|
40
40
|
shared_examples_for "Allow Creating" do
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module SocialStream
|
2
|
+
module Views
|
3
|
+
module Location
|
4
|
+
# Renders the location stack for your view. You can add as many stack levels as you wish.
|
5
|
+
#
|
6
|
+
# Usage:
|
7
|
+
# <%= location(level1,leve2,level3,level4,....) %>
|
8
|
+
#
|
9
|
+
# Output:
|
10
|
+
# base > level1 > level2 > level3 > level 4
|
11
|
+
#
|
12
|
+
# Default configuration:
|
13
|
+
# base => "You are here" ("location.base" on config/locales)
|
14
|
+
# separator => ">" ("location.separator" on config/locales)
|
15
|
+
#
|
16
|
+
# Styles and HTML wrapping:
|
17
|
+
# partial => location/_location.html.erb
|
18
|
+
#
|
19
|
+
# Example:
|
20
|
+
# Render a location with two leves depth:
|
21
|
+
#
|
22
|
+
# <%= location(link_to(leve1.name, level1.url),link_to(leve2.name, level2.url)) %>
|
23
|
+
#
|
24
|
+
def location(*stack)
|
25
|
+
|
26
|
+
location_body = render :partial => "location/location_body", :locals=>{:stack => stack}
|
27
|
+
|
28
|
+
location_div = capture do
|
29
|
+
render :partial => "location/location", :locals=>{:location_body => location_body}
|
30
|
+
end
|
31
|
+
|
32
|
+
case request.format
|
33
|
+
when Mime::JS
|
34
|
+
response = <<-EOJ
|
35
|
+
|
36
|
+
$('#map_location').html("#{ escape_javascript(location_div) }");
|
37
|
+
EOJ
|
38
|
+
|
39
|
+
response.html_safe
|
40
|
+
else
|
41
|
+
content_for(:location) do
|
42
|
+
location_div
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|