/app/assets/javascripts/app/collections/notifications.js

https://github.com/prellele/diaspora · JavaScript · 115 lines · 84 code · 14 blank · 17 comment · 8 complexity · e5e2edcb2a23df73f5693bcf56438421 MD5 · raw file

  1. app.collections.Notifications = Backbone.Collection.extend({
  2. model: app.models.Notification,
  3. // URL parameter
  4. /* eslint-disable camelcase */
  5. url: Routes.notifications({per_page: 10, page: 1}),
  6. /* eslint-enable camelcase */
  7. page: 2,
  8. perPage: 5,
  9. unreadCount: 0,
  10. unreadCountByType: {},
  11. timeout: 300000, // 5 minutes
  12. initialize: function() {
  13. this.fetch();
  14. setInterval(this.pollNotifications.bind(this), this.timeout);
  15. Diaspora.BrowserNotification.requestPermission();
  16. },
  17. pollNotifications: function() {
  18. var unreadCountBefore = this.unreadCount;
  19. this.fetch();
  20. this.once("finishedLoading", function() {
  21. if (unreadCountBefore < this.unreadCount) {
  22. Diaspora.BrowserNotification.spawnNotification(
  23. Diaspora.I18n.t("notifications.new_notifications", {count: this.unreadCount}));
  24. }
  25. }, this);
  26. },
  27. fetch: function(options) {
  28. options = options || {};
  29. options.remove = false;
  30. options.merge = true;
  31. options.parse = true;
  32. Backbone.Collection.prototype.fetch.apply(this, [options]);
  33. },
  34. fetchMore: function() {
  35. var hasMoreNotifications = (this.page * this.perPage) <= this.length;
  36. // There are more notifications to load on the current page
  37. if (hasMoreNotifications) {
  38. this.page++;
  39. // URL parameter
  40. /* eslint-disable camelcase */
  41. var route = Routes.notifications({per_page: this.perPage, page: this.page});
  42. /* eslint-enable camelcase */
  43. this.fetch({url: route, pushBack: true});
  44. }
  45. },
  46. /**
  47. * Adds new models to the collection at the end or at the beginning of the collection and
  48. * then fires an event for each model of the collection. It will fire a different event
  49. * based on whether the models were added at the end (typically when the scroll triggers to load more
  50. * notifications) or at the beginning (new notifications have been added to the front of the list).
  51. */
  52. set: function(items, options) {
  53. options = options || {};
  54. options.at = options.pushBack ? this.length : 0;
  55. // Retreive back the new created models
  56. var models = [];
  57. var accu = function(model) { models.push(model); };
  58. this.on("add", accu);
  59. Backbone.Collection.prototype.set.apply(this, [items, options]);
  60. this.off("add", accu);
  61. if (options.pushBack) {
  62. models.forEach(function(model) { this.trigger("pushBack", model); }.bind(this));
  63. } else {
  64. // Fires events in the reverse order so that the first event is prepended in first position
  65. models.reverse();
  66. models.forEach(function(model) { this.trigger("pushFront", model); }.bind(this));
  67. }
  68. this.trigger("finishedLoading");
  69. },
  70. parse: function(response) {
  71. this.unreadCount = response.unread_count;
  72. this.unreadCountByType = response.unread_count_by_type;
  73. return _.map(response.notification_list, function(item) {
  74. /* eslint-disable new-cap */
  75. var model = new this.model(item);
  76. /* eslint-enable new-cap */
  77. model.on("userChangedUnreadStatus", this.onChangedUnreadStatus.bind(this));
  78. model.on("change:unread", function() { this.trigger("update"); }.bind(this));
  79. return model;
  80. }.bind(this));
  81. },
  82. setAllRead: function() {
  83. this.forEach(function(model) { model.setRead(); });
  84. },
  85. setRead: function(guid) {
  86. this.find(function(model) { return model.guid === guid; }).setRead();
  87. },
  88. setUnread: function(guid) {
  89. this.find(function(model) { return model.guid === guid; }).setUnread();
  90. },
  91. onChangedUnreadStatus: function(model) {
  92. if (model.get("unread") === true) {
  93. this.unreadCount++;
  94. this.unreadCountByType[model.get("type")]++;
  95. } else {
  96. this.unreadCount = Math.max(this.unreadCount - 1, 0);
  97. this.unreadCountByType[model.get("type")] = Math.max(this.unreadCountByType[model.get("type")] - 1, 0);
  98. }
  99. this.trigger("update");
  100. }
  101. });