2016-01-15 22:11:33 +00:00
|
|
|
( function ( mw, $ ) {
|
|
|
|
/**
|
|
|
|
* Abstract notification API handler
|
|
|
|
*
|
|
|
|
* @abstract
|
|
|
|
* @class
|
|
|
|
*
|
|
|
|
* @constructor
|
2016-05-06 13:02:33 +00:00
|
|
|
* @param {mw.Api} api
|
2016-01-15 22:11:33 +00:00
|
|
|
* @param {Object} [config] Configuration object
|
|
|
|
* @cfg {number} [limit=25] The limit on how many notifications to fetch
|
|
|
|
* @cfg {string} [userLang=mw.config.get( 'wgUserLanguage' )] User language. Defaults
|
|
|
|
* to the default user language configuration settings.
|
|
|
|
*/
|
2016-05-06 13:02:33 +00:00
|
|
|
mw.echo.api.APIHandler = function MwEchoApiAPIHandler( api, config ) {
|
2016-01-15 22:11:33 +00:00
|
|
|
config = config || {};
|
|
|
|
|
|
|
|
this.fetchNotificationsPromise = {};
|
|
|
|
this.apiErrorState = {};
|
|
|
|
|
|
|
|
this.limit = config.limit || 25;
|
|
|
|
this.userLang = config.userLang || mw.config.get( 'wgUserLanguage' );
|
|
|
|
|
2016-05-06 13:02:33 +00:00
|
|
|
this.api = api;
|
2016-01-15 22:11:33 +00:00
|
|
|
|
|
|
|
// Map the logical type to the type
|
|
|
|
// that the API recognizes
|
|
|
|
this.normalizedType = {
|
|
|
|
message: 'message',
|
|
|
|
alert: 'alert',
|
|
|
|
all: 'message|alert'
|
|
|
|
};
|
|
|
|
|
|
|
|
// Parameters that are sent through
|
|
|
|
// to the 'fetch notification' promise
|
|
|
|
// per type
|
|
|
|
this.typeParams = {
|
|
|
|
message: {},
|
|
|
|
alert: {},
|
|
|
|
all: {}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Setup */
|
|
|
|
|
|
|
|
OO.initClass( mw.echo.api.APIHandler );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fetch notifications from the API.
|
|
|
|
*
|
|
|
|
* @param {string} type Notification type
|
2016-05-19 20:49:09 +00:00
|
|
|
* @param {Object} [overrideParams] An object defining parameters to override in the API
|
|
|
|
* fetching call.
|
2016-01-15 22:11:33 +00:00
|
|
|
* @return {jQuery.Promise} A promise that resolves with an object containing the
|
|
|
|
* notification items
|
|
|
|
*/
|
|
|
|
mw.echo.api.APIHandler.prototype.fetchNotifications = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new fetchNotifications promise that queries the API and overrides
|
|
|
|
* the cached promise.
|
|
|
|
*
|
|
|
|
* @param {string} type Notification type
|
2016-05-04 00:50:27 +00:00
|
|
|
* @param {string[]} [sources] An array of sources to query
|
2016-05-19 20:49:09 +00:00
|
|
|
* @param {Object} [overrideParams] An object defining parameters to override in the API
|
|
|
|
* fetching call.
|
|
|
|
* @return {jQuery.Promise} Promise that is resolved when notifications are
|
|
|
|
* fetched from the API.
|
2016-01-15 22:11:33 +00:00
|
|
|
*/
|
2016-05-19 20:49:09 +00:00
|
|
|
mw.echo.api.APIHandler.prototype.createNewFetchNotificationPromise = function ( type, sources, overrideParams ) {
|
|
|
|
var apiErrState, fetchNotifPromise,
|
|
|
|
fetchingSource = 'local',
|
2016-05-04 00:50:27 +00:00
|
|
|
me = this,
|
2016-01-15 22:11:33 +00:00
|
|
|
params = $.extend( {
|
|
|
|
action: 'query',
|
|
|
|
meta: 'notifications',
|
|
|
|
notsections: this.normalizedType[ type ],
|
|
|
|
notformat: 'model',
|
|
|
|
notlimit: this.limit,
|
|
|
|
notunreadfirst: 1,
|
2016-04-21 09:13:02 +00:00
|
|
|
notprop: 'list|count',
|
2016-01-15 22:11:33 +00:00
|
|
|
uselang: this.userLang
|
|
|
|
}, this.getTypeParams( type ) );
|
|
|
|
|
2016-05-04 00:50:27 +00:00
|
|
|
if ( Array.isArray( sources ) && sources.indexOf( 'local' ) === -1 ) {
|
|
|
|
params.notwikis = sources.join( '|' );
|
|
|
|
params.notfilter = '!read';
|
|
|
|
fetchingSource = 'foreign';
|
|
|
|
}
|
|
|
|
|
2016-05-19 20:49:09 +00:00
|
|
|
// Initialize the nested value if it doesn't yet exist
|
2016-05-04 00:50:27 +00:00
|
|
|
this.fetchNotificationsPromise[ type ] = this.fetchNotificationsPromise[ type ] || {};
|
2016-05-19 20:49:09 +00:00
|
|
|
me.apiErrorState[ type ] = me.apiErrorState[ type ] || {};
|
|
|
|
|
|
|
|
// Reset cached values
|
|
|
|
apiErrState = false;
|
|
|
|
this.fetchNotificationsPromise[ type ][ fetchingSource ] = null;
|
|
|
|
this.apiErrorState[ type ][ fetchingSource ] = false;
|
|
|
|
|
|
|
|
// Create the fetch promise
|
|
|
|
fetchNotifPromise = this.api.get( $.extend( true, params, overrideParams ) );
|
|
|
|
|
|
|
|
// Only cache promises that don't have override params in them
|
|
|
|
if ( !overrideParams ) {
|
|
|
|
this.fetchNotificationsPromise[ type ][ fetchingSource ] = fetchNotifPromise;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fetchNotifPromise
|
2016-01-15 22:11:33 +00:00
|
|
|
.fail( function () {
|
|
|
|
// Mark API error state
|
2016-05-04 00:50:27 +00:00
|
|
|
me.apiErrorState[ type ][ fetchingSource ] = true;
|
2016-01-15 22:11:33 +00:00
|
|
|
} );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the seen timestamp
|
|
|
|
*
|
|
|
|
* @param {string} [type] Notification type 'message', 'alert' or 'all'.
|
|
|
|
* @return {jQuery.Promise} A promise that resolves with the seen timestamp
|
|
|
|
*/
|
|
|
|
mw.echo.api.APIHandler.prototype.updateSeenTime = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mark all notifications as read
|
|
|
|
*
|
|
|
|
* @param {string|string[]} type Notification type 'message', 'alert' or 'all'.
|
|
|
|
* @return {jQuery.Promise} A promise that resolves when all notifications
|
|
|
|
* are marked as read.
|
|
|
|
*/
|
|
|
|
mw.echo.api.APIHandler.prototype.markAllRead = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mark multiple notification items as read using specific IDs
|
|
|
|
*
|
|
|
|
* @abstract
|
|
|
|
* @param {string[]} itemIdArray An array of notification item IDs
|
2016-03-04 22:44:22 +00:00
|
|
|
* @param {boolean} [isRead] Item's new read state; true for marking the item
|
|
|
|
* as read, false for marking the item as unread
|
2016-01-15 22:11:33 +00:00
|
|
|
* @return {jQuery.Promise} A promise that resolves when all given notifications
|
|
|
|
* are marked as read.
|
|
|
|
*/
|
|
|
|
mw.echo.api.APIHandler.prototype.markItemsRead = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the read status of a notification item in the API
|
|
|
|
*
|
|
|
|
* @param {string} itemId Item id
|
2016-03-04 22:44:22 +00:00
|
|
|
* @param {boolean} [isRead] Item's new read state; true for marking the item
|
|
|
|
* as read, false for marking the item as unread
|
2016-01-15 22:11:33 +00:00
|
|
|
* @return {jQuery.Promise} A promise that resolves when the notifications
|
|
|
|
* are marked as read.
|
|
|
|
*/
|
2016-03-04 22:44:22 +00:00
|
|
|
mw.echo.api.APIHandler.prototype.markItemRead = function ( itemId, isRead ) {
|
2016-03-14 22:23:08 +00:00
|
|
|
return this.markItemsRead( [ itemId ], isRead );
|
2016-01-15 22:11:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Query the API for unread count of the notifications in this model
|
|
|
|
*
|
|
|
|
* @param {string} type Notification type 'message', 'alert' or 'all'.
|
|
|
|
* @return {jQuery.Promise} jQuery promise that's resolved when the unread count is fetched
|
|
|
|
* and the badge label is updated.
|
|
|
|
*/
|
|
|
|
mw.echo.api.APIHandler.prototype.fetchUnreadCount = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check whether the model has an API error state flagged
|
|
|
|
*
|
|
|
|
* @param {string} type Notification type, 'alert', 'message' or 'all'
|
|
|
|
* @return {boolean} The model is in API error state
|
|
|
|
*/
|
2016-05-04 00:50:27 +00:00
|
|
|
mw.echo.api.APIHandler.prototype.isFetchingErrorState = function ( type, sources ) {
|
|
|
|
var fetchingSource = 'local';
|
|
|
|
|
|
|
|
if ( Array.isArray( sources ) && sources.indexOf( 'local' ) === -1 ) {
|
|
|
|
fetchingSource = 'foreign';
|
|
|
|
}
|
|
|
|
return !!( this.apiErrorState[ type ] && this.apiErrorState[ type ][ fetchingSource ] );
|
2016-01-15 22:11:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the fetch notifications promise
|
|
|
|
*
|
|
|
|
* @param {string} type Notification type, 'alert', 'message' or 'all'
|
2016-05-19 20:49:09 +00:00
|
|
|
* @param {string|string[]} [sources] A name of a source or an array of sources to query
|
|
|
|
* @param {Object} [overrideParams] An object defining parameters to override in the API
|
|
|
|
* fetching call.
|
2016-01-15 22:11:33 +00:00
|
|
|
* @return {jQuery.Promise} Promise that is resolved when notifications are
|
|
|
|
* fetched from the API.
|
|
|
|
*/
|
2016-05-19 20:49:09 +00:00
|
|
|
mw.echo.api.APIHandler.prototype.getFetchNotificationPromise = function ( type, sources, overrideParams ) {
|
2016-05-04 00:50:27 +00:00
|
|
|
var fetchingSource = 'local';
|
|
|
|
|
|
|
|
if ( Array.isArray( sources ) && sources.indexOf( 'local' ) === -1 ) {
|
|
|
|
fetchingSource = 'foreign';
|
|
|
|
}
|
2016-05-19 20:49:09 +00:00
|
|
|
if ( overrideParams || !this.fetchNotificationsPromise[ type ] || !this.fetchNotificationsPromise[ type ][ fetchingSource ] ) {
|
|
|
|
this.createNewFetchNotificationPromise( type, sources, overrideParams );
|
2016-01-15 22:11:33 +00:00
|
|
|
}
|
2016-05-04 00:50:27 +00:00
|
|
|
return this.fetchNotificationsPromise[ type ][ fetchingSource ];
|
2016-01-15 22:11:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the extra parameters for fetching notifications for a given
|
|
|
|
* notification type.
|
|
|
|
*
|
|
|
|
* @param {string} type Notification type
|
|
|
|
* @return {Object} Extra API parameters for fetch notifications
|
|
|
|
*/
|
|
|
|
mw.echo.api.APIHandler.prototype.getTypeParams = function ( type ) {
|
|
|
|
return this.typeParams[ type ];
|
|
|
|
};
|
|
|
|
} )( mediaWiki, jQuery );
|