mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-11-30 18:45:07 +00:00
2dd3780966
Change-Id: I01da3714b1f5d9b1926ee4394c15f594efb01245
164 lines
4.5 KiB
JavaScript
164 lines
4.5 KiB
JavaScript
( function () {
|
|
/**
|
|
* Notification groups list data structure.
|
|
* It contains mw.echo.dm.NotificationsList items
|
|
*
|
|
* This contains a list of grouped notifications by source, and
|
|
* serves as a list of lists for cross-wiki notifications based
|
|
* on their remote sources and/or wikis.
|
|
*
|
|
* @class
|
|
* @extends mw.echo.dm.SortedList
|
|
*
|
|
* @constructor
|
|
* @param {Object} [config] Configuration options
|
|
* @param {boolean} [config.foreign] The list contains foreign notifications
|
|
*/
|
|
mw.echo.dm.NotificationGroupsList = function MwEchoDmNotificationGroupsList( config ) {
|
|
config = config || {};
|
|
|
|
// Parent constructor
|
|
mw.echo.dm.NotificationGroupsList.super.call( this );
|
|
|
|
// Sorting callback
|
|
this.setSortingCallback( ( a, b ) => {
|
|
// Reverse sorting
|
|
if ( b.getTimestamp() < a.getTimestamp() ) {
|
|
return -1;
|
|
} else if ( b.getTimestamp() > a.getTimestamp() ) {
|
|
return 1;
|
|
}
|
|
|
|
// Fallback on Source
|
|
return b.getName() - a.getName();
|
|
} );
|
|
|
|
this.foreign = !!config.foreign;
|
|
this.groups = {};
|
|
|
|
this.aggregate( { discard: 'groupDiscardItem' } );
|
|
this.connect( this, { groupDiscardItem: 'onGroupDiscardItem' } );
|
|
};
|
|
|
|
/* Initialization */
|
|
OO.inheritClass( mw.echo.dm.NotificationGroupsList, mw.echo.dm.SortedList );
|
|
|
|
/* Events */
|
|
|
|
/**
|
|
* A group was permanently removed
|
|
*
|
|
* @event mw.echo.dm.NotificationGroupsList#discard
|
|
*/
|
|
|
|
/* Methods */
|
|
|
|
/**
|
|
* Handle a discard event from any list.
|
|
* This means that one of the sources has discarded an item.
|
|
*
|
|
* @param {mw.echo.dm.NotificationsList} groupList List source model for the item
|
|
*/
|
|
mw.echo.dm.NotificationGroupsList.prototype.onGroupDiscardItem = function ( groupList ) {
|
|
// Check if the list has anything at all
|
|
if ( groupList.isEmpty() ) {
|
|
// Remove it
|
|
this.removeGroup( groupList.getName() );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Add a group to the list. This is a more convenient alias to using
|
|
* addItems()
|
|
*
|
|
* @param {string} groupSource Symbolic name for the source of
|
|
* this group, to be recognized for API operations
|
|
* @param {Object} sourceData Source data
|
|
* @param {mw.echo.dm.NotificationItem[]} [groupItems] Optional items to add to this group
|
|
*/
|
|
mw.echo.dm.NotificationGroupsList.prototype.addGroup = function ( groupSource, sourceData, groupItems ) {
|
|
const groupListModel = new mw.echo.dm.NotificationsList( {
|
|
title: sourceData.title,
|
|
name: groupSource,
|
|
source: groupSource,
|
|
sourceURL: sourceData.base,
|
|
timestamp: sourceData.ts
|
|
} );
|
|
|
|
if ( Array.isArray( groupItems ) && groupItems.length > 0 ) {
|
|
groupListModel.addItems( groupItems );
|
|
}
|
|
|
|
// Add the group
|
|
this.addItems( [ groupListModel ] );
|
|
};
|
|
|
|
/**
|
|
* Get the timestamp of the list by taking the latest list's
|
|
* timestamp.
|
|
*
|
|
* @return {string} Latest timestamp
|
|
*/
|
|
mw.echo.dm.NotificationGroupsList.prototype.getTimestamp = function () {
|
|
const items = this.getItems();
|
|
|
|
return (
|
|
items.length > 0 ?
|
|
items[ 0 ].getTimestamp() :
|
|
0
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Add items to a specific group by its source identifier.
|
|
*
|
|
* @param {string} groupSource Source identifier of the group
|
|
* @param {mw.echo.dm.NotificationItem[]} groupItems Items to add to this group
|
|
*/
|
|
mw.echo.dm.NotificationGroupsList.prototype.addItemsToGroup = function ( groupSource, groupItems ) {
|
|
const group = this.getGroupByName( groupSource );
|
|
|
|
if ( group ) {
|
|
group.addItems( groupItems );
|
|
}
|
|
};
|
|
/**
|
|
* Remove a group from the list. This is an easier to use alias
|
|
* to 'removeItems()' method.
|
|
*
|
|
* Since this is an intentional action, we fire 'discard' event.
|
|
* The main reason for this is that the event 'remove' is a general
|
|
* event that is fired both when a user intends on removing an
|
|
* item and also when an item is temporarily removed to be re-added
|
|
* for the sake of sorting. To avoid ambiguity, we use 'discard' event.
|
|
*
|
|
* @param {string} groupName Group name
|
|
* @fires mw.echo.dm.NotificationGroupsList#discard
|
|
*/
|
|
mw.echo.dm.NotificationGroupsList.prototype.removeGroup = function ( groupName ) {
|
|
const group = this.getGroupByName( groupName );
|
|
|
|
if ( group ) {
|
|
this.removeItems( group );
|
|
this.emit( 'discard', group );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Get a group by its source identifier.
|
|
*
|
|
* @param {string} groupName Group name
|
|
* @return {mw.echo.dm.NotificationsList|null} Requested group, null if none was found.
|
|
*/
|
|
mw.echo.dm.NotificationGroupsList.prototype.getGroupByName = function ( groupName ) {
|
|
const items = this.getItems();
|
|
|
|
for ( let i = 0; i < items.length; i++ ) {
|
|
if ( items[ i ].getName() === groupName ) {
|
|
return items[ i ];
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
}() );
|