diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index 507f8c0bf..52c5bd3f7 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -24,7 +24,7 @@ class NotificationsController < VannaController :conditions => conditions, :order => 'created_at desc', :include => [:target, {:actors => :profile}], - :limit => pager.per_page, + :limit => request.format == :json ? 5 : pager.per_page, :offset => pager.offset ) @@ -32,6 +32,7 @@ class NotificationsController < VannaController end notifications.each do |n| n[:actors] = n.actors + n[:translation] = object_link(n, n.actors.map { |a| person_link(a) }) n[:translation_key] = n.popup_translation_key n[:target] = n.translation_key == "notifications.mentioned" ? n.target.post : n.target end @@ -42,9 +43,14 @@ class NotificationsController < VannaController def read_all(opts=params) Notification.where(:recipient_id => current_user.id).update_all(:unread => false) end + post_process :html do def post_read_all(json) Response.new(:status => 302, :location => aspects_path) end end + + def controller + Object.new + end end diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb index 058124822..5c30f9ede 100644 --- a/app/helpers/notifications_helper.rb +++ b/app/helpers/notifications_helper.rb @@ -1,4 +1,8 @@ module NotificationsHelper + include ERB::Util + include ActionView::Helpers::TranslationHelper + include ActionView::Helpers::UrlHelper + include ApplicationHelper def object_link(note, actors) target_type = note.popup_translation_key actors_count = note.actors.count diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index 0bd36b062..55dd8ae51 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -43,6 +43,15 @@ .badge_count{:class => ("hidden" if @unread_message_count == 0)} = @unread_message_count + #notification_dropdown + .header + = link_to t('.view_all'), notifications_path, :id => "view_all_notifications" + %h4 + Recent notifications + .notifications + .ajax_loader + = image_tag("ajax-loader.gif") + %ul#user_menu.dropdown %li .right diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 0fe815845..064663a3e 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -94,8 +94,6 @@ .span-24.last{:style=> "#{yield(:break_the_mold)}"} = yield - .clearfix - =render :partial => 'notifications/overlay' /=render :partial => 'layouts/debug.haml' %footer diff --git a/app/views/notifications/_overlay.html.haml b/app/views/notifications/_overlay.html.haml deleted file mode 100644 index ea149e55b..000000000 --- a/app/views/notifications/_overlay.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -.span-24.last#notifications_overlay - .stream.notifications - .day_group.span-24.last - .span-3 - .date - .day - .month - .span-8.notifications_for_day - .stream_element{:data=>{:guid => nil}} - .right - %span.from - = link_to("", "#", :class => "actor") - = link_to("", "#", :class => "object") - - %br - %time - = link_to("all of them", notifications_path) - %a.close{:href => "#" } - close \ No newline at end of file diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml index 9c7fb6229..b8b5076e9 100644 --- a/config/locales/diaspora/en.yml +++ b/config/locales/diaspora/en.yml @@ -292,6 +292,7 @@ en: login: "log in" code: "code" admin: "admin" + view_all: "View all" application: powered_by: "POWERED BY DIASPORA*" whats_new: "what's new?" diff --git a/features/notifications.feature b/features/notifications.feature index 7c94cb1ea..a5ad1fda3 100644 --- a/features/notifications.feature +++ b/features/notifications.feature @@ -14,8 +14,14 @@ Background: And I go to the destroy user session page -Scenario: someone shares with me - When I sign in as "alice@alice.alice" - And I follow "notifications" in the header + Scenario: someone shares with me + When I sign in as "alice@alice.alice" + And I follow "notifications" in the header Then I should see "started sharing with you" + + Scenario: notification popup + When I sign in as "alice@alice.alice" + And I click the notification badge + And I wait for the ajax to finish + Then the notification dropdown should be visible diff --git a/features/step_definitions/custom_web_steps.rb b/features/step_definitions/custom_web_steps.rb index d239eda9c..9856a7d26 100644 --- a/features/step_definitions/custom_web_steps.rb +++ b/features/step_definitions/custom_web_steps.rb @@ -194,3 +194,11 @@ end When /^I wait for (\d+) seconds$/ do |seconds| sleep seconds.to_i end + +When /^I click the notification badge$/ do + evaluate_script("$('#notification_badge a').click();"); +end + +Then /^the notification dropdown should be visible$/ do + evaluate_script("$('#notification_dropdown').css('display') === 'block'") +end diff --git a/public/javascripts/widgets/notifications-badge.js b/public/javascripts/widgets/notifications-badge.js index 23384aeaf..085923ef4 100644 --- a/public/javascripts/widgets/notifications-badge.js +++ b/public/javascripts/widgets/notifications-badge.js @@ -1,41 +1,92 @@ -$(function() { - $("#notification_badge a").live("_click", function(event){ - event.preventDefault(); - $.getJSON("/notifications", function(hash) { - $("#notifications_overlay").show(); - var notificationsElement = $("#notifications_overlay .notifications"); - var dayElementTemplate = $("#notifications_overlay .day_group").clone(); - dayElementTemplate.find(".notifications_for_day").empty(); - var streamElementTemplate = $("#notifications_overlay .stream_element").clone(); - notificationsElement.empty(); - $.each(hash["group_days"], function(day){ - var dayElement = dayElementTemplate.clone(); - var dayParts = day.split(" "); - dayElement.find(".month").text(dayParts[0]) - dayElement.find(".day").text(dayParts[1]) - var notificationsForDay = hash["group_days"][day], - notificationsForDayElement = dayElement.find('.notifications_for_day'); +(function() { + var NotificationDropdown = function() { + var self = this; - $.each(notificationsForDay, function(i, notificationHash) { - $.each(notificationHash, function(notificationType, notification) { - var actor = notification.actors[0]; - var streamElement = streamElementTemplate.clone().appendTo(notificationsForDayElement); - streamElement.find(".actor") - .text(actor.name) - .attr("href", notification.actors[0]["url"]); - streamElement.find('time').attr("datetime", notification["created_at"]); + this.start = function() { + this.badge = $("#notification_badge"); + this.badgeLink = this.badge.find("a"); + this.documentBody = $(document.body); + this.dropdown = $("#notification_dropdown"); + this.dropdownNotifications = this.dropdown.find(".notifications"); + this.ajaxLoader = this.dropdown.find(".ajax_loader"); + + this.badgeLink.toggle(function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + + self.ajaxLoader.show(); + self.badge.addClass("active"); + self.dropdown.css("display", "block"); + + self.getNotifications(function() { + self.renderNotifications(); }); - }); - notificationsElement.append(dayElement) + }, function(evt) { + evt.preventDefault(); + evt.stopPropagation(); - Diaspora.widgets.timeago.updateTimeAgo("time"); + self.badge.removeClass("active"); + self.dropdown.css("display", "none"); }); - }); - }); - $("#notifications_overlay").delegate('a.close', 'click', function() { - console.log("hi!"); - $('#notifications_overlay').hide(); - }); + this.dropdown.click(function(evt) { + evt.stopPropagation(); + }); -}); + this.documentBody.click(function(evt) { + if(self.dropdownShowing()) { + self.badgeLink.click(); + } + }); + }; + + + this.dropdownShowing = function() { + return this.dropdown.css("display") === "block"; + }; + + this.getNotifications = function(callback) { + $.getJSON("/notifications", function(notifications) { + self.notifications = notifications; + callback.apply(self, []); + }); + }; + + this.renderNotifications = function() { + self.dropdownNotifications.empty(); + + $.each(self.notifications.notifications, function(index, notifications) { + $.each(notifications, function(index, notification) { + var notificationElement = $("
") + .addClass("notification_element") + .html(notification.translation) + .prepend($("