Commit 52abfab277ff3b502924691bf791da5deec3a4b9

Authored by Rodrigo Souto
2 parents 21b5bb7f 06611e5d

Merge branch 'stoa' of gitlab.com:colivre/noosfero into stoa

app/controllers/my_profile/friends_controller.rb
... ... @@ -3,7 +3,7 @@ class FriendsController < MyProfileController
3 3 protect 'manage_friends', :profile
4 4  
5 5 def index
6   - @suggestions = profile.suggested_people.limit(per_page/2)
  6 + @suggestions = profile.profile_suggestions.of_person.enabled.includes(:suggestion).limit(per_page)
7 7 if is_cache_expired?(profile.manage_friends_cache_key(params))
8 8 @friends = profile.friends.paginate(:per_page => per_page, :page => params[:npage])
9 9 end
... ... @@ -18,17 +18,16 @@ class FriendsController < MyProfileController
18 18 end
19 19  
20 20 def suggest
21   - @suggestions = profile.suggested_people.paginate(:per_page => per_page, :page => params[:npage])
  21 + @suggestions = profile.profile_suggestions.of_person.enabled.includes(:suggestion).limit(per_page)
22 22 end
23 23  
24 24 def remove_suggestion
25 25 @person = profile.suggested_people.find_by_identifier(params[:id])
26 26 redirect_to :action => 'suggest' unless @person
27 27 if @person && request.post?
28   - suggestion = profile.profile_suggestions.find_by_suggestion_id @person.id
29   - suggestion.disable
30   - session[:notice] = _('Suggestion removed')
31   - redirect_to :action => 'suggest'
  28 + profile.remove_suggestion(@person)
  29 + @suggestions = profile.profile_suggestions.of_person.enabled.includes(:suggestion).limit(per_page)
  30 + render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :friends_suggestions }
32 31 end
33 32 end
34 33  
... ...
app/controllers/my_profile/memberships_controller.rb
... ... @@ -40,17 +40,23 @@ class MembershipsController < MyProfileController
40 40 end
41 41  
42 42 def suggest
43   - @suggestions = profile.suggested_communities.paginate(:per_page => 8, :page => params[:npage])
  43 + @suggestions = profile.profile_suggestions.of_community.enabled.includes(:suggestion).limit(per_page)
44 44 end
45 45  
46 46 def remove_suggestion
47 47 @community = profile.suggested_communities.find_by_identifier(params[:id])
48 48 redirect_to :action => 'suggest' unless @community
49 49 if @community && request.post?
50   - suggestion = profile.profile_suggestions.find_by_suggestion_id @community.id
51   - suggestion.disable
52   - redirect_to :action => 'suggest'
  50 + profile.remove_suggestion(@community)
  51 + @suggestions = profile.profile_suggestions.of_community.enabled.includes(:suggestion).limit(per_page)
  52 + render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :communities_suggestions }
53 53 end
54 54 end
55 55  
  56 + protected
  57 +
  58 + def per_page
  59 + 10
  60 + end
  61 +
56 62 end
... ...
app/helpers/application_helper.rb
... ... @@ -1419,4 +1419,9 @@ module ApplicationHelper
1419 1419 text_field_tag name, default, options.merge({:id => 'search-input', 'data-asset' => asset})
1420 1420 end
1421 1421  
  1422 + def profile_suggestion_categories(suggestion)
  1423 + suggestion.categories.map do |cat|
  1424 + content_tag(:p, content_tag(:span, "#{suggestion.category_label(cat[0])}: #{cat[1]}", :class => suggestion.category_icon(cat[0])))
  1425 + end.join
  1426 + end
1422 1427 end
... ...
app/mailers/user_mailer.rb
... ... @@ -54,7 +54,7 @@ class UserMailer < ActionMailer::Base
54 54 content_type: 'text/html',
55 55 to: user.email,
56 56 from: "#{user.environment.name} <#{user.environment.contact_email}>",
57   - subject: _("[%s] We have suggestions for your network") % user.environment.name
  57 + subject: _("[%s] What about grow up your network?") % user.environment.name
58 58 )
59 59 end
60 60  
... ...
app/models/article.rb
... ... @@ -507,7 +507,10 @@ class Article &lt; ActiveRecord::Base
507 507 end
508 508  
509 509 alias :allow_delete? :allow_post_content?
510   - alias :allow_spread? :allow_post_content?
  510 +
  511 + def allow_spread?(user = nil)
  512 + user && public?
  513 + end
511 514  
512 515 def allow_create?(user)
513 516 allow_post_content?(user) || allow_publish_content?(user)
... ...
app/models/person.rb
... ... @@ -66,7 +66,7 @@ class Person &lt; Profile
66 66 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people'
67 67 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions'
68 68  
69   - has_many :profile_suggestions, :foreign_key => :person_id, :dependent => :destroy
  69 + has_many :profile_suggestions, :foreign_key => :person_id, :order => 'id ASC', :dependent => :destroy
70 70 has_many :suggested_people, :through => :profile_suggestions, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Person', true]
71 71 has_many :suggested_communities, :through => :profile_suggestions, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Community', true]
72 72  
... ... @@ -498,6 +498,11 @@ class Person &lt; Profile
498 498 person.notifier.reschedule_next_notification_mail
499 499 end
500 500  
  501 + def remove_suggestion(profile)
  502 + suggestion = profile_suggestions.find_by_suggestion_id profile.id
  503 + suggestion.disable if suggestion
  504 + end
  505 +
501 506 protected
502 507  
503 508 def followed_by?(profile)
... ...
app/models/profile_suggestion.rb
... ... @@ -2,7 +2,7 @@ class ProfileSuggestion &lt; ActiveRecord::Base
2 2 belongs_to :person
3 3 belongs_to :suggestion, :class_name => 'Profile', :foreign_key => :suggestion_id
4 4  
5   - attr_accessible :person, :suggestion, :suggestion_type, :categories, :similarity, :enabled
  5 + attr_accessible :person, :suggestion, :suggestion_type, :categories, :enabled
6 6  
7 7 before_create do |profile_suggestion|
8 8 profile_suggestion.suggestion_type = self.suggestion.class.to_s
... ... @@ -18,11 +18,15 @@ class ProfileSuggestion &lt; ActiveRecord::Base
18 18 end
19 19  
20 20 validates_uniqueness_of :suggestion_id, :scope => [ :person_id ]
  21 + scope :of_person, :conditions => { :suggestion_type => 'Person' }
  22 + scope :of_community, :conditions => { :suggestion_type => 'Community' }
  23 + scope :enabled, :conditions => { :enabled => true }
21 24  
  25 + # {:category_type => ['category-icon', 'category-label']}
22 26 CATEGORIES = {
23   - :common_friends => _('Friends in common'),
24   - :common_communities => _('Communities in common'),
25   - :common_tags => _('Tags in common')
  27 + :common_friends => ['menu-people', _('Friends in common')],
  28 + :common_communities => ['menu-community',_('Communities in common')],
  29 + :common_tags => ['edit', _('Tags in common')]
26 30 }
27 31  
28 32 CATEGORIES.keys.each do |category|
... ... @@ -30,6 +34,14 @@ class ProfileSuggestion &lt; ActiveRecord::Base
30 34 attr_accessible category.to_sym
31 35 end
32 36  
  37 + def category_icon(category)
  38 + 'icon-' + ProfileSuggestion::CATEGORIES[category][0]
  39 + end
  40 +
  41 + def category_label(category)
  42 + ProfileSuggestion::CATEGORIES[category][1]
  43 + end
  44 +
33 45 RULES = %w[
34 46 people_with_common_friends
35 47 people_with_common_communities
... ...
app/views/content_viewer/_article_toolbar.html.erb
... ... @@ -15,7 +15,7 @@
15 15 <%= expirable_button @page, :delete, content, url, options %>
16 16 <% end %>
17 17  
18   - <% if !@page.folder? && @page.public? && !remove_content_button(:spread) %>
  18 + <% if !@page.folder? && @page.allow_spread?(user) && !remove_content_button(:spread) %>
19 19 <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'publish', :id => @page.id }) %>
20 20 <%= expirable_button @page, :spread, content_tag( 'span', _('Spread this') ), url, {:class => 'colorbox'} if url %>
21 21 <% end %>
... ...
app/views/content_viewer/view_page.html.erb
... ... @@ -42,7 +42,6 @@
42 42  
43 43 <%= render :partial => 'shared/disabled_enterprise' %>
44 44  
45   -<%= @plugins.dispatch(:social_buttons_javascript, @page).collect { |content| instance_exec(&content) }.join("") %>
46 45 <% if NOOSFERO_CONF['addthis_enabled'] %>
47 46 <%= render :partial => 'addthis' %>
48 47 <% end %>
... ... @@ -71,6 +70,8 @@
71 70  
72 71 <%= display_source_info(@page) %>
73 72  
  73 +<%= @plugins.dispatch(:social_buttons_contents).collect { |content| instance_exec(&content) }.join("") %>
  74 +
74 75 <%= @plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %>
75 76  
76 77 <div class="comments" id="comments_list">
... ...
app/views/friends/_profile_list.html.erb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +<ul class="profile-list">
  2 + <% profiles.each do |profile| %>
  3 + <li>
  4 + <%= link_to_profile profile_image(profile) + '<br/>' + profile.short_name,
  5 + profile.identifier, :class => 'profile-link' %>
  6 + <div class="controll">
  7 + <%= button_without_text :remove, content_tag('span',_('remove')),
  8 + { :action => 'remove', :id => profile.id },
  9 + :title => _('remove') %>
  10 + <%= button_without_text 'menu-mail', content_tag('span',_('contact')),
  11 + profile.url.merge(:controller => 'contact', :action => 'new', :profile => profile.identifier),
  12 + :title => _('contact') %>
  13 + </div><!-- end class="controll" -->
  14 + </li>
  15 + <% end %>
  16 +</ul>
... ...
app/views/friends/index.html.erb
... ... @@ -20,22 +20,18 @@
20 20 <% end %>
21 21 <% end %>
22 22  
23   - <%= render :partial => 'shared/profile_list', :locals => { :profiles => @friends, :collection => :friends } %>
24   - <div id='pagination-friends'>
25   - <%= pagination_links @friends, :param_name => 'npage' %>
26   - </div>
  23 + <%= render :partial => 'profile_list', :locals => { :profiles => @friends } %>
27 24  
  25 + <br style="clear:both" />
  26 + <%= pagination_links @friends, :param_name => 'npage' %>
28 27 <% end %>
29 28  
30 29 <% unless @suggestions.empty? %>
31 30 <br style="clear:both" />
32 31 <h2><%= _("Friends suggestions") %></h2>
33   -
34   - <%= render :partial => 'shared/profile_list', :locals => { :profiles => @suggestions, :collection => :friends_suggestions } %>
35   -
36   - <% button_bar do %>
37   - <%= link_to _('See more suggestions...'), :action => 'suggest' %>
38   - <% end %>
  32 + <div class="profiles-suggestions">
  33 + <%= render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :friends_suggestions } %>
  34 + </div>
39 35 <% end %>
40 36  
41 37 </div><!-- end id="manage_friends" -->
... ...
app/views/friends/suggest.html.erb
1   -<div class='profiles-suggestions'>
2   - <h1><%= _("Friends suggestions for %s") % profile.name %></h1>
  1 +<h1><%= _("Friends suggestions for %s") % profile.name %></h1>
3 2  
4   - <% button_bar do %>
5   - <%= button(:back, _('Go to friends list'), :controller => 'friends') %>
6   - <% end %>
  3 +<% button_bar do %>
  4 + <%= button(:back, _('Go to friends list'), :controller => 'friends') %>
  5 +<% end %>
7 6  
8   - <% if @suggestions.empty? %>
9   - <p>
10   - <em>
11   - <%= _('You have no suggestions yet.') %>
12   - <%= link_to _('Do you want to see other people in this environment?'), :controller => 'search', :action => 'assets', :asset => 'people' %>
13   - </em>
14   - </p>
15   - <% else %>
16   - <%= render :partial => 'shared/profile_list', :locals => { :profiles => @suggestions, :collection => :friends_suggestions } %>
17   -
18   - <%= pagination_links @suggestions, :param_name => 'npage' %>
19   - <% end %>
20   - <br style="clear:both" />
  7 +<div class="profiles-suggestions">
  8 + <%= render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :friends_suggestions } %>
21 9 </div>
... ...
app/views/memberships/suggest.html.erb
1   -<div class='profiles-suggestions'>
2   - <h1><%= _("Communities suggestions for %s") % profile.name %></h1>
  1 +<h1><%= _("Communities suggestions for %s") % profile.name %></h1>
3 2  
4   - <% button_bar do %>
5   - <%= button(:back, _('Go to groups list'), :controller => 'memberships') %>
6   - <% end %>
  3 +<% button_bar do %>
  4 + <%= button(:back, _('Go to groups list'), :controller => 'memberships') %>
  5 +<% end %>
7 6  
8   - <% if @suggestions.empty? %>
9   - <p>
10   - <em>
11   - <%= _('You have no suggestions yet.') %>
12   - <%= link_to _('Do you want to see communities in this environment?'), :controller => 'search', :action => 'assets', :asset => 'communities' %>
13   - </em>
14   - </p>
15   - <% else %>
16   - <%= render :partial => 'shared/profile_list', :locals => { :profiles => @suggestions, :collection => :communities_suggestions } %>
17   - <% end %>
18   -
19   - <%= pagination_links @suggestions, :param_name => 'npage' %>
20   - <br style="clear:both" />
  7 +<div class="profiles-suggestions">
  8 + <%= render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :friends_suggestions } %>
21 9 </div>
... ...
app/views/shared/_profile_list.html.erb
... ... @@ -1,38 +0,0 @@
1   -<ul class="profile-list">
2   - <% profiles.each do |profile| %>
3   - <li>
4   - <%= link_to_profile profile_image(profile) + '<br/>' + profile.short_name,
5   - profile.identifier, :class => 'profile-link' %>
6   - <div class="controll">
7   - <% if collection == :friends %>
8   - <%= button_without_text :remove, content_tag('span',_('remove')),
9   - { :action => 'remove', :id => profile.id },
10   - :title => _('remove') %>
11   - <%= button_without_text 'menu-mail', content_tag('span',_('contact')),
12   - profile.url.merge(:controller => 'contact', :action => 'new', :profile => profile.identifier),
13   - :title => _('contact') %>
14   - <% elsif collection == :friends_suggestions %>
15   - <%= button_without_text :add, content_tag('span',_('add')),
16   - profile.add_url,
17   - :class => 'add-friend',
18   - :title => _('Add friend') %>
19   - <%= button_without_text :remove, content_tag('span',_('remove')),
20   - { :action => 'remove_suggestion', :id => profile.identifier },
21   - :title => _('Remove suggestion'),
22   - :method => 'post',
23   - :confirm => _('Are you sure you want to remove this suggestion?') %>
24   - <% elsif collection == :communities_suggestions %>
25   - <%= button_without_text :add, content_tag('span',_('join')),
26   - profile.join_url,
27   - :class => 'join-community',
28   - :title => _("Join %s") % profile.name %>
29   - <%= button_without_text :remove, content_tag('span',_('remove')),
30   - { :action => 'remove_suggestion', :id => profile.identifier },
31   - :title => _('Remove suggestion'),
32   - :method => 'post',
33   - :confirm => _('Are you sure you want to remove this suggestion?') %>
34   - <% end %>
35   - </div><!-- end class="controll" -->
36   - </li>
37   - <% end %>
38   -</ul>
app/views/shared/_profile_suggestions_list.html.erb 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +<% if suggestions.empty? %>
  2 + <p>
  3 + <em>
  4 + <%= _('You have no more suggestions :(') %>
  5 + </em>
  6 + </p>
  7 +<% else %>
  8 + <ul class="profile-list">
  9 + <% suggestions.each do |s| %>
  10 + <li>
  11 + <%= link_to_profile profile_image(s.suggestion, :minor) + '<br/>' + s.suggestion.short_name,
  12 + s.suggestion.identifier, :class => 'profile-link' %>
  13 + <%= button_without_text :help, content_tag('span',_('info about suggestion')),
  14 + { :action => '#' },
  15 + :class => 'explain-suggestion',
  16 + :title => _('Why this suggestion?') %>
  17 + <div class='extra_info' style='display:none'>
  18 + <%= profile_suggestion_categories(s) %>
  19 + </div>
  20 + <div class="controll">
  21 + <% if collection == :friends_suggestions %>
  22 + <%= button_without_text :add, content_tag('span',_('add')),
  23 + s.suggestion.add_url,
  24 + :class => 'add-friend accept-suggestion',
  25 + :title => _('Add friend') %>
  26 + <%= button_without_text :remove, content_tag('span',_('remove')),
  27 + { :action => 'remove_suggestion', :id => s.suggestion.identifier },
  28 + :class => 'remove-suggestion',
  29 + :title => _('Remove suggestion'),
  30 + :confirm => _('Are you sure you want to remove this suggestion?') %>
  31 + <% elsif collection == :communities_suggestions %>
  32 + <%= button_without_text :add, content_tag('span',_('join')),
  33 + s.suggestion.join_url,
  34 + :class => 'join-community accept-suggestion',
  35 + :title => _("Join %s") % s.suggestion.name %>
  36 + <%= button_without_text :remove, content_tag('span',_('remove')),
  37 + { :action => 'remove_suggestion', :id => s.suggestion.identifier },
  38 + :class => 'remove-suggestion',
  39 + :title => _('Remove suggestion'),
  40 + :confirm => _('Are you sure you want to remove this suggestion?') %>
  41 + <% end %>
  42 + </div><!-- end class="controll" -->
  43 + </li>
  44 + <% end %>
  45 + </ul>
  46 +<% end %>
  47 +<br style="clear:both" />
... ...
app/views/user_mailer/profiles_suggestions_email.html.erb
1 1 <%= _('Hi, %{recipient}!') % { :recipient => @recipient } %>
2 2  
3   -<p><%= _('We want to give you some suggestions to grow up your network. Check it out!') %></p>
  3 +<p><%= _('We want to give you some suggestions to grow up your network.') %>
  4 +<p><%= _('Check it out!') %></p>
4 5  
5 6 <% unless @people_suggestions.empty? %>
6 7 <p><%= _('Friends suggestions:') %></p>
... ...
lib/noosfero/plugin.rb
... ... @@ -395,8 +395,8 @@ class Noosfero::Plugin
395 395 end
396 396  
397 397 # -> Adds social networks share buttons to content
398   - # returns = lambda block that creates html code
399   - def social_buttons_javascript(environment)
  398 + # returns = proc that creates html code
  399 + def social_buttons_contents
400 400 nil
401 401 end
402 402  
... ...
plugins/social_share_privacy/lib/ext/environment.rb
... ... @@ -1,8 +0,0 @@
1   -require_dependency 'environment'
2   -
3   -class Environment
4   -
5   - settings_items :socialshare, :type => Array, :default => []
6   -
7   -end
8   -
plugins/social_share_privacy/lib/social_share_privacy_plugin.rb
... ... @@ -21,9 +21,10 @@ class SocialSharePrivacyPlugin &lt; Noosfero::Plugin
21 21 settings = Noosfero::Plugin::Settings.new(environment, SocialSharePrivacyPlugin)
22 22 locale = FastGettext.locale
23 23 javascript_include_tag('plugins/social_share_privacy/socialshareprivacy/javascripts/socialshareprivacy.js') +
  24 + javascript_include_tag('plugins/social_share_privacy/socialshareprivacy/javascripts/localstorage.js') +
24 25 javascript_include_tag(settings.get_setting(:networks).map { |service| "plugins/social_share_privacy/socialshareprivacy/javascripts/modules/#{service}.js" }) +
25 26 (locale != 'en' ? javascript_include_tag("plugins/social_share_privacy/socialshareprivacy/javascripts/locale/jquery.socialshareprivacy.min.#{locale}.js") : '') +
26   - javascript_tag("jQuery.fn.socialSharePrivacy.settings.path_prefix = '../../plugins/social_share_privacy/socialshareprivacy/'; jQuery.fn.socialSharePrivacy.settings.order = #{settings.get_setting(:networks)}; jQuery(document).ready(function () { jQuery('.social-buttons').socialSharePrivacy({perma_option: false, info_link_target: '_blank'});});") +
  27 + javascript_tag("jQuery.fn.socialSharePrivacy.settings.path_prefix = '../../plugins/social_share_privacy/socialshareprivacy/'; jQuery.fn.socialSharePrivacy.settings.order = #{settings.get_setting(:networks)}; jQuery(document).ready(function () { jQuery('.social-buttons').socialSharePrivacy({info_link_target: '_blank'});});") +
27 28 content_tag(:div, '', :class => "social-buttons")
28 29 end
29 30 end
... ...
plugins/social_share_privacy/public/style.css
... ... @@ -7,4 +7,5 @@
7 7 .social-buttons {
8 8 display: inline-block;
9 9 width: 100%;
  10 + margin: 10px 0;
10 11 }
... ...
public/javascripts/add-and-join.js
... ... @@ -120,4 +120,23 @@ jQuery(function($) {
120 120 return false;
121 121 })
122 122  
  123 + $(".remove-suggestion").live('click', function(){
  124 + clicked = $(this)
  125 + url = clicked.attr("href");
  126 + loading_for_button(this);
  127 + $.post(url, function(data){
  128 + clicked.fadeOut();
  129 + clicked.parents('.profiles-suggestions').html(data);
  130 + });
  131 + return false;
  132 + })
  133 +
  134 + /* After adding a suggestion need to remove it from list */
  135 + $(".accept-suggestion").live('click', function(){
  136 + clicked = $(this)
  137 + loading_for_button(this);
  138 + clicked.parents('li').fadeOut();
  139 + return false;
  140 + })
  141 +
123 142 });
... ...
public/javascripts/application.js
... ... @@ -1053,6 +1053,13 @@ function showHideTermsOfUse() {
1053 1053 }
1054 1054 }
1055 1055  
  1056 +jQuery('.profiles-suggestions .explain-suggestion').live('click', function() {
  1057 + var clicked = jQuery(this);
  1058 + clicked.toggleClass('active');
  1059 + clicked.next('.extra_info').toggle();
  1060 + return false;
  1061 +});
  1062 +
1056 1063 jQuery(document).ready(function(){
1057 1064 showHideTermsOfUse();
1058 1065  
... ...
public/stylesheets/application.css
... ... @@ -2131,7 +2131,8 @@ a.button.disabled, input.disabled {
2131 2131 #content .common-profile-list-block .sex-male span, #content .common-profile-list-block .sex-female span, #content .common-profile-list-block .sex-undef span {
2132 2132 display: none;
2133 2133 }
2134   -.common-profile-list-block .extra_info {
  2134 +.common-profile-list-block .extra_info,
  2135 +.profile-list .extra_info {
2135 2136 font-size: 9px;
2136 2137 opacity: 0.5;
2137 2138 filter: alpha(opacity=50);
... ... @@ -3955,16 +3956,24 @@ h1#agenda-title {
3955 3956 .controller-friends .profile-list li,
3956 3957 .profiles-suggestions .profile-list li {
3957 3958 float: left;
3958   - width: 90px;
  3959 + margin: 5px;
3959 3960 height: 90px;
3960   - max-width: 80px;
3961 3961 max-height: 80px;
3962   - margin: 5px;
3963 3962 padding: 5px;
3964 3963 border: 2px solid transparent;
3965 3964 list-style: none;
3966 3965 position: relative;
3967 3966 }
  3967 +.controller-favorite_enterprises .profile-list li,
  3968 +.controller-friends .profile-list li {
  3969 + width: 90px;
  3970 + max-width: 80px;
  3971 +}
  3972 +.profiles-suggestions .profile-list li {
  3973 + width: 76px;
  3974 + max-width: 76px;
  3975 +}
  3976 +
3968 3977 .controller-favorite_enterprises .profile-list li:hover,
3969 3978 .controller-friends .profile-list li:hover,
3970 3979 .profiles-suggestions .profile-list li:hover {
... ... @@ -4000,12 +4009,22 @@ h1#agenda-title {
4000 4009 .profiles-suggestions .profile-list {
4001 4010 position: relative;
4002 4011 }
  4012 +.profiles-suggestions .profile-list .explain-suggestion {
  4013 + position: absolute;
  4014 + top: 7px;
  4015 + left: -5px;
  4016 + z-index: 10;
  4017 +}
  4018 +#content .profiles-suggestions .profile-list .explain-suggestion.active {
  4019 + border-bottom-color: transparent;
  4020 +}
  4021 +
4003 4022 .controller-favorite_enterprises .profile-list .controll,
4004 4023 .controller-friends .profile-list .controll,
4005 4024 .profiles-suggestions .profile-list .controll {
4006 4025 position: absolute;
4007 4026 top: 7px;
4008   - right: -10px;
  4027 + right: -5px;
4009 4028 }
4010 4029 .controller-favorite_enterprises .profile-list .controll a,
4011 4030 .controller-friends .profile-list .controll a,
... ... @@ -4024,6 +4043,31 @@ h1#agenda-title {
4024 4043 clear: both;
4025 4044 padding-top: 20px;
4026 4045 }
  4046 +
  4047 +.profiles-suggestions .profile-list .extra_info {
  4048 + background: url("/images/down-arrow.png") no-repeat scroll center top #eee;
  4049 + border: 1px solid #ccc;
  4050 + left: -66px;
  4051 + min-width: 135px;
  4052 + padding: 5px;
  4053 + position: absolute;
  4054 + top: 29px;
  4055 + opacity: 0.9;
  4056 + z-index: 5;
  4057 +}
  4058 +
  4059 +.profiles-suggestions .profile-list .extra_info p {
  4060 + margin: 0px;
  4061 +}
  4062 +
  4063 +.profiles-suggestions .profile-list .extra_info span {
  4064 + background-position: 4px 50%;
  4065 + background-repeat: no-repeat;
  4066 + display: block;
  4067 + line-height: 20px;
  4068 + padding: 0 0 0 25px;
  4069 +}
  4070 +
4027 4071 /* ==> public/stylesheets/controller_friends.css <== */
4028 4072  
4029 4073 .controller-friends #remove_friend .friend_picture,
... ...
test/functional/content_viewer_controller_test.rb
... ... @@ -1391,4 +1391,29 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1391 1391 assert_tag :tag => 'meta', :attributes => { :property => 'og:image', :content => /\/images\/x.png/ }
1392 1392 end
1393 1393  
  1394 + should 'add social content on content view page from plugins' do
  1395 + class Plugin1 < Noosfero::Plugin
  1396 + def social_buttons_contents
  1397 + proc {"<strong>Plugin1 text</strong>"}
  1398 + end
  1399 + end
  1400 + class Plugin2 < Noosfero::Plugin
  1401 + def social_buttons_contents
  1402 + proc {"<div class='social-buttons'></div>"}
  1403 + end
  1404 + end
  1405 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
  1406 +
  1407 + Environment.default.enable_plugin(Plugin1.name)
  1408 + Environment.default.enable_plugin(Plugin2.name)
  1409 +
  1410 + page = profile.articles.build(:name => 'test')
  1411 + page.save!
  1412 +
  1413 + get :view_page, :profile => profile.identifier, :page => ['test']
  1414 +
  1415 + assert_tag :tag => 'strong', :content => 'Plugin1 text'
  1416 + assert_tag :tag => 'div', :attributes => {:class => 'social-buttons'}
  1417 + end
  1418 +
1394 1419 end
... ...
test/unit/person_test.rb
... ... @@ -1544,6 +1544,28 @@ class PersonTest &lt; ActiveSupport::TestCase
1544 1544 assert_equal [suggested_community], person.suggested_communities
1545 1545 end
1546 1546  
  1547 + should 'disable friend suggestion' do
  1548 + person = create_user('person').person
  1549 + suggested_person = fast_create(Person)
  1550 +
  1551 + suggestion = ProfileSuggestion.create(:person => person, :suggestion => suggested_person)
  1552 +
  1553 + assert_difference 'person.suggested_people.count', -1 do
  1554 + person.remove_suggestion(suggested_person)
  1555 + end
  1556 + end
  1557 +
  1558 + should 'disable community suggestion' do
  1559 + person = create_user('person').person
  1560 + suggested_community = fast_create(Community)
  1561 +
  1562 + suggestion = ProfileSuggestion.create(:person => person, :suggestion => suggested_community)
  1563 +
  1564 + assert_difference 'person.suggested_communities.count', -1 do
  1565 + person.remove_suggestion(suggested_community)
  1566 + end
  1567 + end
  1568 +
1547 1569 should 'return url to people suggestions for a person' do
1548 1570 environment = create_environment('mycolivre.net')
1549 1571 profile = build(Person, :identifier => 'testprofile', :environment_id => create_environment('mycolivre.net').id)
... ...