javascripts for marking notifications items as unread on both the notifications page and popup menu.

This commit is contained in:
Steven Fuchs 2012-01-17 19:20:42 -05:00
parent 641cedf343
commit a11c8d8a96
5 changed files with 155 additions and 36 deletions

View file

@ -4,8 +4,8 @@
this.subscribe("widget/ready", function(evt, header) { this.subscribe("widget/ready", function(evt, header) {
self.notifications = self.instantiate("Notifications", self.notifications = self.instantiate("Notifications",
header.find("#notifications"), header.find("#notification_badge .badge_count"),
header.find("#notification_badge .badge_count") header.find(".notifications")
); );
self.notificationsDropdown = self.instantiate("NotificationsDropdown", self.notificationsDropdown = self.instantiate("NotificationsDropdown",

View file

@ -63,6 +63,7 @@
$.each(notifications, function(index, notification) { $.each(notifications, function(index, notification) {
var notificationElement = $("<div/>") var notificationElement = $("<div/>")
.addClass("notification_element") .addClass("notification_element")
.data( "guid", notification.id )
.html(notification.translation) .html(notification.translation)
.prepend($("<img/>", { src: notification.actors[0].avatar })) .prepend($("<img/>", { src: notification.actors[0].avatar }))
.append("<br />") .append("<br />")
@ -70,19 +71,15 @@
"class": "timeago", "class": "timeago",
"title": notification.created_at "title": notification.created_at
})) }))
.append('<a class="unread-setter">mark unread</a>')
.appendTo(self.dropdownNotifications); .appendTo(self.dropdownNotifications);
notificationElement.find("abbr.timeago").timeago(); notificationElement.find("abbr.timeago").timeago();
if(notification.unread) { if(notification.unread) {
notificationElement.addClass("unread"); Diaspora.page.header.notifications.setUpUnread( notificationElement );
$.ajax({ }else{
url: "/notifications/" + notification.id, Diaspora.page.header.notifications.setUpRead( notificationElement );
type: "PUT",
success: function() {
Diaspora.page.header.notifications.decrementCount();
}
});
} }
}); });
}); });

View file

@ -8,32 +8,99 @@
var Notifications = function() { var Notifications = function() {
var self = this; var self = this;
this.subscribe("widget/ready", function(evt, notificationArea, badge) { this.subscribe("widget/ready", function(evt, badge, notificationMenu) {
$.extend(self, { $.extend(self, {
badge: badge, badge: badge,
count: parseInt(badge.html()) || 0, count: parseInt(badge.html()) || 0,
notificationArea: notificationArea notificationArea: null,
notificationMenu: notificationMenu
}); });
$(".stream_element.unread").live("mousedown", function() { $("a.more").click( function(evt) {
self.decrementCount();
$.ajax({
url: "notifications/" + $(this).removeClass("unread").data("guid"),
type: "PUT"
});
});
$("a.more").live("click", function(evt) {
evt.preventDefault(); evt.preventDefault();
$(this).hide() $(this).hide()
.next(".hidden") .next(".hidden")
.removeClass("hidden"); .removeClass("hidden");
}); });
}); });
this.setUpNotificationPage = function( contentArea ) {
self.notificationArea = contentArea;
contentArea.find(".unread,.read").each(function(index) {
if ( $(this).hasClass("unread") ) {
self.setUpUnread( $(this) );
} else {
self.setUpRead( $(this) );
}
});
}
this.unreadClick = function() {
$.ajax({
url: "/notifications/" + $(this).parent().data("guid"),
data: { set_unread: true },
type: "PUT",
success: self.clickSuccess
});
};
this.readClick = function() {
$.ajax({
url: "/notifications/" + $(this).data("guid"),
data: { set_unread: false },
type: "PUT",
success: self.clickSuccess
});
};
this.setUpUnread = function( an_obj ) {
an_obj.removeClass("read").addClass( "unread" );
an_obj.find('.unread-setter').hide();
an_obj.find('.unread-setter').unbind("click");
an_obj.unbind( "mouseenter mouseleave" );
an_obj.click(self.readClick);
}
this.setUpRead = function( an_obj ) {
an_obj.removeClass("unread").addClass( "read" );
an_obj.unbind( "click" );
an_obj.find(".unread-setter").click(Diaspora.page.header.notifications.unreadClick);
an_obj.hover(
function () {
$(this).find(".unread-setter").show();
},
function () {
$(this).find(".unread-setter").hide();
}
);
}
this.clickSuccess = function( data ) {
var jsList = jQuery.parseJSON(data);
var itemID = jsList["guid"]
var isUnread = jsList["unread"]
if ( isUnread ) {
self.incrementCount();
}else{
self.decrementCount();
}
self.notificationMenu.find('.read,.unread').each(function(index) {
if ( $(this).data("guid") == itemID ) {
if ( isUnread ) {
self.setUpUnread( $(this) )
} else {
self.setUpRead( $(this) )
}
}
});
if ( self.notificationArea ) {
self.notificationArea.find('.read,.unread').each(function(index) {
if ( $(this).data("guid") == itemID ) {
if ( isUnread ) {
self.setUpUnread( $(this) )
} else {
self.setUpRead( $(this) )
}
}
});
}
};
this.showNotification = function(notification) { this.showNotification = function(notification) {
$(notification.html).prependTo(this.notificationArea) $(notification.html).prependTo(this.notificationMenu)
.fadeIn(200) .fadeIn(200)
.delay(8000) .delay(8000)
.fadeOut(200, function() { .fadeOut(200, function() {
@ -50,13 +117,20 @@
if(self.badge.text() !== "") { if(self.badge.text() !== "") {
self.badge.text(self.count); self.badge.text(self.count);
if ( self.notificationArea ) {
self.notificationArea.find( ".notification_count" ).text(self.count);
if(self.count === 0) { if(self.count === 0) {
self.badge.addClass("hidden"); self.badge.addClass("hidden");
} if ( self.notificationArea )
else if(self.count === 1) { self.notificationArea.find( ".notification_count" ).removeClass("unread");
self.badge.removeClass("hidden"); }
} else if(self.count === 1) {
self.badge.removeClass("hidden");
if ( self.notificationArea )
self.notificationArea.find( ".notification_count" ).addClass("unread");
}
}
} }
}; };

View file

@ -3,13 +3,46 @@
* the COPYRIGHT file. * the COPYRIGHT file.
*/ */
describe("Diaspora.Widgets.Notifications", function() { describe("Diaspora.Widgets.Notifications", function() {
var changeNotificationCountSpy, notifications; var changeNotificationCountSpy, notifications, incrementCountSpy, decrementCountSpy;
beforeEach(function() { beforeEach(function() {
spec.loadFixture("aspects_index"); spec.loadFixture("aspects_index");
notifications = Diaspora.BaseWidget.instantiate("Notifications", $("#notifications"), $("#notification_badge .badge_count")); this.view = new app.views.Header().render();
notifications = Diaspora.BaseWidget.instantiate("Notifications", this.view.$("#notification_badge .badge_count"), this.view.$(".notifications"));
changeNotificationCountSpy = spyOn(notifications, "changeNotificationCount").andCallThrough(); changeNotificationCountSpy = spyOn(notifications, "changeNotificationCount").andCallThrough();
incrementCountSpy = spyOn(notifications, "incrementCount").andCallThrough();
decrementCountSpy = spyOn(notifications, "decrementCount").andCallThrough();
});
describe("clickSuccess", function(){
it("changes the css to a read cell", function() {
this.view.$(".notifications").html(
'<div id="1" class="stream_element read" data-guid=1></div>' +
'<div id="2" class="stream_element unread" data-guid=2></div>'
);
notifications.clickSuccess(JSON.stringify({guid:2,unread:false}));
expect( this.view.$('.stream_element#2')).toHaveClass("read");
});
it("changes the css to an unread cell", function() {
this.view.$(".notifications").html(
'<div id="1" class="stream_element read" data-guid=1></div>' +
'<div id="2" class="stream_element unread" data-guid=2></div>'
);
notifications.clickSuccess(JSON.stringify({guid:1,unread:true}));
expect( this.view.$('.stream_element#1')).toHaveClass("unread");
});
it("calls Notifications.decrementCount on a read cell", function() {
notifications.clickSuccess(JSON.stringify({guid:1,unread:false}));
expect(notifications.decrementCount).toHaveBeenCalled();
});
it("calls Notifications.incrementCount on a unread cell", function() {
notifications.clickSuccess(JSON.stringify({guid:1,unread:true}));
expect(notifications.incrementCount).toHaveBeenCalled();
});
}); });
describe("decrementCount", function() { describe("decrementCount", function() {
@ -40,13 +73,13 @@ describe("Diaspora.Widgets.Notifications", function() {
describe("showNotification", function() { describe("showNotification", function() {
it("prepends a div to div#notifications", function() { it("prepends a div to div#notifications", function() {
expect($("#notifications div").length).toEqual(0); expect(this.view.$(".notifications div").length).toEqual(1);
notifications.showNotification({ notifications.showNotification({
html: '<div class="notification"></div>' html: '<div class="notification_element"></div>'
}); });
expect($("#notifications div").length).toEqual(1); expect(this.view.$(".notifications div").length).toEqual(2);
}); });
it("only increments the notification count if specified to do so", function() { it("only increments the notification count if specified to do so", function() {
@ -61,4 +94,4 @@ describe("Diaspora.Widgets.Notifications", function() {
}); });
}); });
}); });

View file

@ -40,6 +40,21 @@ describe Notification do
end end
end end
describe 'set_read_state method' do
it "should set an unread notification to read" do
@note.unread = true
@note.set_read_state( true )
@note.unread.should == false
end
it "should set an read notification to unread" do
@note.unread = false
@note.set_read_state( false )
@note.unread.should == true
end
end
describe '.concatenate_or_create' do describe '.concatenate_or_create' do
it 'creates a new notificiation if the notification does not exist, or if it is unread' do it 'creates a new notificiation if the notification does not exist, or if it is unread' do
@note.unread = false @note.unread = false