diff --git a/app/assets/javascripts/app/views/header_view.js b/app/assets/javascripts/app/views/header_view.js index a3a2197aa4f2141fdd2b72d8da2223aa24d8f13b..985c28652c94eaeecd47c8b71a5084189ee404a1 100644 --- a/app/assets/javascripts/app/views/header_view.js +++ b/app/assets/javascripts/app/views/header_view.js @@ -20,7 +20,7 @@ app.views.Header = app.views.Base.extend({ postRenderTemplate: function(){ new app.views.Notifications({ el: '#notification_dropdown' }); - new app.views.NotificationsBadge({ el: '#notification_badge' }); + new app.views.NotificationDropdown({ el: '#notification_badge' }); new app.views.SearchBar({ el: '#search_people_form' }); }, diff --git a/app/assets/javascripts/app/views/notifications_badge_view.js b/app/assets/javascripts/app/views/notifications_dropdown_view.js similarity index 62% rename from app/assets/javascripts/app/views/notifications_badge_view.js rename to app/assets/javascripts/app/views/notifications_dropdown_view.js index 2c3bfee4fa46f5c999007613c82e1678ab350529..7273dd906e5088fecd10da9995782e47aec0a68e 100644 --- a/app/assets/javascripts/app/views/notifications_badge_view.js +++ b/app/assets/javascripts/app/views/notifications_dropdown_view.js @@ -1,33 +1,35 @@ // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later -app.views.NotificationsBadge = app.views.Base.extend({ +app.views.NotificationDropdown = app.views.Base.extend({ events:{ - "click #notifications-badge": "toggleNotifDropdown" + "click #notifications-badge": "toggleDropdown" }, initialize: function(){ - $(document.body).click($.proxy(this.hideNotifDropdown, this)); + $(document.body).click($.proxy(this.hideDropdown, this)); - this.currentPage = 2; - this.notificationsLoaded = 10; + this.notifications = []; + this.perPage = 5; + this.hasMoreNotifs = true; this.badge = this.$el; this.dropdown = $('#notification_dropdown'); this.dropdownNotifications = this.dropdown.find(".notifications"); this.ajaxLoader = this.dropdown.find(".ajax_loader"); }, - toggleNotifDropdown: function(evt){ + toggleDropdown: function(evt){ evt.preventDefault(); evt.stopPropagation(); - if(this.notifDropdownShowing()){ this.hideNotifDropdown(evt); } - else{ this.showNotifDropdown(); } + if(this.dropdownShowing()){ this.hideDropdown(evt); } + else{ this.showDropdown(); } }, - notifDropdownShowing: function(){ + dropdownShowing: function(){ return this.dropdown.css("display") === "block"; }, - showNotifDropdown: function(){ + showDropdown: function(){ + this.resetParams(); this.ajaxLoader.show(); this.badge.addClass("active"); this.dropdown.css("display", "block"); @@ -35,31 +37,47 @@ app.views.NotificationsBadge = app.views.Base.extend({ this.getNotifications(); }, - hideNotifDropdown: function(evt){ + hideDropdown: function(evt){ var inDropdown = $(evt.target).parents().is(this.dropdown); var inHovercard = $.contains(app.hovercard.el, evt.target); - if(!inDropdown && !inHovercard && this.notifDropdownShowing()){ + if(!inDropdown && !inHovercard && this.dropdownShowing()){ this.badge.removeClass("active"); this.dropdown.css("display", "none"); this.dropdownNotifications.perfectScrollbar('destroy'); } }, - notifDropdownScroll: function(){ - var bottom = this.dropdownNotifications.prop('scrollHeight') - this.dropdownNotifications.height(); - var currentPosition = this.dropdownNotifications.scrollTop(); + dropdownScroll: function(){ var isLoading = ($('.loading').length === 1); - if (currentPosition + 50 >= bottom && this.notificationsLoaded <= this.notifications.length && !isLoading){ - this.dropdownNotifications.addClass("loading"); - this.getMoreNotifications(++this.currentPage); + if (this.isBottom() && this.hasMoreNotifs && !isLoading){ + this.dropdownNotifications.addClass('loading'); + this.getNotifications(); } }, - getMoreNotifications: function(page){ + getParams: function(){ + if(this.notifications.length === 0){ return{ per_page: 10, page: 1 }; } + else{ return{ per_page: this.perPage, page: this.nextPage }; } + }, + + resetParams: function(){ + this.notifications.length = 0; + this.hasMoreNotifs = true; + delete this.nextPage; + }, + + isBottom: function(){ + var bottom = this.dropdownNotifications.prop('scrollHeight') - this.dropdownNotifications.height(); + var currentPosition = this.dropdownNotifications.scrollTop(); + return currentPosition + 50 >= bottom; + }, + + getNotifications: function(){ var self = this; - $.getJSON(Routes.notifications_path({ per_page:5, page: page }), function(notifications){ - for(var i = 0; i < notifications.length; ++i){ self.notifications.push(notifications[i]); } - self.notificationsLoaded += 5; + $.getJSON(Routes.notifications_path(this.getParams()), function(notifications){ + $.each(notifications, function(){ self.notifications.push(this); }); + self.hasMoreNotifs = notifications.length >= self.perPage; + self.nextPage = self.nextPage++ || 3; self.renderNotifications(); }); }, @@ -73,14 +91,6 @@ app.views.NotificationsBadge = app.views.Base.extend({ }); }, - getNotifications: function(){ - var self = this; - $.getJSON(Routes.notifications_path({ per_page: self.notificationsLoaded }), function(notifications){ - self.notifications = notifications; - self.renderNotifications(); - }); - }, - renderNotifications: function(){ var self = this; this.dropdownNotifications.find('.media.stream_element').remove(); @@ -100,7 +110,7 @@ app.views.NotificationsBadge = app.views.Base.extend({ this.dropdownNotifications.perfectScrollbar('destroy').perfectScrollbar(); this.dropdownNotifications.removeClass('loading'); this.dropdownNotifications.scroll(function(){ - self.notifDropdownScroll(); + self.dropdownScroll(); }); } }); diff --git a/spec/javascripts/app/views/search_view_spec.js b/spec/javascripts/app/views/search_view_spec.js index 2a1e4fa62307c7251fc4bd88e02eadb970b0c292..3ea52e03a22bc14703bb17e67e32421fa312828a 100644 --- a/spec/javascripts/app/views/search_view_spec.js +++ b/spec/javascripts/app/views/search_view_spec.js @@ -1,13 +1,13 @@ describe("app.views.SearchBar", function() { beforeEach(function(){ + spec.content().html('<form action="#" id="search_people_form"></form>'); this.view = new app.views.SearchBar({ el: '#search_people_form' }); }); describe("parse", function() { it("escapes a persons name", function() { - $("#jasmine_content").html('<form action="#" id="searchForm"></form>'); - var person = { 'name': '</script><script>alert("xss");</script' }; - var result = this.view.search.parse([$.extend({}, person)]); + this.view.context = this.view; + var result = this.view.parse([$.extend({}, person)]); expect(result[0].data.name).not.toEqual(person.name); }); });