mediawiki-extensions-Echo/modules/viewmodel/mw.echo.dm.UnreadNotificationCounter.js
Stephane Bisson 623d07011c Stop counting notifications objects on the client
The flyout loads no more than 25 notifications
from a given source. Using those in-memory notification
objects to count how many are currently unread (and
update the badge) produces a result of at most 25.

This patch extracts the responsibility or counting the
unread from the Model/Item/Groupitem structure into
a new UnreadNotificationCounter class. It receives
estimated updates from other components and synchronizes
with the server after markRead/markUnread operations
have completed.

Bug: T129726
Change-Id: I9af4defc00dd491ed2b355eb4e85073476e08ce7
2016-03-25 15:31:00 -04:00

93 lines
2.2 KiB
JavaScript

( function ( mw ) {
/**
* Echo notification UnreadNotificationCounter model
*
* @class
* @mixins OO.EventEmitter
*
* @constructor
* @param {Object} api An instance of EchoAPI.
* @param {string} type The notification type 'message', 'alert', or 'all'.
* @param {number} max Maximum number supported. Above this number there is no precision, we only know it is 'more than max'.
*/
mw.echo.dm.UnreadNotificationCounter = function mwEchoDmUnreadNotificationCounter( api, type, max ) {
// Mixin constructor
OO.EventEmitter.call( this );
this.api = api;
this.type = type;
this.max = max;
this.count = 0;
this.source = 'local';
};
/* Inheritance */
OO.mixinClass( mw.echo.dm.UnreadNotificationCounter, OO.EventEmitter );
/* Events */
/**
* @event countChange
* @param {number} count Notification count
*
* The number of unread notification represented by this counter has changed.
*/
/* Methods */
/**
* Get the current count
*
* @return {number} current count
*/
mw.echo.dm.UnreadNotificationCounter.prototype.getCount = function () {
return this.count;
};
/**
* Set the current count
*
* @param {number} count
* @param {boolean} isEstimation Whether this number is estimated or accurate
*/
mw.echo.dm.UnreadNotificationCounter.prototype.setCount = function ( count, isEstimation ) {
if ( isEstimation ) {
if ( this.count > this.max ) {
// this prevents toggling between 90-ish and 99+
return;
}
if ( count < 0 ) {
// wrong estimation?
return;
}
}
if ( count !== this.count ) {
this.count = count;
this.emit( 'countChange', this.count );
}
};
/**
* Report an estimated change to this counter
*
* @param {number} delta
*/
mw.echo.dm.UnreadNotificationCounter.prototype.estimateChange = function ( delta ) {
this.setCount( this.count + delta, true );
};
/**
* Request that this counter update itself from the API
*/
mw.echo.dm.UnreadNotificationCounter.prototype.update = function () {
var model = this;
this.api.fetchUnreadCount( this.source, this.type ).then( function ( actualCount ) {
model.setCount( actualCount, false );
} );
};
}( mediaWiki ) );