diff --git a/app/controllers/my_profile/followers_controller.rb b/app/controllers/my_profile/followers_controller.rb new file mode 100644 index 0000000..1be40ae --- /dev/null +++ b/app/controllers/my_profile/followers_controller.rb @@ -0,0 +1,16 @@ +class FollowersController < MyProfileController + + def index + @followed_people = current_person.following_profiles.paginate(:per_page => 5, :page => params[:npage]) + end + + def set_category + if request.method == "GET" + render :partial => "set_category_modal", :locals => { :followed_profile_id => params[:followed_profile_id] } + elsif request.method == "POST" + follower = ProfileFollower.find_by(follower_id: current_person.id, profile_id: params[:followed_profile_id]) + follower.update_attributes(:group => params[:category_name]) if follower + redirect_to url_for(:controller => "followers", :action => "index") + end + end +end diff --git a/app/controllers/public/profile_controller.rb b/app/controllers/public/profile_controller.rb index cccc352..50e8a1c 100644 --- a/app/controllers/public/profile_controller.rb +++ b/app/controllers/public/profile_controller.rb @@ -3,7 +3,7 @@ class ProfileController < PublicController needs_profile before_filter :check_access_to_profile, :except => [:join, :join_not_logged, :index, :add] before_filter :store_location, :only => [:join, :join_not_logged, :report_abuse, :send_mail] - before_filter :login_required, :only => [:add, :join, :leave, :unblock, :leave_scrap, :remove_scrap, :remove_activity, :view_more_activities, :view_more_network_activities, :report_abuse, :register_report, :leave_comment_on_activity, :send_mail] + before_filter :login_required, :only => [:add, :join, :leave, :unblock, :leave_scrap, :remove_scrap, :remove_activity, :view_more_activities, :view_more_network_activities, :report_abuse, :register_report, :leave_comment_on_activity, :send_mail, :follow, :unfollow] helper TagsHelper helper ActionTrackerHelper @@ -65,6 +65,10 @@ class ProfileController < PublicController end end + def following + @followed_people = [].paginate(:per_page => per_page, :page => params[:npage], :total_entries => profile.friends.count) + end + def members if is_cache_expired?(profile.members_cache_key(params)) sort = (params[:sort] == 'desc') ? params[:sort] : 'asc' @@ -151,6 +155,22 @@ class ProfileController < PublicController end end + def follow + if !current_person.follows?(profile) + group = params['follow'] ? params['follow']['category'] : '' + current_person.follow(profile, group) + end + redirect_to profile.url + end + + def unfollow + if current_person.follows?(profile) + current_person.unfollow(profile) + end + redirect_url = params["redirect_to"] ? params["redirect_to"] : profile.url + redirect_to redirect_url + end + def check_friendship unless logged_in? render :text => '' diff --git a/app/models/person.rb b/app/models/person.rb index 8a6d98e..255bc7b 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -200,7 +200,7 @@ class Person < Profile end end - def follow(profile, group = nil) + def follow(profile, group = "") unless self.following_profiles.include?(profile) profile_follower = ProfileFollower.new profile_follower.profile = profile @@ -601,7 +601,7 @@ class Person < Profile protected def followed_by?(profile) - self == profile || self.is_a_friend?(profile) || self.followers.include(profile) + self == profile || self.followers.include?(profile) end end diff --git a/app/models/profile.rb b/app/models/profile.rb index 499291c..2e11755 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -204,7 +204,7 @@ class Profile < ApplicationRecord scope :more_recent, -> { order "created_at DESC" } scope :following_profiles, -> person { - distinct.select('profiles.*'). + distinct.select('profiles.*, profile_followers.group'). joins('join profile_followers ON profile_followers.profile_id = profiles.id'). where('profile_followers.follower_id = ?', person.id) } diff --git a/app/models/profile_follower.rb b/app/models/profile_follower.rb index d389bdd..c91e769 100644 --- a/app/models/profile_follower.rb +++ b/app/models/profile_follower.rb @@ -1,5 +1,6 @@ class ProfileFollower < ApplicationRecord track_actions :new_follower, :after_create, :keep_params => ["follower.name", "follower.url", "follower.profile_custom_icon"], :custom_user => :profile + attr_accessible :group belongs_to :profile, :foreign_key => :profile_id belongs_to :follower, :class_name => 'Person', :foreign_key => :follower_id diff --git a/app/views/blocks/profile_info_actions/_person.html.erb b/app/views/blocks/profile_info_actions/_person.html.erb index c655b4e..b523369 100644 --- a/app/views/blocks/profile_info_actions/_person.html.erb +++ b/app/views/blocks/profile_info_actions/_person.html.erb @@ -7,6 +7,20 @@ <% end %> +
  • + <% if user.follows?(profile) %> + <%= button(:unfollow, content_tag('span', _('Unfollow')), {:profile => profile.identifier, :controller => 'profile', :action => 'unfollow'}) %> + <% else %> +
    + + <%= submit_button('follow', _('Follow')) %> +
    + <% end %> +
  • + + <% if user.is_a_friend?(profile) && profile.enable_contact? %>
  • <%= button(:back, _('Send an e-mail'), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}) %>
  • <% end %> diff --git a/app/views/followers/_profile_list.html.erb b/app/views/followers/_profile_list.html.erb new file mode 100644 index 0000000..5143323 --- /dev/null +++ b/app/views/followers/_profile_list.html.erb @@ -0,0 +1,18 @@ + diff --git a/app/views/followers/_set_category_modal.html.erb b/app/views/followers/_set_category_modal.html.erb new file mode 100644 index 0000000..b63507f --- /dev/null +++ b/app/views/followers/_set_category_modal.html.erb @@ -0,0 +1,13 @@ +
    +

    <%= _("Choose a new category") %>

    + <%= form_for :follower_category, :url => url_for(:controller => 'followers', :action => 'set_category') do |f| %> +
    + <%= labelled_text_field _("Category: "), "category_name" %> +
    + <%= hidden_field_tag 'followed_profile_id', followed_profile_id %> +
    + <%= submit_button('save', _('Save')) %> + <%= modal_close_button _("Cancel") %> +
    + <% end %> +
    diff --git a/app/views/followers/index.html.erb b/app/views/followers/index.html.erb new file mode 100644 index 0000000..c496b67 --- /dev/null +++ b/app/views/followers/index.html.erb @@ -0,0 +1,25 @@ +
    + +

    <%= _("%s following") % profile.name %>

    + +<% cache_timeout(profile.manage_friends_cache_key(params), 4.hours) do %> + <% if @followed_people.empty? %> +

    + + <%= _("You don't follow anybody yet.") %> + +

    + <% end %> + + <%= button_bar do %> + <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> + <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %> + <% end %> + + <%= render :partial => 'profile_list', :locals => { :profiles => @followed_people } %> + +
    + <%= pagination_links @followed_people, :param_name => 'npage' %> +<% end %> + +
    diff --git a/app/views/profile/following.html.erb b/app/views/profile/following.html.erb new file mode 100644 index 0000000..3492e78 --- /dev/null +++ b/app/views/profile/following.html.erb @@ -0,0 +1,24 @@ +
    + +

    <%= _("%s is following") % profile.name %>

    + +<% cache_timeout(profile.friends_cache_key(params), 4.hours) do %> + + +
    + <%= pagination_links @followed_people, :param_name => 'npage' %> +
    +<% end %> + +<%= button_bar do %> + <%= button :back, _('Go back'), { :controller => 'profile' } %> + <% if user == profile %> + <%= button :edit, _('Manage followed people'), :controller => 'friends', :action => 'index', :profile => profile.identifier %> + <% end %> +<% end %> + +
    diff --git a/app/views/profile_editor/edit.html.erb b/app/views/profile_editor/edit.html.erb index 2bc3c45..f6e4d0e 100644 --- a/app/views/profile_editor/edit.html.erb +++ b/app/views/profile_editor/edit.html.erb @@ -26,6 +26,11 @@ <% if profile.person? %>
    + + <%= labelled_check_box _("Allow other users to follow me"), 'profile_data[can_be_followed]', true, profile.secret, :class => "person-can-be-followed" %> +
    +
    +
    <%= labelled_radio_button _('Public — show my contents to all internet users').html_safe, 'profile_data[public_profile]', true, @profile.public_profile? %>
    diff --git a/app/views/profile_editor/index.html.erb b/app/views/profile_editor/index.html.erb index 9c99687..4874b04 100644 --- a/app/views/profile_editor/index.html.erb +++ b/app/views/profile_editor/index.html.erb @@ -72,6 +72,8 @@ <%= control_panel_button(_('Email Templates'), 'email-templates', :controller => :profile_email_templates) if profile.organization? %> + <%= control_panel_button(_('Manage followed people'), 'manage-followed-people', :controller => :followers) %> + <% @plugins.dispatch(:control_panel_buttons).each do |button| %> <%= control_panel_button(button[:title], button[:icon], button[:url], button[:html_options]) %> <% end %> diff --git a/public/javascripts/application.js b/public/javascripts/application.js index fff7e9b..25d00c6 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -26,6 +26,7 @@ *= require pagination.js * views speficics *= require add-and-join.js +*= require followers.js *= require report-abuse.js *= require autogrow.js *= require require_login.js diff --git a/public/javascripts/followers.js b/public/javascripts/followers.js new file mode 100644 index 0000000..d7fcece --- /dev/null +++ b/public/javascripts/followers.js @@ -0,0 +1,5 @@ +$("#follower-container").live("mouseenter", function() { + $("#category-form").fadeIn(); +}).live("mouseleave", function() { + $("#category-form").fadeOut(); +}); diff --git a/public/stylesheets/blocks/profile-info.scss b/public/stylesheets/blocks/profile-info.scss index 80fd7f0..b1d8611 100644 --- a/public/stylesheets/blocks/profile-info.scss +++ b/public/stylesheets/blocks/profile-info.scss @@ -99,3 +99,16 @@ margin: 0px 0px 5px 0px; padding: 2px; } +#follower-container:hover { + background-color: #eee; + -o-transition:.5s; + -ms-transition:.5s; + -moz-transition:.5s; + -webkit-transition:.5s; + transition:.5s; + padding-top: 5px; + padding-bottom: 5px; +} +#follower-container #category-form { + margin-bottom: 5px; +} diff --git a/public/stylesheets/profile-list.scss b/public/stylesheets/profile-list.scss index cbd9bc1..3458bb9 100644 --- a/public/stylesheets/profile-list.scss +++ b/public/stylesheets/profile-list.scss @@ -23,6 +23,7 @@ } .controller-favorite_enterprises .profile-list a.profile-link, .controller-friends .profile-list a.profile-link, +.controller-followers .profile-list a.profile-link, .list-profile-connections .profile-list a.profile-link, .profiles-suggestions .profile-list a.profile-link { text-decoration: none; @@ -32,11 +33,13 @@ } .controller-favorite_enterprises .profile-list a.profile-link:hover, .controller-friends .profile-list a.profile-link:hover, +.controller-followers .profile-list a.profile-link:hover, .profiles-suggestions .profile-list a.profile-link:hover { color: #FFF; } .controller-favorite_enterprises .profile-list .profile_link span, .controller-friends .profile-list .profile_link span, +.controller-followers .profile-list .profile_link span, .box-1 .profiles-suggestions .profile-list .profile_link span { width: 80px; display: block; @@ -44,12 +47,14 @@ } .controller-favorite_enterprises .profile-list, .controller-friends .profile-list, +.controller-followers .profile-list, .profiles-suggestions .profile-list { position: relative; } .controller-favorite_enterprises .profile-list .controll, .controller-friends .profile-list .controll, +.controller-followers .profile-list .controll, .profiles-suggestions .profile-list .controll { position: absolute; top: 7px; @@ -57,17 +62,20 @@ } .controller-favorite_enterprises .profile-list .controll a, .controller-friends .profile-list .controll a, +.controller-followers .profile-list .controll a, .profiles-suggestions .profile-list .controll a { display: block; margin-bottom: 2px; } .controller-favorite_enterprises .msie6 .profile-list .controll a, .controller-friends .msie6 .profile-list .controll a, +.controller-folloed_people .msie6 .profile-list .controll a, .profiles-suggestions .msie6 .profile-list .controll a { width: 0px; } .controller-favorite_enterprises .button-bar, .controller-friends .button-bar, +.controller-followers .button-bar, .profiles-suggestions .button-bar { clear: both; padding-top: 20px; @@ -208,22 +216,35 @@ font-size: 12px; } .action-profile-members .profile_link{ - position: relative; + position: relative; } .action-profile-members .profile_link span.new-profile:last-child{ - position: absolute; - top: 3px; - right: 2px; - text-transform: uppercase; - color: #FFF; - font-size: 9px; - background: #66CC33; - padding: 2px; - display: block; - width: 35px; - font-weight: 700; + position: absolute; + top: 3px; + right: 2px; + text-transform: uppercase; + color: #FFF; + font-size: 9px; + background: #66CC33; + padding: 2px; + display: block; + width: 35px; + font-weight: 700; } .action-profile-members .profile_link .fn{ - font-style: normal; - color: #000; + font-style: normal; + color: #000; +} +.category-name { + margin-top: 0px; + margin-bottom: 0px; + font-style: italic; + color: #888a85; + text-align: center; +} +.set-category-modal { + width: 250px; +} +.set-category-modal #actions-container { + margin-top: 20px } diff --git a/test/functional/followers_controller_test.rb b/test/functional/followers_controller_test.rb new file mode 100644 index 0000000..30f9076 --- /dev/null +++ b/test/functional/followers_controller_test.rb @@ -0,0 +1,48 @@ +require_relative "../test_helper" +require 'followers_controller' + +class FollowersControllerTest < ActionController::TestCase + def setup + @profile = create_user('testuser').person + end + + should 'return followed people list' do + login_as(@profile.identifier) + person = fast_create(Person) + fast_create(ProfileFollower, :profile_id => person.id, :follower_id => @profile.id) + + get :index, :profile => @profile.identifier + assert_includes assigns(:followed_people), person + end + + should 'redirect to login page if not logged in' do + person = fast_create(Person) + get :index, :profile => @profile.identifier + assert_redirected_to :controller => 'account', :action => 'login' + end + + should 'render set category modal' do + login_as(@profile.identifier) + get :set_category, :profile => @profile.identifier, :followed_profile_id => 3 + assert_tag :tag => "input", :attributes => { :id => "followed_profile_id", :value => 3 } + end + + should 'update followed person category' do + login_as(@profile.identifier) + person = fast_create(Person) + fast_create(ProfileFollower, :profile_id => person.id, :follower_id => @profile.id) + + post :set_category, :profile => @profile.identifier, :category_name => "category test", :followed_profile_id => person.id + follower = ProfileFollower.find_by(:profile_id => person.id, :follower_id => @profile.id) + assert_equal follower.group, "category test" + end + + should 'not update category of not followed person' do + login_as(@profile.identifier) + person = fast_create(Person) + + post :set_category, :profile => @profile.identifier, :category_name => "category test", :followed_profile_id => person.id + follower = ProfileFollower.find_by(:profile_id => person.id, :follower_id => @profile.id) + ProfileFollower.any_instance.expects(:update_attributes).times(0) + end +end diff --git a/test/functional/profile_controller_test.rb b/test/functional/profile_controller_test.rb index 57da6e0..6d78980 100644 --- a/test/functional/profile_controller_test.rb +++ b/test/functional/profile_controller_test.rb @@ -1932,4 +1932,76 @@ class ProfileControllerTest < ActionController::TestCase assert_redirected_to :controller => 'account', :action => 'login' end + should 'follow a user without defining a group' do + login_as(@profile.identifier) + person = fast_create(Person) + get :follow, :profile => person.identifier + + follower = ProfileFollower.find_by(:profile_id => person.id, :follower_id => @profile.id) + assert_not_nil follower + end + + should "not follow user if not logged" do + person = fast_create(Person) + get :follow, :profile => person.identifier + + assert_redirected_to :controller => 'account', :action => 'login' + end + + should 'follow a user with a group' do + login_as(@profile.identifier) + person = fast_create(Person) + get :follow, :profile => person.identifier, :follow => { :category => "A Group" } + + follower = ProfileFollower.find_by(:profile_id => person.id, :follower_id => @profile.id) + assert_not_nil follower + assert_equal "A Group", follower.group + end + + should 'not follow if current_person already follows the person' do + login_as(@profile.identifier) + person = fast_create(Person) + fast_create(ProfileFollower, :profile_id => person.id, :follower_id => @profile.id) + + assert_no_difference 'ProfileFollower.count' do + get :follow, :profile => person.identifier, :follow => { :category => "A Group" } + end + end + + should "not unfollow user if not logged" do + person = fast_create(Person) + get :unfollow, :profile => person.identifier + + assert_redirected_to :controller => 'account', :action => 'login' + end + + should "unfollow a followed person" do + login_as(@profile.identifier) + person = fast_create(Person) + follower = fast_create(ProfileFollower, :profile_id => person.id, :follower_id => @profile.id) + assert_not_nil follower + + get :unfollow, :profile => person.identifier + follower = ProfileFollower.find_by(:profile_id => person.id, :follower_id => @profile.id) + assert_nil follower + end + + should "not unfollow a not followed person" do + login_as(@profile.identifier) + person = fast_create(Person) + + assert_no_difference 'ProfileFollower.count' do + get :unfollow, :profile => person.identifier + end + end + + should "redirect to page after unfollow" do + login_as(@profile.identifier) + person = fast_create(Person) + fast_create(ProfileFollower, :profile_id => person.id, :follower_id => @profile.id) + + get :unfollow, :profile => person.identifier, :redirect_to => "/some/url" + assert_redirected_to "/some/url" + end + end -- libgit2 0.21.2