diff --git a/Changelog.md b/Changelog.md index 1c034f7193ef83a20f5cef20d5c62f4d0e7abf3a..e2543a0c2e81f744729ca6efe4659ec08b6efe70 100644 --- a/Changelog.md +++ b/Changelog.md @@ -18,6 +18,7 @@ ## Features * Hide post title of limited post in comment notification email [#5843](https://github.com/diaspora/diaspora/pull/5843) * More and better environment checks in script/server [#5891](https://github.com/diaspora/diaspora/pull/5891) +* Enable aspect sorting again [#5559](https://github.com/diaspora/diaspora/pull/5559) # 0.5.0.0 diff --git a/Gemfile b/Gemfile index 42688dc406a9e699eafbe1097c79f14907081e1e..5727347e9beec345843b241400d2477f454a81e5 100644 --- a/Gemfile +++ b/Gemfile @@ -86,6 +86,7 @@ gem "entypo-rails", "2.2.2" gem "backbone-on-rails", "1.1.2" gem "handlebars_assets", "0.20.1" gem "jquery-rails", "3.1.2" +gem "jquery-ui-rails", "5.0.3" gem "js_image_paths", "0.0.2" gem "js-routes", "1.0.0" @@ -252,6 +253,11 @@ group :test do gem "database_cleaner" , "1.4.1" gem "selenium-webdriver", "2.45.0" + source "https://rails-assets.org" do + gem "rails-assets-jquery-simulate", "1.0.1" + gem "rails-assets-jquery-simulate-ext", "1.3.0" + end + # General helpers gem "factory_girl_rails", "4.5.0" diff --git a/Gemfile.lock b/Gemfile.lock index 87cfbd1919702c69a05f96588341113ff723d052..3a3e50dd67caa0c090e186cc7e3ac833b2d3329f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -500,6 +500,9 @@ GEM rails-assets-jquery-idletimer (1.0.1) rails-assets-jquery-placeholder (2.1.1) rails-assets-jquery (>= 1.6) + rails-assets-jquery-simulate (1.0.1) + rails-assets-jquery-simulate-ext (1.3.0) + rails-assets-jquery (>= 1.7.0) rails-assets-jquery-textchange (0.2.3) rails-assets-jquery rails-assets-jquery-ui (1.10.4) @@ -739,6 +742,7 @@ DEPENDENCIES jasmine (= 2.2.0) jasmine-jquery-rails (= 2.0.3) jquery-rails (= 3.1.2) + jquery-ui-rails (= 5.0.3) js-routes (= 1.0.0) js_image_paths (= 0.0.2) jshintrb (= 0.3.0) @@ -772,6 +776,8 @@ DEPENDENCIES rails-assets-jquery (= 1.11.1)! rails-assets-jquery-idletimer (= 1.0.1)! rails-assets-jquery-placeholder (= 2.1.1)! + rails-assets-jquery-simulate (= 1.0.1)! + rails-assets-jquery-simulate-ext (= 1.3.0)! rails-assets-jquery-textchange (= 0.2.3)! rails-assets-markdown-it (= 4.2.0)! rails-assets-markdown-it--markdown-it-for-inline (= 0.1.0)! diff --git a/app/assets/javascripts/app/pages/contacts.js b/app/assets/javascripts/app/pages/contacts.js index 4ae44878b4b4827c28497e07a0b5e7534455a0ef..27e7ec1268e8519913e6df12ba2dbbc754eaaf5f 100644 --- a/app/assets/javascripts/app/pages/contacts.js +++ b/app/assets/javascripts/app/pages/contacts.js @@ -22,6 +22,8 @@ app.pages.Contacts = Backbone.View.extend({ this.aspectCreateView = new app.views.AspectCreate({ el: $("#newAspectContainer") }); this.aspectCreateView.render(); + + this.setupAspectSorting(); }, toggleChatPrivilege: function() { @@ -73,6 +75,21 @@ app.pages.Contacts = Backbone.View.extend({ searchContactList: function(e) { this.stream.search($(e.target).val()); + }, + + setupAspectSorting: function() { + $("#aspect_nav .nav").sortable({ + items: "li.aspect[data-aspect-id]", + update: function() { + $("#aspect_nav .ui-sortable").removeClass("synced"); + var data = JSON.stringify({ ordered_aspect_ids: $(this).sortable("toArray", { attribute: "data-aspect-id" }) }); + $.ajax(Routes.order_aspects_path(), + { type: "put", dataType: "text", contentType: "application/json", data: data }) + .done(function() { $("#aspect_nav .ui-sortable").addClass("synced"); }); + }, + revert: true, + helper: "clone" + }); } }); // @license-end diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index aaa0c50ea6843edf96ec994ff5e81ee22d401a30..cc3a4f440c182cca8c5a1f36945496c5dc77d196 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -20,6 +20,10 @@ //= require jquery-idletimer/dist/idle-timer //= require jquery.infinitescroll-custom //= require jquery.autocomplete-custom +//= require jquery-ui/core +//= require jquery-ui/widget +//= require jquery-ui/mouse +//= require jquery-ui/sortable //= require keycodes //= require fileuploader-custom //= require handlebars.runtime diff --git a/app/assets/stylesheets/contacts.scss b/app/assets/stylesheets/contacts.scss index d43bd6eb7b9346a80744e956b6e848a3e4dfd98d..9a356689d4c7b3ddb90030885eb4fae0147cba9c 100644 --- a/app/assets/stylesheets/contacts.scss +++ b/app/assets/stylesheets/contacts.scss @@ -64,6 +64,7 @@ #aspect_nav { li.aspect > a { padding-left: 30px; } li.new_aspect > a { padding-left: 30px; } + li.aspect.ui-sortable-handle.ui-sortable-helper { background: #FFF; } } #no_contacts { diff --git a/app/controllers/aspects_controller.rb b/app/controllers/aspects_controller.rb index 77e8bfc4a7dc598fafbc22cbd4e5f6ff825ea2f6..5c6f5de7941cca5b339f3e332678faacf89222a0 100644 --- a/app/controllers/aspects_controller.rb +++ b/app/controllers/aspects_controller.rb @@ -64,6 +64,13 @@ class AspectsController < ApplicationController render :json => { :id => @aspect.id, :name => @aspect.name } end + def update_order + params[:ordered_aspect_ids].each_with_index do |id, i| + current_user.aspects.find(id).update_attributes(order_id: i) + end + render nothing: true + end + def toggle_chat_privilege @aspect = current_user.aspects.where(:id => params[:aspect_id]).first diff --git a/app/models/aspect.rb b/app/models/aspect.rb index 97c812f815f1e5889c6992f8aa7574e83ca2c0be..dfacdc8117208456938f9152678a6f94a3d90f15 100644 --- a/app/models/aspect.rb +++ b/app/models/aspect.rb @@ -20,6 +20,10 @@ class Aspect < ActiveRecord::Base name.strip! end + before_create do + self.order_id ||= Aspect.where(user_id: user_id).maximum(:order_id || 0).to_i + 1 + end + def to_s name end diff --git a/app/views/contacts/_aspect_listings.haml b/app/views/contacts/_aspect_listings.haml index 2e0d98945f7adfd348450ef465e4e0c884a85be8..664b412c65407a96100adc40e269fdc428b32f32 100644 --- a/app/views/contacts/_aspect_listings.haml +++ b/app/views/contacts/_aspect_listings.haml @@ -1,5 +1,5 @@ #aspect_nav - %ul.nav.nav-tabs.nav-stacked + %ul.nav.nav-tabs.nav-stacked.synced %li.all_contacts{:class => ("active" if params["set"] == "all")} %a{:href => contacts_path(:set => "all")} = t('contacts.index.all_contacts') diff --git a/config/routes.rb b/config/routes.rb index c7f924bae50ad23c1691f2b5b1ad32a9e9e0b792..997c8f77fe142bf7a737d88efc57816612c79c8b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -66,6 +66,9 @@ Diaspora::Application.routes.draw do resources :aspects do put :toggle_contact_visibility put :toggle_chat_privilege + collection do + put "order" => :update_order + end end get 'bookmarklet' => 'status_messages#bookmarklet' diff --git a/features/desktop/manages_aspects.feature b/features/desktop/manages_aspects.feature index 1d4f7e1dfa1b217a809373ec41bf2b4fcfda073e..5f6865eaf59aedb3ad9b2315b716762a3d452b3a 100644 --- a/features/desktop/manages_aspects.feature +++ b/features/desktop/manages_aspects.feature @@ -75,3 +75,13 @@ Feature: User manages contacts And I click on my name in the header When I follow "Contacts" Then I should not see "Community spotlight" within ".span9" + + Scenario: sorting the aspects + Given I am signed in + And I have an aspect called "People" + And I have an aspect called "Cat People" + When I am on the contacts page + And I drag "Cat People" up 40 pixels + And I go to the contacts page + Then I should see "Cat People" as 2. aspect + And I should see "People" as 3. aspect diff --git a/features/step_definitions/aspects_steps.rb b/features/step_definitions/aspects_steps.rb index 620c56b409a8d14ae29b512b7190f0dcc462365f..5d71150663ed0e7cc06ca44d30dadc49fa3479e2 100644 --- a/features/step_definitions/aspects_steps.rb +++ b/features/step_definitions/aspects_steps.rb @@ -88,6 +88,25 @@ When /^(.*) in the aspect creation modal$/ do |action| end end +When /^I drag "([^"]*)" (up|down) (\d+) pixels?$/ do |aspect_name, direction, distance| + distance = distance.to_i * -1 if direction == "up" + page.execute_script %{ + function drag() { + $("li.aspect:contains('#{aspect_name}')") + .simulate("drag-n-drop", { dy: #{distance}, interpolation: { stepWidth: 10, stepDelay: 5 } }); + } + function loadScripts() { + $.getScript("/assets/jquery-simulate/jquery.simulate.js", function(){ + $.getScript("/assets/jquery-simulate-ext/src/jquery.simulate.ext.js", function(){ + $.getScript("/assets/jquery-simulate-ext/src/jquery.simulate.drag-n-drop.js", drag); + }); + }); + } + if (!$.simulate) { loadScripts(); } else { drag(); } + } + expect(find("#aspect_nav")).to have_css ".synced" +end + And /^I toggle the aspect "([^"]*)"$/ do |name| toggle_aspect(name) end @@ -109,3 +128,7 @@ end Then /^the aspect dropdown should be visible$/ do aspect_dropdown_visible? end + +Then /^I should see "([^"]*)" as (\d+). aspect$/ do |aspect_name, position| + expect(find("#aspect_nav li:nth-child(#{position.to_i + 2})")).to have_text aspect_name +end diff --git a/spec/controllers/aspects_controller_spec.rb b/spec/controllers/aspects_controller_spec.rb index 65d413fde48b7cb46c52230ae1b9e4a43e77bd88..779e510dee0f50f2078f64464f16043b10b949ca 100644 --- a/spec/controllers/aspects_controller_spec.rb +++ b/spec/controllers/aspects_controller_spec.rb @@ -96,6 +96,19 @@ describe AspectsController, :type => :controller do end end + describe "update_order" do + it "updates the aspect order" do + @alices_aspect_1.update_attributes(order_id: 10) + @alices_aspect_2.update_attributes(order_id: 20) + ordered_aspect_ids = [@alices_aspect_2.id, @alices_aspect_1.id] + + put(:update_order, ordered_aspect_ids: ordered_aspect_ids) + + expect(Aspect.find(@alices_aspect_1.id).order_id).to eq(1) + expect(Aspect.find(@alices_aspect_2.id).order_id).to eq(0) + end + end + describe "#destroy" do before do @alices_aspect_1 = alice.aspects.create(name: "Contacts") diff --git a/spec/models/aspect_spec.rb b/spec/models/aspect_spec.rb index 4315345ae1b44f07c3bcaf25dedffab33325704f..4d85a2b1fc695ebfe876de45dc2a5b66b28404f2 100644 --- a/spec/models/aspect_spec.rb +++ b/spec/models/aspect_spec.rb @@ -39,6 +39,13 @@ describe Aspect, :type => :model do it 'has a contacts_visible? method' do expect(alice.aspects.first.contacts_visible?).to be true end + + it "sets an order_id" do + aspect_2 = alice.aspects.create(name: "People") + expect(aspect_2.order_id).to eq(2) + aspect_3 = alice.aspects.create(name: "Cat People") + expect(aspect_3.order_id).to eq(3) + end end describe 'validation' do