diff --git a/app/controllers/aspect_memberships_controller.rb b/app/controllers/aspect_memberships_controller.rb index 4b1096ccc..69b6c07d9 100644 --- a/app/controllers/aspect_memberships_controller.rb +++ b/app/controllers/aspect_memberships_controller.rb @@ -6,6 +6,8 @@ class AspectMembershipsController < ApplicationController before_filter :authenticate_user! + respond_to :html, :json, :js + def destroy #note :id is garbage @@ -17,14 +19,14 @@ class AspectMembershipsController < ApplicationController if membership && membership.destroy @aspect = membership.aspect - flash.now[:notice] = I18n.t 'aspect_memberships.destroy.success' - respond_to do |format| - format.js { } - format.html{ - redirect_to :back - } + respond_with do |format| + format.all{ } + format.json{ render :json => { + :person_id => @person_id, + :aspect_ids => @contact.aspects.map{|a| a.id} + } } end else @@ -44,12 +46,12 @@ 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' - + respond_with AspectMembership.where(:contact_id => @contact.id, :aspect_id => @aspect.id).first else flash[:error] = I18n.t 'contacts.create.failure' - redirect_to :back + #TODO(dan) take this out once the .js template is removed + render :nothing => true end end diff --git a/app/controllers/contacts_controller.rb b/app/controllers/contacts_controller.rb index 5752e1c10..667dda4c4 100644 --- a/app/controllers/contacts_controller.rb +++ b/app/controllers/contacts_controller.rb @@ -24,4 +24,5 @@ class ContactsController < ApplicationController @contacts = current_user.contacts.sharing.includes(:aspect_memberships) render :layout => false end + end diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 292d8c02d..f76adfbad 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -109,7 +109,7 @@ class PeopleController < ApplicationController respond_to do |format| format.all { respond_with @person, :locals => {:post_type => :all} } format.json { - render :json => @person.to_json(:aspect_ids => @aspects_with_person.to_json) + render :json => @person.to_json } end end @@ -120,6 +120,7 @@ class PeopleController < ApplicationController end end + def retrieve_remote if params[:diaspora_handle] webfinger(params[:diaspora_handle], :single_aspect_form => true) @@ -136,7 +137,6 @@ class PeopleController < ApplicationController @aspect = :profile @contacts_of_contact = @contact.contacts.paginate(:page => params[:page], :per_page => (params[:limit] || 15)) @hashes = hashes_for_people @contacts_of_contact, @aspects - @contact = current_user.contact_for(@person) @aspects_with_person = @contact.aspects @aspect_ids = @aspects_with_person.map(&:id) else @@ -144,8 +144,16 @@ class PeopleController < ApplicationController redirect_to people_path end end + + def aspect_membership_dropdown + @person = Person.find(params[:id]) + @contact = current_user.contact_for(@person) || Contact.new + render :partial => 'aspect_memberships/aspect_dropdown', :locals => {:contact => @contact, :person => @person, :hang => 'left'} + end + private def webfinger(account, opts = {}) Resque.enqueue(Job::SocketWebfinger, current_user.id, account, opts) end + end diff --git a/app/helpers/aspect_global_helper.rb b/app/helpers/aspect_global_helper.rb index dac264005..5d7b71c76 100644 --- a/app/helpers/aspect_global_helper.rb +++ b/app/helpers/aspect_global_helper.rb @@ -68,16 +68,12 @@ module AspectGlobalHelper def aspect_dropdown_list_item(aspect, contact, person) checked = (contact.persisted? && contact.aspect_memberships.detect{ |am| am.aspect_id == aspect.id}) klass = checked ? "selected" : "" - hidden = !checked ? "hidden" : "" str = < - + #{aspect.name} -
- #{aspect_membership_button(aspect, contact, person)} -
LISTITEM str.html_safe diff --git a/app/models/aspect_membership.rb b/app/models/aspect_membership.rb index 372e744ea..64abd8f9c 100644 --- a/app/models/aspect_membership.rb +++ b/app/models/aspect_membership.rb @@ -16,4 +16,12 @@ class AspectMembership < ActiveRecord::Base true end + def as_json(opts={}) + { + :id => self.id, + :person_id => self.person.id, + :contact_id => self.contact.id, + :aspect_ids => self.contact.aspects.map{|a| a.id} + } + end end diff --git a/app/models/person.rb b/app/models/person.rb index 59ac74889..ec2c525f6 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -227,7 +227,6 @@ class Person < ActiveRecord::Base :handle => self.diaspora_handle, :url => "/people/#{self.id}" } - json.merge(:aspect_ids => opts[:aspect_ids]) end protected diff --git a/app/views/aspect_memberships/create.js.erb b/app/views/aspect_memberships/create.js.erb index 595304cf6..2292d0ae6 100644 --- a/app/views/aspect_memberships/create.js.erb +++ b/app/views/aspect_memberships/create.js.erb @@ -19,4 +19,3 @@ if($('#aspects_list').length == 1) { }; element.fadeTo(200,1); - diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index 63cf6cbcc..359b02e60 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -56,7 +56,8 @@ %img.avatar %h4 %a.person - = render 'aspect_memberships/aspect_dropdown', :contact => Contact.new, :person => Person.new, :hang => 'left' + #hovercard_dropdown_container + .hovercard_footer .footer_container Message diff --git a/config/routes.rb b/config/routes.rb index 1dd4938fa..e78d8b2ec 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -104,6 +104,8 @@ Diaspora::Application.routes.draw do end end + get "people/:id/aspect_membership_button" => "people#aspect_membership_dropdown", :as => "aspect_membership_button" + diff --git a/public/javascripts/contact-edit.js b/public/javascripts/contact-edit.js index 68a235492..bcdb86542 100644 --- a/public/javascripts/contact-edit.js +++ b/public/javascripts/contact-edit.js @@ -9,12 +9,9 @@ var ContactEdit = { }); }, - updateNumber: function(personId){ - var dropdown = $(".dropdown_list[data-person_id=" + personId.toString() +"]"), - number = dropdown.find(".selected").length, - button = dropdown.parents(".dropdown").children('.button.toggle'); - - var replacement; + updateNumber: function(dropdown, personId, number){ + var button = dropdown.parents(".dropdown").children('.button.toggle'), + replacement; if (number == 0) { button.removeClass("in_aspects"); @@ -36,7 +33,6 @@ var ContactEdit = { toggleCheckbox: function(check){ - check.toggleClass('hidden'); check.parent('li').toggleClass('selected'); }, @@ -44,10 +40,18 @@ var ContactEdit = { var button = li.find('.button'); if(button.hasClass('disabled') || li.hasClass('newItem')){ return; } - var checkbox = li.find('img.check'); - ContactEdit.toggleCheckbox(checkbox); + var checkbox = li.find('img.check'), + selected = li.hasClass("selected"), + routedId = selected ? "/42" : ""; - $.fn.callRemote.apply(button); + $.post("/aspect_memberships" + routedId + ".json", { + "aspect_id": li.data("aspect_id"), + "person_id": li.parent().data("person_id"), + "_method": (selected) ? "DELETE" : "POST" + }, function(aspectMembership) { + ContactEdit.toggleCheckbox(checkbox); + ContactEdit.updateNumber(li.closest(".dropdown_list"), li.parent().data("person_id"), aspectMembership.aspect_ids.length); + }); }, }; diff --git a/public/javascripts/widgets/hovercard.js b/public/javascripts/widgets/hovercard.js index a2a4458b7..ed9e64bd0 100644 --- a/public/javascripts/widgets/hovercard.js +++ b/public/javascripts/widgets/hovercard.js @@ -54,6 +54,27 @@ self.hoverCard.tip.fadeIn('fast'); }); + + $.get(self.target.attr('href')+'/aspect_membership_button',function(data){ + self.hoverCard.tip.find('#hovercard_dropdown_container').html(data); + }); + }; + + this.populateDropdown = function(aspect_ids){ + var dropdown = this.hoverCard.tip.find('.dropdown_list'), + listElements = dropdown.children('li'), + inAspects = false; + + // check-off aspects + $.each(listElements, function(idx,el){ + var element = $(el); + if( aspect_ids.indexOf(element.attr('data-aspect_id')) !== -1 ){ + element.addClass('selected'); + inAspects = true; + } + }); + + // make button green }; this.clearTimeout = function(delayed) { @@ -63,7 +84,7 @@ }; if((typeof delayed === "boolean" && delayed) || (typeof delayed === "object" && delayed.type === "mouseleave")) { - self.hoverCardTimeout = setTimeout(callback, 300); + self.hoverCardTimeout = setTimeout(callback, 400); } else { callback(); diff --git a/public/stylesheets/sass/application.sass b/public/stylesheets/sass/application.sass index a1c23868e..bbf8b4a52 100644 --- a/public/stylesheets/sass/application.sass +++ b/public/stylesheets/sass/application.sass @@ -3071,8 +3071,8 @@ ul.left_nav :display none #hovercard - @include box-shadow(0,0,7px,#333) @include border-radius(2px) + @include dropdown-shadow .avatar :position relative diff --git a/public/stylesheets/sass/ui.sass b/public/stylesheets/sass/ui.sass index f870ceeae..c811f7da6 100644 --- a/public/stylesheets/sass/ui.sass +++ b/public/stylesheets/sass/ui.sass @@ -150,7 +150,10 @@ &:hover :text-decoration none - + + &:not(.selected) + .check + :display none &.hang_right .wrapper @@ -170,7 +173,7 @@ @include border-radius(3px, 3px, 0, 0) :border 1px solid #444 :bottom none - + .selected :font-weight bold diff --git a/spec/controllers/aspect_memberships_controller_spec.rb b/spec/controllers/aspect_memberships_controller_spec.rb index 7772de8f1..7d4cb8c5c 100644 --- a/spec/controllers/aspect_memberships_controller_spec.rb +++ b/spec/controllers/aspect_memberships_controller_spec.rb @@ -40,7 +40,6 @@ describe AspectMembershipsController do }.should change{ alice.contact_for(bob.person).aspect_memberships.count }.by(1) - end it 'creates a contact' do @@ -62,8 +61,19 @@ describe AspectMembershipsController do :aspect_id => @aspect0.id flash[:error].should_not be_empty end - end + context 'json' do + it 'returns a list of aspect ids for the person' do + post :create, + :format => 'json', + :person_id => @person.id, + :aspect_id => @aspect0.id + + contact = @controller.current_user.contact_for(@person) + response.body.should == contact.aspect_memberships.first.to_json + end + end + end describe "#destroy" do it 'removes contacts from an aspect' do