Loading Changelog.md +2 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ * Add a dark color theme [#7152](https://github.com/diaspora/diaspora/pull/7152) * Added setting for custom changelog URL [#7166](https://github.com/diaspora/diaspora/pull/7166) * Show more information of recipients on conversation creation [#7129](https://github.com/diaspora/diaspora/pull/7129) * Update notifications every 5 minutes and when opening the notification dropdown [#6952](https://github.com/diaspora/diaspora/pull/6952) * Show browser notifications when receiving new unread notifications [#6952](https://github.com/diaspora/diaspora/pull/6952) # 0.6.1.0 Loading app/assets/javascripts/app/app.js +1 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ var app = { setupHeader: function() { if(app.currentUser.authenticated()) { app.notificationsCollection = new app.collections.Notifications(); app.header = new app.views.Header(); $("header").prepend(app.header.el); app.header.render(); Loading app/assets/javascripts/app/collections/notifications.js 0 → 100644 +118 −0 Original line number Diff line number Diff line app.collections.Notifications = Backbone.Collection.extend({ model: app.models.Notification, // URL parameter /* eslint-disable camelcase */ url: Routes.notifications({per_page: 10, page: 1}), /* eslint-enable camelcase */ page: 2, perPage: 5, unreadCount: 0, unreadCountByType: {}, timeout: 300000, // 5 minutes initialize: function() { this.pollNotifications(); setTimeout(function() { setInterval(this.pollNotifications.bind(this), this.timeout); }.bind(this), this.timeout); Diaspora.BrowserNotification.requestPermission(); }, pollNotifications: function() { var unreadCountBefore = this.unreadCount; this.fetch(); this.once("finishedLoading", function() { if (unreadCountBefore < this.unreadCount) { Diaspora.BrowserNotification.spawnNotification( Diaspora.I18n.t("notifications.new_notifications", {count: this.unreadCount})); } }, this); }, fetch: function(options) { options = options || {}; options.remove = false; options.merge = true; options.parse = true; Backbone.Collection.prototype.fetch.apply(this, [options]); }, fetchMore: function() { var hasMoreNotifications = (this.page * this.perPage) <= this.length; // There are more notifications to load on the current page if (hasMoreNotifications) { this.page++; // URL parameter /* eslint-disable camelcase */ var route = Routes.notifications({per_page: this.perPage, page: this.page}); /* eslint-enable camelcase */ this.fetch({url: route, pushBack: true}); } }, /** * Adds new models to the collection at the end or at the beginning of the collection and * then fires an event for each model of the collection. It will fire a different event * based on whether the models were added at the end (typically when the scroll triggers to load more * notifications) or at the beginning (new notifications have been added to the front of the list). */ set: function(items, options) { options = options || {}; options.at = options.pushBack ? this.length : 0; // Retreive back the new created models var models = []; var accu = function(model) { models.push(model); }; this.on("add", accu); Backbone.Collection.prototype.set.apply(this, [items, options]); this.off("add", accu); if (options.pushBack) { models.forEach(function(model) { this.trigger("pushBack", model); }.bind(this)); } else { // Fires events in the reverse order so that the first event is prepended in first position models.reverse(); models.forEach(function(model) { this.trigger("pushFront", model); }.bind(this)); } this.trigger("finishedLoading"); }, parse: function(response) { this.unreadCount = response.unread_count; this.unreadCountByType = response.unread_count_by_type; return _.map(response.notification_list, function(item) { /* eslint-disable new-cap */ var model = new this.model(item); /* eslint-enable new-cap */ model.on("change:unread", this.onChangedUnreadStatus.bind(this)); return model; }.bind(this)); }, setAllRead: function() { this.forEach(function(model) { model.setRead(); }); }, setRead: function(guid) { this.find(function(model) { return model.guid === guid; }).setRead(); }, setUnread: function(guid) { this.find(function(model) { return model.guid === guid; }).setUnread(); }, onChangedUnreadStatus: function(model) { if (model.get("unread") === true) { this.unreadCount++; this.unreadCountByType[model.get("type")]++; } else { this.unreadCount = Math.max(this.unreadCount - 1, 0); this.unreadCountByType[model.get("type")] = Math.max(this.unreadCountByType[model.get("type")] - 1, 0); } this.trigger("update"); } }); app/assets/javascripts/app/models/notification.js 0 → 100644 +69 −0 Original line number Diff line number Diff line app.models.Notification = Backbone.Model.extend({ constructor: function(attributes, options) { options = options || {}; options.parse = true; Backbone.Model.apply(this, [attributes, options]); this.guid = this.get("id"); }, /** * Flattens the notification object returned by the server. * * The server returns an object that looks like: * * { * "reshared": { * "id": 45, * "target_type": "Post", * "target_id": 11, * "recipient_id": 1, * "unread": true, * "created_at": "2015-10-27T19:56:30.000Z", * "updated_at": "2015-10-27T19:56:30.000Z", * "note_html": <html/> * }, * "type": "reshared" * } * * The returned object looks like: * * { * "type": "reshared", * "id": 45, * "target_type": "Post", * "target_id": 11, * "recipient_id": 1, * "unread": true, * "created_at": "2015-10-27T19:56:30.000Z", * "updated_at": "2015-10-27T19:56:30.000Z", * "note_html": <html/>, * } */ parse: function(response) { var result = {type: response.type}; result = $.extend(result, response[result.type]); return result; }, setRead: function() { this.setUnreadStatus(false); }, setUnread: function() { this.setUnreadStatus(true); }, setUnreadStatus: function(state) { if (this.get("unread") !== state) { $.ajax({ url: Routes.notification(this.guid), /* eslint-disable camelcase */ data: {set_unread: state}, /* eslint-enable camelcase */ type: "PUT", context: this, success: function() { this.set("unread", state); } }); } } }); app/assets/javascripts/app/router.js +1 −1 Original line number Diff line number Diff line Loading @@ -139,7 +139,7 @@ app.Router = Backbone.Router.extend({ notifications: function() { this._loadContacts(); this.renderAspectMembershipDropdowns($(document)); new app.views.Notifications({el: "#notifications_container"}); new app.views.Notifications({el: "#notifications_container", collection: app.notificationsCollection}); }, peopleSearch: function() { Loading Loading
Changelog.md +2 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ * Add a dark color theme [#7152](https://github.com/diaspora/diaspora/pull/7152) * Added setting for custom changelog URL [#7166](https://github.com/diaspora/diaspora/pull/7166) * Show more information of recipients on conversation creation [#7129](https://github.com/diaspora/diaspora/pull/7129) * Update notifications every 5 minutes and when opening the notification dropdown [#6952](https://github.com/diaspora/diaspora/pull/6952) * Show browser notifications when receiving new unread notifications [#6952](https://github.com/diaspora/diaspora/pull/6952) # 0.6.1.0 Loading
app/assets/javascripts/app/app.js +1 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ var app = { setupHeader: function() { if(app.currentUser.authenticated()) { app.notificationsCollection = new app.collections.Notifications(); app.header = new app.views.Header(); $("header").prepend(app.header.el); app.header.render(); Loading
app/assets/javascripts/app/collections/notifications.js 0 → 100644 +118 −0 Original line number Diff line number Diff line app.collections.Notifications = Backbone.Collection.extend({ model: app.models.Notification, // URL parameter /* eslint-disable camelcase */ url: Routes.notifications({per_page: 10, page: 1}), /* eslint-enable camelcase */ page: 2, perPage: 5, unreadCount: 0, unreadCountByType: {}, timeout: 300000, // 5 minutes initialize: function() { this.pollNotifications(); setTimeout(function() { setInterval(this.pollNotifications.bind(this), this.timeout); }.bind(this), this.timeout); Diaspora.BrowserNotification.requestPermission(); }, pollNotifications: function() { var unreadCountBefore = this.unreadCount; this.fetch(); this.once("finishedLoading", function() { if (unreadCountBefore < this.unreadCount) { Diaspora.BrowserNotification.spawnNotification( Diaspora.I18n.t("notifications.new_notifications", {count: this.unreadCount})); } }, this); }, fetch: function(options) { options = options || {}; options.remove = false; options.merge = true; options.parse = true; Backbone.Collection.prototype.fetch.apply(this, [options]); }, fetchMore: function() { var hasMoreNotifications = (this.page * this.perPage) <= this.length; // There are more notifications to load on the current page if (hasMoreNotifications) { this.page++; // URL parameter /* eslint-disable camelcase */ var route = Routes.notifications({per_page: this.perPage, page: this.page}); /* eslint-enable camelcase */ this.fetch({url: route, pushBack: true}); } }, /** * Adds new models to the collection at the end or at the beginning of the collection and * then fires an event for each model of the collection. It will fire a different event * based on whether the models were added at the end (typically when the scroll triggers to load more * notifications) or at the beginning (new notifications have been added to the front of the list). */ set: function(items, options) { options = options || {}; options.at = options.pushBack ? this.length : 0; // Retreive back the new created models var models = []; var accu = function(model) { models.push(model); }; this.on("add", accu); Backbone.Collection.prototype.set.apply(this, [items, options]); this.off("add", accu); if (options.pushBack) { models.forEach(function(model) { this.trigger("pushBack", model); }.bind(this)); } else { // Fires events in the reverse order so that the first event is prepended in first position models.reverse(); models.forEach(function(model) { this.trigger("pushFront", model); }.bind(this)); } this.trigger("finishedLoading"); }, parse: function(response) { this.unreadCount = response.unread_count; this.unreadCountByType = response.unread_count_by_type; return _.map(response.notification_list, function(item) { /* eslint-disable new-cap */ var model = new this.model(item); /* eslint-enable new-cap */ model.on("change:unread", this.onChangedUnreadStatus.bind(this)); return model; }.bind(this)); }, setAllRead: function() { this.forEach(function(model) { model.setRead(); }); }, setRead: function(guid) { this.find(function(model) { return model.guid === guid; }).setRead(); }, setUnread: function(guid) { this.find(function(model) { return model.guid === guid; }).setUnread(); }, onChangedUnreadStatus: function(model) { if (model.get("unread") === true) { this.unreadCount++; this.unreadCountByType[model.get("type")]++; } else { this.unreadCount = Math.max(this.unreadCount - 1, 0); this.unreadCountByType[model.get("type")] = Math.max(this.unreadCountByType[model.get("type")] - 1, 0); } this.trigger("update"); } });
app/assets/javascripts/app/models/notification.js 0 → 100644 +69 −0 Original line number Diff line number Diff line app.models.Notification = Backbone.Model.extend({ constructor: function(attributes, options) { options = options || {}; options.parse = true; Backbone.Model.apply(this, [attributes, options]); this.guid = this.get("id"); }, /** * Flattens the notification object returned by the server. * * The server returns an object that looks like: * * { * "reshared": { * "id": 45, * "target_type": "Post", * "target_id": 11, * "recipient_id": 1, * "unread": true, * "created_at": "2015-10-27T19:56:30.000Z", * "updated_at": "2015-10-27T19:56:30.000Z", * "note_html": <html/> * }, * "type": "reshared" * } * * The returned object looks like: * * { * "type": "reshared", * "id": 45, * "target_type": "Post", * "target_id": 11, * "recipient_id": 1, * "unread": true, * "created_at": "2015-10-27T19:56:30.000Z", * "updated_at": "2015-10-27T19:56:30.000Z", * "note_html": <html/>, * } */ parse: function(response) { var result = {type: response.type}; result = $.extend(result, response[result.type]); return result; }, setRead: function() { this.setUnreadStatus(false); }, setUnread: function() { this.setUnreadStatus(true); }, setUnreadStatus: function(state) { if (this.get("unread") !== state) { $.ajax({ url: Routes.notification(this.guid), /* eslint-disable camelcase */ data: {set_unread: state}, /* eslint-enable camelcase */ type: "PUT", context: this, success: function() { this.set("unread", state); } }); } } });
app/assets/javascripts/app/router.js +1 −1 Original line number Diff line number Diff line Loading @@ -139,7 +139,7 @@ app.Router = Backbone.Router.extend({ notifications: function() { this._loadContacts(); this.renderAspectMembershipDropdowns($(document)); new app.views.Notifications({el: "#notifications_container"}); new app.views.Notifications({el: "#notifications_container", collection: app.notificationsCollection}); }, peopleSearch: function() { Loading