social_stream-base 0.9.4 → 0.9.5

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 (44) hide show
  1. data/Rakefile +1 -1
  2. data/app/assets/stylesheets/0_devise_sign.css +8 -0
  3. data/app/assets/stylesheets/activities.css +1 -1
  4. data/app/assets/stylesheets/base.css +2 -2
  5. data/app/assets/stylesheets/frontpage.css +14 -4
  6. data/app/assets/stylesheets/search.css +47 -9
  7. data/app/controllers/groups_controller.rb +2 -2
  8. data/app/controllers/search_controller.rb +62 -16
  9. data/app/helpers/activities_helper.rb +4 -4
  10. data/app/helpers/search_helper.rb +5 -0
  11. data/app/models/activity.rb +12 -18
  12. data/app/models/actor.rb +5 -0
  13. data/app/models/group.rb +20 -21
  14. data/app/views/activities/_new.html.erb +7 -1
  15. data/app/views/devise/passwords/new.html.erb +6 -3
  16. data/app/views/devise/registrations/new.html.erb +14 -9
  17. data/app/views/devise/sessions/new.html.erb +5 -6
  18. data/app/views/groups/_new.html.erb +3 -3
  19. data/app/views/groups/_new_activity.html.erb +1 -0
  20. data/app/views/groups/_new_activity_fields.html.erb +7 -0
  21. data/app/views/layouts/_search.html.erb +3 -0
  22. data/app/views/layouts/application.html.erb +0 -1
  23. data/app/views/objects/_new_activity.html.erb +0 -6
  24. data/app/views/search/_focus_search.html.erb +21 -0
  25. data/app/views/search/_form.html.erb +22 -0
  26. data/app/views/search/_global_search.html.erb +19 -0
  27. data/app/views/search/_header_search.html.erb +14 -13
  28. data/app/views/search/_index.html.erb +10 -30
  29. data/app/views/search/index.html.erb +2 -1
  30. data/config/locales/en.yml +14 -4
  31. data/config/routes.rb +1 -1
  32. data/lib/social_stream/ability.rb +1 -1
  33. data/lib/social_stream/base/version.rb +1 -1
  34. data/lib/social_stream/models/object.rb +19 -1
  35. data/lib/social_stream/toolbar_config.rb +0 -8
  36. data/lib/social_stream-base.rb +1 -1
  37. data/lib/tasks/db/populate.rake +10 -4
  38. data/spec/controllers/groups_controller_spec.rb +3 -3
  39. data/spec/controllers/posts_controller_spec.rb +1 -1
  40. data/spec/factories/group.rb +1 -1
  41. data/spec/models/activity_spec.rb +0 -21
  42. data/spec/models/group_spec.rb +1 -1
  43. data/spec/models/post_spec.rb +26 -0
  44. metadata +9 -4
data/Rakefile CHANGED
@@ -27,7 +27,7 @@ end
27
27
 
28
28
  Bundler::GemHelper.install_tasks
29
29
 
30
- # Modify this gem tags
30
+ # Modify this gem's tags
31
31
  class Bundler::GemHelper
32
32
  def version_tag
33
33
  "base#{version}"
@@ -1,8 +1,16 @@
1
+ /* This stylesheet overwrites some of the parameters fixed by other stylesheets found in
2
+ * assets/stylesheets. Since they are compiled all together in alphabetic order, it should be
3
+ * start by zero to make sure it is the first one to be executed.
4
+ */
5
+
1
6
  #center_body{
2
7
  border: none;
3
8
  width:100%;
4
9
  }
5
10
 
11
+ #footer ul{
12
+ padding-left: 59px;
13
+ }
6
14
  #sidebar{
7
15
  display:none;
8
16
  }
@@ -13,7 +13,7 @@
13
13
  #wrapper_activities_header { padding-top: 5px; padding-bottom: 5px; background-color: #deeff8;}
14
14
  #activities_title { vertical-align: top; margin-left: 10px; font-weight: bold;}
15
15
  #activities_header { width: 100%; margin-bottom: 5px; text-align: center; padding-top: 5px;}
16
- #input_activities { border-color: #0656a4; color: #2A3890; padding: 5px 5px 5px 5px;
16
+ #activities_header input[type="text"] { border-color: #0656a4; color: #2A3890; padding: 5px 5px 5px 5px;
17
17
  border:1px solid #BDC7D8; width:95%;}
18
18
  #activities_share_btn { text-align: right; padding: 5px 16px 0px 10px; vertical-align: middle;}
19
19
  #securities{ display:inline-block; text-align:left; float: left; padding-left:5px;}
@@ -18,7 +18,7 @@ h2{padding-left:10px;}
18
18
  body{font-size:1.0em; color:#2A3890; background-color:#ffffff; overflow-y: scroll;}
19
19
  #wrapper { background-color: #f5f5f5; width: 100%; margin: 0px auto; }
20
20
  #wrapper_body{min-height: 552px; width: 960px; margin:0px auto; margin-left: auto; margin-right: auto;
21
- margin-top: auto; margin-bottom:auto; background-image:none;}
21
+ margin-top: auto; margin-bottom:auto; background-image:none; padding-bottom: 9px;}
22
22
 
23
23
 
24
24
  /*********** Notices SECTION *********************/
@@ -208,7 +208,7 @@ textarea.new_contact_text_area{ height: 100px; color: #2A3890;}
208
208
  }
209
209
 
210
210
  .activity_form_selector{
211
- padding: 2px;
211
+ padding: 5px;
212
212
  margin-bottom: 5px;
213
213
  float: left;
214
214
  border: 2px solid transparent;
@@ -14,13 +14,23 @@
14
14
  span.find{ padding-right:5px;}
15
15
 
16
16
  /************** sub structure Frontpage **************/
17
- #devise_links {padding: 5px 0 5px 0;}
18
- #devise_links a{font-weight: bold;line-height: 15px; }
17
+ #devise_links {padding: 20px 0 5px 5px; margin-left: 20%;}
18
+ #devise_links a{font-weight: bold;line-height: 15px; color: #777;}
19
19
  #login{ padding-top: 5px;}
20
20
  .instructions{text-align: left; padding-bottom: 5px;}
21
- #welcome{ margin: 50px auto 50px auto; width:330px; padding:20px; border: 3px solid #BDC7D8;
22
- text-align:center; background-color: white;-moz-border-radius: 20px;
21
+ #remember{padding-left:22%; text-align: left;}
22
+ #user_password_confirmation{vertical-align: 30%;}
23
+ #user_password_confirmation_label {padding-top: 0;}
24
+ #welcome{ margin: 50px auto 50px auto; width:330px; padding:20px; border: 4px solid #BDC7D8;
25
+ background-color: white;-moz-border-radius: 20px;
23
26
  -webkit-border-radius: 20px; border-radius: 20px;}
27
+ #welcome .form_field{ width: 75%;}
28
+ #welcome .btn_login { text-align: right; padding-right: 10px;}
29
+ #welcome .form_label{ width: 20%;}
30
+ #welcome .form_row{ padding-left: 5px;}
31
+ #welcome .form_tag{ width: 98%;}
32
+ #welcome h2{ font-variant: small-caps; text-transform: capitalize; padding: 0; font-size: 20px;
33
+ text-align: center; }
24
34
  #wrapper_left{ vertical-align:top; width:49%; display:inline-block; padding-left: 20px;}
25
35
  #wrapper_right{ vertical-align:top; width:48%; display:inline-block;}
26
36
 
@@ -51,6 +51,7 @@
51
51
  height: 35px;
52
52
  background: whiteSmoke;
53
53
  overflow: hidden;
54
+ text-align: center;
54
55
  }
55
56
  #header_search_display li:hover {
56
57
  background: #CFDEFF;
@@ -77,6 +78,7 @@
77
78
  #header_search_display li.subject_result {
78
79
  padding: 0px;
79
80
  height: 45px;
81
+ text-align: left;
80
82
  }
81
83
  #header_search_display li.title {
82
84
  overflow: hidden;
@@ -86,12 +88,12 @@
86
88
  color: whiteSmoke;
87
89
  font-weight: bold;
88
90
  }
89
- #header_search_display li.loading {
91
+ #header_search_display li.loading, #header_search_display li.more, #header_search_display li.none {
90
92
  text-align: center;
91
93
  }
92
- #header_search_display li.more, #header_search_display li.none {
93
- height: 15px;
94
- text-align: center;
94
+ #header_search_display li.more {
95
+ padding-top: 10px;
96
+ height: 30px;
95
97
  }
96
98
  #header_search_display li.title:hover, #header_search_display li.more:hover, #header_search_display li.none:hover {
97
99
  }
@@ -106,16 +108,52 @@
106
108
  padding: 5px;
107
109
  }
108
110
  .subject_search_results {
109
- width: 270px;
110
- float: left;
111
+ width: 280px;
111
112
  text-align: center;
112
- margin: 3px;
113
113
  }
114
- .subject_search_results .title {
115
- width: 260px;
114
+ #search_results {
115
+ text-align: center;
116
+ }
117
+ #search_results .left {
118
+ float: left;
119
+ padding: 0;
120
+ }
121
+ #search_results .right {
122
+ float: right;
123
+ padding: 0;
124
+ }
125
+ #search_results .title {
126
+ width: 540px;
116
127
  margin: auto;
117
128
  background-color: #E1EEF5;
118
129
  padding: 5px;
119
130
  font-weight: bold;
131
+ text-align: center;
132
+ }
133
+ #search_results .subject_search_results .title {
134
+ width: 260px;
135
+ }
136
+ /********************************* Focus options ***********/
137
+ #focus_options ul {
138
+ list-style: none;
139
+ }
140
+ #focus_options ul li {
141
+ line-height: 27px;
142
+ vertical-align: top;
143
+ display: inline;
144
+ }
145
+ #focus_options li span:hover {
146
+ background: #CFDEFF;
147
+ color: #2A3890;
148
+ }
149
+ #focus_options ul li a:hover{
150
+ text-decoration: none;
151
+ }
152
+ #focus_options ul li span{
153
+ padding: 5px 10px;
154
+ background-color: #E1EEF5;
155
+ }
156
+ #focus_options ul li span.selected{
157
+ border: solid 1px #2A3890;
120
158
  }
121
159
  /******************** Search css END ***********************/
@@ -48,7 +48,7 @@ class GroupsController < InheritedResources::Base
48
48
  def set_founder
49
49
  return unless user_signed_in?
50
50
 
51
- params[:group] ||= {}
52
- params[:group][:_founder] ||= current_subject.slug
51
+ params[:group] ||= {}
52
+ params[:group][:_contact_id] ||= current_subject.ego_contact.id
53
53
  end
54
54
  end
@@ -1,35 +1,81 @@
1
1
  class SearchController < ApplicationController
2
-
2
+ include ActionView::Helpers::SanitizeHelper
3
+
3
4
  #before_filter :authenticate_user! #??
4
-
5
+
6
+ FOCUS_SEARCH_PER_PAGE = 10
5
7
  def index
6
- if params[:mode].eql? "header_search"
7
- @search_result = header_search params[:search_query]
8
- render :partial => "header_search", :locals => {:search_result => @search_result}
9
- return
8
+ if params[:search_query].blank?
9
+ @search_result = nil_search
10
+ @search_class_sym = params[:focus].singularize.to_sym unless params[:focus].blank?
10
11
  else
11
- @search_result = global_search params[:search_query]
12
+ search_query = get_search_query params[:search_query]
13
+ if params[:mode].eql? "header_search"
14
+ @search_result = header_search search_query
15
+ render :partial => "header_search", :locals => {:search_result => @search_result}
16
+ return
17
+ else
18
+ if params[:focus].present?
19
+ @search_result = focus_search params[:focus], search_query, params[:page].present? ? params[:page].to_i : 1
20
+ @search_class_sym = params[:focus].singularize.to_sym
21
+ else
22
+ @search_result = global_search search_query
23
+ end
24
+ end
12
25
  end
13
26
  end
14
27
 
28
+ private
15
29
 
30
+ def get_search_query bare_query
31
+ search_query = ""
32
+ bare_query = strip_tags(bare_query) unless bare_query.html_safe?
33
+ search_query_words = bare_query.strip.split
34
+ search_query_words.each_index do |i|
35
+ search_query+= search_query_words[i] + " " if i < (search_query_words.size - 1)
36
+ search_query+= "*" + search_query_words[i] + "* " if i == (search_query_words.size - 1)
37
+ end
38
+ return search_query.strip
39
+ end
16
40
 
17
- private
18
41
  def global_search query
19
- return search query, params[:page].present? ? params[:page] : 1, 10
42
+ return search query, 10
20
43
  end
21
-
44
+
22
45
  def header_search query
23
- return search query, params[:page].present? ? params[:page] : 1, 3
46
+ return search query, 3
47
+ end
48
+
49
+ def search query, max_results
50
+ result = Hash.new
51
+ total = 0
52
+ total_shown = 0
53
+ SocialStream.subjects.each do |subject_sym|
54
+ result.update({subject_sym => ThinkingSphinx.search(query, :page => 1, :per_page => max_results, :classes => [subject_sym.to_s.classify.constantize])})
55
+ result.update({(subject_sym.to_s+"_total").to_sym => ThinkingSphinx.count(query, :classes => [subject_sym.to_s.classify.constantize])})
56
+ total+=ThinkingSphinx.count(query, :classes => [subject_sym.to_s.classify.constantize])
57
+ end
58
+ result.update({:total => total})
59
+ result.update({:total_shown => total_shown})
60
+ return result
24
61
  end
25
-
26
- def search query, page, per_page
62
+
63
+ def focus_search string_class, query, page
64
+ string_class = string_class.singularize
65
+ search_class = string_class.classify.constantize
66
+ result = Hash.new
67
+ result.update({string_class.to_sym => ThinkingSphinx.search(query, :page => page, :per_page => FOCUS_SEARCH_PER_PAGE, :classes => [search_class])})
68
+ result.update({(string_class+"_total").to_sym => ThinkingSphinx.count(query, :classes => [search_class])})
69
+ return result
70
+ end
71
+
72
+ def nil_search
27
73
  result = Hash.new
28
74
  SocialStream.subjects.each do |subject_sym|
29
- result.update({subject_sym => ThinkingSphinx.search("*#{query}*", :page => page, :per_page => per_page, :classes => [subject_sym.to_s.classify.constantize])})
30
- result.update({(subject_sym.to_s+"_total").to_sym => ThinkingSphinx.count("*#{query}*", :classes => [subject_sym.to_s.classify.constantize])})
75
+ result.update({subject_sym => []})
76
+ result.update({(subject_sym.to_s+"_total").to_sym => 0})
31
77
  end
78
+ result.update({:total => 0})
32
79
  return result
33
-
34
80
  end
35
81
  end
@@ -27,10 +27,10 @@ module ActivitiesHelper
27
27
  end
28
28
  end
29
29
 
30
- # Build a new activity based on the current_subject. Useful for authorization queries
31
- def new_activity(receiver)
32
- return Activity.new unless user_signed_in?
30
+ # Build a new post based on the current_subject. Useful for authorization queries
31
+ def new_post(receiver)
32
+ return Post.new unless user_signed_in?
33
33
 
34
- Activity.new :contact_id => current_subject.contact_to!(receiver).id
34
+ Post.new :_contact_id => current_subject.contact_to!(receiver).id
35
35
  end
36
36
  end
@@ -4,4 +4,9 @@ module SearchHelper
4
4
  render :partial => subject.class.to_s.pluralize.downcase + '/' + subject.class.to_s.downcase + '_with_details',
5
5
  :locals => {subject.class.to_s.downcase.to_sym => subject}
6
6
  end
7
+
8
+ def focus_search_link text, search_class, query
9
+ search_class = search_class.to_s if search_class.is_a? Class or search_class.is_a? Symbol
10
+ link_to text, search_path(:focus => search_class.downcase.pluralize, :search_query => query )
11
+ end
7
12
  end
@@ -222,24 +222,18 @@ class Activity < ActiveRecord::Base
222
222
  when 'create'
223
223
  return false if contact.sender_id != Actor.normalize_id(subject)
224
224
 
225
- val =
226
- if relation_ids.present?
227
- rels = Relation.normalize(relation_ids)
228
-
229
- foreign_rels = rels.select{ |r| r.actor_id != contact.sender_id }
230
-
231
- # Only posting to own relations
232
- foreign_rels.blank? ||
233
- Relation.
234
- allow(subject, action, 'activity', :in => foreign_rels).all.size == foreign_rels.size
235
- else
236
- contact.reflexive? ||
237
- receiver.
238
- relation_customs.allow(sender, 'create', 'activity').
239
- present?
240
- end
241
-
242
- return val
225
+ rels = Relation.normalize(relation_ids)
226
+
227
+ own_rels = rels.select{ |r| r.actor_id == contact.sender_id }
228
+ foreign_rels = rels - own_rels
229
+
230
+ # Only posting to own relations or allowed to post to foreign relations
231
+ return foreign_rels.blank? && own_rels.present? ||
232
+ foreign_rels.present? && Relation.allow(subject,
233
+ action,
234
+ 'activity',
235
+ :in => foreign_rels).
236
+ all.size == foreign_rels.size
243
237
 
244
238
  when 'read'
245
239
  return true if relations.select{ |r| r.is_a?(Relation::Public) }.any?
data/app/models/actor.rb CHANGED
@@ -259,6 +259,11 @@ class Actor < ActiveRecord::Base
259
259
  sent_contacts.create!(:receiver => Actor.normalize(subject))
260
260
  end
261
261
 
262
+ # The {Contact} of this {Actor} to self (totally close!)
263
+ def ego_contact
264
+ contact_to!(self)
265
+ end
266
+
262
267
  def sent_active_contact_ids
263
268
  @sent_active_contact_ids ||=
264
269
  load_sent_active_contact_ids
data/app/models/group.rb CHANGED
@@ -1,13 +1,11 @@
1
1
  class Group < ActiveRecord::Base
2
2
  include SocialStream::Models::Subject
3
3
 
4
- attr_accessor :_founder
5
4
  attr_accessor :_participants
6
5
 
7
6
  delegate :description, :description=, :to => :profile!
8
7
 
9
- after_create :create_founder
10
- after_create :create_participants
8
+ after_create :create_ties
11
9
 
12
10
  def profile!
13
11
  actor!.profile || actor!.build_profile
@@ -23,26 +21,27 @@ class Group < ActiveRecord::Base
23
21
  merge(Contact.recent)
24
22
  end
25
23
  end
26
-
27
- # Creates the ties between the group and the founder
28
- def create_founder
29
- founder =
30
- Actor.find_by_slug(_founder) || raise("Cannot create group without founder")
31
24
 
32
- sent_contacts.create! :receiver => founder,
33
- :relation_ids => Array(relation_customs.sort.first.id)
25
+ private
26
+
27
+ # Creates ties from founder to the group, based on _relation_ids,
28
+ # and ties from the group to founder and participants.
29
+ def create_ties
30
+ create_ties_from_founder
31
+ create_ties_to_participants
32
+ end
33
+
34
+ # Creates the ties from the founder to the group
35
+ def create_ties_from_founder
36
+ _contact.sender.sent_contacts.create! :receiver_id => actor_id,
37
+ :relation_ids => _relation_ids
34
38
  end
35
39
 
36
- # Creates the ties between the group and the participants
37
- def create_participants
38
- return if @_participants.blank?
39
-
40
- @_participants.each do |participant|
41
-
42
- participant_actor = Actor.find(participant)
43
-
44
- sent_contacts.create! :receiver => participant_actor,
45
- :relation_ids => Array(relation_customs.sort.first.id)
46
- end
40
+ # Creates the ties from the group to the participants
41
+ def create_ties_to_participants
42
+ ([ _contact.sender_id, _contact.receiver_id ] | Array.wrap(@_participants)).uniq.each do |a|
43
+ sent_contacts.create! :receiver_id => a,
44
+ :relation_ids => Array(relation_customs.sort.first.id)
45
+ end
47
46
  end
48
47
  end
@@ -1,4 +1,4 @@
1
- <% if can? :create, new_activity(receiver) %>
1
+ <% if can? :create, new_post(receiver) %>
2
2
  <div id="activities_header" class="content_size">
3
3
  <% SocialStream.activity_forms.each do |element| %>
4
4
  <%= render :partial => element.to_s.pluralize+'/new_activity',
@@ -6,6 +6,12 @@
6
6
  :receiver => receiver
7
7
  } %>
8
8
  <% end %>
9
+
10
+ <%= javascript_tag do %>
11
+ $(function(){
12
+ activate_anti_rebounds();
13
+ });
14
+ <% end %>
9
15
  </div>
10
16
 
11
17
  <div id="activity_form_select">
@@ -1,11 +1,14 @@
1
+ <% content_for :headers do%>
2
+ <%= stylesheet_link_tag "0_devise_sign", :media => "screen, projection" %>
3
+ <%end%>
1
4
  <div id="welcome">
2
5
  <div id="login" class="block">
3
- <h2><%= t('password.forgot') %></h2>
6
+ <h2><%= t('devise.passwords.forgot') %></h2>
4
7
  <div class="space_center"></div>
5
8
  <div class="space_center"></div>
6
9
  <%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
7
10
  <%= devise_error_messages! %>
8
- <div class="instructions"><%= t('devise.passwords.acquire') %></div>
11
+ <div class="instructions"><%= t('devise.passwords.instructions') %></div>
9
12
  <div class="form_row">
10
13
  <div class="form_label"<%= f.label :email %></div>
11
14
  <div class="form_field"><%= f.text_field :email, :class => "form_tag" %></div>
@@ -17,7 +20,7 @@
17
20
 
18
21
  <div class="space_center"></div>
19
22
  <div class="btn_login">
20
- <%= f.submit t('action.send'), :class =>"myButton" %>
23
+ <%= f.submit t('action.send'), :class =>"button" %>
21
24
  </div>
22
25
  <% end %>
23
26
  </div>
@@ -1,3 +1,7 @@
1
+ <% content_for :headers do%>
2
+ <%= stylesheet_link_tag "0_devise_sign", :media => "screen, projection" %>
3
+ <%end%>
4
+
1
5
  <div id="welcome">
2
6
  <div id="login" class="block">
3
7
  <h2><%= t('sign_up').capitalize %></h2>
@@ -18,22 +22,23 @@
18
22
  <div class="form_field"><%= f.password_field :password, :class =>"form_tag", :id => "password" %></div>
19
23
  </div>
20
24
  <div class="form_row">
21
- <div class="form_label"><%= f.label t('devise.passwords.confirm') %></div>
25
+ <div class="form_label" id="user_password_confirmation_label">
26
+ <%= f.label t('devise.passwords.confirm') %>
27
+ </div>
22
28
  <div class="form_field"><%= f.password_field :password_confirmation, :class =>"form_tag" %></div>
23
29
  </div>
24
30
  <div class="form_row center">
25
- <div id="btn_login"><%= f.submit t('action.accept').capitalize,:class=>"myButton" %></div>
31
+ <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
32
+ <%= link_to t('confirmation.not_received.long'), new_confirmation_path(resource_name) %><br />
33
+ <% end -%>
26
34
  </div>
27
- <% end %>
28
- <div class="form_row center">
29
- <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
30
- <%= link_to t('confirmation.not_received.long'), new_confirmation_path(resource_name) %><br />
31
- <% end -%>
32
- </div>
33
35
  <div id="devise_links">
34
36
  <%= render :partial => "devise/shared/links" %>
35
37
  </div>
36
- </div>
38
+ <div class="form_row center">
39
+ <div class="btn_login"><%= f.submit t('action.accept').capitalize,:class=>"button" %></div>
40
+ </div>
41
+ <% end %>
37
42
  </div>
38
43
 
39
44
 
@@ -17,13 +17,12 @@
17
17
  <div class="form_label"><%= f.label :password %></div>
18
18
  <div class="form_field"><%= f.password_field :password, :class => "form_tag" %></div>
19
19
  </div>
20
-
21
-
20
+ <% if devise_mapping.rememberable? -%>
21
+ <div id="remember">
22
+ <%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
23
+ </div>
24
+ <% end -%>
22
25
  <div id="devise_links">
23
- <% if devise_mapping.rememberable? -%>
24
- <%= f.check_box :remember_me %> <%= f.label :remember_me %>
25
- <% end -%>
26
- <div class="space_center"></div>
27
26
  <%= render :partial => "devise/shared/links" %>
28
27
  </div>
29
28
 
@@ -13,14 +13,14 @@
13
13
 
14
14
  <%= location(
15
15
  link_to(image_tag("btn/btn_group.png", :class => "menu_icon")+t('group.other'), groups_path),
16
- link_to(image_tag("btn/btn_group.png", :class => "menu_icon")+t('group.new.action'), new_group_path('group' => { '_founder' => current_subject.slug }))
16
+ link_to(image_tag("btn/btn_group.png", :class => "menu_icon")+t('group.new.action'), new_group_path)
17
17
  ) %>
18
18
 
19
19
  <div class="space_center"></div>
20
20
 
21
21
  <%= form_for @group do |f| %>
22
- <% f.object._founder = current_subject.slug %>
23
- <%= f.hidden_field :_founder %>
22
+ <% f.object._contact_id ||= current_subject.ego_contact.id %>
23
+ <%= f.hidden_field :_contact_id %>
24
24
 
25
25
  <% if @group.errors.any? %>
26
26
  <div id="notice">
@@ -0,0 +1 @@
1
+ <%= render :partial => 'objects/new_activity', :locals => {:receiver => receiver, :object => Group.new, :remote => false} %>
@@ -0,0 +1,7 @@
1
+ <%= f.text_field :name %>
2
+
3
+ <%= javascript_tag do %>
4
+ $(function() {
5
+ $('#group_name').Watermark("<%= t('group.input') %>", "#666");
6
+ });
7
+ <% end %>
@@ -15,6 +15,9 @@ $(document).ready(function() {
15
15
  });
16
16
  $('#header_search_input').click(function(e) {
17
17
  e.stopPropagation();
18
+ if($("#header_search_input").val()!=""){
19
+ $("#header_search_display").show();
20
+ }
18
21
  });
19
22
  $('#header_search_display').click(function(e) {
20
23
  e.stopPropagation();
@@ -51,7 +51,6 @@
51
51
  <%= yield :sidebar %>
52
52
  </div>
53
53
  </aside>
54
- <div class="space_center white"></div>
55
54
  </div>
56
55
  <footer><%= render :partial => "layouts/footer" %></footer>
57
56
  </div>
@@ -6,9 +6,3 @@
6
6
 
7
7
  <%= render :partial => object.class.to_s.tableize+'/new_activity_fields' , :locals => {:f => f} %>
8
8
  <% end %>
9
-
10
- <%= javascript_tag do %>
11
- $(document).ready(function(){
12
- activate_anti_rebounds();
13
- });
14
- <% end %>
@@ -0,0 +1,21 @@
1
+ <div class="title">
2
+ <%= @search_class_sym.to_s.capitalize.pluralize %>
3
+ </div>
4
+ <br class="clearfloat" />
5
+ <% if @search_result[@search_class_sym].empty? %>
6
+ <div class="subject_with_details">
7
+ <%= I18n.t('search.no_subject_found', :subject => @search_class_sym.to_s) %>
8
+ </div>
9
+ <% else %>
10
+ <% total = 0 %>
11
+ <div class="subject_search_results block left">
12
+ <% @search_result[@search_class_sym].each do |subject|%>
13
+ <%= subject_with_details subject %>
14
+ <% total+=1 %>
15
+ <% if (total%(SearchController::FOCUS_SEARCH_PER_PAGE/2)==0) %>
16
+ </div>
17
+ <div class="subject_search_results block left">
18
+ <% end %>
19
+ <% end %>
20
+ </div>
21
+ <% end %>
@@ -0,0 +1,22 @@
1
+ <div id="search_form">
2
+ <form action="<%= search_path %>" method="get">
3
+ <div class="block">
4
+ <%= hidden_field_tag :focus, params[:focus] %>
5
+ <div class="form_row search_row">
6
+ <%= text_field_tag :search_query, params[:search_query].present? ? params[:search_query] : nil ,:autocomplete => :off, :id => :global_search_input %>
7
+ </div>
8
+ <div id="focus_options" class="form_row search_row">
9
+ <ul>
10
+ <li><%= link_to content_tag(:span,t('search.show_all'),:class => params[:focus].blank? ? 'selected' : ''), search_path, :search_query => params[:search_query] %></li>
11
+ <% SocialStream.subjects.each do |subject| %>
12
+ <% selected_class = (params[:focus].present? and params[:focus].pluralize.downcase.eql?(subject.to_s.pluralize.downcase)) ? 'selected' : ''%>
13
+ <li><%= focus_search_link content_tag(:span, subject.to_s.pluralize.capitalize,
14
+ :class => selected_class),
15
+ subject.to_s.classify.constantize,
16
+ params[:search_query] %></li>
17
+ <% end %>
18
+ </ul>
19
+ </div>
20
+ </div>
21
+ </form>
22
+ </div>
@@ -0,0 +1,19 @@
1
+ <% SocialStream.subjects.each do |subject_type| %>
2
+ <div class="subject_search_results block <%= cycle "left", "right" %>">
3
+ <div class="title">
4
+ <%= subject_type.to_s.capitalize.pluralize %>
5
+ </div>
6
+ <% if @search_result[subject_type].empty? %>
7
+ <div class="subject_with_details">
8
+ <%= I18n.t('search.no_subject_found', :subject => subject_type.to_s) %>
9
+ </div>
10
+ <% else %>
11
+ <% @search_result[subject_type].each do |subject|%>
12
+ <%= subject_with_details subject %>
13
+ <% end %>
14
+ <div class="subject_with_details">
15
+ <%= focus_search_link(I18n.t('search.all_subject_results', :subject => subject_type.to_s.pluralize, :count => @search_result[(subject_type.to_s+"_total").to_sym].to_s),subject_type.to_s,params[:search_query]) %>
16
+ </div>
17
+ <% end %>
18
+ </div>
19
+ <% end %>
@@ -1,21 +1,22 @@
1
+ <% total = 0 %>
1
2
  <ul>
2
- <% SocialStream.subjects.each do |subject_type| %>
3
-
4
- <li class="title">
5
- <%= subject_type.to_s.capitalize.pluralize %>
6
- </li>
7
- <% if @search_result[subject_type].empty? %>
8
- <li class="none">
9
- <%= I18n.t('search.no_subject_found', :subject => subject_type.to_s) %>
3
+ <% SocialStream.subjects.each do |subject_type| %>
4
+ <% unless @search_result[subject_type].empty? %>
5
+ <li class="title">
6
+ <%= subject_type.to_s.capitalize.pluralize %>
10
7
  </li>
11
- <% else %>
12
8
  <% @search_result[subject_type].each do |subject|%>
9
+ <% total+=1 %>
13
10
  <li class="subject_result"><%= subject_with_details subject %></li>
14
11
  <% end %>
15
- <li class="more">
16
- <%= I18n.t('search.all_subject_results', :subject => subject_type.to_s.pluralize, :count => @search_result[(subject_type.to_s+"_total").to_sym].to_s) %>
17
- </li>
18
12
  <% end %>
19
13
  </li>
20
- <% end %>
14
+ <% end %>
15
+
16
+ <%= link_to raw('<li class="more">' +
17
+ t('search.global.query', :query => truncate(params[:search_query],:length => 20)) +
18
+ '<br>' +
19
+ t('search.global.first_result.' + (total==1 ? 'one' : 'more'),
20
+ :count => total.to_s) + '</li>'),
21
+ search_path(:search_query => params[:search_query]) %>
21
22
  </ul>
@@ -1,35 +1,15 @@
1
- <%= location(link_to(t('search.name')))%>
1
+ <%= location(link_to(t('search.global.name')))%>
2
2
  <br class="clearfloat" />
3
3
  <div class="space_center"></div>
4
- <h2><%= t('search.name') %></h2>
4
+ <h2><%= t('search.searching', :query => truncate(params[:search_query],:length => 45)) %></h2>
5
5
  <div class="space_center"></div>
6
- <div id="search_form">
7
- <form action="<%=search_path%>" method="get">
8
- <div class="block">
9
- <div class="form_row search_row">
10
- <%= text_field_tag :search_query, params[:search_query].present? ? params[:search_query] : nil ,:autocomplete => :off, :id => :global_search_input %>
11
- </div>
12
- </div>
13
- </form>
14
- </div>
15
- <div id="search_results" class="block">
16
- <% SocialStream.subjects.each do |subject_type| %>
17
- <div class="subject_search_results" class="block">
18
- <div class="title">
19
- <%= subject_type.to_s.capitalize.pluralize %>
20
- </div>
21
- <% if @search_result[subject_type].empty? %>
22
- <div class="subject_with_details">
23
- <%= I18n.t('search.no_subject_found', :subject => subject_type.to_s) %>
24
- </div>
25
- <% else %>
26
- <% @search_result[subject_type].each do |subject|%>
27
- <%= subject_with_details subject %>
28
- <% end %>
29
- <div class="subject_with_details">
30
- <%= I18n.t('search.all_subject_results', :subject => subject_type.to_s.pluralize, :count => @search_result[(subject_type.to_s+"_total").to_sym].to_s) %>
31
- </div>
32
- <% end %>
33
- </div>
6
+ <%= render :partial => 'form' %>
7
+ <div class="space_center"></div>
8
+ <div class="space_center"></div>
9
+ <div id="search_results" class="block">
10
+ <% unless params[:focus].present? %>
11
+ <%= render :partial => 'global_search' %>
12
+ <% else %>
13
+ <%= render :partial => 'focus_search' %>
34
14
  <% end %>
35
15
  </div>
@@ -12,4 +12,5 @@
12
12
 
13
13
  <% end %>
14
14
 
15
- <%= render :partial => 'index' %>
15
+
16
+ <%= render :partial => 'index' %>
@@ -127,8 +127,9 @@ en:
127
127
  confirm: Delete %{element}}?
128
128
  devise:
129
129
  passwords:
130
- acquire: "Type the email address bound to your account and we will sent you a new one:"
131
130
  confirm: "Confirm password"
131
+ forgot: "Forgot your password?"
132
+ instructions: "Type the email address bound to your account and we will sent you instructions to change it:"
132
133
  update: "Change your password"
133
134
  follower:
134
135
  n:
@@ -163,6 +164,9 @@ en:
163
164
  all: "All groups"
164
165
  all_n: "All groups (%{count})"
165
166
  by: "By groups"
167
+ form:
168
+ title: "Group"
169
+ input: "What is the name of the group?"
166
170
  last: "Last groups"
167
171
  my: "My groups"
168
172
  new:
@@ -233,8 +237,6 @@ en:
233
237
  read: "Mark as read"
234
238
  read_all: "Mark all as read"
235
239
  unread: "Mark as unread"
236
- password:
237
- forgot: "Acquire a new password"
238
240
  post:
239
241
  confirm_delete: "Delete post?"
240
242
  form:
@@ -327,10 +329,18 @@ en:
327
329
  search:
328
330
  actor:
329
331
  none: "Nothing found"
332
+ all_subject_results: "Search all %{subject} (%{count})"
330
333
  at_least: "Write at least two characters"
334
+ global:
335
+ name: "Global search"
336
+ first_result:
337
+ more: "Showing the first %{count} results."
338
+ one: "Showing the first result."
339
+ query: "See more results for %{query} >"
331
340
  name: "Search"
332
341
  no_subject_found: "No %{subject} was found."
333
- all_subject_results: "Search all %{subject} (%{count})"
342
+ searching: "Searching: %{query}"
343
+ show_all: "Show all results"
334
344
  write: "Write your query ..."
335
345
  wrong: "There seems to be a problem with the search engine"
336
346
  settings:
data/config/routes.rb CHANGED
@@ -65,7 +65,7 @@ Rails.application.routes.draw do
65
65
  resource :like
66
66
  end
67
67
 
68
- match 'search' => 'search#index', :as => :search
68
+ match 'search' => 'search#index', :as => :search
69
69
 
70
70
  match 'ties' => 'ties#index', :as => :ties
71
71
 
@@ -74,7 +74,7 @@ module SocialStream
74
74
 
75
75
  can :create, Group do |g|
76
76
  subject.present? &&
77
- g._founder == subject.slug
77
+ g._contact.sender_id == Actor.normalize_id(subject)
78
78
  end
79
79
 
80
80
  can :update, Group do |g|
@@ -1,5 +1,5 @@
1
1
  module SocialStream
2
2
  module Base
3
- VERSION = "0.9.4".freeze
3
+ VERSION = "0.9.5".freeze
4
4
  end
5
5
  end
@@ -7,7 +7,8 @@ module SocialStream
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  included do
10
- attr_accessor :_contact_id, :_relation_ids
10
+ attr_accessor :_contact_id
11
+ attr_writer :_relation_ids
11
12
  attr_accessor :_activity_parent_id
12
13
 
13
14
  belongs_to :activity_object, :dependent => :destroy, :autosave => true
@@ -61,6 +62,23 @@ module SocialStream
61
62
  @_contact ||= Contact.find(_contact_id)
62
63
  end
63
64
 
65
+ def _relation_ids
66
+ @_relation_ids ||=
67
+ if _contact_id.nil?
68
+ nil
69
+ else
70
+ if _contact.reflexive?
71
+ Array.wrap(_contact.sender.relation_public.id)
72
+ else
73
+ _contact.
74
+ receiver.
75
+ relation_customs.
76
+ allow(_contact.sender, 'create', 'activity').
77
+ map(&:id)
78
+ end
79
+ end
80
+ end
81
+
64
82
  def _activity_parent
65
83
  @_activity_parent ||= Activity.find(_activity_parent_id)
66
84
  end
@@ -43,14 +43,6 @@ module SocialStream
43
43
  {:key => :invitations, :name => image_tag("btn/btn_invitation.png")+t('invitation.toolbar'), :url => new_invitation_path}
44
44
  ]}
45
45
 
46
- #Subjects
47
- items << {:key => :groups,
48
- :name => image_tag("btn/btn_group.png")+t('group.other'),
49
- :url => "#",
50
- :options => {:link => {:id => "groups_menu"}},
51
- :items => [{:key => :new_group ,:name => image_tag("btn/btn_group.png")+t('group.new.action'),:url => new_group_path('group' => { '_founder' => current_subject.slug })}]
52
- }
53
-
54
46
  render_items items
55
47
  end
56
48
 
@@ -72,7 +72,7 @@ module SocialStream
72
72
  @@objects = [ :post, :comment ]
73
73
 
74
74
  mattr_accessor :activity_forms
75
- @@activity_forms = [:post]
75
+ @@activity_forms = [ :post, :group ]
76
76
 
77
77
  class << self
78
78
  def setup
@@ -11,6 +11,12 @@ namespace :db do
11
11
  task :create => :environment do
12
12
 
13
13
  LOGOS_PATH = File.join(Rails.root, 'lib', 'logos')
14
+ USERS = ENV["USERS"].to_i || 9
15
+ GROUPS = ENV["GROUPS"].to_i || 10
16
+ if ENV["HARDCORE"].present?
17
+ USERS = 999
18
+ GROUPS = 1000
19
+ end
14
20
 
15
21
  Mailboxer.setup do |config|
16
22
  config.uses_emails = false
@@ -40,7 +46,7 @@ namespace :db do
40
46
  end
41
47
  end
42
48
 
43
- puts 'User population'
49
+ puts 'User population (Demo and ' + USERS.to_s + ' users more)'
44
50
  users_start = Time.now
45
51
 
46
52
  # = Users
@@ -55,7 +61,7 @@ namespace :db do
55
61
 
56
62
  require 'forgery'
57
63
 
58
- 9.times do
64
+ USERS.times do
59
65
  User.create! :name => Forgery::Name.full_name,
60
66
  :email => Forgery::Internet.email_address,
61
67
  :password => 'demonstration',
@@ -66,13 +72,13 @@ namespace :db do
66
72
  users_end = Time.now
67
73
  puts ' -> ' + (users_end - users_start).round(4).to_s + 's'
68
74
 
69
- puts 'Groups population'
75
+ puts 'Groups population (' + GROUPS.to_s + ' groups)'
70
76
  groups_start = Time.now
71
77
 
72
78
  # = Groups
73
79
  available_actors = Actor.all
74
80
 
75
- 10.times do
81
+ GROUPS.times do
76
82
  founder = available_actors[rand(available_actors.size)]
77
83
 
78
84
  Group.create! :name => Forgery::Name.company_name,
@@ -30,7 +30,7 @@ describe GroupsController do
30
30
 
31
31
  context "faking a new group" do
32
32
  before do
33
- model_attributes[:_founder] = Factory(:user).slug
33
+ model_attributes[:_contact_id] = Factory(:user).ego_contact.id
34
34
  end
35
35
 
36
36
  it_should_behave_like "Deny Creating"
@@ -81,7 +81,7 @@ describe GroupsController do
81
81
 
82
82
  context "a new own group" do
83
83
  before do
84
- model_attributes[:_founder] = @user.slug
84
+ model_attributes[:_contact_id] = @user.ego_contact.id
85
85
  end
86
86
 
87
87
  it "should allow creating" do
@@ -127,7 +127,7 @@ describe GroupsController do
127
127
 
128
128
  context "a new fake group" do
129
129
  before do
130
- model_attributes[:_founder] = Factory(:user).slug
130
+ model_attributes[:_contact_id] = Factory(:user).ego_contact.id
131
131
  end
132
132
 
133
133
  it_should_behave_like "Deny Creating"
@@ -143,7 +143,7 @@ describe PostsController do
143
143
 
144
144
  post :create, :post => { :text => "Test",
145
145
  :_contact_id => @tie.contact.inverse!.id,
146
- :_relation_ids => [""] }
146
+ }
147
147
 
148
148
  post = assigns(:post)
149
149
 
@@ -1,4 +1,4 @@
1
1
  Factory.define :group do |g|
2
2
  g.sequence(:name) { |n| "Group #{ n }" }
3
- g._founder { |g| Factory(:user).slug }
3
+ g._contact_id { |g| Factory(:user).ego_contact.id }
4
4
  end
@@ -128,25 +128,4 @@ describe Activity do
128
128
  end
129
129
  end
130
130
  end
131
-
132
- context "without relations" do
133
- it "should allow create to friend" do
134
- tie = Factory(:friend)
135
-
136
- activity = Activity.new :contact_id => tie.contact.inverse!.id
137
-
138
- assert activity.allow?(tie.receiver, 'create')
139
- end
140
-
141
- it "should fill relation" do
142
- tie = Factory(:friend)
143
-
144
- post = Post.new :text => "testing",
145
- :_contact_id => tie.contact.inverse!.id
146
-
147
- post.save!
148
-
149
- post.post_activity.relations.should include(tie.relation)
150
- end
151
- end
152
131
  end
@@ -4,7 +4,7 @@ describe Group do
4
4
  it "should save description" do
5
5
  g = Group.create(:name => "Test",
6
6
  :description => "Testing description",
7
- :_founder => Factory(:user).slug)
7
+ :_contact_id => Factory(:user).ego_contact.id)
8
8
 
9
9
  g.reload.description.should be_present
10
10
  end
@@ -30,4 +30,30 @@ describe Post do
30
30
  end
31
31
  end
32
32
  end
33
+
34
+ context "without relations" do
35
+ it "should allow create to friend" do
36
+ tie = Factory(:friend)
37
+
38
+ post = Post.new :text => "testing",
39
+ :_contact_id => tie.contact.inverse!.id
40
+
41
+ assert post.build_post_activity.allow? tie.receiver_subject, 'create'
42
+
43
+ ability = Ability.new(tie.receiver_subject)
44
+
45
+ ability.should be_able_to(:create, post)
46
+ end
47
+
48
+ it "should fill relation" do
49
+ tie = Factory(:friend)
50
+
51
+ post = Post.new :text => "testing",
52
+ :_contact_id => tie.contact.inverse!.id
53
+
54
+ post.save!
55
+
56
+ post.post_activity.relations.should include(tie.relation)
57
+ end
58
+ end
33
59
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: social_stream-base
3
3
  version: !ruby/object:Gem::Version
4
- hash: 51
4
+ hash: 49
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 4
10
- version: 0.9.4
9
+ - 5
10
+ version: 0.9.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - GING - DIT - UPM
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-09-16 00:00:00 +02:00
19
+ date: 2011-09-20 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -775,6 +775,8 @@ files:
775
775
  - app/views/groups/_group_with_details.html.erb
776
776
  - app/views/groups/_index.html.erb
777
777
  - app/views/groups/_new.html.erb
778
+ - app/views/groups/_new_activity.html.erb
779
+ - app/views/groups/_new_activity_fields.html.erb
778
780
  - app/views/groups/_sidebar_index.html.erb
779
781
  - app/views/groups/_sidebar_show.html.erb
780
782
  - app/views/groups/index.html.erb
@@ -853,6 +855,9 @@ files:
853
855
  - app/views/relation/customs/create.js.erb
854
856
  - app/views/relation/customs/index.html.erb
855
857
  - app/views/relation/customs/update.js.erb
858
+ - app/views/search/_focus_search.html.erb
859
+ - app/views/search/_form.html.erb
860
+ - app/views/search/_global_search.html.erb
856
861
  - app/views/search/_header_search.html.erb
857
862
  - app/views/search/_index.html.erb
858
863
  - app/views/search/index.html.erb