Unverified Commit af331bfb authored by Augier's avatar Augier Committed by Steffen van Bergerem
Browse files

Add collection to app.views.NotificationDropdown and app.views.Notifications

closes #6952
parent 9b72527f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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

+1 −0
Original line number Diff line number Diff line
@@ -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();
+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");
  }
});
+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); }
      });
    }
  }
});
+1 −1
Original line number Diff line number Diff line
@@ -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