diff --git a/app/controllers/aspect_memberships_controller.rb b/app/controllers/aspect_memberships_controller.rb index d9a55d761..189c1fb5b 100644 --- a/app/controllers/aspect_memberships_controller.rb +++ b/app/controllers/aspect_memberships_controller.rb @@ -46,12 +46,11 @@ class AspectMembershipsController < ApplicationController @aspect = current_user.aspects.where(:id => params[:aspect_id]).first if @contact = current_user.share_with(@person, @aspect) - flash.now[:notice] = I18n.t 'aspects.add_to_aspect.success' + flash.now[:notice] = I18n.t('aspects.add_to_aspect.success') respond_with AspectMembership.where(:contact_id => @contact.id, :aspect_id => @aspect.id).first else - flash[:error] = I18n.t 'contacts.create.failure' - #TODO(dan) take this out once the .js template is removed - render :nothing => true + flash.now[:error] = I18n.t('contacts.create.failure') + render :nothing => true, :status => 409 end end diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index f842f59ec..623618ebb 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -95,6 +95,7 @@ class PeopleController < ApplicationController unless params[:format] == "json" # hovercard if current_user + @block = current_user.blocks.where(:person_id => @person.id).first @contact = current_user.contact_for(@person) @aspects_with_person = [] if @contact && !params[:only_posts] diff --git a/app/models/contact.rb b/app/models/contact.rb index b1e961207..1d19283b1 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -15,7 +15,8 @@ class Contact < ActiveRecord::Base has_many :share_visibilities, :source => :shareable, :source_type => 'Post' has_many :posts, :through => :share_visibilities, :source => :shareable, :source_type => 'Post' - validate :not_contact_for_self + validate :not_contact_for_self, + :not_blocked_user validates_uniqueness_of :person_id, :scope => :user_id @@ -98,5 +99,14 @@ class Contact < ActiveRecord::Base errors[:base] << 'Cannot create self-contact' end end + + def not_blocked_user + if user.blocks.where(:person_id => person_id).exists? + errors[:base] << 'Cannot connect to an ignored user' + false + else + true + end + end end diff --git a/app/views/people/_sub_header.html.haml b/app/views/people/_sub_header.html.haml index 334c60fe4..e11abc0b2 100644 --- a/app/views/people/_sub_header.html.haml +++ b/app/views/people/_sub_header.html.haml @@ -1,7 +1,13 @@ #author_info .right - if user_signed_in? && current_user.person != person - = aspect_membership_dropdown(contact, person, 'right') + - if @block.present? + = link_to t('users.privacy_settings.stop_ignoring'), block_path(@block), + :method => :delete, + :class => "button" + + - else + = aspect_membership_dropdown(contact, person, 'right') - elsif user_signed_in? && current_user.person == person = link_to t('people.profile_sidebar.edit_my_profile'), edit_profile_path, :class => 'button creation' diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 185152750..314b6282f 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -39,5 +39,8 @@ - else #main_stream %div{:style=>"text-align:center;", :class => "dull"} - = t('.has_not_shared_with_you_yet', :name => @person.first_name) + - if @block.present? + = t('.ignoring', :name => @person.first_name) + - else + = t('.has_not_shared_with_you_yet', :name => @person.first_name) diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml index 594d24a6a..d1f4d555c 100644 --- a/config/locales/diaspora/en.yml +++ b/config/locales/diaspora/en.yml @@ -544,6 +544,7 @@ en: start_sharing: "start sharing" message: "Message" mention: "Mention" + ignoring: "You are ignoring all posts from %{name}." sub_header: you_have_no_tags: "you have no tags!" add_some: "add some" diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml index 3e2e91877..3497eba47 100644 --- a/config/locales/javascript/javascript.en.yml +++ b/config/locales/javascript/javascript.en.yml @@ -40,6 +40,7 @@ en: all_aspects: "All aspects" stopped_sharing_with: "You have stopped sharing with {{name}}." started_sharing_with: "You have started sharing with {{name}}!" + error: "Couldn't start sharing with {{name}}. Are you ignoring them?" toggle: zero: "Select aspects" one: "In {{count}} aspect" diff --git a/lib/diaspora/user/connecting.rb b/lib/diaspora/user/connecting.rb index be2c150a6..47ef5f07a 100644 --- a/lib/diaspora/user/connecting.rb +++ b/lib/diaspora/user/connecting.rb @@ -11,6 +11,8 @@ module Diaspora # @return [Contact] The newly made contact for the passed in person. def share_with(person, aspect) contact = self.contacts.find_or_initialize_by_person_id(person.id) + return false unless contact.valid? + unless contact.receiving? contact.dispatch_request contact.receiving = true diff --git a/public/javascripts/contact-edit.js b/public/javascripts/contact-edit.js index 4e55200df..0e00c1c08 100644 --- a/public/javascripts/contact-edit.js +++ b/public/javascripts/contact-edit.js @@ -6,7 +6,6 @@ var ContactEdit = { init: function(){ $.extend(ContactEdit, AspectsDropdown); $('.dropdown.aspect_membership .dropdown_list > li, .dropdown.inviter .dropdown_list > li').live('click', function(evt){ - ContactEdit.processClick($(this), evt); }); }, @@ -64,7 +63,10 @@ var ContactEdit = { }, toggleAspectMembership: function(li, evt) { - var button = li.find('.button'); + var button = li.find('.button'), + dropdown = li.closest('.dropdown'), + dropdownList = li.parent('.dropdown_list'); + if(button.hasClass('disabled') || li.hasClass('newItem')){ return; } var selected = li.hasClass("selected"), @@ -75,12 +77,19 @@ var ContactEdit = { "person_id": li.parent().data("person_id"), "_method": (selected) ? "DELETE" : "POST" }, function(aspectMembership) { - li.removeClass("loading"); ContactEdit.toggleCheckbox(li); ContactEdit.updateNumber(li.closest(".dropdown_list"), li.parent().data("person_id"), aspectMembership.aspect_ids.length, 'in_aspects'); Diaspora.page.publish("aspectDropdown/updated", [li.parent().data("person_id"), li.parents(".dropdown").parent(".right").html()]); - }); + }) + .error(function() { + var message = Diaspora.I18n.t("aspect_dropdown.error", {name: dropdownList.data('person-short-name')}); + Diaspora.page.flashMessages.render({success: false, notice: message}); + dropdown.removeClass('active'); + }) + .complete(function() { + li.removeClass("loading"); + }); } }; diff --git a/spec/models/contact_spec.rb b/spec/models/contact_spec.rb index 26cce4b53..1a3c507aa 100644 --- a/spec/models/contact_spec.rb +++ b/spec/models/contact_spec.rb @@ -199,4 +199,27 @@ describe Contact do @contact.destroy end end + + describe "#not_blocked_user" do + before do + @contact = alice.contact_for(bob.person) + end + + it "is called on validate" do + @contact.should_receive(:not_blocked_user) + @contact.valid? + end + + it "adds to errors if potential contact is blocked by user" do + person = eve.person + block = alice.blocks.create(:person => person) + bad_contact = alice.contacts.create(:person => person) + + bad_contact.send(:not_blocked_user).should be_false + end + + it "does not add to errors" do + @contact.send(:not_blocked_user).should be_true + end + end end