diff --git a/app/views/aspects/_aspect_listings.haml b/app/views/aspects/_aspect_listings.haml index 6e5339134..940ab6f53 100644 --- a/app/views/aspects/_aspect_listings.haml +++ b/app/views/aspects/_aspect_listings.haml @@ -4,10 +4,10 @@ %ul#aspect_nav.left_nav %li.all_aspects{:class => ("active" if params["set"] != "all" && params["set"] != "only_sharing" && !@featured && !@finder)} - %a.home_selector{:href => aspects_path, :class => ("sub_selected" if params["a_id"])} - = t('aspects.index.your_aspects') + .root_element= t('aspects.index.your_aspects') %ul.sub_nav + %a.toggle_selector{:href => '#'} - for aspect in all_aspects %li{:data => {:aspect_id => aspect.id}, :class => ("active" if params["a_id"].to_i == aspect.id)} .edit diff --git a/config/assets.yml b/config/assets.yml index 6c45eac3c..2bd5b17e9 100644 --- a/config/assets.yml +++ b/config/assets.yml @@ -55,7 +55,6 @@ javascripts: - public/javascripts/friend-finder.js home: - public/javascripts/publisher.js - - public/javascripts/aspect-filters.js - public/javascripts/aspect-edit-pane.js - public/javascripts/fileuploader-custom.js people: diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml index b2288dd55..13f8ff7bd 100644 --- a/config/locales/javascript/javascript.en.yml +++ b/config/locales/javascript/javascript.en.yml @@ -53,3 +53,7 @@ en: hide: "hide comments" reshares: duplicate: "You've already reshared that post!" + aspect_navigation: + select_all: "Select all" + deselect_all: "Deselect all" + no_aspects: "No aspects selected" diff --git a/features/comments.feature b/features/comments.feature index 82fcbd9be..fa73d5fca 100644 --- a/features/comments.feature +++ b/features/comments.feature @@ -62,8 +62,7 @@ Feature: commenting When I focus the comment field Then the first comment field should be open - When I follow "Besties" - And I wait for the ajax to finish + When I select "Besties" aspect Then I should see "Look at this dog" Then the first comment field should be closed When I focus the comment field diff --git a/features/connects_users.feature b/features/connects_users.feature index bb0feacbf..6f698c292 100644 --- a/features/connects_users.feature +++ b/features/connects_users.feature @@ -47,7 +47,6 @@ Feature: following and being followed And I add the person to my "Unicorns" aspect When I go to the home page - When I follow "Your Aspects" Then I should have 1 contact in "Unicorns" Then I should have 1 contact in "Besties" @@ -59,7 +58,6 @@ Feature: following and being followed Then I go to the destroy user session page When I sign in as "bob@bob.bob" - When I follow "Your Aspects" Then I should have 1 contacts in "Besties" When I am on the home page diff --git a/features/mentions_from_profile_page.feature b/features/mentions_from_profile_page.feature index 3487302df..247ddba76 100644 --- a/features/mentions_from_profile_page.feature +++ b/features/mentions_from_profile_page.feature @@ -32,7 +32,7 @@ Feature: mentioning a contact from their profile page And I wait for the ajax to finish Then I should see "I am eating a yogurt" - When I follow "Your Aspects" within "#aspect_nav" + When I am on the aspects page And I follow "NotPostingThingsHere" within "#aspect_nav" And I wait for the ajax to finish Then I should see "I am eating a yogurt" @@ -50,11 +50,13 @@ Feature: mentioning a contact from their profile page And I press "Share" in the modal window When I am on the aspects page + And I follow "Deselect all" within "#aspect_nav" And I follow "PostingTo" within "#aspect_nav" And I wait for the ajax to finish Then I should see "I am eating a yogurt" - When I follow "Your Aspects" within "#aspect_nav" + When I am on the aspects page + And I follow "Deselect all" within "#aspect_nav" And I follow "NotPostingThingsHere" within "#aspect_nav" And I wait for the ajax to finish Then I should not see "I am eating a yogurt" diff --git a/features/posts_from_main_page.feature b/features/posts_from_main_page.feature index d7f4e2a27..7a8ba929b 100644 --- a/features/posts_from_main_page.feature +++ b/features/posts_from_main_page.feature @@ -22,25 +22,22 @@ Feature: posting from the main page Given I expand the publisher When I fill in "status_message_fake_text" with "I am eating a yogurt" And I press "Share" - And I follow "Your Aspects" + And I go to the aspects page Then I should see "I am eating a yogurt" within ".stream_element" Scenario: post a text-only message to just one aspect - When I follow "PostingTo" - And I wait for the ajax to finish + When I select "PostingTo" aspect And I expand the publisher And I fill in "status_message_fake_text" with "I am eating a yogurt" And I press "Share" And I wait for the ajax to finish When I am on the aspects page - And I follow "PostingTo" within "#aspect_nav" - And I wait for the ajax to finish + And I select "PostingTo" aspect Then I should see "I am eating a yogurt" - When I follow "Your Aspects" within "#aspect_nav" - And I follow "NotPostingThingsHere" within "#aspect_nav" - And I wait for the ajax to finish + When I am on the aspects page + And I select "NotPostingThingsHere" aspect Then I should not see "I am eating a yogurt" Scenario: post a photo with text @@ -49,7 +46,7 @@ Feature: posting from the main page And I fill in "status_message_fake_text" with "Look at this dog" And I press "Share" And I wait for the ajax to finish - And I follow "Your Aspects" + And I go to the aspects page Then I should see a "img" within ".stream_element div.photo_attachments" And I should see "Look at this dog" within ".stream_element" Then I log out @@ -65,7 +62,7 @@ Feature: posting from the main page Then I should see an uploaded image within the photo drop zone And I press "Share" And I wait for the ajax to finish - And I follow "Your Aspects" + And I go to the aspects page Then I should see a "img" within ".stream_element div.photo_attachments" Then I log out And I sign in as "alice@alice.alice" @@ -130,10 +127,10 @@ Feature: posting from the main page And I press "Share" And I wait for the ajax to finish - When I follow "Your Aspects" + When I go to the aspects page And I hover over the ".stream_element" And I preemptively confirm the alert And I click to delete the first post And I wait for the ajax to finish - And I follow "Your Aspects" + And I go to the aspects page Then I should not see "I am eating a yogurt" diff --git a/features/reshare.feature b/features/reshare.feature index e7f166cb9..4e527dd9c 100644 --- a/features/reshare.feature +++ b/features/reshare.feature @@ -49,10 +49,9 @@ Feature: public repost And I go to the home page And I wait for the ajax to finish Then I should see a ".reshare" - And I follow "Your Aspects" - Then I should see "reshare this!" - Then I should see a ".reshare" - And I should see "Bob" + And I should see "reshare this!" + And I should see a ".reshare" + And I should see "Bob" Scenario: I can delete a post that has been reshared Given "bob@bob.bob" has a public post with text "reshare this!" @@ -63,11 +62,9 @@ Feature: public repost And I go to the home page Then I should see a ".reshare" - - When I follow "Your Aspects" - Then I should see "reshare this!" - Then I should see a ".reshare" - And I should see "Bob" + And I should see "reshare this!" + And I should see a ".reshare" + And I should see "Bob" When I go to the destroy user session page And I sign in as "bob@bob.bob" @@ -88,10 +85,9 @@ Feature: public repost When I go to the home page Then I should see a ".reshare" - When I follow "Your Aspects" - Then I should see "reshare this!" + And I should see "reshare this!" And I should see a ".reshare" - And I should see "Bob" + And I should see "Bob" When I go to the home page Then I should see "1 reshare" diff --git a/features/step_definitions/aspects_steps.rb b/features/step_definitions/aspects_steps.rb new file mode 100644 index 000000000..3f6505f27 --- /dev/null +++ b/features/step_definitions/aspects_steps.rb @@ -0,0 +1,14 @@ +When /^I click on "([^"]*)" aspect edit icon$/ do |aspect_name| + When %{I hover over the "ul.sub_nav > li:contains('#{aspect_name}')"} + within("#aspect_nav") do + find(:xpath, "//a[@rel='facebox'][.//img[@title='Edit #{aspect_name}']]").click + end +end + +When /^I select "([^"]*)" aspect$/ do |aspect_name| + within('#aspect_nav') do + click_link 'Deselect all' + click_link aspect_name + end + And %{I wait for the ajax to finish} +end diff --git a/features/step_definitions/custom_web_steps.rb b/features/step_definitions/custom_web_steps.rb index 1a0ca0922..e37235364 100644 --- a/features/step_definitions/custom_web_steps.rb +++ b/features/step_definitions/custom_web_steps.rb @@ -193,13 +193,6 @@ When /^I resize my window to 800x600$/ do JS end -When /^I click on "([^"]*)" aspect edit icon$/ do |aspect_name| - When %{I hover over the "ul.sub_nav > li:contains('#{aspect_name}')"} - within("#aspect_nav") do - find(:xpath, "//a[@rel='facebox'][.//img[@title='Edit #{aspect_name}']]").click - end -end - Then /^I follow Edit Profile in the same window$/ do page.execute_script("$('a[href=\"#{edit_profile_path}\"]').removeAttr('target')") @@ -212,4 +205,4 @@ end Then 'I press the attached image' do Then %{I press the 1st "img" within ".stream_element div.photo_attachments"} -end \ No newline at end of file +end diff --git a/public/javascripts/aspect-filters.js b/public/javascripts/aspect-filters.js deleted file mode 100644 index 5e3e732de..000000000 --- a/public/javascripts/aspect-filters.js +++ /dev/null @@ -1,173 +0,0 @@ -/* Copyright (c) 2010-2011, Diaspora Inc. This file is - * licensed under the Affero General Public License version 3 or later. See - * the COPYRIGHT file. - */ - -var AspectFilters = { - selectedGUIDS: [], - activeRequest: null, - initialize: function(){ - AspectFilters.initializeSelectedGUIDS(); - AspectFilters.interceptAspectLinks(); - AspectFilters.interceptAspectNavLinks(); - }, - initializeSelectedGUIDS: function(){ - $("#aspect_nav .aspect_selector").each(function(){ - var button = $(this), - guid = button.attr('data-guid'); - - if(guid && location.href.search("a_ids..="+guid+"(#|&|$)") != -1){ - button.parent().addClass('active'); - AspectFilters.selectedGUIDS.push(guid); - $("#aspect_nav li.all_aspects").removeClass('active'); - } - }); - }, - interceptAspectLinks: function(){ - $("a.hard_aspect_link").live("click", AspectFilters.aspectLinkClicked); - }, - aspectLinkClicked: function(e){ - var link = $(this); - e.preventDefault(); - if( !link.hasClass('aspect_selector') ){ - AspectFilters.switchToAspect(link); - } - - // remove focus - this.blur(); - - $('html, body').animate({scrollTop:0}, 'fast'); - }, - switchToAspect: function(aspectLi){ - var guid = aspectLi.attr('data-guid'); - - // select correct aspect in filter list & deselect others - $("#aspect_nav li.active").removeClass('active'); - aspectLi.addClass('active'); - - AspectFilters.fadeOut(); - - AspectFilters.performAjax( aspectLi.attr('href')); - }, - interceptAspectNavLinks: function(){ - $("#aspect_nav a.aspect_selector").click(function(e){ - e.preventDefault(); - - // loading animation - AspectFilters.fadeOut(); - - // filtering ////////////////////// - var $this = $(this), - listElement = $this.parent(), - guid = $this.attr('data-guid'), - homeListElement = $("#aspect_nav li.all_aspects"); - - if( listElement.hasClass('active') ){ - // remove filter - var idx = AspectFilters.selectedGUIDS.indexOf( guid ); - if( idx != -1 ){ - AspectFilters.selectedGUIDS.splice(idx,1); - } - listElement.removeClass('active'); - - if(AspectFilters.selectedGUIDS.length === 0){ - homeListElement.addClass('active'); - } - - } else { - // append filter - if(AspectFilters.selectedGUIDS.indexOf( guid == 1)){ - AspectFilters.selectedGUIDS.push( guid ); - } - listElement.addClass('active'); - - homeListElement.removeClass('active'); - } - - AspectFilters.performAjax(AspectFilters.generateURL()); - }); - }, - generateURL: function(){ - var baseURL = location.href.split("?")[0]; - - // generate new url - baseURL = baseURL.replace('#',''); - baseURL += '?'; - for(i=0; i < AspectFilters.selectedGUIDS.length; i++){ - baseURL += 'a_ids[]='+ AspectFilters.selectedGUIDS[i] +'&'; - } - - if(!$("#publisher").hasClass("closed")) { - // open publisher - baseURL += "op=true"; - } else { - // slice last '&' - baseURL = baseURL.slice(0,baseURL.length-1); - } - return baseURL; - }, - performAjax: function(newURL) { - var post = $("#publisher textarea").val(), - photos = {}; - - //pass photos - $('#photodropzone img').each(function(){ - var img = $(this); - var guid = img.attr('data-id'); - var url = img.attr('src'); - photos[guid] = url; - }); - - // set url - // some browsers (Firefox for example) don't support pushState - if (typeof(history.pushState) == 'function') { - history.pushState(null, document.title, newURL); - } - - try { - AspectFilters.activeRequest.abort(); - } catch(e) {} finally { - AspectFilters.activeRequest = null; - } - AspectFilters.activeRequest = $.ajax({ - url : newURL, - dataType : 'script', - success : function(data){ - // fill in publisher - // (not cached because this element changes) - - var textarea = $("#publisher textarea"); - var photozone = $('#photodropzone'); - - if( post !== "" ) { - textarea.val(post); - textarea.focus(); - } - - var photos_html = ""; - for(var key in photos){ - $("#publisher textarea").addClass("with_attachments"); - photos_html = photos_html + "
  • " + ("") + "
  • "; - } - - // reinit listeners on stream - photozone.html(photos_html); - Diaspora.page.publish("stream/reloaded"); - - // fade contents back in - AspectFilters.fadeIn(); - } - }); - }, - fadeIn: function(){ - $("#aspect_stream_container").fadeTo(100, 1); - $("#aspect_contact_pictures").fadeTo(100, 1); - }, - fadeOut: function(){ - $("#aspect_stream_container").fadeTo(100, 0.4); - $("#aspect_contact_pictures").fadeTo(100, 0.4); - } -} -$(document).ready(function(){ - AspectFilters.initialize(); -}); diff --git a/public/javascripts/pages/aspects-index.js b/public/javascripts/pages/aspects-index.js index 898db0372..071f6e4d5 100644 --- a/public/javascripts/pages/aspects-index.js +++ b/public/javascripts/pages/aspects-index.js @@ -2,6 +2,7 @@ Diaspora.Pages.AspectsIndex = function() { var self = this; this.subscribe("page/ready", function(evt, document) { + self.aspectNavigation = self.instantiate("AspectNavigation", document.find("ul#aspect_nav")); self.stream = self.instantiate("Stream", document.find("#aspect_stream_container")); self.infiniteScroll = self.instantiate("InfiniteScroll"); }); diff --git a/public/javascripts/publisher.js b/public/javascripts/publisher.js index e215a5388..398847692 100644 --- a/public/javascripts/publisher.js +++ b/public/javascripts/publisher.js @@ -375,11 +375,11 @@ var Publisher = { } }, onSuccess: function(data, json, xhr){ - if(Publisher.bookmarklet == false){ - var isPostVisible = AspectFilters.selectedGUIDS.length == 0; + if (Publisher.bookmarklet == false) { + var isPostVisible = Diaspora.page.aspectNavigation.selectedAspects().length == 0; var postedTo = Publisher.selectedAspectIds(); - $.each(AspectFilters.selectedGUIDS, function(index, value){ - if(postedTo.indexOf(parseInt(value))>-1) + $.each(Diaspora.page.aspectNavigation.selectedAspects(), function(index, value) { + if (postedTo.indexOf(parseInt(value)) > -1) isPostVisible = true; }); diff --git a/public/javascripts/widgets/aspect-navigation.js b/public/javascripts/widgets/aspect-navigation.js new file mode 100644 index 000000000..6fc00079d --- /dev/null +++ b/public/javascripts/widgets/aspect-navigation.js @@ -0,0 +1,162 @@ +/* Copyright (c) 2010, Diaspora Inc. This file is + * licensed under the Affero General Public License version 3 or later. See + * the COPYRIGHT file. + */ + +(function() { + Diaspora.Widgets.AspectNavigation = function() { + var self = this; + + this.subscribe("widget/ready", function(evt, aspectNavigation) { + $.extend(self, { + aspectNavigation: aspectNavigation, + aspectSelectors: aspectNavigation.find("a.aspect_selector[data-guid]"), + aspectLis: aspectNavigation.find("li[data-aspect_id]"), + toggleSelector: aspectNavigation.find("a.toggle_selector") + }); + + self.initializeSelectedAspects(); + self.calculateToggleText(); + self.aspectSelectors.click(self.toggleAspect); + self.toggleSelector.click(self.toggleAll); + }); + + this.selectedAspects = function() { + return self.aspectNavigation.find("li.active[data-aspect_id]").map(function() { return $(this).data('aspect_id') }); + }; + + this.initializeSelectedAspects = function() { + if (location.href.search("a_ids..=") == -1) { + self.aspectLis.addClass("active"); + } else { + self.aspectSelectors.each(function() { + guid = $(this).data('guid'); + if (guid && location.href.search("a_ids..=" + guid + "(#|&|$)") != -1) + $(this).parent().addClass('active'); + }); + } + }; + + this.toggleAspect = function(evt) { + evt.preventDefault(); + + $(this).parent().toggleClass("active"); + self.perform(); + }; + + this.toggleAll = function(evt) { + evt.preventDefault(); + + if (self.allSelected()) { + self.aspectLis.removeClass("active"); + } else { + self.aspectLis.addClass("active"); + } + self.perform(); + }; + + this.perform = function() { + if (self.noneSelected()) { + self.abortAjax(); + Diaspora.page.stream.empty(); + Diaspora.page.stream.setHeaderTitle(Diaspora.I18n.t('aspect_navigation.no_aspects')); + self.fadeIn(); + } else { + self.performAjax(); + } + self.calculateToggleText(); + }; + + this.calculateToggleText = function() { + if (self.allSelected()) { + self.toggleSelector.text(Diaspora.I18n.t('aspect_navigation.deselect_all')); + } else { + self.toggleSelector.text(Diaspora.I18n.t('aspect_navigation.select_all')); + } + }; + + this.generateURL = function() { + var baseURL = location.href.split("?")[0]; + + // generate new url + baseURL = baseURL.replace('#',''); + baseURL += '?'; + + self.aspectLis.each(function() { + var aspectLi = $(this); + if (aspectLi.hasClass("active")) { + baseURL += "a_ids[]=" + aspectLi.data("aspect_id") + "&"; + } + }); + + if(!$("#publisher").hasClass("closed")) { + // open publisher + baseURL += "op=true"; + } else { + // slice last '&' + baseURL = baseURL.slice(0,baseURL.length-1); + } + return baseURL; + }; + + this.performAjax = function() { + var post = $("#publisher textarea").val(), + newURL = self.generateURL(), + photos = {}; + + //pass photos + $('#photodropzone img').each(function() { + var img = $(this); + photos[img.attr("data-id")] = img.attr("src"); + }); + + self.abortAjax(); + self.fadeOut(); + + self.jXHR = $.getScript(newURL, function(data) { + var textarea = $("#publisher textarea"), + photozone = $("#photodropzone"); + + if( post !== "" ) { + textarea.val(post).focus(); + } + + $.each(photos, function(GUID, URL) { + photozone.append([ + '
  • ', + '', + '
  • ' + ].join("")); + }); + + self.globalPublish("stream/reloaded"); + self.fadeIn(); + }); + }; + + this.abortAjax = function() { + if (self.jXHR) { + self.jXHR.abort(); + self.jXHR = null; + } + }; + + this.noneSelected = function() { + return self.aspectLis.filter(".active").length === 0; + } + + this.allSelected = function() { + return self.aspectLis.not(".active").length === 0; + } + + this.fadeOut = function() { + $("#aspect_stream_container").fadeTo(100, 0.4); + $("#selected_aspect_contacts").fadeTo(100, 0.4); + }; + + this.fadeIn = function() { + $("#aspect_stream_container").fadeTo(100, 1); + $("#selected_aspect_contacts").fadeTo(100, 1); + }; + }; +})(); diff --git a/public/javascripts/widgets/stream.js b/public/javascripts/widgets/stream.js index 037b76ed9..09630c6ae 100644 --- a/public/javascripts/widgets/stream.js +++ b/public/javascripts/widgets/stream.js @@ -5,7 +5,9 @@ this.subscribe("widget/ready", function(evt, stream) { $.extend(self, { - stream: $(stream) + stream: $(stream), + mainStream: $(stream).find('#main_stream'), + headerTitle: $(stream).find('#aspect_stream_header > h3') }); $.each(self.stream.find(".stream_element"), function() { @@ -31,6 +33,15 @@ this.addPost = function(post) { self.streamElements[post.attr("id")] = self.instantiate("StreamElement", post); }; + + this.empty = function() { + self.mainStream.empty(); + self.headerTitle.text(Diaspora.I18n.t('stream.no_aspects')); + }; + + this.setHeaderTitle = function(newTitle) { + self.headerTitle.text(newTitle); + }; }; Diaspora.Widgets.Stream = Stream; diff --git a/public/stylesheets/sass/application.sass b/public/stylesheets/sass/application.sass index 55e48a7cc..1ad40c3f8 100644 --- a/public/stylesheets/sass/application.sass +++ b/public/stylesheets/sass/application.sass @@ -2923,12 +2923,19 @@ ul.left_nav :width 155px a.aspect_selector, + a.toggle_selector, .new_aspect, a.tag_selector :padding :left 15px :width 182px + a.toggle_selector + :outline none + :color #999 + :font + :size 95% + .section .left_nav a.aspect_selector, diff --git a/spec/javascripts/aspect-filters-spec.js b/spec/javascripts/aspect-filters-spec.js deleted file mode 100644 index 50fd9ad4f..000000000 --- a/spec/javascripts/aspect-filters-spec.js +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright (c) 2010-2011, Diaspora Inc. This file is -* licensed under the Affero General Public License version 3 or later. See -* the COPYRIGHT file. -*/ - -describe('AspectFilters', function(){ - it('initializes selectedGUIDS', function(){ - expect(AspectFilters.selectedGUIDS).toEqual([]); - }); - it('initializes activeRequest', function(){ - expect(AspectFilters.activeRequest).toEqual(null); - }); -}); diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml index a26934412..bc3844754 100644 --- a/spec/javascripts/support/jasmine.yml +++ b/spec/javascripts/support/jasmine.yml @@ -40,7 +40,6 @@ src_files: - public/javascripts/stream.js - public/javascripts/validation.js - public/javascripts/rails.js - - public/javascripts/aspect-filters.js - public/javascripts/aspects-dropdown.js - public/javascripts/content-updater.js - public/javascripts/tag-followings.js