diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index 507f8c0bf..af52b16a3 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -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..eaf066ee0 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -43,6 +43,8 @@ .badge_count{:class => ("hidden" if @unread_message_count == 0)} = @unread_message_count + #notification_dropdown + %ul#user_menu.dropdown %li .right 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..cff936674 100644 --- a/public/javascripts/widgets/notifications-badge.js +++ b/public/javascripts/widgets/notifications-badge.js @@ -1,41 +1,67 @@ -$(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() { + this.start = function() { + this.badge = $("#notification_badge a"); + this.documentBody = $(document.body); + this.dropdown = $("#notification_dropdown"); - $.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.badge.click($.proxy(function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + + if(!this.dropdownShowing()) { + this.getNotifications(function() { + this.toggleDropdown(); }); - }); - notificationsElement.append(dayElement) + } + else { + this.toggleDropdown(); + } + }, this)); - Diaspora.widgets.timeago.updateTimeAgo("time"); - }); - }); - }); + this.documentBody.click($.proxy(function(evt) { + if(this.dropdownShowing()) { + this.toggleDropdown(evt); + } + }, this)); + }; + }; - $("#notifications_overlay").delegate('a.close', 'click', function() { - console.log("hi!"); - $('#notifications_overlay').hide(); - }); + NotificationDropdown.prototype.dropdownShowing = function() { + return this.dropdown.css("display") === "block"; + } -}); + NotificationDropdown.prototype.toggleDropdown = function() { + if(!this.dropdownShowing()) { + this.renderNotifications(); + this.showDropdown(); + } else { + this.hideDropdown(); + } + } + + NotificationDropdown.prototype.showDropdown = function() { + this.dropdown.css("display", "block"); + } + + NotificationDropdown.prototype.hideDropdown = function() { + this.dropdown.css("display", "none"); + } + + NotificationDropdown.prototype.getNotifications = function(callback) { + $.getJSON("/notifications", $.proxy(function(notifications) { + this.notifications = notifications; + callback.apply(this, [notifications]); + }, this)); + }; + + NotificationDropdown.prototype.renderNotifications = function() { + $.each(this.notifications.notifications, $.proxy(function(index, notifications) { + $.each(notifications, $.proxy(function(index, notification) { + this.dropdown.append(notification.translation); + }, this)); + }, this)); + }; + + Diaspora.widgets.add("notificationDropdown", NotificationDropdown); +})(); diff --git a/public/stylesheets/sass/application.sass b/public/stylesheets/sass/application.sass index bc2746938..dd0c01363 100644 --- a/public/stylesheets/sass/application.sass +++ b/public/stylesheets/sass/application.sass @@ -2828,7 +2828,7 @@ ul#requested-scopes img :height 30px :width 30px - + .scope-description :display none @@ -3061,3 +3061,13 @@ ul.left_nav .big_stream_photo :display block + +#notification_dropdown + :background white + :border solid #000 1px + :padding 25px + :position absolute + :top 29px + :left 540px + :display none +