social_stream-base 0.12.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/app/assets/images/flags/en.png +0 -0
  2. data/app/assets/images/flags/es.png +0 -0
  3. data/app/assets/javascripts/toolbar.js +22 -1
  4. data/app/assets/stylesheets/activities.css.scss +1 -1
  5. data/app/assets/stylesheets/cheesecake.css.scss +46 -4
  6. data/app/assets/stylesheets/settings.css +11 -0
  7. data/app/controllers/cheesecake_controller.rb +15 -3
  8. data/app/controllers/contacts_controller.rb +2 -0
  9. data/app/controllers/conversations_controller.rb +5 -5
  10. data/app/controllers/likes_controller.rb +1 -1
  11. data/app/helpers/notifications_helper.rb +10 -0
  12. data/app/models/activity.rb +55 -36
  13. data/app/models/activity_object.rb +3 -23
  14. data/app/models/actor.rb +20 -4
  15. data/app/models/channel.rb +13 -1
  16. data/app/models/comment.rb +4 -0
  17. data/app/models/contact.rb +55 -19
  18. data/app/models/group.rb +5 -2
  19. data/app/models/like.rb +2 -2
  20. data/app/models/relation/custom.rb +1 -1
  21. data/app/models/tie.rb +4 -3
  22. data/app/views/cheesecake/_cheesecake.html.erb +63 -0
  23. data/app/views/cheesecake/_index.html.erb +43 -86
  24. data/app/views/cheesecake/index.html.erb +2 -0
  25. data/app/views/cheesecake/update.js.erb +3 -0
  26. data/app/views/devise/passwords/new.html.erb +1 -1
  27. data/app/views/devise/registrations/new.html.erb +1 -1
  28. data/app/views/devise/sessions/new.html.erb +1 -1
  29. data/app/{assets/stylesheets/0_devise_sign.css → views/layouts/_devise_style.html.erb} +3 -1
  30. data/app/views/layouts/_header_signed_in.erb +1 -1
  31. data/app/views/message_mailer/new_message_email.html.erb +2 -1
  32. data/app/views/message_mailer/new_message_email.text.erb +2 -1
  33. data/app/views/message_mailer/reply_message_email.html.erb +2 -1
  34. data/app/views/message_mailer/reply_message_email.text.erb +2 -1
  35. data/app/views/notification_mailer/new_notification_email.html.erb +2 -1
  36. data/app/views/notification_mailer/new_notification_email.text.erb +2 -1
  37. data/app/views/notifications/activities/_post.html.erb +24 -1
  38. data/app/views/notifications/activities/_post.text.erb +22 -3
  39. data/app/views/settings/_language.html.erb +1 -1
  40. data/config/locales/en.yml +3 -2
  41. data/config/locales/es.yml +4 -3
  42. data/config/routes.rb +1 -0
  43. data/db/migrate/20120111141717_activity_channels.rb +74 -0
  44. data/lib/social_stream-base.rb +1 -0
  45. data/lib/social_stream/base/engine.rb +2 -1
  46. data/lib/social_stream/base/version.rb +1 -1
  47. data/lib/social_stream/models/channeled.rb +50 -0
  48. data/lib/social_stream/models/object.rb +4 -13
  49. data/lib/social_stream/toolbar_config/base.rb +1 -1
  50. data/lib/tasks/db/populate.rake +1 -1
  51. data/social_stream-base.gemspec +2 -2
  52. data/spec/controllers/comments_controller_spec.rb +3 -3
  53. data/spec/factories/activity.rb +3 -3
  54. data/spec/factories/contact.rb +2 -0
  55. data/spec/models/activity_authorization_spec.rb +5 -1
  56. data/spec/models/like_spec.rb +3 -3
  57. data/spec/models/tie_spec.rb +4 -4
  58. metadata +70 -64
  59. data/vendor/assets/javascripts/menu.js +0 -25
@@ -5,6 +5,8 @@
5
5
  <% toolbar :option => :contacts %>
6
6
 
7
7
  <% location link_to(t("contact.other"),contacts_path) %>
8
+ <div id="cheesecake">
8
9
  <%= render :partial => "index"%>
10
+ </div>
9
11
 
10
12
  <div class="space_center"></div>
@@ -0,0 +1,3 @@
1
+ $('#cheesecake').html("<%= escape_javascript render :partial => 'index' %>");
2
+
3
+ <%= render :partial => 'cheesecake' %>
@@ -1,5 +1,5 @@
1
1
  <% content_for :headers do%>
2
- <%= stylesheet_link_tag "0_devise_sign", :media => "screen, projection" %>
2
+ <%= render :partial => 'layouts/devise_style' %>
3
3
  <%end%>
4
4
  <div id="welcome">
5
5
  <div id="login" class="block">
@@ -1,5 +1,5 @@
1
1
  <% content_for :headers do%>
2
- <%= stylesheet_link_tag "0_devise_sign", :media => "screen, projection" %>
2
+ <%= render :partial => 'layouts/devise_style' %>
3
3
  <%end%>
4
4
 
5
5
  <div id="welcome">
@@ -1,5 +1,5 @@
1
1
  <% content_for :headers do%>
2
- <%= stylesheet_link_tag "0_devise_sign", :media => "screen, projection" %>
2
+ <%= render :partial => 'layouts/devise_style' %>
3
3
  <%end%>
4
4
 
5
5
  <div id="welcome">
@@ -1,3 +1,4 @@
1
+ <style type="text/css">
1
2
  /* This stylesheet overwrites some of the parameters fixed by other stylesheets found in
2
3
  * assets/stylesheets. Since they are compiled all together in alphabetic order, it should be
3
4
  * start by zero to make sure it is the first one to be executed.
@@ -21,8 +22,9 @@
21
22
 
22
23
  #wrapper_body{
23
24
  background-color: inherit;
24
- background-image: url("/assets/big-logo.png");
25
+ background-image: url("<%= asset_path("big-logo.png") %>");
25
26
  background-repeat: no-repeat;
26
27
  background-position: bottom left;
27
28
  width:100%;
28
29
  }
30
+ </style>
@@ -23,7 +23,7 @@
23
23
  <li>
24
24
  <%= link_to(t('message.other'), conversations_path) %>
25
25
  <span id="header_inbox_count">
26
- <%= link_to(current_subject.mailbox.inbox(:unread => true).count.to_s, conversations_path) %>
26
+ <%= link_to(current_subject.unread_messages_count.to_s, conversations_path) %>
27
27
  </span>
28
28
  </li>
29
29
  <li class="pipe">·</li>
@@ -1,4 +1,5 @@
1
- <% self.class.send :include, SubjectsHelper %>
1
+ <% self.class.send :include, SubjectsHelper, NotificationsHelper %>
2
+ <% locale_as @receiver.subject %>
2
3
  <!DOCTYPE html>
3
4
  <html>
4
5
  <head>
@@ -1,4 +1,5 @@
1
- <% self.class.send :include, SubjectsHelper %>
1
+ <% self.class.send :include, SubjectsHelper, NotificationsHelper %>
2
+ <% locale_as @receiver.subject %>
2
3
  <%=truncate_name(@message.sender.name)%> <%= t('mailboxer.message_mailer.has_sent_new.' + @receiver.subject.class.to_s.downcase, :receiver => @receiver.name) %>
3
4
 
4
5
  -----------------------------------------------
@@ -1,4 +1,5 @@
1
- <% self.class.send :include, SubjectsHelper %>
1
+ <% self.class.send :include, SubjectsHelper, NotificationsHelper %>
2
+ <% locale_as @receiver.subject %>
2
3
  <!DOCTYPE html>
3
4
  <html>
4
5
  <head>
@@ -1,4 +1,5 @@
1
- <% self.class.send :include, SubjectsHelper %>
1
+ <% self.class.send :include, SubjectsHelper, NotificationsHelper %>
2
+ <% locale_as @receiver.subject %>
2
3
  <%= truncate_name(@message.sender.name)%> <%= t('mailboxer.message_mailer.has_sent_reply.' + @receiver.subject.class.to_s.downcase, :receiver => @receiver.name) %>
3
4
 
4
5
  -----------------------------------------------
@@ -1,4 +1,5 @@
1
- <% self.class.send :include, SubjectsHelper, ActionView::Helpers::TextHelper %>
1
+ <% self.class.send :include, SubjectsHelper, NotificationsHelper, ActionView::Helpers::TextHelper %>
2
+ <% locale_as @receiver.subject %>
2
3
  <!DOCTYPE html>
3
4
  <html>
4
5
  <head>
@@ -1,4 +1,5 @@
1
- <% self.class.send :include, SubjectsHelper, ActionView::Helpers::TextHelper %>
1
+ <% self.class.send :include, SubjectsHelper, NotificationsHelper, ActionView::Helpers::TextHelper %>
2
+ <% locale_as @receiver.subject %>
2
3
  <%= t('notification.hello', :receiver => @receiver.name)%>
3
4
 
4
5
  <%= render :partial => "notifications/activities/#{ @notification.notified_object.verb }",
@@ -1,16 +1,39 @@
1
1
  <div class="subject">
2
+ <% if activity.direct_object.is_a? Comment %>
2
3
  <%= raw t('notification.post.'+ activity.receiver.subject.class.to_s.underscore,
3
4
  :sender => link_to(truncate_name(activity.sender.name),
4
5
  polymorphic_url(activity.sender.subject)),
5
6
  :whose => t('notification.whose.'+ activity.receiver.subject.class.to_s.underscore,
6
7
  :receiver => truncate_name(activity.receiver.name)),
7
- :thing => link_to(t(activity.direct_object.class.to_s.underscore+'.one'),
8
+ :title => link_to(activity.direct_object.parent_post.text.truncate(30, :separator => ' '),
8
9
  polymorphic_url(activity.direct_object))) %>
10
+ <% elsif activity.direct_object.is_a? Post %>
11
+ <%= raw t('notification.post.'+ activity.receiver.subject.class.to_s.underscore,
12
+ :sender => link_to(truncate_name(activity.sender.name),
13
+ polymorphic_url(activity.sender.subject)),
14
+ :whose => t('notification.whose.'+ activity.receiver.subject.class.to_s.underscore,
15
+ :receiver => truncate_name(activity.receiver.name)),
16
+ :title => link_to(activity.direct_object.text.truncate(30, :separator => ' '),
17
+ polymorphic_url(activity.direct_object))) %>
18
+ <% elsif activity.direct_object.respond_to? :title %>
19
+ <%= raw t('notification.post.'+ activity.receiver.subject.class.to_s.underscore,
20
+ :sender => link_to(truncate_name(activity.sender.name),
21
+ polymorphic_url(activity.sender.subject)),
22
+ :whose => t('notification.whose.'+ activity.receiver.subject.class.to_s.underscore,
23
+ :receiver => truncate_name(activity.receiver.name)),
24
+ :title => link_to(activity.direct_object.title.truncate(30, :separator => ' '),
25
+ polymorphic_url(activity.direct_object))) %>
26
+ <% else %>
27
+ <%= raw t('notification.default') %>
28
+ <% end %>
9
29
  </div>
10
30
  <div class="briefing">
11
31
  <% if activity.direct_object.respond_to? :text %>
12
32
  "<%= link_to(sanitize(activity.direct_object.text.truncate(100, :separator =>' ')),
13
33
  polymorphic_url(activity.direct_object))%>"
34
+ <% elsif activity.direct_object.respond_to? :description and not activity.direct_object.description.blank? %>
35
+ "<%= link_to(sanitize(activity.direct_object.description.truncate(100, :separator =>' ')),
36
+ polymorphic_url(activity.direct_object))%>"
14
37
  <% else%>
15
38
  <%= link_to(t('notification.watch_it'),
16
39
  polymorphic_url( activity.direct_object))%>
@@ -1,17 +1,36 @@
1
1
 
2
+ <% if activity.direct_object.is_a? Comment %>
2
3
  <%= raw t('notification.post.'+ activity.receiver.subject.class.to_s.underscore,
3
4
  :sender => truncate_name(activity.sender.name),
4
5
  :whose => t('notification.whose.'+ activity.receiver.subject.class.to_s.underscore,
5
- :receiver => truncate_name(activity.receiver.name)),
6
- :thing => t(activity.direct_object.class.to_s.underscore+'.one')) %>
6
+ :receiver => truncate_name(activity.receiver.name)),
7
+ :title => activity.direct_object.parent_post.text.truncate(30, :separator => ' ')) %>
8
+ <% elsif activity.direct_object.is_a? Post %>
9
+ <%= raw t('notification.post.'+ activity.receiver.subject.class.to_s.underscore,
10
+ :sender => truncate_name(activity.sender.name),
11
+ :whose => t('notification.whose.'+ activity.receiver.subject.class.to_s.underscore,
12
+ :receiver => truncate_name(activity.receiver.name)),
13
+ :title => activity.direct_object.text.truncate(30, :separator => ' ')) %>
14
+ <% elsif activity.direct_object.respond_to? :title %>
15
+ <%= raw t('notification.post.'+ activity.receiver.subject.class.to_s.underscore,
16
+ :sender => truncate_name(activity.sender.name),
17
+ :whose => t('notification.whose.'+ activity.receiver.subject.class.to_s.underscore,
18
+ :receiver => truncate_name(activity.receiver.name)),
19
+ :title => activity.direct_object.title.truncate(30, :separator => ' ')) %>
20
+ <% else %>
21
+ <%= raw t('notification.default') %>
22
+ <% end %>
7
23
 
8
24
 
9
25
  <% if activity.direct_object.respond_to? :text %>
10
26
  "<%= sanitize(activity.direct_object.text.truncate(100, :separator =>' '))%>"
11
27
  --><%= t('notification.all_text', :url => polymorphic_url(activity.direct_object))%>
28
+ <% elsif activity.direct_object.respond_to? :description and not activity.direct_object.description.blank? %>
29
+ "<%= sanitize(activity.direct_object.description.truncate(100, :separator =>' '))%>"
30
+ --><%= t('notification.all_text', :url => polymorphic_url(activity.direct_object))%>
12
31
  <% else%>
13
32
  <%= t('notification.watch', :url => polymorphic_url(activity.direct_object))%>
14
33
  <% end%>
15
34
 
16
35
  <%= raw t('notification.look',
17
- :sender => truncate_name(activity.sender.name))%>: <%=polymorphic_url(activity.sender.subject)%>
36
+ :sender => truncate_name(activity.sender.name))%>: <%=polymorphic_url(activity.sender.subject)%>
@@ -17,7 +17,7 @@
17
17
  <div class="form_row">
18
18
  <div class="form_label"><%= label_tag :language, t('settings.lang_change.name') %></div>
19
19
  <div class="form_field">
20
- <%= select_tag(:language, options_for_select([[t('lang.browser'), 'browser']] + I18n.available_locales.map{|l| [ t("lang_names.#{l.to_s}") + ' (' + l.to_s + ')' , l.to_s ] }, (current_user.language.blank? ? 'browser' : current_user.language)), :class => 'form_tag', :onchange => "$(\'#form_lang\').submit();" )%>
20
+ <%= select_tag(:language, options_for_select([[t('lang.browser'), 'browser']] + I18n.available_locales.map{|l| [ t(:language_name, :locale => l.to_s), l.to_s ] }, (current_user.language.blank? ? 'browser' : current_user.language)), :class => 'form_tag', :onchange => "$(\'#form_lang\').submit();" )%>
21
21
  </div>
22
22
  </div>
23
23
  <div class="actions center">
@@ -1,4 +1,5 @@
1
1
  en:
2
+ language_name: "English"
2
3
  actor:
3
4
  name: "Name"
4
5
  action:
@@ -300,8 +301,8 @@ en:
300
301
  one: "Notification"
301
302
  other: "Notifications"
302
303
  post:
303
- group: "%{sender} added %{thing} in %{whose} wall."
304
- user: "%{sender} added %{thing} in %{whose} wall."
304
+ group: "%{title} -- by %{sender} in %{whose} wall"
305
+ user: "%{title} -- by %{sender} in %{whose} wall"
305
306
  read: "Mark as read"
306
307
  read_all: "Mark all as read"
307
308
  unread: "Mark as unread"
@@ -1,4 +1,5 @@
1
1
  es:
2
+ language_name: "Español"
2
3
  actor:
3
4
  name: "Nombre"
4
5
  action:
@@ -146,7 +147,7 @@ es:
146
147
  confirm: "¿Borrar %{element}}?"
147
148
  devise:
148
149
  links:
149
- sign_in: "Ingresar"
150
+ sign_in: "Entrar"
150
151
  sign_up: "Registrarse"
151
152
  forgot_password: "¿Olvidaste tu contraseña?"
152
153
  confirmation_instructions: "¿No recibiste instrucciones de confirmación?"
@@ -300,8 +301,8 @@ es:
300
301
  one: "Notificación"
301
302
  other: "Notificaciones"
302
303
  post:
303
- group: "%{sender} añadió %{thing} en el muro %{whose}."
304
- user: "%{sender} añadió %{thing} en tu muro."
304
+ group: "%{title} -- por %{sender} en el muro %{whose}"
305
+ user: "%{title} -- por %{sender} en tu muro"
305
306
  read: "Marcar como leída"
306
307
  read_all: "Marcar todas como leídas"
307
308
  unread: "Marcar como no leídas"
data/config/routes.rb CHANGED
@@ -85,6 +85,7 @@ Rails.application.routes.draw do
85
85
  match 'search' => 'search#index', :as => :search
86
86
 
87
87
  match 'cheesecake' => 'cheesecake#index', :as => :cheesecake
88
+ match 'update_cheesecake' => 'cheesecake#update', :as => :update_cheesecake
88
89
 
89
90
  match 'ties' => 'ties#index', :as => :ties
90
91
 
@@ -0,0 +1,74 @@
1
+ class ActivityChannels < ActiveRecord::Migration
2
+ class ActivityMigration < ActiveRecord::Base
3
+ self.record_timestamps = false
4
+ set_table_name "activities"
5
+ end
6
+
7
+ def up
8
+ change_table :activities do |t|
9
+ t.integer :channel_id
10
+ end
11
+
12
+ add_index "activities", "channel_id"
13
+
14
+ add_foreign_key "activities", "channels", :name => "index_activities_on_channel_id"
15
+
16
+ ActivityMigration.reset_column_information
17
+
18
+ ActivityMigration.all.each do |a|
19
+ activity = Activity.find(a.id)
20
+
21
+ case activity.verb
22
+
23
+ when "post", "update"
24
+ a.channel_id = activity.direct_object.channel_id
25
+ else
26
+ contact = Contact.find activity.contact_id
27
+
28
+ author_id = contact.sender_id
29
+ owner_id = contact.receiver_id
30
+
31
+ user_author_id =
32
+ (contact.sender_subject.is_a?(User) ?
33
+ contact.sender :
34
+ contact.sender.sent_ties.order(:created_at).first.receiver).id
35
+
36
+ a.channel_id =
37
+ Channel.find_or_create_by_author_id_and_user_author_id_and_owner_id(author_id,
38
+ user_author_id,
39
+ owner_id).id
40
+ end
41
+
42
+ a.save!
43
+ end
44
+
45
+ remove_foreign_key "activities", :name => "index_activities_on_contact_id"
46
+
47
+ remove_column :activities, :contact_id
48
+
49
+ Activity.reset_column_information
50
+ end
51
+
52
+ def down
53
+ change_table :activities do |t|
54
+ t.integer :contact_id
55
+ end
56
+
57
+ add_index "activities", "contact_id"
58
+
59
+ add_foreign_key "activities", "contacts", :name => "index_activities_on_contact_id"
60
+
61
+ ActivityMigration.reset_column_information
62
+
63
+ ActivityMigration.all.each do |a|
64
+ channel = Channel.find a.channel_id
65
+ a.contact_id = Contact.find_by_sender_id_and_receiver_id(channel.author_id, channel.owner_id)
66
+
67
+ a.save!
68
+ end
69
+
70
+ remove_foreign_key "activities", :name => "index_activities_on_channel_id"
71
+
72
+ remove_column :activities, :channel_id
73
+ end
74
+ end
@@ -18,6 +18,7 @@ module SocialStream
18
18
  end
19
19
 
20
20
  module Models
21
+ autoload :Channeled, 'social_stream/models/channeled'
21
22
  autoload :Object, 'social_stream/models/object'
22
23
  autoload :Subject, 'social_stream/models/subject'
23
24
  autoload :Subtype, 'social_stream/models/subtype'
@@ -18,8 +18,9 @@ module SocialStream
18
18
  Mime::Type.register 'application/xrd+xml', :xrd
19
19
  end
20
20
 
21
- initializer "social_stream-base.model.supertype" do
21
+ initializer "social_stream-base.model.supertypes" do
22
22
  ActiveSupport.on_load(:active_record) do
23
+ include SocialStream::Models::Channeled::ActiveRecord
23
24
  include SocialStream::Models::Subtype::ActiveRecord
24
25
  include SocialStream::Models::Supertype::ActiveRecord
25
26
  end
@@ -1,5 +1,5 @@
1
1
  module SocialStream
2
2
  module Base
3
- VERSION = "0.12.1".freeze
3
+ VERSION = "0.13.0".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,50 @@
1
+ module SocialStream
2
+ module Models
3
+ # Models that have author, user_author and owner, properties saved in {Channel}.
4
+ # Currently {Activity} and {ActivityObject}
5
+ module Channeled
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ # Channeled models are subtypes of {Channel}
10
+ # Author, owner and user_author are defined in its channel
11
+ subtype_of :channel,
12
+ :belongs => { :dependent => nil }
13
+
14
+ before_validation :check_existing_channel
15
+ end
16
+
17
+ module InstanceMethods
18
+
19
+ protected
20
+
21
+ # Use existing channel, do not create a new one
22
+ def check_existing_channel
23
+ return unless channel!.new_record?
24
+
25
+ existing_channel =
26
+ Channel.
27
+ where(:author_id => author_id,
28
+ :owner_id => owner_id,
29
+ :user_author_id => user_author_id).
30
+ first
31
+
32
+ return if existing_channel.blank?
33
+
34
+ self.channel = existing_channel
35
+ end
36
+ end
37
+
38
+ module ActiveRecord
39
+ extend ActiveSupport::Concern
40
+
41
+ module ClassMethods
42
+ # This class is channeled. See {Channel}
43
+ def channeled
44
+ include SocialStream::Models::Channeled
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -16,8 +16,6 @@ module SocialStream
16
16
  has_one :channel, :through => :activity_object
17
17
  has_many :activity_object_activities, :through => :activity_object
18
18
 
19
- # before_create :create_activity_object_with_type
20
-
21
19
  unless self == Actor
22
20
  validates_presence_of :author_id, :owner_id, :user_author_id
23
21
 
@@ -48,19 +46,12 @@ module SocialStream
48
46
 
49
47
  # Build the post activity when this object is not saved
50
48
  def build_post_activity
51
- Activity.new :contact_id => _contact_id,
49
+ Activity.new :author => author,
50
+ :user_author => user_author,
51
+ :owner => owner,
52
52
  :relation_ids => Array(_relation_ids)
53
53
  end
54
54
 
55
- # before_create callback
56
- #
57
- # Build corresponding ActivityObject including this class type
58
- def create_activity_object_with_type #:nodoc:
59
- o = create_activity_object! :object_type => self.class.to_s
60
- # WEIRD: Rails 3.1.0.rc3 does not assign activity_object_id
61
- self.activity_object_id = o.id
62
- end
63
-
64
55
  def _contact
65
56
  @_contact ||= author && owner && author.contact_to!(owner)
66
57
  end
@@ -105,7 +96,7 @@ module SocialStream
105
96
 
106
97
  def create_activity(verb)
107
98
  a = Activity.new :verb => verb,
108
- :contact => _contact,
99
+ :channel => channel,
109
100
  :relation_ids => _relation_ids,
110
101
  :parent_id => _activity_parent_id
111
102