From 6461135bfd8182189c788c4de78a4bdf74620c6e Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Sun, 24 Aug 2014 13:40:03 +0200 Subject: [PATCH 1/4] Redesign contacts page --- app/assets/javascripts/app/router.js | 5 + .../javascripts/app/views/contacts_view.js | 47 ++++++ app/assets/stylesheets/contacts.css.scss | 156 +++++------------- app/assets/stylesheets/new-templates.css.scss | 6 +- .../_buttons.css.scss} | 0 app/assets/stylesheets/new_styles/_navs.scss | 14 ++ .../stylesheets/new_styles/_viewer_nav.scss | 18 -- app/assets/stylesheets/notifications.css.scss | 10 -- app/assets/stylesheets/people.css.scss | 34 ++-- app/controllers/contacts_controller.rb | 1 + app/helpers/contacts_helper.rb | 7 +- app/views/aspects/edit.html.haml | 24 --- .../aspects/toggle_contact_visibility.js.erb | 15 -- app/views/community_spotlight/_user.html.haml | 13 -- app/views/contacts/_aspect_listings.haml | 57 +++---- app/views/contacts/_contact.html.haml | 21 +-- app/views/contacts/_header.html.haml | 32 ++++ app/views/contacts/_sidebar.html.haml | 7 + app/views/contacts/index.html.haml | 62 +++---- app/views/contacts/spotlight.haml | 39 ++--- app/views/people/_person.html.haml | 27 ++- app/views/people/_relationship_action.haml | 3 +- app/views/shared/_contact_sidebar.html.haml | 13 -- 23 files changed, 269 insertions(+), 342 deletions(-) create mode 100644 app/assets/javascripts/app/views/contacts_view.js rename app/assets/stylesheets/{buttons.css.scss => new_styles/_buttons.css.scss} (100%) create mode 100644 app/assets/stylesheets/new_styles/_navs.scss delete mode 100644 app/assets/stylesheets/new_styles/_viewer_nav.scss delete mode 100644 app/views/aspects/edit.html.haml delete mode 100644 app/views/aspects/toggle_contact_visibility.js.erb delete mode 100644 app/views/community_spotlight/_user.html.haml create mode 100644 app/views/contacts/_header.html.haml create mode 100644 app/views/contacts/_sidebar.html.haml delete mode 100644 app/views/shared/_contact_sidebar.html.haml diff --git a/app/assets/javascripts/app/router.js b/app/assets/javascripts/app/router.js index 4f6568b2c..717c4e1ba 100644 --- a/app/assets/javascripts/app/router.js +++ b/app/assets/javascripts/app/router.js @@ -1,6 +1,7 @@ app.Router = Backbone.Router.extend({ routes: { "help": "help", + "contacts": "contacts", //new hotness "posts/:id": "singlePost", @@ -37,6 +38,10 @@ app.Router = Backbone.Router.extend({ app.help.render(); }, + contacts: function() { + app.contacts = new app.views.Contacts(); + }, + singlePost : function(id) { this.renderPage(function(){ return new app.pages.SinglePostViewer({ id: id })}); }, diff --git a/app/assets/javascripts/app/views/contacts_view.js b/app/assets/javascripts/app/views/contacts_view.js new file mode 100644 index 000000000..5475f9b7b --- /dev/null +++ b/app/assets/javascripts/app/views/contacts_view.js @@ -0,0 +1,47 @@ +app.views.Contacts = Backbone.View.extend({ + + el: "#contacts_container", + + events: { + "click #contacts_visibility_toggle" : "toggleContactVisibility", + "click #change_aspect_name" : "showNameChangeForm" + }, + + initialize: function() { + this.visibility_toggle = $("#contacts_visibility_toggle .entypo"); + $("#people_stream.contacts .header .entypo").tooltip({ 'placement': 'bottom'}); + $(".contact_remove-from-aspect").tooltip(); + $(document).on('ajax:success', 'form.edit_aspect', this.updateAspectName); + }, + + toggleContactVisibility: function() { + if (this.visibility_toggle.hasClass("lock-open")) { + this.visibility_toggle.removeClass("lock-open") + .addClass("lock") + .tooltip("destroy") + .removeAttr("data-original-title") + .attr("title", Diaspora.I18n.t("aspects.edit.aspect_list_is_not_visible")) + .tooltip(); + } + else { + this.visibility_toggle.removeClass("lock") + .addClass("lock-open") + .tooltip("destroy") + .removeAttr("data-original-title") + .attr("title", Diaspora.I18n.t("aspects.edit.aspect_list_is_visible")) + .tooltip(); + } + }, + + showNameChangeForm: function() { + $(".header > h3").hide(); + $(".header > #aspect_name_form").show(); + }, + + updateAspectName: function(evt,data,status,xhr){ + $(".header #aspect_name").text(data['name']); + $("#aspect_nav [data-aspect-id='"+data['id']+"'] .name").text(data['name']); + $(".header > #aspect_name_form").hide(); + $(".header > h3").show(); + } +}); diff --git a/app/assets/stylesheets/contacts.css.scss b/app/assets/stylesheets/contacts.css.scss index d2f786321..1ccb84f4d 100644 --- a/app/assets/stylesheets/contacts.css.scss +++ b/app/assets/stylesheets/contacts.css.scss @@ -1,121 +1,53 @@ -#section_header { - h3 { - border-bottom: 1px solid $border-grey; - } -} - -#people_stream { - .bd { - font-size: 13px; - line-height: 19.5px; - } - - .btn-group { - margin-top: 5px; - - .caret { - margin-top: 8px; - } - - .text { - text-shadow: none; - } - } - - .info { - font-size: 11px; - line-height: 16.5px; - } - - .stream_element { - border-bottom: 1px solid $border-grey; - - .icons-monotone_close_exit_delete { - margin-top: 8px; - } - - .media { - margin: 10px; - } - } -} -#people_stream.contacts { - .stream_element { - padding: 10px; - min-height: 30px; - - .media { overflow: visible; } - - .float-right { - top: 16px; - - a { - @include opacity(1); - - &:hover { - @include opacity(0.6); +#contacts_container { + #people_stream.contacts { + .header { + border-bottom: 1px solid $border-grey; + margin-top: 10px; + min-height: 53px; + #change_aspect_name { cursor: pointer; } + #aspect_name_form { + display: none; + form { margin: 0px; } + input { + margin-bottom: 0px; + margin-top: 10px; } + .btn { margin-top: 10px; } + } + a { + text-decoration: none; + margin-right: 25px; + } + .entypo { + font-size: 24.5px; + line-height: 40px; + color: lighten($black,75%); + &:hover { color: $black; } + } + .btn { margin-top: 8px; } + } + + .contact_remove-from-aspect { + text-decoration: none; + .entypo { + font-size: 20px; + line-height: 50px; + margin: 10px; + color: lighten($black,75%); + &:hover { color: $black; } } } - - .info { margin-top: -2px; } - } - - .avatar { - height: 30px; - width: 30px; - } - - .icons-monotone_close_exit_delete { - height: 14px; - width: 14px; - } - - .no_contacts { - text-align: center; - margin-top: 50px; + + .no_contacts { + text-align: center; + margin-top: 50px; + } } } -#community_spotlight { - .avatar { - width: 140px; - height: 140px; - } - - .user_card { - @include border-radius(3px); - @include box-shadow(0,1px,5px,#ccc); - - border: 1px solid #ccc; - display: inline-block; - margin-bottom: 15px; - margin-right: 10px; - min-height: 220px; - padding: 10px 10px 30px 10px; - position: relative; - vertical-align: top; - width: 140px; - - h4 { - margin-bottom: 0px; - padding-bottom: 2px; - } - - .add_user_to_aspect { - bottom: 10px; - right: 10px; - position: absolute; - } - - .dropdown { - width: 100%; - } - - .tags { - color: $text-grey; - } - } +#aspect_nav { + li.aspect > a { padding-left: 30px; } + li.new_aspect > a { padding-left: 30px; } } #no_contacts { diff --git a/app/assets/stylesheets/new-templates.css.scss b/app/assets/stylesheets/new-templates.css.scss index 27d619a6d..e98b7bc6b 100644 --- a/app/assets/stylesheets/new-templates.css.scss +++ b/app/assets/stylesheets/new-templates.css.scss @@ -9,8 +9,7 @@ @import 'sprites'; @import 'new_styles/base'; -@import 'new_styles/viewer_nav'; -@import 'buttons'; +@import 'new_styles/buttons'; /* font overrides */ @import 'new_styles/typography'; @@ -22,6 +21,9 @@ @import 'new_styles/forms'; +/* navs */ +@import 'new_styles/navs'; + /* profile and settings pages */ @import 'new_styles/settings'; diff --git a/app/assets/stylesheets/buttons.css.scss b/app/assets/stylesheets/new_styles/_buttons.css.scss similarity index 100% rename from app/assets/stylesheets/buttons.css.scss rename to app/assets/stylesheets/new_styles/_buttons.css.scss diff --git a/app/assets/stylesheets/new_styles/_navs.scss b/app/assets/stylesheets/new_styles/_navs.scss new file mode 100644 index 000000000..f433eebf1 --- /dev/null +++ b/app/assets/stylesheets/new_styles/_navs.scss @@ -0,0 +1,14 @@ +.nav.nav-tabs{ + li > a { + color: $text-dark-grey; + .entypo { + color: $text-dark-grey; + margin-right: 5px; + } + } + li.active > a { + background-color: $background-grey; + color: $black; + .entypo { color: $black; } + } +} diff --git a/app/assets/stylesheets/new_styles/_viewer_nav.scss b/app/assets/stylesheets/new_styles/_viewer_nav.scss deleted file mode 100644 index 36b847652..000000000 --- a/app/assets/stylesheets/new_styles/_viewer_nav.scss +++ /dev/null @@ -1,18 +0,0 @@ -@import '../mixins'; - -body.idle { - #post-nav { - @include opacity(0); - - .nav-arrow{ - &.right { - margin-right: -40px; - } - - &.left { - margin-left: -40px; - } - } - - } -} diff --git a/app/assets/stylesheets/notifications.css.scss b/app/assets/stylesheets/notifications.css.scss index a2998d139..8e93fdedd 100644 --- a/app/assets/stylesheets/notifications.css.scss +++ b/app/assets/stylesheets/notifications.css.scss @@ -1,18 +1,8 @@ #notifications_container { .nav.nav-tabs{ li > a { - color: $text-dark-grey; - .entypo { - color: $text-dark-grey; - margin-right: 5px; - } .badge.badge-default { display: none; } } - li.active > a { - background-color: $background-grey; - color: $black; - .entypo { color: $black; } - } } .stream { diff --git a/app/assets/stylesheets/people.css.scss b/app/assets/stylesheets/people.css.scss index 682d412a9..0c0c67783 100644 --- a/app/assets/stylesheets/people.css.scss +++ b/app/assets/stylesheets/people.css.scss @@ -1,17 +1,29 @@ #people_search { - #people_stream { - .stream_element { - border-bottom: 1px solid $border-grey; - padding-right: 10px; - .avatar { - width: 50px; - height: 50px; - } - .info { font-size: 11px; } - } - } #search_title { .term { font-weight: 700; } small { margin-left: 15px; } } } +#people_stream { + .media, .media-body { + overflow: visible; + } + .stream_element.media { + border-bottom: 1px solid $border-grey; + padding: 10px; + margin: 0px; + font-size: 13px; + line-height: 16px; + min-height: 50px; + .avatar { + width: 50px; + height: 50px; + } + .btn-group.aspect_membership_dropdown { margin: 12px 0; } + .thats_you { + line-height: 50px; + margin-right: 20px; + } + .info { font-size: 11px; } + } +} diff --git a/app/controllers/contacts_controller.rb b/app/controllers/contacts_controller.rb index 9508b4eb2..e8941e21c 100644 --- a/app/controllers/contacts_controller.rb +++ b/app/controllers/contacts_controller.rb @@ -5,6 +5,7 @@ class ContactsController < ApplicationController before_action :authenticate_user! + layout ->(c) { request.format == :mobile ? "application" : "with_header_with_footer" } use_bootstrap_for :index, :spotlight def index diff --git a/app/helpers/contacts_helper.rb b/app/helpers/contacts_helper.rb index 53edbc6e0..7db5f2498 100644 --- a/app/helpers/contacts_helper.rb +++ b/app/helpers/contacts_helper.rb @@ -3,7 +3,7 @@ module ContactsHelper membership = contact.aspect_memberships.where(:aspect_id => @aspect.id).first unless @aspect.nil? if membership - link_to(content_tag(:div, nil, :class => 'icons-monotone_close_exit_delete'), + link_to(content_tag(:i, nil, :class => 'entypo circled-cross'), { :controller => "aspect_memberships", :action => 'destroy', :id => membership.id @@ -24,12 +24,11 @@ module ContactsHelper def start_a_conversation_link(aspect, contacts_size) suggested_limit = 16 - conv_opts = { class: "btn conversation_button", rel: "facebox"} + conv_opts = { class: "conversation_button", rel: "facebox"} conv_opts[:title] = t('.many_people_are_you_sure', suggested_limit: suggested_limit) if contacts_size > suggested_limit link_to new_conversation_path(aspect_id: aspect.id, name: aspect.name), conv_opts do - concat t('.start_a_conversation') - concat content_tag(:span, nil, class: "icons-mail") + content_tag(:i, nil, :class => 'entypo mail', :title => t('contacts.index.start_a_conversation')) end end end diff --git a/app/views/aspects/edit.html.haml b/app/views/aspects/edit.html.haml deleted file mode 100644 index f2c2d7d75..000000000 --- a/app/views/aspects/edit.html.haml +++ /dev/null @@ -1,24 +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. - -#aspect_edit_pane - #facebox_header{:data=>{:guid=>@aspect.id}} - %h3#aspect_name_title - %span.name= @aspect - %span.tiny_text - = link_to t('.rename'), '#', :id => 'rename_aspect_link' - - #aspect_name_edit.hidden - = form_for @aspect, :remote => true do |aspect| - = aspect.text_field :name, :maxlength => 20 - = aspect.submit t('.update'), 'data-disable-with' => t('.updating'), :class => 'btn' - - - if @contacts.count > 0 - = render 'shared/contact_list', :aspect => @aspect, :contacts => @contacts - - .bottom_submit_section - = button_to t('delete'), @aspect, :method => "delete", :data => { :confirm => t('.confirm_remove_aspect') }, :class => 'btn delete' - = aspect_visibility_link(@aspect) - = submit_tag t('.done'), :class => 'btn creation', :rel => 'close' - diff --git a/app/views/aspects/toggle_contact_visibility.js.erb b/app/views/aspects/toggle_contact_visibility.js.erb deleted file mode 100644 index 1470cadb1..000000000 --- a/app/views/aspects/toggle_contact_visibility.js.erb +++ /dev/null @@ -1,15 +0,0 @@ -$(document).ready(function() { - - var padlockImg = $(".contact_visibility_padlock"); - var linkText = $(".contact_visibility_link"); - - if (padlockImg.hasClass('icons-padlock-open')) { - padlockImg.removeClass('icons-padlock-open'); - padlockImg.addClass('icons-padlock-closed'); - linkText.attr('title', "<%= t('aspects.edit.aspect_list_is_not_visible') %>"); - } else { - padlockImg.removeClass('icons-padlock-closed'); - padlockImg.addClass('icons-padlock-open'); - linkText.attr('title', "<%= t('aspects.edit.aspect_list_is_visible') %>"); - } -}); diff --git a/app/views/community_spotlight/_user.html.haml b/app/views/community_spotlight/_user.html.haml deleted file mode 100644 index 3b7ae837d..000000000 --- a/app/views/community_spotlight/_user.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -.user_card - = person_image_link(person, :size => :thumb_large) - %h4 - = person.name - - .tags - - person.tags.each do |tag| - = link_to "##{tag}", tag_path(:name => tag.name) - - .add_user_to_aspect - = render :partial => 'people/relationship_action', - :locals => { :person => person, :contact => current_user.contact_for(person), - :current_user => current_user } diff --git a/app/views/contacts/_aspect_listings.haml b/app/views/contacts/_aspect_listings.haml index bdad07996..413ac2b4b 100644 --- a/app/views/contacts/_aspect_listings.haml +++ b/app/views/contacts/_aspect_listings.haml @@ -1,36 +1,31 @@ --# Copyright (c) 2010-2011, Diaspora Inc. This file is --# licensed under the Affero General Public License version 3 or later. See --# the COPYRIGHT file. +#aspect_nav + %ul.nav.nav-tabs.nav-stacked + %li.all_contacts{:class => ("active" if params["set"] == "all")} + %a{:href => contacts_path(:set => "all")} + = t('contacts.index.all_contacts') + .badge.badge-default.pull-right + = all_contacts_count -%ul#aspect_nav - %li.all_aspects{:class => ("active" if params["set"] != "all" && params["set"] != "only_sharing" && !@spotlight)} - %a.home_selector.hoverable{:href => contacts_path, :class => ("sub_selected" if params["a_id"])} - = t('contacts.index.my_contacts') - .label.pull-right - = my_contacts_count - - %ul.sub_nav#aspects_list - - all_aspects.each do |aspect| - %li.hoverable{:data => {:aspect_id => aspect.id}, :class => ("active" if params["a_id"].to_i == aspect.id)} - .label.pull-right + %li.all_aspects{:class => ("active" if !params["set"] && !params["a_id"] && !@spotlight)} + %a{:href => contacts_path} + = t('contacts.index.my_contacts') + .badge.badge-default.pull-right + = my_contacts_count + + - all_aspects.each do |aspect| + %li.aspect{:data => {:aspect_id => aspect.id}, :class => ("active" if params["a_id"].to_i == aspect.id)} + %a{:href => contacts_path(:a_id => aspect.id)} + .badge.badge-default.pull-right = aspect.contacts.size - .icons-check_yes_ok{:class => ("selected" if params["a_id"].to_i == aspect.id) } - %a.selectable{:href => contacts_path(:a_id => aspect.id)} + .name = aspect - %li.hoverable - = link_to t('aspects.aspect_listings.add_an_aspect'), new_aspect_path, :class => "selectable new_aspect", :rel => "facebox" + %li.new_aspect + %a{:href => new_aspect_path, :rel => "facebox"} + = t('aspects.aspect_listings.add_an_aspect') - %li.all_contacts{:class => ("active" if params["set"] == "all" || params["set"] == "only_sharing")} - %a.home_selector.hoverable{:href => contacts_path(:set => "all"), :class => ("sub_selected" if params["set"] == "only_sharing")} - = t('contacts.index.all_contacts') - .label.pull-right - = all_contacts_count - - %ul.sub_nav - %li.hoverable{:class => ("active" if params["set"] == "only_sharing")} - .icons-check_yes_ok{:class => ("invisible" if params["set"] == "only_sharing")} - %a.selectable{:href => contacts_path(:set => "only_sharing")} - = t('contacts.index.only_sharing_with_me') - .label.pull-right - = only_sharing_count + %li.only_sharing{:class => ("active" if params["set"] == "only_sharing")} + %a{:href => contacts_path(:set => "only_sharing")} + = t('contacts.index.only_sharing_with_me') + .badge.badge-default.pull-right + = only_sharing_count diff --git a/app/views/contacts/_contact.html.haml b/app/views/contacts/_contact.html.haml index bc7a9756f..2a005f457 100644 --- a/app/views/contacts/_contact.html.haml +++ b/app/views/contacts/_contact.html.haml @@ -1,10 +1,11 @@ -.stream_element{:id => contact.person_id} - .media - .pull-right - = contact_aspect_dropdown(contact) - .img - = person_image_link(contact.person, :size => :thumb_small) - .bd - = person_link(contact.person) - .info - = contact.person_diaspora_handle +.media.stream_element{:id => contact.person_id} + .pull-right + = contact_aspect_dropdown(contact) + .media-object.pull-left + = person_image_link(contact.person, :size => :thumb_small) + .media-body + = person_link(contact.person) + .info.diaspora_handle + = contact.person_diaspora_handle + .info.tags + = Diaspora::Taggable.format_tags(contact.person.profile.tag_string) diff --git a/app/views/contacts/_header.html.haml b/app/views/contacts/_header.html.haml new file mode 100644 index 000000000..e930b4edb --- /dev/null +++ b/app/views/contacts/_header.html.haml @@ -0,0 +1,32 @@ +.header + - if @aspect + #aspect_control.pull-right + - if @contacts_size > 0 && @contacts_size < 20 + = start_a_conversation_link(@aspect, @contacts_size) + = link_to aspect_toggle_contact_visibility_path(@aspect), id: "contacts_visibility_toggle", method: :put, remote: true do + -if @aspect.contacts_visible? + %i.entypo.lock-open{:title => t('aspects.edit.aspect_list_is_visible')} + -else + %i.entypo.lock{:title => t('aspects.edit.aspect_list_is_not_visible')} + = link_to @aspect, method: "delete", data: { confirm: t('aspects.edit.confirm_remove_aspect') }, class: 'delete' do + %i.entypo.trash{:title => t('delete')} + %h3 + %span#aspect_name + = @aspect.name + %span#change_aspect_name + %i.entypo.pencil{:title => t('aspects.edit.rename')} + #aspect_name_form + = form_for @aspect, :remote => true do |aspect| + = aspect.text_field :name, :maxlength => 20 + = aspect.submit t('aspects.edit.update'), 'data-disable-with' => t('aspects.edit.updating'), :class => "btn green" + + - else + %h3 + - case params["set"] + - when "only_sharing" + = t('contacts.index.only_sharing_with_me') + - when "all" + = t('contacts.index.all_contacts') + - else + = t('contacts.index.my_contacts') + diff --git a/app/views/contacts/_sidebar.html.haml b/app/views/contacts/_sidebar.html.haml new file mode 100644 index 000000000..2c92a9c2b --- /dev/null +++ b/app/views/contacts/_sidebar.html.haml @@ -0,0 +1,7 @@ +%h3 + = t('contacts.index.title') += render 'contacts/aspect_listings' +- if AppConfig.settings.community_spotlight.enable? + %hr + .text-center.spotlight + = link_to t('contacts.spotlight.community_spotlight'), community_spotlight_path, :class => "element_selector" diff --git a/app/views/contacts/index.html.haml b/app/views/contacts/index.html.haml index 0fc1a81c9..53f7aaf2f 100644 --- a/app/views/contacts/index.html.haml +++ b/app/views/contacts/index.html.haml @@ -1,49 +1,31 @@ --# Copyright (c) 2010-2011, Diaspora Inc. This file is --# licensed under the Affero General Public License version 3 or later. See --# the COPYRIGHT file. - - content_for :page_title do = t('.title') - content_for :head do = javascript_include_tag :people -.row - .span12 - #section_header - %h3 - = t('.title') +.container-fluid#contacts_container + .row-fluid + .span3 + = render 'contacts/sidebar' -.row - = render 'shared/contact_sidebar' + .span9 + #people_stream.stream.contacts + = render 'contacts/header' - .span9 - #people_stream.stream.contacts - - if @aspect - #aspect_controls - - if @contacts_size > 0 && @contacts_size < 20 - = start_a_conversation_link(@aspect, @contacts_size) - = link_to edit_aspect_path(@aspect), rel: "facebox", class: "btn" do - = t('aspects.edit.manage') - %span.modify_aspect - = aspect_visibility_link(@aspect) - = link_to @aspect, method: "delete", data: { confirm: t('aspects.edit.confirm_remove_aspect') }, class: 'btn delete' do - = t('delete') - %span.icons-monotone_close_exit_delete + - if @contacts_size > 0 + = render @contacts - - if @contacts_size > 0 - = render @contacts - - = will_paginate @contacts - - else - .no_contacts - %h3 - = t('.no_contacts') - %p - - if @aspect - != t('.no_contacts_message_with_aspect', - :community_spotlight => link_to(t('.community_spotlight'), community_spotlight_path), - :add_to_aspect_link => link_to(t('.add_to_aspect_link', :name => @aspect.name), edit_aspect_path(@aspect), :rel => "facebox")) - - else - != t('.no_contacts_message', - :community_spotlight => link_to(t('.community_spotlight'), community_spotlight_path)) + = will_paginate @contacts + - else + .no_contacts + %h3 + = t('.no_contacts') + %p + - if @aspect + != t('.no_contacts_message_with_aspect', + :community_spotlight => link_to(t('.community_spotlight'), community_spotlight_path), + :add_to_aspect_link => link_to(t('.add_to_aspect_link', :name => @aspect.name), edit_aspect_path(@aspect), :rel => "facebox")) + - else + != t('.no_contacts_message', + :community_spotlight => link_to(t('.community_spotlight'), community_spotlight_path)) diff --git a/app/views/contacts/spotlight.haml b/app/views/contacts/spotlight.haml index 53c8515ea..6dc2fbbc3 100644 --- a/app/views/contacts/spotlight.haml +++ b/app/views/contacts/spotlight.haml @@ -1,31 +1,28 @@ --# Copyright (c) 2010-2011, Diaspora Inc. This file is --# licensed under the Affero General Public License version 3 or later. See --# the COPYRIGHT file. - - content_for :page_title do = t('contacts.spotlight.community_spotlight') - content_for :head do = javascript_include_tag :people -.row - .span12 - #section_header - %h3 - = t('contacts.index.title') -.row - = render 'shared/contact_sidebar' +.container-fluid#contacts_container + .row-fluid + .span3 + = render 'contacts/sidebar' - .span9 - - if AppConfig.settings.community_spotlight.suggest_email.present? - .right - = link_to t('contacts.spotlight.suggest_member'), "mailto:#{AppConfig.settings.community_spotlight.suggest_email}", :class => "button" + .span9 + #people_stream.stream.contacts + .header + - if AppConfig.settings.community_spotlight.suggest_email.present? + .pull-right + = link_to t('contacts.spotlight.suggest_member'), "mailto:#{AppConfig.settings.community_spotlight.suggest_email}", :class => "btn btn-default" + %h3 + = t('contacts.spotlight.community_spotlight') - %h3 - = t('contacts.spotlight.community_spotlight') + #community_spotlight + - unless @people.blank? + - @people.each do |person| + = render 'people/person', :person => person, :contact => current_user.contact_for(person) - #community_spotlight - - unless @people.blank? - - @people.each do |person| - = render 'community_spotlight/user', :person => person + -# if @contacts_size > 0 + = render @contacts diff --git a/app/views/people/_person.html.haml b/app/views/people/_person.html.haml index 3b52a18dc..15f4ca690 100644 --- a/app/views/people/_person.html.haml +++ b/app/views/people/_person.html.haml @@ -1,20 +1,13 @@ --# Copyright (c) 2010-2011, Diaspora Inc. This file is --# licensed under the Affero General Public License version 3 or later. See --# the COPYRIGHT file. - -.stream_element{:id => person.id} - %div{:style => "float:right;margin-top:2px;"} +.media.stream_element{:id => person.id} + .pull-right = render :partial => 'people/relationship_action', :locals => { :person => person, :contact => contact, :current_user => current_user } - - .media - .img - = person_image_link(person) - - .bd - =person_link(person) - - .info - = Diaspora::Taggable.format_tags(person.profile.tag_string) - + .media-object.pull-left + = person_image_link(person) + .media-body + = person_link(person) + .info.diaspora_handle + = person.diaspora_handle + .info.tags + = Diaspora::Taggable.format_tags(person.profile.tag_string) diff --git a/app/views/people/_relationship_action.haml b/app/views/people/_relationship_action.haml index 8a73875b5..b4ab1df04 100644 --- a/app/views/people/_relationship_action.haml +++ b/app/views/people/_relationship_action.haml @@ -3,4 +3,5 @@ - contact ||= Contact.new(:person => person) = aspect_membership_dropdown(contact, person, 'right') -else - = t('people.person.thats_you') + %span.thats_you + = t('people.person.thats_you') diff --git a/app/views/shared/_contact_sidebar.html.haml b/app/views/shared/_contact_sidebar.html.haml deleted file mode 100644 index 4a8fd9335..000000000 --- a/app/views/shared/_contact_sidebar.html.haml +++ /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. - -#leftNavBar.span3 - = render 'contacts/aspect_listings' - - - if AppConfig.settings.community_spotlight.enable? - %hr - - %ul.left_nav - %li{:class => ("active" if @spotlight)} - = link_to t('contacts.spotlight.community_spotlight'), community_spotlight_path, :class => "element_selector" From 95879618836d09f0fd94274976907cfdd6d50ca7 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Mon, 25 Aug 2014 03:11:38 +0200 Subject: [PATCH 2/4] Display all contacts in the contact list --- .../javascripts/app/views/contacts_view.js | 4 +- app/assets/javascripts/aspect-edit-pane.js | 31 --- app/assets/stylesheets/aspects.css.scss | 218 ------------------ app/assets/stylesheets/contacts.css.scss | 8 +- app/controllers/aspects_controller.rb | 2 +- app/controllers/contacts_controller.rb | 33 ++- app/helpers/contacts_helper.rb | 17 +- app/views/aspects/edit.html.haml | 13 ++ app/views/contacts/_header.html.haml | 13 +- app/views/contacts/index.html.haml | 5 +- app/views/contacts/sharing.haml | 30 --- app/views/contacts/spotlight.haml | 2 +- config/routes.rb | 1 - 13 files changed, 72 insertions(+), 305 deletions(-) create mode 100644 app/views/aspects/edit.html.haml delete mode 100644 app/views/contacts/sharing.haml diff --git a/app/assets/javascripts/app/views/contacts_view.js b/app/assets/javascripts/app/views/contacts_view.js index 5475f9b7b..1c85a3599 100644 --- a/app/assets/javascripts/app/views/contacts_view.js +++ b/app/assets/javascripts/app/views/contacts_view.js @@ -4,7 +4,7 @@ app.views.Contacts = Backbone.View.extend({ events: { "click #contacts_visibility_toggle" : "toggleContactVisibility", - "click #change_aspect_name" : "showNameChangeForm" + "click #change_aspect_name" : "showAspectNameForm" }, initialize: function() { @@ -33,7 +33,7 @@ app.views.Contacts = Backbone.View.extend({ } }, - showNameChangeForm: function() { + showAspectNameForm: function() { $(".header > h3").hide(); $(".header > #aspect_name_form").show(); }, diff --git a/app/assets/javascripts/aspect-edit-pane.js b/app/assets/javascripts/aspect-edit-pane.js index 57be91bd2..27dc0f07d 100644 --- a/app/assets/javascripts/aspect-edit-pane.js +++ b/app/assets/javascripts/aspect-edit-pane.js @@ -1,34 +1,3 @@ -/* Copyright (c) 2010-2011, Diaspora Inc. This file is - * licensed under the Affero General Public License version 3 or later. See - * the COPYRIGHT file. - */ - -function toggleAspectTitle(){ - $("#aspect_name_title").toggleClass('hidden'); - $("#aspect_name_edit").toggleClass('hidden'); -} - -function updateAspectName(new_name) { - $('#aspect_name_title .name').text(new_name); - $('input#aspect_name').val(new_name); -} -function updatePageAspectName( an_id, new_name) { - $('ul#aspect_nav [data-aspect-id="'+an_id+'"] .selectable').text(new_name); -} - -$(document).ready(function() { - $(document).on('click', '#rename_aspect_link', function(){ - toggleAspectTitle(); - }); - - $(document).on('ajax:success', 'form.edit_aspect', function(evt, data, status, xhr) { - updateAspectName(data['name']); - updatePageAspectName( data['id'], data['name'] ); - toggleAspectTitle(); - }); -}); - - /** * TEMPORARY SOLUTION * TODO remove me, when the contacts section is done with Backbone.js ... diff --git a/app/assets/stylesheets/aspects.css.scss b/app/assets/stylesheets/aspects.css.scss index 8b2730d08..a6603be88 100644 --- a/app/assets/stylesheets/aspects.css.scss +++ b/app/assets/stylesheets/aspects.css.scss @@ -38,224 +38,6 @@ display: inline-block; } - - -/* -- Used in contacts/index.html.haml -- */ -#aspect_controls { - @include border-radius(2px); - background-color: #fafafa; - border: 1px solid #ccc; - padding: 10px; - min-height: 23px; - - .button, .button_to { - margin-right: 5px; - } - - .button_to { display: inline-block; } - - .contact_visibility_padlock, - .modify_aspect, - .icons-mail, - .icons-monotone_close_exit_delete { - margin-left: 4px; - margin-bottom: -2px; - display: inline-block; - } - - .icons-mail { - width: 16px; - height: 13px; - margin-bottom: -1px; - } -} - -#aspect_nav { - list-style-type: none; - - .icons-check_yes_ok { - height:18px; - width:18px; - background: url('icons/check_yes_ok.png') no-repeat; - float: left; - visibility: hidden; - - &.selected { - visibility: visible; - } - - &.selected + a { - color: #333333; - } - } -} - -.contact_visibility_padlock { - height: 16px; - width: 16px; - /* -- To remove when the facebox will be deleted -- */ - display: inline-block; - margin-left: 4px; - margin-bottom: -2px; -} - -/* -- Used in aspects/edit.haml and in contacts/sharing.haml -- */ -#aspect_edit_controls { margin-top: 8px; } -#aspect_edit_pane { - width: 772px; - - .contact_list_controls { - height: 30px; - margin-bottom: 5px; - } - - #aspect_name_title { - margin: 0px 0px 5px 0px; - } - - #contact_list_search { - width: 200px; - margin-bottom: 2px; - margin-top: 0px; - float: right; - } - - .contact_list, - .aspect_list { - @include border-radius(3px); - height: 300px; - max-height: 300px; - overflow-y: auto; - overflow-x: hidden; - border: 1px solid #bbb; - background-color: rgb(252,252,252); - - .avatar { - float: left; - height: 50px; - width: 50px; - margin-right: 10px !important; - } - - .button.share { - padding-right: 20px; - .right { - right: 8px; - top: 3px; - } - } - - .icons-monotone_plus_add_round, - .icons-monotone_check_yes { - height: 20px; - width: 20px; - } - - & > .contacts { - margin: 0px; - padding: 5px; - padding-right: 0px; - - & > .contact { - @include border-radius(3px); - @include box-shadow(0, 1px, 5px, #ccc); - position: relative; - display: inline-block; - float: left; - height: 50px; - width: 170px; - overflow-x: hidden; - overflow-y: hidden; - margin-bottom: 5px; - margin-right: 5px; - padding: 5px; - background-color: #fff; - border: 1px solid $border-dark-grey; - - &.hidden { display: none; } - &.remote_friend { width: 285px; } - - & > .name { - font-size: 16px; - margin: 0px 0px 5px 0px; - white-space: nowrap; - } - - a.btn { - @include box-shadow(0,0,0); - border-bottom: none; - min-width: 90px; - float: right; - padding: 2px 0px; - margin-top: 5px; - margin-right: -5px; - - &.added { - @include linear-gradient(rgb(158,255,153), rgb(92,199,86)); - background-color: rgb(92,199,86); - } - - &.added.remove { - @include linear-gradient(rgb(255,153,153), rgb(199,86,86)); - - &:active { @include linear-gradient(rgb(199,119,119), rgb(130,55,55)); } - } - } - } - } - } - - .aspect_list { - height: 300px; - max-height: 300px; - - .name { left: 1em; } - - ul > li { - padding: 1em; - height: 1em; - - .right { - top: 2px; - right: 1em; - } - } - } - - .person_tiles .tile { - @include border-radius(2px); - padding: 6px; - padding-left: 65px; - margin: 3px; - margin-left: 0px; - display: inline-block; - width: 126px; - height: 50px; - border: 1px solid #eee; - position: relative; - - img { - position: absolute; - left: 6px; - } - } - - &.larger { width: 650px; } - - .bottom_submit_section { - margin-top: 12px; - - form { - display: inline-block; - margin: 0px; - } - - .creation { - float: right; - } - } -} - #new_aspect { #aspect_contacts_visible.checkbox { margin: 0px; diff --git a/app/assets/stylesheets/contacts.css.scss b/app/assets/stylesheets/contacts.css.scss index 1ccb84f4d..337660435 100644 --- a/app/assets/stylesheets/contacts.css.scss +++ b/app/assets/stylesheets/contacts.css.scss @@ -14,20 +14,20 @@ } .btn { margin-top: 10px; } } - a { + & > a, #aspect_controls > a { text-decoration: none; margin-right: 25px; } - .entypo { + .entypo.contacts-header-icon { font-size: 24.5px; line-height: 40px; color: lighten($black,75%); &:hover { color: $black; } } - .btn { margin-top: 8px; } + #suggest_member.btn { margin-top: 8px; } } - .contact_remove-from-aspect { + .contact_remove-from-aspect, .contact_add-to-aspect { text-decoration: none; .entypo { font-size: 20px; diff --git a/app/controllers/aspects_controller.rb b/app/controllers/aspects_controller.rb index 4afce2b8d..18c354826 100644 --- a/app/controllers/aspects_controller.rb +++ b/app/controllers/aspects_controller.rb @@ -78,7 +78,7 @@ class AspectsController < ApplicationController @contacts_not_in_aspect = current_user.contacts.where(c[:id].not_in(@contacts_in_aspect.map(&:id))).includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } end - @contacts = @contacts_in_aspect + @contacts_not_in_aspect + @contacts = @contacts_not_in_aspect unless @aspect render :file => Rails.root.join('public', '404.html').to_s, :layout => false, :status => 404 diff --git a/app/controllers/contacts_controller.rb b/app/controllers/contacts_controller.rb index e8941e21c..ad8b76013 100644 --- a/app/controllers/contacts_controller.rb +++ b/app/controllers/contacts_controller.rb @@ -11,11 +11,11 @@ class ContactsController < ApplicationController def index respond_to do |format| - # Used for normal requests to contacts#index and subsequent infinite scroll calls + # Used for normal requests to contacts#index format.html { set_up_contacts } # Used by the mobile site - format.mobile { set_up_contacts } + format.mobile { set_up_contacts_mobile } # Used to populate mentions in the publisher format.json { @@ -26,11 +26,6 @@ class ContactsController < ApplicationController end end - def sharing - @contacts = current_user.contacts.sharing.includes(:aspect_memberships) - render :layout => false - end - def spotlight @spotlight = true @people = Person.community_spotlight @@ -39,6 +34,30 @@ class ContactsController < ApplicationController private def set_up_contacts + c = Contact.arel_table + @contacts = case params[:set] + when "only_sharing" + current_user.contacts.only_sharing.to_a.sort_by { |c| c.person.name } + when "all" + current_user.contacts.to_a.sort_by { |c| c.person.name } + else + if params[:a_id] + @aspect = current_user.aspects.find(params[:a_id]) + @contacts_in_aspect = @aspect.contacts.includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } + if @contacts_in_aspect.empty? + @contacts_not_in_aspect = current_user.contacts.includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } + else + @contacts_not_in_aspect = current_user.contacts.where(c[:id].not_in(@contacts_in_aspect.map(&:id))).includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } + end + @contacts_in_aspect + @contacts_not_in_aspect + else + current_user.contacts.receiving.to_a.sort_by { |c| c.person.name } + end + end + @contacts_size = @contacts.length + end + + def set_up_contacts_mobile @contacts = case params[:set] when "only_sharing" current_user.contacts.only_sharing diff --git a/app/helpers/contacts_helper.rb b/app/helpers/contacts_helper.rb index 7db5f2498..edd4bc56f 100644 --- a/app/helpers/contacts_helper.rb +++ b/app/helpers/contacts_helper.rb @@ -14,11 +14,24 @@ module ContactsHelper 'data-membership_id' => membership.id ) - else + elsif @aspect.nil? render :partial => 'people/relationship_action', :locals => { :person => contact.person, :contact => contact, :current_user => current_user } + else + link_to(content_tag(:i, nil, :class => 'entypo circled-plus'), + { :controller => "aspect_memberships", + :action => 'create', + :person_id => contact.person_id, + :aspect_id => @aspect.id + }, + :title => t('people.person.add_contact'), + :class => 'contact_add-to-aspect', + :method => 'create', + 'data-aspect_id' => @aspect.id, + 'data-person_id' => contact.person_id + ) end end @@ -28,7 +41,7 @@ module ContactsHelper conv_opts[:title] = t('.many_people_are_you_sure', suggested_limit: suggested_limit) if contacts_size > suggested_limit link_to new_conversation_path(aspect_id: aspect.id, name: aspect.name), conv_opts do - content_tag(:i, nil, :class => 'entypo mail', :title => t('contacts.index.start_a_conversation')) + content_tag(:i, nil, :class => 'entypo mail contacts-header-icon', :title => t('contacts.index.start_a_conversation')) end end end diff --git a/app/views/aspects/edit.html.haml b/app/views/aspects/edit.html.haml new file mode 100644 index 000000000..0ee1d00ba --- /dev/null +++ b/app/views/aspects/edit.html.haml @@ -0,0 +1,13 @@ +#people_stream.stream.contacts + - @contacts.each do |contact| + .media.stream_element{:id => contact.person_id} + .pull-right.contact_add-to-aspect + %i.entypo.circled-plus{:title => t('people.person.add_contact')} + .media-object.pull-left + = person_image_link(contact.person, :size => :thumb_small) + .media-body + = person_link(contact.person) + .info.diaspora_handle + = contact.person_diaspora_handle + .info.tags + = Diaspora::Taggable.format_tags(contact.person.profile.tag_string) diff --git a/app/views/contacts/_header.html.haml b/app/views/contacts/_header.html.haml index e930b4edb..5732ee081 100644 --- a/app/views/contacts/_header.html.haml +++ b/app/views/contacts/_header.html.haml @@ -1,20 +1,23 @@ .header - if @aspect - #aspect_control.pull-right + #aspect_controls.pull-right - if @contacts_size > 0 && @contacts_size < 20 = start_a_conversation_link(@aspect, @contacts_size) + = link_to aspect_toggle_contact_visibility_path(@aspect), id: "contacts_visibility_toggle", method: :put, remote: true do -if @aspect.contacts_visible? - %i.entypo.lock-open{:title => t('aspects.edit.aspect_list_is_visible')} + %i.entypo.lock-open.contacts-header-icon{:title => t('aspects.edit.aspect_list_is_visible')} -else - %i.entypo.lock{:title => t('aspects.edit.aspect_list_is_not_visible')} + %i.entypo.lock.contacts-header-icon{:title => t('aspects.edit.aspect_list_is_not_visible')} + = link_to @aspect, method: "delete", data: { confirm: t('aspects.edit.confirm_remove_aspect') }, class: 'delete' do - %i.entypo.trash{:title => t('delete')} + %i.entypo.trash.contacts-header-icon{:title => t('delete')} + %h3 %span#aspect_name = @aspect.name %span#change_aspect_name - %i.entypo.pencil{:title => t('aspects.edit.rename')} + %i.entypo.pencil.contacts-header-icon{:title => t('aspects.edit.rename')} #aspect_name_form = form_for @aspect, :remote => true do |aspect| = aspect.text_field :name, :maxlength => 20 diff --git a/app/views/contacts/index.html.haml b/app/views/contacts/index.html.haml index 53f7aaf2f..d833e9118 100644 --- a/app/views/contacts/index.html.haml +++ b/app/views/contacts/index.html.haml @@ -14,9 +14,8 @@ = render 'contacts/header' - if @contacts_size > 0 - = render @contacts - - = will_paginate @contacts + - @contacts.each do |contact| + = render 'contacts/contact', :contact => contact - else .no_contacts %h3 diff --git a/app/views/contacts/sharing.haml b/app/views/contacts/sharing.haml deleted file mode 100644 index b35f3fa1a..000000000 --- a/app/views/contacts/sharing.haml +++ /dev/null @@ -1,30 +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. - -#aspect_edit_pane - #facebox_header - .right - = t('contacts', :count =>@contacts.count) - - %h3#aspect_name_title - %span.name= t('.people_sharing') - - - if @contacts.count > 0 - .contact_list - = search_field_tag :contact_search, "", :id => 'contact_list_search', :class => 'contact_list_search', :results => 5, :placeholder => "People sharing with you" - %ul - - for contact in @contacts - %li{:data=>{:contact_id=>contact.id}} - = person_image_tag contact.person - %h4.name - = link_to contact.person_name, contact.person - .description - = contact.person_diaspora_handle - - .right - = aspect_membership_dropdown(contact, contact.person, 'right') - - %br - %div{:style => "text-align:right;"} - = link_to t('aspects.edit.done'), '#', :class => 'btn', :rel => 'close' diff --git a/app/views/contacts/spotlight.haml b/app/views/contacts/spotlight.haml index 6dc2fbbc3..0ad67fc04 100644 --- a/app/views/contacts/spotlight.haml +++ b/app/views/contacts/spotlight.haml @@ -15,7 +15,7 @@ .header - if AppConfig.settings.community_spotlight.suggest_email.present? .pull-right - = link_to t('contacts.spotlight.suggest_member'), "mailto:#{AppConfig.settings.community_spotlight.suggest_email}", :class => "btn btn-default" + = link_to t('contacts.spotlight.suggest_member'), "mailto:#{AppConfig.settings.community_spotlight.suggest_email}", :class => "btn btn-default", :id => "suggest_member" %h3 = t('contacts.spotlight.community_spotlight') diff --git a/config/routes.rb b/config/routes.rb index 6bc3b0265..558c8de7b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -146,7 +146,6 @@ Diaspora::Application.routes.draw do resources :contacts, :except => [:update, :create] do - get :sharing, :on => :collection end resources :aspect_memberships, :only => [:destroy, :create] resources :share_visibilities, :only => [:update] From f1408a7a09363912a1ceccb47ffe00b02efe65d5 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Mon, 25 Aug 2014 15:50:33 +0200 Subject: [PATCH 3/4] Add contacts search and port aspect membership save/destroy to backbone --- .../javascripts/app/views/contacts_view.js | 73 +++++++++++++-- app/assets/javascripts/aspect-edit-pane.js | 89 ------------------- app/assets/javascripts/contact-edit.js | 58 ------------ app/assets/javascripts/contact-list.js | 33 ------- app/assets/javascripts/home.js | 1 - app/assets/javascripts/main.js | 2 - app/assets/javascripts/people.js | 1 - app/assets/stylesheets/contacts.css.scss | 13 ++- app/assets/stylesheets/new_styles/_forms.scss | 2 +- app/controllers/aspects_controller.rb | 22 ----- app/helpers/contacts_helper.rb | 31 ++----- app/views/aspects/edit.html.haml | 13 --- app/views/contacts/_contact.html.haml | 5 +- app/views/contacts/_header.html.haml | 5 +- config/locales/diaspora/en.yml | 1 + config/locales/javascript/javascript.en.yml | 7 ++ 16 files changed, 102 insertions(+), 254 deletions(-) delete mode 100644 app/assets/javascripts/aspect-edit-pane.js delete mode 100644 app/assets/javascripts/contact-edit.js delete mode 100644 app/views/aspects/edit.html.haml diff --git a/app/assets/javascripts/app/views/contacts_view.js b/app/assets/javascripts/app/views/contacts_view.js index 1c85a3599..770e03ab5 100644 --- a/app/assets/javascripts/app/views/contacts_view.js +++ b/app/assets/javascripts/app/views/contacts_view.js @@ -4,13 +4,17 @@ app.views.Contacts = Backbone.View.extend({ events: { "click #contacts_visibility_toggle" : "toggleContactVisibility", - "click #change_aspect_name" : "showAspectNameForm" + "click #change_aspect_name" : "showAspectNameForm", + "click .contact_remove-from-aspect" : "removeContactFromAspect", + "click .contact_add-to-aspect" : "addContactToAspect", + "keyup #contact_list_search" : "searchContactList" }, initialize: function() { this.visibility_toggle = $("#contacts_visibility_toggle .entypo"); $("#people_stream.contacts .header .entypo").tooltip({ 'placement': 'bottom'}); $(".contact_remove-from-aspect").tooltip(); + $(".contact_add-to-aspect").tooltip(); $(document).on('ajax:success', 'form.edit_aspect', this.updateAspectName); }, @@ -20,16 +24,16 @@ app.views.Contacts = Backbone.View.extend({ .addClass("lock") .tooltip("destroy") .removeAttr("data-original-title") - .attr("title", Diaspora.I18n.t("aspects.edit.aspect_list_is_not_visible")) - .tooltip(); + .attr("title", Diaspora.I18n.t("contacts.aspect_list_is_not_visible")) + .tooltip({'placement': 'bottom'}); } else { this.visibility_toggle.removeClass("lock") .addClass("lock-open") .tooltip("destroy") .removeAttr("data-original-title") - .attr("title", Diaspora.I18n.t("aspects.edit.aspect_list_is_visible")) - .tooltip(); + .attr("title", Diaspora.I18n.t("contacts.aspect_list_is_visible")) + .tooltip({'placement': 'bottom'}); } }, @@ -43,5 +47,64 @@ app.views.Contacts = Backbone.View.extend({ $("#aspect_nav [data-aspect-id='"+data['id']+"'] .name").text(data['name']); $(".header > #aspect_name_form").hide(); $(".header > h3").show(); + }, + + addContactToAspect: function(e){ + var contact = $(e.currentTarget); + var aspect_membership = new app.models.AspectMembership({ + 'person_id': contact.data('person_id'), + 'aspect_id': contact.data('aspect_id') + }); + + aspect_membership.save({ + success: function(model,response){ + contact.attr('data-membership_id',model.id) + .tooltip('destroy') + .removeAttr('data-original-title') + .removeClass("contact_add-to_aspect").removeClass("circled-plus") + .addClass("contact_remove-from_aspect").addClass("circled-cross") + .attr('title', Diaspora.I18n.t('contacts.add_contact')) + .tooltip() + .closest('.stream_element').removeClass('not_in_aspect'); + }, + error: function(model,response){ + alert("SAVE ERROR " + JSON.stringify(model)); + } + }); + }, + + removeContactFromAspect: function(e){ + var contact = $(e.currentTarget); + var aspect_membership = new app.models.AspectMembership({ + 'id': contact.data('membership_id') + }); + + aspect_membership.destroy({ + success: function(model,response){ + contact.removeAttr('data-membership_id') + .tooltip('destroy') + .removeAttr('data-original-title') + .removeClass("contact_remove-from_aspect").removeClass("circled-cross") + .addClass("contact_add-to_aspect").addClass("circled-plus") + .attr('title', Diaspora.I18n.t('contacts.add_contact')) + .tooltip() + .closest('.stream_element').addClass('not_in_aspect'); + }, + error: function(model,response){ + alert("DESTROY ERROR " + JSON.stringify(model)); + } + }); + }, + + searchContactList: function(e) { + var query = new RegExp($(e.target).val(),'i'); + + $("#people_stream.stream.contacts .stream_element").each(function(){ + if($(this).find(".name").text().match(query)){ + $(this).show(); + } else { + $(this).hide(); + } + }); } }); diff --git a/app/assets/javascripts/aspect-edit-pane.js b/app/assets/javascripts/aspect-edit-pane.js deleted file mode 100644 index 27dc0f07d..000000000 --- a/app/assets/javascripts/aspect-edit-pane.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * TEMPORARY SOLUTION - * TODO remove me, when the contacts section is done with Backbone.js ... - * (this is about as much covered by tests as the old code ... not at all) - * - * see also 'contact-edit.js' - */ - -app.tmp || (app.tmp = {}); - -// on the contacts page, viewing the facebox for single aspect -app.tmp.ContactAspectsBox = function() { - $('body').on('click', '#aspect_edit_pane a.add.btn', _.bind(this.addToAspect, this)); - $('body').on('click', '#aspect_edit_pane a.added.btn', _.bind(this.removeFromAspect, this)); -}; -_.extend(app.tmp.ContactAspectsBox.prototype, { - addToAspect: function(evt) { - var el = $(evt.currentTarget); - var aspect_membership = new app.models.AspectMembership({ - 'person_id': el.data('person_id'), - 'aspect_id': el.data('aspect_id') - }); - - aspect_membership.on('sync', this._successSaveCb, this); - aspect_membership.on('error', function() { - this._displayError('aspect_dropdown.error', el); - }, this); - - aspect_membership.save(); - - return false; - }, - - _successSaveCb: function(aspect_membership) { - var membership_id = aspect_membership.get('id'); - var person_id = aspect_membership.get('person_id'); - var el = $('li.contact').find('a.add[data-person_id="'+person_id+'"]'); - - el.removeClass('add') - .addClass('added') - .attr('data-membership_id', membership_id) // just to be sure... - .data('membership_id', membership_id); - - el.find('div').removeClass('icons-monotone_plus_add_round') - .addClass('icons-monotone_check_yes'); - }, - - removeFromAspect: function(evt) { - var el = $(evt.currentTarget); - - var aspect_membership = new app.models.AspectMembership({ - 'id': el.data('membership_id') - }); - aspect_membership.on('sync', this._successDestroyCb, this); - aspect_membership.on('error', function(aspect_membership) { - this._displayError('aspect_dropdown.error_remove', el); - }, this); - - aspect_membership.destroy(); - - return false; - }, - - _successDestroyCb: function(aspect_membership) { - var membership_id = aspect_membership.get('id'); - var el = $('li.contact').find('a.added[data-membership_id="'+membership_id+'"]'); - - el.removeClass('added') - .addClass('add') - .removeAttr('data-membership_id') - .removeData('membership_id'); - - el.find('div').removeClass('icons-monotone_check_yes') - .addClass('icons-monotone_plus_add_round'); - }, - - _displayError: function(msg_id, contact_el) { - var name = $('li.contact') - .has(contact_el) - .find('h4.name') - .text(); - var msg = Diaspora.I18n.t(msg_id, { 'name': name }); - Diaspora.page.flashMessages.render({ 'success':false, 'notice':msg }); - } -}); - -$(function() { - var contact_aspects_box = new app.tmp.ContactAspectsBox(); -}); diff --git a/app/assets/javascripts/contact-edit.js b/app/assets/javascripts/contact-edit.js deleted file mode 100644 index 99647bfb3..000000000 --- a/app/assets/javascripts/contact-edit.js +++ /dev/null @@ -1,58 +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. - -/** - * TEMPORARY SOLUTION - * TODO remove me, when the contacts section is done with Backbone.js ... - * (this is about as much covered by tests as the old code ... not at all) - * - * see also 'aspect-edit-pane.js' - */ - -app.tmp || (app.tmp = {}); - -// on the contacts page, viewing the list of people in a single aspect -app.tmp.ContactAspects = function() { - $('#people_stream').on('click', '.contact_remove-from-aspect', _.bind(this.removeFromAspect, this)); -}; -_.extend(app.tmp.ContactAspects.prototype, { - removeFromAspect: function(evt) { - evt.stopImmediatePropagation(); - evt.preventDefault(); - - var el = $(evt.currentTarget); - var id = el.data('membership_id'); - - var aspect_membership = new app.models.AspectMembership({'id':id}); - aspect_membership.on('sync', this._successDestroyCb, this); - aspect_membership.on('error', function(aspect_membership) { - this._displayError('aspect_dropdown.error_remove', aspect_membership.get('id')); - }, this); - - aspect_membership.destroy(); - - return false; - }, - - _successDestroyCb: function(aspect_membership) { - var membership_id = aspect_membership.get('id'); - - $('.stream_element').has('[data-membership_id="'+membership_id+'"]') - .fadeOut(300, function() { $(this).remove() }); - }, - - _displayError: function(msg_id, membership_id) { - var name = $('.stream_element') - .has('[data-membership_id="'+membership_id+'"]') - .find('div.bd > a') - .text(); - var msg = Diaspora.I18n.t(msg_id, { 'name': name }); - Diaspora.page.flashMessages.render({ 'success':false, 'notice':msg }); - } -}); - - -$(function() { - var contact_aspects = new app.tmp.ContactAspects(); -}); diff --git a/app/assets/javascripts/contact-list.js b/app/assets/javascripts/contact-list.js index 5d8785a6e..e4caeabd6 100644 --- a/app/assets/javascripts/contact-list.js +++ b/app/assets/javascripts/contact-list.js @@ -4,37 +4,6 @@ */ var List = { - initialize: function() { - $(document).on("keyup", ".contact_list_search", function(e) { - var search = $(this); - var list = $(".contacts", ".searchable"); - var query = new RegExp(search.val(),'i'); - - $("> .contact", list).each( function(idx, element) { - element = $(element); - if( !element.find(".name").text().match(query) ) { - element.addClass('hidden'); - } else { - element.removeClass('hidden'); - } - }); - }); - }, - - disconnectUser: function(contact_id){ - $.ajax({ - url: "/contacts/" + contact_id, - type: "DELETE", - success: function(){ - if( $('.searchable').length == 1){ - $('.searchable .contact[data-contact_id='+contact_id+']').fadeOut(200); - } else if($('#aspects_list').length == 1) { - $.facebox.close(); - }; - } - }); - }, - runDelayedSearch: function( searchTerm ) { $.getJSON('/people/refresh_search', { q: searchTerm }, @@ -77,6 +46,4 @@ $(document).ready(function() { $this.removeClass("remove"); $this.children("img").attr("src","/images/icons/monotone_check_yes.png"); }); - - List.initialize(); }); diff --git a/app/assets/javascripts/home.js b/app/assets/javascripts/home.js index 2d14f6045..f8a196cf0 100644 --- a/app/assets/javascripts/home.js +++ b/app/assets/javascripts/home.js @@ -3,5 +3,4 @@ * the COPYRIGHT file. */ -//= require aspect-edit-pane //= require fileuploader-custom diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 389e824af..483ee493c 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -32,8 +32,6 @@ //= require_tree ./widgets //= require view //= require aspects-dropdown -//= require contact-edit -//= require contact-list //= require mentions //= require bootstrap-tooltip //= require bootstrap-popover diff --git a/app/assets/javascripts/people.js b/app/assets/javascripts/people.js index d204d481c..78f1e519e 100644 --- a/app/assets/javascripts/people.js +++ b/app/assets/javascripts/people.js @@ -2,7 +2,6 @@ * licensed under the Affero General Public License version 3 or later. See * the COPYRIGHT file. */ -//= require aspect-edit-pane //= require fileuploader-custom //= require jquery.autoSuggest.custom diff --git a/app/assets/stylesheets/contacts.css.scss b/app/assets/stylesheets/contacts.css.scss index 337660435..5c565b355 100644 --- a/app/assets/stylesheets/contacts.css.scss +++ b/app/assets/stylesheets/contacts.css.scss @@ -14,6 +14,10 @@ } .btn { margin-top: 10px; } } + #contact_list_search { + margin: 6px 30px 0 0; + width: 150px; + } & > a, #aspect_controls > a { text-decoration: none; margin-right: 25px; @@ -27,15 +31,18 @@ #suggest_member.btn { margin-top: 8px; } } - .contact_remove-from-aspect, .contact_add-to-aspect { - text-decoration: none; - .entypo { + .stream_element { + .contact_remove-from-aspect, .contact_add-to-aspect { + text-decoration: none; + cursor: pointer; font-size: 20px; line-height: 50px; margin: 10px; color: lighten($black,75%); &:hover { color: $black; } } + + &.not_in_aspect { background-color: $background-grey; } } .no_contacts { diff --git a/app/assets/stylesheets/new_styles/_forms.scss b/app/assets/stylesheets/new_styles/_forms.scss index c85da9ec0..a6ecf1569 100644 --- a/app/assets/stylesheets/new_styles/_forms.scss +++ b/app/assets/stylesheets/new_styles/_forms.scss @@ -86,7 +86,7 @@ form.block-form { } } -textarea, input[type=text], input[type=password] { +textarea, input[type=text], input[type=password], input[type=search] { &:focus, &:invalid:focus { border: 1px solid $border-dark-grey; outline: none; diff --git a/app/controllers/aspects_controller.rb b/app/controllers/aspects_controller.rb index 18c354826..becffae3b 100644 --- a/app/controllers/aspects_controller.rb +++ b/app/controllers/aspects_controller.rb @@ -67,28 +67,6 @@ class AspectsController < ApplicationController end end - def edit - @aspect = current_user.aspects.where(:id => params[:id]).includes(:contacts => {:person => :profile}).first - - @contacts_in_aspect = @aspect.contacts.includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } - c = Contact.arel_table - if @contacts_in_aspect.empty? - @contacts_not_in_aspect = current_user.contacts.includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } - else - @contacts_not_in_aspect = current_user.contacts.where(c[:id].not_in(@contacts_in_aspect.map(&:id))).includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } - end - - @contacts = @contacts_not_in_aspect - - unless @aspect - render :file => Rails.root.join('public', '404.html').to_s, :layout => false, :status => 404 - else - @aspect_ids = [@aspect.id] - @aspect_contacts_count = @aspect.contacts.size - render :layout => false - end - end - def update @aspect = current_user.aspects.where(:id => params[:id]).first diff --git a/app/helpers/contacts_helper.rb b/app/helpers/contacts_helper.rb index edd4bc56f..a197bb4e8 100644 --- a/app/helpers/contacts_helper.rb +++ b/app/helpers/contacts_helper.rb @@ -3,16 +3,11 @@ module ContactsHelper membership = contact.aspect_memberships.where(:aspect_id => @aspect.id).first unless @aspect.nil? if membership - link_to(content_tag(:i, nil, :class => 'entypo circled-cross'), - { :controller => "aspect_memberships", - :action => 'destroy', - :id => membership.id - }, - :title => t('contacts.index.remove_person_from_aspect', :person_name => contact.person_first_name, :aspect_name => @aspect.name), - :class => 'contact_remove-from-aspect', - :method => 'delete', - 'data-membership_id' => membership.id - ) + content_tag(:i, nil, :class => 'entypo circled-cross contact_remove-from-aspect', + :title => t('contacts.index.remove_person_from_aspect', :person_name => contact.person_first_name, :aspect_name => @aspect.name), + 'data-aspect_id' => @aspect.id, + 'data-person_id' => contact.person_id, + 'data-membership_id' => membership.id ) elsif @aspect.nil? render :partial => 'people/relationship_action', @@ -20,18 +15,10 @@ module ContactsHelper :contact => contact, :current_user => current_user } else - link_to(content_tag(:i, nil, :class => 'entypo circled-plus'), - { :controller => "aspect_memberships", - :action => 'create', - :person_id => contact.person_id, - :aspect_id => @aspect.id - }, - :title => t('people.person.add_contact'), - :class => 'contact_add-to-aspect', - :method => 'create', - 'data-aspect_id' => @aspect.id, - 'data-person_id' => contact.person_id - ) + content_tag(:i, nil, :class => 'entypo circled-plus contact_add-to-aspect', + :title => t('people.person.add_contact'), + 'data-aspect_id' => @aspect.id, + 'data-person_id' => contact.person_id ) end end diff --git a/app/views/aspects/edit.html.haml b/app/views/aspects/edit.html.haml deleted file mode 100644 index 0ee1d00ba..000000000 --- a/app/views/aspects/edit.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -#people_stream.stream.contacts - - @contacts.each do |contact| - .media.stream_element{:id => contact.person_id} - .pull-right.contact_add-to-aspect - %i.entypo.circled-plus{:title => t('people.person.add_contact')} - .media-object.pull-left - = person_image_link(contact.person, :size => :thumb_small) - .media-body - = person_link(contact.person) - .info.diaspora_handle - = contact.person_diaspora_handle - .info.tags - = Diaspora::Taggable.format_tags(contact.person.profile.tag_string) diff --git a/app/views/contacts/_contact.html.haml b/app/views/contacts/_contact.html.haml index 2a005f457..ed484a85d 100644 --- a/app/views/contacts/_contact.html.haml +++ b/app/views/contacts/_contact.html.haml @@ -1,10 +1,11 @@ -.media.stream_element{:id => contact.person_id} +- membership = contact.aspect_memberships.where(:aspect_id => @aspect.id).first unless @aspect.nil? +.media.stream_element{:id => contact.person_id, :class => ("not_in_aspect" unless membership)} .pull-right = contact_aspect_dropdown(contact) .media-object.pull-left = person_image_link(contact.person, :size => :thumb_small) .media-body - = person_link(contact.person) + = person_link(contact.person, :class => 'name') .info.diaspora_handle = contact.person_diaspora_handle .info.tags diff --git a/app/views/contacts/_header.html.haml b/app/views/contacts/_header.html.haml index 5732ee081..bedae3a8d 100644 --- a/app/views/contacts/_header.html.haml +++ b/app/views/contacts/_header.html.haml @@ -12,7 +12,8 @@ = link_to @aspect, method: "delete", data: { confirm: t('aspects.edit.confirm_remove_aspect') }, class: 'delete' do %i.entypo.trash.contacts-header-icon{:title => t('delete')} - + .pull-right + = search_field_tag :contact_search, "", id: "contact_list_search", placeholder: t('contacts.index.user_search') %h3 %span#aspect_name = @aspect.name @@ -21,7 +22,7 @@ #aspect_name_form = form_for @aspect, :remote => true do |aspect| = aspect.text_field :name, :maxlength => 20 - = aspect.submit t('aspects.edit.update'), 'data-disable-with' => t('aspects.edit.updating'), :class => "btn green" + = aspect.submit t('aspects.edit.update'), 'data-disable-with' => t('aspects.edit.updating'), :class => "btn" - else %h3 diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml index a6db18f67..6aab979c4 100644 --- a/config/locales/diaspora/en.yml +++ b/config/locales/diaspora/en.yml @@ -345,6 +345,7 @@ en: only_sharing_with_me: "Only sharing with me" remove_person_from_aspect: "Remove %{person_name} from \"%{aspect_name}\"" many_people_are_you_sure: "Are you sure you want to start a private conversation with more than %{suggested_limit} contacts? Posting to this aspect may be a better way to contact them." + user_search: "User Search" spotlight: community_spotlight: "Community Spotlight" suggest_member: "Suggest a member" diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml index f99a08d90..dd25785d1 100644 --- a/config/locales/javascript/javascript.en.yml +++ b/config/locales/javascript/javascript.en.yml @@ -38,6 +38,13 @@ en: years: "%d years" wordSeparator: " " + contacts: + add_contact: "Add contact" + aspect_list_is_visible: "Contacts in this aspect are able to see each other." + aspect_list_is_not_visible: "Contacts in this aspect are not able to see each other." + remove_contact: "Remove contact" + + my_activity: "My Activity" my_stream: "Stream" my_aspects: "My Aspects" From ff84ee0485fd4e3e36d59f86633113f266ba3510 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Mon, 25 Aug 2014 19:22:23 +0200 Subject: [PATCH 4/4] Small style changes, add tests --- Changelog.md | 3 +- app/assets/javascripts/app/router.js | 2 +- .../javascripts/app/views/contacts_view.js | 28 +-- app/assets/javascripts/contact-list.js | 28 --- app/assets/javascripts/jasmine-load-all.js | 1 + app/assets/stylesheets/aspects.css.scss | 2 +- app/assets/stylesheets/contacts.css.scss | 18 +- app/assets/stylesheets/people.css.scss | 4 +- app/controllers/aspects_controller.rb | 1 + app/controllers/contacts_controller.rb | 53 +++-- app/helpers/contacts_helper.rb | 8 +- app/views/contacts/_aspect_listings.haml | 2 +- app/views/contacts/_contact.html.haml | 2 +- app/views/contacts/_header.html.haml | 2 +- app/views/contacts/index.html.haml | 9 +- config/locales/diaspora/en.yml | 3 +- config/locales/javascript/javascript.en.yml | 3 +- config/routes.rb | 4 +- features/desktop/contacts.feature | 8 +- features/desktop/manages_aspects.feature | 33 +-- .../desktop/stops_following_users.feature | 5 +- features/step_definitions/aspects_steps.rb | 12 +- spec/controllers/aspects_controller_spec.rb | 49 +--- spec/controllers/contacts_controller_spec.rb | 19 +- .../jasmine_fixtures/contacts_spec.rb | 4 +- .../app/views/contacts_view_spec.js | 215 ++++++++++++++++++ spec/javascripts/contact-list-spec.js | 19 -- spec/javascripts/search-spec.js | 1 - 28 files changed, 323 insertions(+), 215 deletions(-) create mode 100644 spec/javascripts/app/views/contacts_view_spec.js delete mode 100644 spec/javascripts/contact-list-spec.js diff --git a/Changelog.md b/Changelog.md index c5414fd08..7edd18e74 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,6 +16,7 @@ Diaspora::Application.config.secret_key_base = '*************...' The default for including jQuery from a CDN has changed. If you want to continue to include it from a CDN, please explicitly set the `jquery_cdn` setting to `true` in diaspora.yml. ## Refactor +* Redesign contacts page [#5153](https://github.com/diaspora/diaspora/pull/5153) ## Bug fixes * orca cannot see 'Add Contact' button [#5158](https://github.com/diaspora/diaspora/pull/5158) @@ -105,7 +106,7 @@ Read more in [#4249](https://github.com/diaspora/diaspora/pull/4249) and [#4883] * Reorder and reword items on user settings page [#4912](https://github.com/diaspora/diaspora/pull/4912) * SPV: Improve padding and interaction counts [#4426](https://github.com/diaspora/diaspora/pull/4426) * Remove auto 'mark as read' for notifications [#4810](https://github.com/diaspora/diaspora/pull/4810) -* Improve set read/unread in notifications dropdown [#4869](https://github.com/diaspora/diaspora/pull/4869) +* Improve set read/unread in notifications dropdown [#4869](https://github.com/diaspora/diaspora/pull/4869) * Refactor publisher: trigger events for certain actions, introduce 'disabled' state [#4932](https://github.com/diaspora/diaspora/pull/4932) ## Bug fixes diff --git a/app/assets/javascripts/app/router.js b/app/assets/javascripts/app/router.js index 717c4e1ba..76b9895d5 100644 --- a/app/assets/javascripts/app/router.js +++ b/app/assets/javascripts/app/router.js @@ -24,7 +24,7 @@ app.Router = Backbone.Router.extend({ "people/:id": "stream", "u/:name": "stream" }, - + initialize: function() { // To support encoded linefeeds (%0A) we need to specify // our own internal router.route call with the correct regexp. diff --git a/app/assets/javascripts/app/views/contacts_view.js b/app/assets/javascripts/app/views/contacts_view.js index 770e03ab5..7ddd9fdf4 100644 --- a/app/assets/javascripts/app/views/contacts_view.js +++ b/app/assets/javascripts/app/views/contacts_view.js @@ -52,23 +52,24 @@ app.views.Contacts = Backbone.View.extend({ addContactToAspect: function(e){ var contact = $(e.currentTarget); var aspect_membership = new app.models.AspectMembership({ - 'person_id': contact.data('person_id'), - 'aspect_id': contact.data('aspect_id') + 'person_id': contact.attr('data-person_id'), + 'aspect_id': contact.attr('data-aspect_id') }); - aspect_membership.save({ + aspect_membership.save({},{ success: function(model,response){ contact.attr('data-membership_id',model.id) .tooltip('destroy') .removeAttr('data-original-title') - .removeClass("contact_add-to_aspect").removeClass("circled-plus") - .addClass("contact_remove-from_aspect").addClass("circled-cross") - .attr('title', Diaspora.I18n.t('contacts.add_contact')) + .removeClass("contact_add-to-aspect").removeClass("circled-plus") + .addClass("contact_remove-from-aspect").addClass("circled-cross") + .attr('title', Diaspora.I18n.t('contacts.remove_contact')) .tooltip() - .closest('.stream_element').removeClass('not_in_aspect'); + .closest('.stream_element').addClass('in_aspect'); }, error: function(model,response){ - alert("SAVE ERROR " + JSON.stringify(model)); + var msg = Diaspora.I18n.t('contacts.error_add', { 'name':contact.closest('.stream_element').find('.name').text() }); + Diaspora.page.flashMessages.render({ 'success':false, 'notice':msg }); } }); }, @@ -76,7 +77,7 @@ app.views.Contacts = Backbone.View.extend({ removeContactFromAspect: function(e){ var contact = $(e.currentTarget); var aspect_membership = new app.models.AspectMembership({ - 'id': contact.data('membership_id') + 'id': contact.attr('data-membership_id') }); aspect_membership.destroy({ @@ -84,14 +85,15 @@ app.views.Contacts = Backbone.View.extend({ contact.removeAttr('data-membership_id') .tooltip('destroy') .removeAttr('data-original-title') - .removeClass("contact_remove-from_aspect").removeClass("circled-cross") - .addClass("contact_add-to_aspect").addClass("circled-plus") + .removeClass("contact_remove-from-aspect").removeClass("circled-cross") + .addClass("contact_add-to-aspect").addClass("circled-plus") .attr('title', Diaspora.I18n.t('contacts.add_contact')) .tooltip() - .closest('.stream_element').addClass('not_in_aspect'); + .closest('.stream_element').removeClass('in_aspect'); }, error: function(model,response){ - alert("DESTROY ERROR " + JSON.stringify(model)); + var msg = Diaspora.I18n.t('contacts.error_remove', { 'name':contact.closest('.stream_element').find('.name').text() }); + Diaspora.page.flashMessages.render({ 'success':false, 'notice':msg }); } }); }, diff --git a/app/assets/javascripts/contact-list.js b/app/assets/javascripts/contact-list.js index e4caeabd6..f8ee17374 100644 --- a/app/assets/javascripts/contact-list.js +++ b/app/assets/javascripts/contact-list.js @@ -1,8 +1,3 @@ -/* 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 List = { runDelayedSearch: function( searchTerm ) { $.getJSON('/people/refresh_search', @@ -23,27 +18,4 @@ var List = { startSearchDelay: function (theSearch) { setTimeout( "List.runDelayedSearch('" + theSearch + "')", 10000); } - }; - -$(document).ready(function() { - $('.added').bind('ajax:loading', function() { - var $this = $(this); - - $this.addClass('disabled'); - $this.fadeTo(200,0.4); - }); - - $('.added').bind('hover', - function() { - var $this = $(this) - $this.addClass("remove"); - $this.children("img").attr("src","/images/icons/monotone_close_exit_delete.png"); - }, - - function() { - var $this = $(this) - $this.removeClass("remove"); - $this.children("img").attr("src","/images/icons/monotone_check_yes.png"); - }); -}); diff --git a/app/assets/javascripts/jasmine-load-all.js b/app/assets/javascripts/jasmine-load-all.js index 7395aba77..5872aee01 100644 --- a/app/assets/javascripts/jasmine-load-all.js +++ b/app/assets/javascripts/jasmine-load-all.js @@ -7,4 +7,5 @@ //= require mobile //= require profile //= require people +//= require contact-list //= require sinon diff --git a/app/assets/stylesheets/aspects.css.scss b/app/assets/stylesheets/aspects.css.scss index a6603be88..1b9cf7da9 100644 --- a/app/assets/stylesheets/aspects.css.scss +++ b/app/assets/stylesheets/aspects.css.scss @@ -1,5 +1,5 @@ .aspect_dropdown { - + li { .status_indicator { width: 19px; diff --git a/app/assets/stylesheets/contacts.css.scss b/app/assets/stylesheets/contacts.css.scss index 5c565b355..fe872dd27 100644 --- a/app/assets/stylesheets/contacts.css.scss +++ b/app/assets/stylesheets/contacts.css.scss @@ -1,14 +1,14 @@ #contacts_container { #people_stream.contacts { - .header { + .header { border-bottom: 1px solid $border-grey; margin-top: 10px; min-height: 53px; #change_aspect_name { cursor: pointer; } - #aspect_name_form { + #aspect_name_form { display: none; form { margin: 0px; } - input { + input { margin-bottom: 0px; margin-top: 10px; } @@ -17,8 +17,9 @@ #contact_list_search { margin: 6px 30px 0 0; width: 150px; + &:focus { width: 250px; } } - & > a, #aspect_controls > a { + & > a, #aspect_controls > a { text-decoration: none; margin-right: 25px; } @@ -41,10 +42,13 @@ color: lighten($black,75%); &:hover { color: $black; } } - - &.not_in_aspect { background-color: $background-grey; } + &.in_aspect { + border-left: 3px solid $green; + background-color: lighten($green,35%); + } + &:not(.in_aspect) { border-left: 3px solid $white; } } - + .no_contacts { text-align: center; margin-top: 50px; diff --git a/app/assets/stylesheets/people.css.scss b/app/assets/stylesheets/people.css.scss index 0c0c67783..c217dcca4 100644 --- a/app/assets/stylesheets/people.css.scss +++ b/app/assets/stylesheets/people.css.scss @@ -20,9 +20,9 @@ height: 50px; } .btn-group.aspect_membership_dropdown { margin: 12px 0; } - .thats_you { + .thats_you { line-height: 50px; - margin-right: 20px; + margin-right: 10px; } .info { font-size: 11px; } } diff --git a/app/controllers/aspects_controller.rb b/app/controllers/aspects_controller.rb index becffae3b..13988f814 100644 --- a/app/controllers/aspects_controller.rb +++ b/app/controllers/aspects_controller.rb @@ -87,6 +87,7 @@ class AspectsController < ApplicationController @aspect.contacts_visible = true end @aspect.save + render :nothing => true end private diff --git a/app/controllers/contacts_controller.rb b/app/controllers/contacts_controller.rb index ad8b76013..462bc1692 100644 --- a/app/controllers/contacts_controller.rb +++ b/app/controllers/contacts_controller.rb @@ -34,29 +34,40 @@ class ContactsController < ApplicationController private def set_up_contacts - c = Contact.arel_table - @contacts = case params[:set] - when "only_sharing" - current_user.contacts.only_sharing.to_a.sort_by { |c| c.person.name } - when "all" - current_user.contacts.to_a.sort_by { |c| c.person.name } - else - if params[:a_id] - @aspect = current_user.aspects.find(params[:a_id]) - @contacts_in_aspect = @aspect.contacts.includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } - if @contacts_in_aspect.empty? - @contacts_not_in_aspect = current_user.contacts.includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } - else - @contacts_not_in_aspect = current_user.contacts.where(c[:id].not_in(@contacts_in_aspect.map(&:id))).includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } - end - @contacts_in_aspect + @contacts_not_in_aspect - else - current_user.contacts.receiving.to_a.sort_by { |c| c.person.name } - end - end + type = params[:set].presence + type ||= "by_aspect" if params[:a_id].present? + type ||= "receiving" + + @contacts = contacts_by_type(type) @contacts_size = @contacts.length end - + + def contacts_by_type(type) + contacts = case type + when "all" + [current_user.contacts] + when "only_sharing" + [current_user.contacts.only_sharing] + when "receiving" + [current_user.contacts.receiving] + when "by_aspect" + @aspect = current_user.aspects.find(params[:a_id]) + @contacts_in_aspect = @aspect.contacts + @contacts_not_in_aspect = current_user.contacts.where.not(contacts: {id: @contacts_in_aspect.pluck(:id) }) + [@contacts_in_aspect, @contacts_not_in_aspect].map {|relation| + relation.includes(:aspect_memberships) + } + else + raise ArgumentError, "unknown type #{type}" + end + + contacts.map {|relation| + relation.includes(:person => :profile).to_a.tap {|contacts| + contacts.sort_by! {|contact| contact.person.name } + } + }.inject(:+) + end + def set_up_contacts_mobile @contacts = case params[:set] when "only_sharing" diff --git a/app/helpers/contacts_helper.rb b/app/helpers/contacts_helper.rb index a197bb4e8..0dd9d4bd2 100644 --- a/app/helpers/contacts_helper.rb +++ b/app/helpers/contacts_helper.rb @@ -4,9 +4,9 @@ module ContactsHelper if membership content_tag(:i, nil, :class => 'entypo circled-cross contact_remove-from-aspect', - :title => t('contacts.index.remove_person_from_aspect', :person_name => contact.person_first_name, :aspect_name => @aspect.name), + :title => t('contacts.index.remove_contact'), 'data-aspect_id' => @aspect.id, - 'data-person_id' => contact.person_id, + 'data-person_id' => contact.person_id, 'data-membership_id' => membership.id ) elsif @aspect.nil? @@ -16,7 +16,7 @@ module ContactsHelper :current_user => current_user } else content_tag(:i, nil, :class => 'entypo circled-plus contact_add-to-aspect', - :title => t('people.person.add_contact'), + :title => t('contacts.index.add_contact'), 'data-aspect_id' => @aspect.id, 'data-person_id' => contact.person_id ) end @@ -26,7 +26,7 @@ module ContactsHelper suggested_limit = 16 conv_opts = { class: "conversation_button", rel: "facebox"} conv_opts[:title] = t('.many_people_are_you_sure', suggested_limit: suggested_limit) if contacts_size > suggested_limit - + link_to new_conversation_path(aspect_id: aspect.id, name: aspect.name), conv_opts do content_tag(:i, nil, :class => 'entypo mail contacts-header-icon', :title => t('contacts.index.start_a_conversation')) end diff --git a/app/views/contacts/_aspect_listings.haml b/app/views/contacts/_aspect_listings.haml index 413ac2b4b..a9b9be9b8 100644 --- a/app/views/contacts/_aspect_listings.haml +++ b/app/views/contacts/_aspect_listings.haml @@ -11,7 +11,7 @@ = t('contacts.index.my_contacts') .badge.badge-default.pull-right = my_contacts_count - + - all_aspects.each do |aspect| %li.aspect{:data => {:aspect_id => aspect.id}, :class => ("active" if params["a_id"].to_i == aspect.id)} %a{:href => contacts_path(:a_id => aspect.id)} diff --git a/app/views/contacts/_contact.html.haml b/app/views/contacts/_contact.html.haml index ed484a85d..3e6aeb8a4 100644 --- a/app/views/contacts/_contact.html.haml +++ b/app/views/contacts/_contact.html.haml @@ -1,5 +1,5 @@ - membership = contact.aspect_memberships.where(:aspect_id => @aspect.id).first unless @aspect.nil? -.media.stream_element{:id => contact.person_id, :class => ("not_in_aspect" unless membership)} +.media.stream_element{:id => contact.person_id, :class => ("in_aspect" if membership)} .pull-right = contact_aspect_dropdown(contact) .media-object.pull-left diff --git a/app/views/contacts/_header.html.haml b/app/views/contacts/_header.html.haml index bedae3a8d..e51c36957 100644 --- a/app/views/contacts/_header.html.haml +++ b/app/views/contacts/_header.html.haml @@ -10,7 +10,7 @@ -else %i.entypo.lock.contacts-header-icon{:title => t('aspects.edit.aspect_list_is_not_visible')} - = link_to @aspect, method: "delete", data: { confirm: t('aspects.edit.confirm_remove_aspect') }, class: 'delete' do + = link_to @aspect, method: "delete", data: { confirm: t('aspects.edit.confirm_remove_aspect') }, class: 'delete', id: 'delete_aspect' do %i.entypo.trash.contacts-header-icon{:title => t('delete')} .pull-right = search_field_tag :contact_search, "", id: "contact_list_search", placeholder: t('contacts.index.user_search') diff --git a/app/views/contacts/index.html.haml b/app/views/contacts/index.html.haml index d833e9118..d2a6b7743 100644 --- a/app/views/contacts/index.html.haml +++ b/app/views/contacts/index.html.haml @@ -21,10 +21,5 @@ %h3 = t('.no_contacts') %p - - if @aspect - != t('.no_contacts_message_with_aspect', - :community_spotlight => link_to(t('.community_spotlight'), community_spotlight_path), - :add_to_aspect_link => link_to(t('.add_to_aspect_link', :name => @aspect.name), edit_aspect_path(@aspect), :rel => "facebox")) - - else - != t('.no_contacts_message', - :community_spotlight => link_to(t('.community_spotlight'), community_spotlight_path)) + != t('.no_contacts_message', + :community_spotlight => link_to(t('.community_spotlight'), community_spotlight_path)) diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml index 6aab979c4..cbd2ed9c1 100644 --- a/config/locales/diaspora/en.yml +++ b/config/locales/diaspora/en.yml @@ -343,7 +343,8 @@ en: my_contacts: "My Contacts" all_contacts: "All Contacts" only_sharing_with_me: "Only sharing with me" - remove_person_from_aspect: "Remove %{person_name} from \"%{aspect_name}\"" + add_contact: "Add contact" + remove_contact: "Remove contact" many_people_are_you_sure: "Are you sure you want to start a private conversation with more than %{suggested_limit} contacts? Posting to this aspect may be a better way to contact them." user_search: "User Search" spotlight: diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml index dd25785d1..a977d733f 100644 --- a/config/locales/javascript/javascript.en.yml +++ b/config/locales/javascript/javascript.en.yml @@ -43,7 +43,8 @@ en: aspect_list_is_visible: "Contacts in this aspect are able to see each other." aspect_list_is_not_visible: "Contacts in this aspect are not able to see each other." remove_contact: "Remove contact" - + error_add: "Couldn't add <%= name %> to the aspect :(" + error_remove: "Couldn't remove <%= name %> from the aspect :(" my_activity: "My Activity" my_stream: "Stream" diff --git a/config/routes.rb b/config/routes.rb index 558c8de7b..e32770a80 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -84,7 +84,7 @@ Diaspora::Application.routes.draw do get :read_all end end - + resources :tags, :only => [:index] @@ -221,7 +221,7 @@ Diaspora::Application.routes.draw do #Statistics get :statistics, controller: :statistics - + # Terms if AppConfig.settings.terms.enable? get 'terms' => 'terms#index' diff --git a/features/desktop/contacts.feature b/features/desktop/contacts.feature index 9e59a9c93..33639826e 100644 --- a/features/desktop/contacts.feature +++ b/features/desktop/contacts.feature @@ -16,7 +16,7 @@ Feature: show contacts And I press the first "a" within ".section.contact_pictures" Then I should see "Alice Smith" - Scenario: see contacts of a visible aspect list + Scenario: see contacts of a visible aspect list When I am on "bob@bob.bob"'s page And I add the person to my "Unicorns" aspect And I sign out @@ -25,14 +25,12 @@ Feature: show contacts And I press the first "a" within ".section.contact_pictures" Then I should see "Bob Jones" - Scenario: don't see contacts of an invisible aspect list + Scenario: don't see contacts of an invisible aspect list When I am on "bob@bob.bob"'s page And I add the person to my "Unicorns" aspect And I am on the contacts page And I follow "Unicorns" - And I follow "Manage" - And I press the first "a.contact_visibility_link" in the modal window - And I press "Done" in the modal window + And I press the first "a#contacts_visibility_toggle" And I sign out And I sign in as "alice@alice.alice" diff --git a/features/desktop/manages_aspects.feature b/features/desktop/manages_aspects.feature index 9c285844e..360709474 100644 --- a/features/desktop/manages_aspects.feature +++ b/features/desktop/manages_aspects.feature @@ -25,55 +25,42 @@ Feature: User manages contacts And I have an aspect called "People" When I am on the contacts page And I follow "People" - And I follow "add contacts to People" - And I press "Delete" in the modal window + And I click on selector "#delete_aspect" And I confirm the alert Then I should be on the contacts page - And I should not see "People" within "#aspects_list" + And I should not see "People" within "#aspect_nav" Scenario: deleting an aspect from homepage Given I am signed in And I have an aspect called "People" When I am on the aspects page And I click on "People" aspect edit icon - And I follow "Delete" within "#aspect_controls" + And I click on selector "#delete_aspect" And I confirm the alert Then I should be on the contacts page - And I should not see "People" within "#aspects_list" + And I should not see "People" within "#aspect_nav" - Scenario: Editing the aspect memberships of a contact from the aspect edit facebox + Scenario: Editing the aspect memberships of a contact from the contacts page Given I am signed in And I have 2 contacts And I have an aspect called "Cat People" When I am on the contacts page And I follow "Cat People" - And I follow "add contacts to Cat People" - And I check the first contact list button + And I add the first person to the aspect Then I should have 1 contact in "Cat People" - When I uncheck the first contact list button + When I remove the first person from the aspect Then I should have 0 contacts in "Cat People" - + Scenario: Renaming an aspect Given I am signed in And I have an aspect called "Cat People" When I am on the contacts page And I follow "Cat People" - And I follow "Manage" within "#aspect_controls" - And I follow "rename" + And I click on selector "#change_aspect_name" And I fill in "aspect_name" with "Unicorn People" And I press "update" - Then I should see "Unicorn People" within "#aspect_name_title" - - Scenario: infinite scroll on contacts index - Given I am signed in - And I resize my window to 800x600 - And I have 30 contacts - And I am on the contacts page - Then I should see 25 contacts - - When I scroll down - Then I should see 30 contacts + Then I should see "Unicorn People" within "#aspect_name" Scenario: clicking on the contacts link in the header with zero contacts directs a user to the featured users page Given I am signed in diff --git a/features/desktop/stops_following_users.feature b/features/desktop/stops_following_users.feature index 30a5b97af..b2a066324 100644 --- a/features/desktop/stops_following_users.feature +++ b/features/desktop/stops_following_users.feature @@ -27,14 +27,13 @@ Feature: Unfollowing Then I should not see "is sharing with you." - Scenario: stop following someone while on the aspect edit page + Scenario: stop following someone while on the contacts page When I go to the home page And I go to the contacts page And I follow "Besties" - And I follow "Manage" - And I press the first ".added" within "#facebox .contact_list ul > li:first-child" + And I remove the first person from the aspect When I follow "My Contacts" Then I should have 0 contacts in "Besties" diff --git a/features/step_definitions/aspects_steps.rb b/features/step_definitions/aspects_steps.rb index 83539e80f..f1e53a852 100644 --- a/features/step_definitions/aspects_steps.rb +++ b/features/step_definitions/aspects_steps.rb @@ -41,17 +41,17 @@ When /^I select "([^"]*)" aspect as well$/ do |aspect_name| step %Q(I should see "#{aspect_name}" aspect selected) end -When /^I check the first contact list button$/ do - find(".contact_list .btn", match: :first).tap do |button| +When /^I add the first person to the aspect$/ do + find(".contact_add-to-aspect", match: :first).tap do |button| button.click - button.parent.should have_css ".added" + button.parent.should have_css ".contact_remove-from-aspect" end end -When /^I uncheck the first contact list button$/ do - find(".contact_list .btn", match: :first).tap do |button| +When /^I remove the first person from the aspect$/ do + find(".contact_remove-from-aspect", match: :first).tap do |button| button.click - button.parent.should have_css ".add" + button.parent.should have_css ".contact_add-to-aspect" sleep 1 # The expectation above should wait for the request to finsh, but that doesn't work for some reason end end diff --git a/spec/controllers/aspects_controller_spec.rb b/spec/controllers/aspects_controller_spec.rb index 86adf5895..c8369f94b 100644 --- a/spec/controllers/aspects_controller_spec.rb +++ b/spec/controllers/aspects_controller_spec.rb @@ -112,57 +112,12 @@ describe AspectsController do end end - describe '#edit' do - before do - eve.profile.first_name = eve.profile.last_name = nil - eve.profile.save - eve.save - - @zed = FactoryGirl.create(:user_with_aspect, :username => "zed") - @zed.profile.first_name = "zed" - @zed.profile.save - @zed.save - @katz = FactoryGirl.create(:user_with_aspect, :username => "katz") - @katz.profile.first_name = "katz" - @katz.profile.save - @katz.save - - connect_users(alice, @alices_aspect_2, eve, eve.aspects.first) - connect_users(alice, @alices_aspect_2, @zed, @zed.aspects.first) - connect_users(alice, @alices_aspect_1, @katz, @katz.aspects.first) - end - - it 'renders' do - get :edit, :id => @alices_aspect_1.id - response.should be_success - end - - it 'assigns the contacts in alphabetical order with people in aspects first' do - get :edit, :id => @alices_aspect_2.id - assigns[:contacts].map(&:id).should == [alice.contact_for(eve.person), alice.contact_for(@zed.person), alice.contact_for(bob.person), alice.contact_for(@katz.person)].map(&:id) - end - - it 'assigns all the contacts if noone is there' do - alices_aspect_3 = alice.aspects.create(:name => "aspect 3") - - get :edit, :id => alices_aspect_3.id - assigns[:contacts].map(&:id).should == [alice.contact_for(bob.person), alice.contact_for(eve.person), alice.contact_for(@katz.person), alice.contact_for(@zed.person)].map(&:id) - end - - it 'eager loads the aspect memberships for all the contacts' do - get :edit, :id => @alices_aspect_2.id - assigns[:contacts].each do |c| - c.aspect_memberships.loaded?.should be_true - end - end - end - describe "#toggle_contact_visibility" do it 'sets contacts visible' do @alices_aspect_1.contacts_visible = false @alices_aspect_1.save - xhr :get, :toggle_contact_visibility, :format => 'js', :aspect_id => @alices_aspect_1.id + xhr :get, :toggle_contact_visibility, :aspect_id => @alices_aspect_1.id @alices_aspect_1.reload.contacts_visible.should be_true end @@ -170,7 +125,7 @@ describe AspectsController do @alices_aspect_1.contacts_visible = true @alices_aspect_1.save - xhr :get, :toggle_contact_visibility, :format => 'js', :aspect_id => @alices_aspect_1.id + xhr :get, :toggle_contact_visibility, :aspect_id => @alices_aspect_1.id @alices_aspect_1.reload.contacts_visible.should be_false end end diff --git a/spec/controllers/contacts_controller_spec.rb b/spec/controllers/contacts_controller_spec.rb index 91be1c5dc..de2380e70 100644 --- a/spec/controllers/contacts_controller_spec.rb +++ b/spec/controllers/contacts_controller_spec.rb @@ -10,23 +10,6 @@ describe ContactsController do @controller.stub(:current_user).and_return(bob) end - describe '#sharing' do - it "succeeds" do - get :sharing - response.should be_success - end - - it 'eager loads the aspects' do - get :sharing - assigns[:contacts].first.aspect_memberships.loaded?.should be_true - end - - it "assigns only the people sharing with you with 'share_with' flag" do - get :sharing, :id => 'share_with' - assigns[:contacts].to_set.should == bob.contacts.sharing.to_set - end - end - describe '#index' do context 'format mobile' do it "succeeds" do @@ -51,7 +34,7 @@ describe ContactsController do contact = bob.contacts.first contact.update_attributes(:sharing => false) - get :index, :set => "mine" + get :index contacts = assigns(:contacts) contacts.to_set.should == bob.contacts.receiving.to_set end diff --git a/spec/controllers/jasmine_fixtures/contacts_spec.rb b/spec/controllers/jasmine_fixtures/contacts_spec.rb index d2a5321de..e672dec41 100644 --- a/spec/controllers/jasmine_fixtures/contacts_spec.rb +++ b/spec/controllers/jasmine_fixtures/contacts_spec.rb @@ -7,11 +7,13 @@ require 'spec_helper' describe ContactsController do describe '#index' do before do + @aspect = bob.aspects.create(:name => "another aspect") + bob.share_with alice.person, @aspect sign_in :user, bob end it "generates a jasmine fixture", :fixture => true do - get :index + get :index, :a_id => @aspect.id save_fixture(html_for("body"), "aspects_manage") end end diff --git a/spec/javascripts/app/views/contacts_view_spec.js b/spec/javascripts/app/views/contacts_view_spec.js new file mode 100644 index 000000000..d9236c0d7 --- /dev/null +++ b/spec/javascripts/app/views/contacts_view_spec.js @@ -0,0 +1,215 @@ +describe("app.views.Contacts", function(){ + beforeEach(function() { + spec.loadFixture("aspects_manage"); + this.view = new app.views.Contacts(); + Diaspora.I18n.load({ + contacts: { + add_contact: "Add contact", + aspect_list_is_visible: "Contacts in this aspect are able to see each other.", + aspect_list_is_not_visible: "Contacts in this aspect are not able to see each other.", + remove_contact: "Remove contact", + error_add: "Couldn't add <%= name %> to the aspect :(", + error_remove: "Couldn't remove <%= name %> from the aspect :(" + } + }); + }); + + context('toggle contacts visibility', function() { + beforeEach(function() { + this.visibility_toggle = $("#contacts_visibility_toggle"); + this.lock_icon = $("#contacts_visibility_toggle .entypo"); + }); + + it('updates the title for the tooltip', function() { + expect(this.lock_icon.attr('data-original-title')).toBe( + Diaspora.I18n.t("contacts.aspect_list_is_visible") + ); + + this.visibility_toggle.trigger('click'); + + expect(this.lock_icon.attr('data-original-title')).toBe( + Diaspora.I18n.t("contacts.aspect_list_is_not_visible") + ); + }); + + it('toggles the lock icon', function() { + expect(this.lock_icon.hasClass('lock-open')).toBeTruethy; + expect(this.lock_icon.hasClass('lock')).toBeFalsy; + + this.visibility_toggle.trigger('click'); + + expect(this.lock_icon.hasClass('lock')).toBeTruethy; + expect(this.lock_icon.hasClass('lock-open')).toBeFalsy; + }); + }); + + context('show aspect name form', function() { + beforeEach(function() { + this.button = $('#change_aspect_name'); + }); + + it('shows the form', function() { + expect($('#aspect_name_form').css('display')).toBe('none'); + this.button.trigger('click'); + expect($('#aspect_name_form').css('display')).not.toBe('none'); + }); + + it('hides the aspect name', function() { + expect($('.header > h3').css('display')).not.toBe('none'); + this.button.trigger('click'); + expect($('.header > h3').css('display')).toBe('none'); + }); + }); + + context('add contact to aspect', function() { + beforeEach(function() { + this.contact = $('#people_stream .stream_element').last(); + this.button = this.contact.find('.contact_add-to-aspect'); + this.person_id = this.button.attr('data-person_id'); + this.aspect_id = this.button.attr('data-aspect_id'); + }); + + it('sends a correct ajax request', function() { + jasmine.Ajax.install(); + $('.contact_add-to-aspect',this.contact).trigger('click'); + var obj = $.parseJSON(jasmine.Ajax.requests.mostRecent().params); + expect(obj.person_id).toBe(this.person_id); + expect(obj.aspect_id).toBe(this.aspect_id); + }); + + it('adds a membership id to the contact', function() { + jasmine.Ajax.install(); + $('.contact_add-to-aspect',this.contact).trigger('click'); + jasmine.Ajax.requests.mostRecent().response({ + status: 200, // success + responseText: '{ "id": 42 }' + }); + expect(this.button.attr('data-membership_id')).toBe('42'); + }); + + it('displays a flash message on errors', function(){ + jasmine.Ajax.install(); + $('.contact_add-to-aspect',this.contact).trigger('click'); + jasmine.Ajax.requests.mostRecent().response({ + status: 400, // fail + }); + expect($('[id^="flash"]')).toBeErrorFlashMessage( + Diaspora.I18n.t( + 'contacts.error_add', + {name: this.contact.find('.name').text()} + ) + ); + }); + + it('changes the appearance of the contact', function() { + expect(this.button.hasClass('contact_add-to-aspect')).toBeTruethy; + expect(this.button.hasClass('circled-cross')).toBeTruethy; + expect(this.contact.hasClass('in_aspect')).toBeTruethy; + expect(this.button.hasClass('contact_remove-from-aspect')).toBeFalsy; + expect(this.button.hasClass('circled-plus')).toBeFalsy; + expect(this.button.attr('data-original-title')).toBe( + Diaspora.I18n.t('contacts.add_contact') + ); + jasmine.Ajax.install(); + $('.contact_add-to-aspect',this.contact).trigger('click'); + jasmine.Ajax.requests.mostRecent().response({ + status: 200, // success + responseText: '{ "id": 42 }' + }); + expect(this.button.hasClass('contact_add-to-aspect')).toBeFalsy; + expect(this.button.hasClass('circled-cross')).toBeFalsy; + expect(this.contact.hasClass('in_aspect')).toBeFalsy; + expect(this.button.hasClass('contact_remove-from-aspect')).toBeTruethy; + expect(this.button.hasClass('circled-plus')).toBeTruethy; + expect(this.button.attr('data-original-title')).toBe( + Diaspora.I18n.t('contacts.remove_contact') + ); + }); + }); + + context('remove contact from aspect', function() { + beforeEach(function() { + this.contact = $('#people_stream .stream_element').first(); + this.button = this.contact.find('.contact_remove-from-aspect'); + this.person_id = this.button.attr('data-person_id'); + this.aspect_id = this.button.attr('data-aspect_id'); + this.membership_id = this.button.attr('data-membership_id'); + + }); + + it('sends a correct ajax request', function() { + jasmine.Ajax.install(); + $('.contact_remove-from-aspect',this.contact).trigger('click'); + expect(jasmine.Ajax.requests.mostRecent().url).toBe( + "/aspect_memberships/"+this.membership_id + ); + }); + + it('removes the membership id from the contact', function() { + jasmine.Ajax.install(); + $('.contact_remove-from-aspect',this.contact).trigger('click'); + jasmine.Ajax.requests.mostRecent().response({ + status: 200, // success + responseText: '{}' + }); + expect(this.button.attr('data-membership_id')).toBe(undefined); + }); + + it('displays a flash message on errors', function(){ + jasmine.Ajax.install(); + $('.contact_remove-from-aspect',this.contact).trigger('click'); + jasmine.Ajax.requests.mostRecent().response({ + status: 400, // fail + }); + expect($('[id^="flash"]')).toBeErrorFlashMessage( + Diaspora.I18n.t( + 'contacts.error_remove', + {name: this.contact.find('.name').text()} + ) + ); + }); + + it('changes the appearance of the contact', function() { + expect(this.button.hasClass('contact_add-to-aspect')).toBeFalsy; + expect(this.button.hasClass('circled-cross')).toBeFalsy; + expect(this.contact.hasClass('in_aspect')).toBeFalsy; + expect(this.button.hasClass('contact_remove-from-aspect')).toBeTruethy; + expect(this.button.hasClass('circled-plus')).toBeTruethy; + expect(this.button.attr('data-original-title')).toBe( + Diaspora.I18n.t('contacts.remove_contact') + ); + + jasmine.Ajax.install(); + $('.contact_remove-from-aspect',this.contact).trigger('click'); + jasmine.Ajax.requests.mostRecent().response({ + status: 200, // success + responseText: '{}' + }); + + expect(this.button.hasClass('contact_add-to-aspect')).toBeTruethy; + expect(this.button.hasClass('circled-cross')).toBeTruethy; + expect(this.contact.hasClass('in_aspect')).toBeTruethy; + expect(this.button.hasClass('contact_remove-from-aspect')).toBeFalsy; + expect(this.button.hasClass('circled-plus')).toBeFalsy; + expect(this.button.attr('data-original-title')).toBe( + Diaspora.I18n.t('contacts.add_contact') + ); + }); + }); + + context('search contact list', function() { + beforeEach(function() { + this.searchinput = $('#contact_list_search'); + this.username = $('.stream_element .name').first().text(); + }); + + it('filters the contact list by name', function() { + expect($('.stream_element').length).toBeGreaterThan(1); + this.searchinput.val(this.username); + this.searchinput.trigger('keyup'); + expect($('.stream_element:visible').length).toBe(1); + expect($('.stream_element:visible .name').first().text()).toBe(this.username); + }); + }); + +}); diff --git a/spec/javascripts/contact-list-spec.js b/spec/javascripts/contact-list-spec.js deleted file mode 100644 index 6bafe6653..000000000 --- a/spec/javascripts/contact-list-spec.js +++ /dev/null @@ -1,19 +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("Contact List", function() { - describe("disconnectUser", function() { - it("does an ajax call to person delete with the passed in id", function(){ - var id = '3'; - spyOn($,'ajax'); - List.disconnectUser(id); - expect($.ajax).toHaveBeenCalled(); - var option_hash = $.ajax.calls.mostRecent().args[0]; - expect(option_hash.url).toEqual("/contacts/" + id); - expect(option_hash.type).toEqual("DELETE"); - expect(option_hash.success).toBeDefined(); - }); - }); -}); diff --git a/spec/javascripts/search-spec.js b/spec/javascripts/search-spec.js index f1c41d0ba..99f018dbf 100644 --- a/spec/javascripts/search-spec.js +++ b/spec/javascripts/search-spec.js @@ -7,7 +7,6 @@ describe("List", function() { describe("runDelayedSearch", function() { beforeEach( function(){ spec.loadFixture('empty_people_search'); - List.initialize(); }); it('inserts contact html', function(){