mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-11-28 09:40:41 +00:00
5aaf6d26d8
When we are viewing a certain read state filter ('read' or 'unread') the visibility of items should correspond to that state even when the user marks a specific item as read/unread. That means that the system should remove these items from view when the action is taken. In this commit: * The controller makes the judgment of whether to remove items when read/unread action is taken, based on whether a filter is set. * We clean up the terminology of discard - no more 'remove' - to make sure we have consistency in the code. * Related: The 'discard' event is now scoped within the hierarchy; meaning, lists emit 'discard' when an item is removed, grouplist emits 'discard' when a group is removed, and the manager emits 'discard' when an entire notification model is removed. This means we can actually have proper hierarchy and organization with a single event, and not worry about clashing between the intentional 'discard' action and the event 'remove' that is also used while resorting happens. * The model manager emits a discard event when a model is removed so that the general list can listen to the manager and remove an entire batch of items if needed. * The pagination model now updates the count for the current page rather than some vague notion of the last page. This is also updated when the controller removes items, so we can get an accurate count in the page for the number of notifications that are displayed. Bug: T136891 Change-Id: I247c618042ef256fadf09922f7b83bd1ad361f64
650 lines
20 KiB
JavaScript
650 lines
20 KiB
JavaScript
( function ( mw, $ ) {
|
|
/**
|
|
* Controller for Echo notifications
|
|
*
|
|
* @param {mw.echo.api.EchoApi} echoApi Echo API
|
|
* @param {mw.echo.dm.ModelManager} manager Model manager
|
|
* @param {Object} [config] Configuration
|
|
*/
|
|
mw.echo.Controller = function MwEchoController( echoApi, manager, config ) {
|
|
config = config || {};
|
|
|
|
this.api = echoApi;
|
|
this.manager = manager;
|
|
};
|
|
|
|
/* Initialization */
|
|
OO.initClass( mw.echo.Controller );
|
|
|
|
/**
|
|
* Update a filter value.
|
|
* The method accepts a filter name and as many arguments
|
|
* as needed.
|
|
*
|
|
* @param {string} filter Filter name
|
|
*/
|
|
mw.echo.Controller.prototype.setFilter = function ( filter ) {
|
|
var filtersModel = this.manager.getFiltersModel(),
|
|
values = Array.prototype.slice.call( arguments );
|
|
|
|
values.shift();
|
|
|
|
if ( filter === 'readState' ) {
|
|
filtersModel.setReadState( values[ 0 ] );
|
|
} else if ( filter === 'sourcePage' ) {
|
|
filtersModel.setCurrentSourcePage( values[ 0 ], values[ 1 ] );
|
|
}
|
|
|
|
// Reset pagination
|
|
this.manager.getPaginationModel().reset();
|
|
};
|
|
|
|
/**
|
|
* Fetch the next page by date
|
|
*
|
|
* @return {jQuery.Promise} A promise that resolves with an object where the keys are
|
|
* days and the items are item IDs.
|
|
*/
|
|
mw.echo.Controller.prototype.fetchNextPageByDate = function () {
|
|
this.manager.getPaginationModel().forwards();
|
|
return this.fetchLocalNotificationsByDate();
|
|
};
|
|
|
|
/**
|
|
* Fetch the previous page by date
|
|
*
|
|
* @return {jQuery.Promise} A promise that resolves with an object where the keys are
|
|
* days and the items are item IDs.
|
|
*/
|
|
mw.echo.Controller.prototype.fetchPrevPageByDate = function () {
|
|
this.manager.getPaginationModel().backwards();
|
|
return this.fetchLocalNotificationsByDate();
|
|
};
|
|
|
|
/**
|
|
* Fetch the first page by date
|
|
*
|
|
* @return {jQuery.Promise} A promise that resolves with an object where the keys are
|
|
* days and the items are item IDs.
|
|
*/
|
|
mw.echo.Controller.prototype.fetchFirstPageByDate = function () {
|
|
this.manager.getPaginationModel().setCurrPageIndex( 0 );
|
|
return this.fetchLocalNotificationsByDate();
|
|
};
|
|
|
|
/**
|
|
* Fetch unread pages in all wikis and create foreign API sources
|
|
* as needed.
|
|
*
|
|
* @return {jQuery.Promise} A promise that resolves when the page filter
|
|
* model is updated with the unread notification count per page per wiki
|
|
*/
|
|
mw.echo.Controller.prototype.fetchUnreadPagesByWiki = function () {
|
|
var controller = this,
|
|
filterModel = this.manager.getFiltersModel(),
|
|
sourcePageModel = filterModel.getSourcePagesModel();
|
|
|
|
return this.api.fetchUnreadNotificationPages()
|
|
.then( function ( data ) {
|
|
var source,
|
|
result = {},
|
|
foreignSources = {};
|
|
|
|
for ( source in data ) {
|
|
if ( source !== mw.config.get( 'wgDBname' ) ) {
|
|
// Collect sources for API
|
|
foreignSources[ source ] = data[ source ].source;
|
|
}
|
|
result[ source === mw.config.get( 'wgDBname' ) ? 'local' : source ] = data[ source ];
|
|
}
|
|
|
|
// Register the foreign sources in the API
|
|
controller.api.registerForeignSources( foreignSources, false );
|
|
|
|
// Register pages
|
|
sourcePageModel.setAllSources( result );
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Fetch notifications from the local API and sort them by date.
|
|
* This method ignores cross-wiki notifications and bundles.
|
|
*
|
|
* @param {number} [page] Page number. If not given, it defaults to the current
|
|
* page.
|
|
* @return {jQuery.Promise} A promise that resolves with an object where the keys are
|
|
* days and the items are item IDs.
|
|
*/
|
|
mw.echo.Controller.prototype.fetchLocalNotificationsByDate = function ( page ) {
|
|
var controller = this,
|
|
pagination = this.manager.getPaginationModel(),
|
|
filters = this.manager.getFiltersModel(),
|
|
currentSource = filters.getSourcePagesModel().getCurrentSource(),
|
|
continueValue = pagination.getPageContinue( page || pagination.getCurrPageIndex() );
|
|
|
|
pagination.setItemsPerPage( this.api.getLimit() );
|
|
|
|
return this.api.fetchFilteredNotifications(
|
|
this.manager.getTypeString(),
|
|
currentSource,
|
|
{
|
|
continue: continueValue,
|
|
readState: filters.getReadState(),
|
|
titles: filters.getSourcePagesModel().getCurrentPage()
|
|
}
|
|
)
|
|
.then( function ( data ) {
|
|
var i, notifData, newNotifData, date, itemModel, symbolicName,
|
|
dateItemIds = {},
|
|
dateItems = {},
|
|
models = {};
|
|
|
|
data = data || { list: [] };
|
|
|
|
// Go over the data
|
|
for ( i = 0; i < data.list.length; i++ ) {
|
|
notifData = data.list[ i ];
|
|
|
|
// Collect common data
|
|
newNotifData = controller.createNotificationData( notifData );
|
|
if ( notifData.type !== 'foreign' ) {
|
|
date = newNotifData.timestamp.substring( 0, 8 );
|
|
newNotifData.modelName = 'local_' + date;
|
|
newNotifData.source = currentSource;
|
|
|
|
// Single notifications
|
|
itemModel = new mw.echo.dm.NotificationItem(
|
|
notifData.id,
|
|
newNotifData
|
|
);
|
|
|
|
dateItems[ date ] = dateItems[ date ] || [];
|
|
dateItems[ date ].push( itemModel );
|
|
|
|
dateItemIds[ date ] = dateItemIds[ date ] || [];
|
|
dateItemIds[ date ].push( notifData.id );
|
|
}
|
|
}
|
|
|
|
// Fill in the models
|
|
for ( date in dateItems ) {
|
|
symbolicName = 'local_' + date;
|
|
|
|
// Set up model
|
|
models[ symbolicName ] = new mw.echo.dm.NotificationsList( {
|
|
type: controller.manager.getTypes(),
|
|
name: symbolicName,
|
|
source: currentSource,
|
|
title: date,
|
|
timestamp: date
|
|
} );
|
|
|
|
models[ symbolicName ].setItems( dateItems[ date ] );
|
|
}
|
|
|
|
// Register local sources
|
|
controller.api.registerLocalSources( Object.keys( models ) );
|
|
|
|
// Update the manager
|
|
controller.manager.setNotificationModels( models );
|
|
|
|
// Update the pagination
|
|
pagination.setNextPageContinue( data.continue );
|
|
|
|
return dateItemIds;
|
|
} );
|
|
};
|
|
/**
|
|
* Fetch notifications from the local API and update the notifications list.
|
|
*
|
|
* @param {boolean} [isForced] Force a renewed fetching promise. If set to false, the
|
|
* model will request the stored/cached fetching promise from the API. A 'true' value
|
|
* will force the API to re-request that information from the server and update the
|
|
* notifications.
|
|
* @return {jQuery.Promise} A promise that resolves with an array of notification IDs
|
|
*/
|
|
mw.echo.Controller.prototype.fetchLocalNotifications = function ( isForced ) {
|
|
var controller = this,
|
|
// Create a new local list model
|
|
localListModel = new mw.echo.dm.NotificationsList( {
|
|
type: this.manager.getTypes()
|
|
} ),
|
|
localItems = [],
|
|
idArray = [];
|
|
|
|
this.manager.counter.update();
|
|
|
|
// Fetch the notifications from the database
|
|
// Initially, we're going to have to split the operation
|
|
// between local notifications and x-wiki notifications
|
|
// until the backend gives us the x-wiki notifications as
|
|
// part of the original response.
|
|
return this.api.fetchNotifications( this.manager.getTypeString(), 'local', !!isForced, { unreadFirst: true } /* filters */ )
|
|
.then(
|
|
// Success
|
|
function ( data ) {
|
|
var i, notifData, content, newNotifData,
|
|
foreignListModel, source, itemModel,
|
|
allModels = { local: localListModel },
|
|
createBundledNotification = function ( modelName, rawBundledNotifData ) {
|
|
var bundleNotifData = controller.createNotificationData( rawBundledNotifData );
|
|
bundleNotifData.bundled = true;
|
|
bundleNotifData.modelName = modelName;
|
|
return new mw.echo.dm.NotificationItem(
|
|
rawBundledNotifData.id,
|
|
bundleNotifData
|
|
);
|
|
};
|
|
|
|
data = data || { list: [] };
|
|
|
|
// Go over the data
|
|
for ( i = 0; i < data.list.length; i++ ) {
|
|
notifData = data.list[ i ];
|
|
content = notifData[ '*' ] || {};
|
|
|
|
// Collect common data
|
|
newNotifData = controller.createNotificationData( notifData );
|
|
if ( notifData.type === 'foreign' ) {
|
|
// x-wiki notification multi-group
|
|
// We need to request a new list model
|
|
newNotifData.name = 'xwiki';
|
|
allModels.xwiki = foreignListModel = new mw.echo.dm.CrossWikiNotificationItem( notifData.id, newNotifData );
|
|
foreignListModel.setForeign( true );
|
|
|
|
// Register foreign sources
|
|
controller.api.registerForeignSources( notifData.sources, true );
|
|
// Add the lists according to the sources
|
|
for ( source in notifData.sources ) {
|
|
foreignListModel.getList().addGroup(
|
|
source,
|
|
notifData.sources[ source ]
|
|
);
|
|
}
|
|
} else if ( newNotifData.bundledNotifications ) {
|
|
// local bundle
|
|
newNotifData.modelName = 'bundle_' + notifData.id;
|
|
itemModel = new mw.echo.dm.BundleNotificationItem(
|
|
notifData.id,
|
|
newNotifData.bundledNotifications.map( createBundledNotification.bind( null, newNotifData.modelName ) ),
|
|
newNotifData
|
|
);
|
|
allModels[ newNotifData.modelName ] = itemModel;
|
|
} else {
|
|
// Local single notifications
|
|
itemModel = new mw.echo.dm.NotificationItem(
|
|
notifData.id,
|
|
newNotifData
|
|
);
|
|
|
|
idArray.push( notifData.id );
|
|
localItems.push( itemModel );
|
|
}
|
|
|
|
}
|
|
|
|
// Refresh local items
|
|
localListModel.addItems( localItems );
|
|
|
|
// Update the controller
|
|
controller.manager.setNotificationModels( allModels );
|
|
|
|
return idArray;
|
|
},
|
|
// Failure
|
|
function ( errCode, errObj ) {
|
|
if ( !controller.manager.getNotificationModel( 'local' ) ) {
|
|
// Update the controller
|
|
controller.manager.setNotificationModels( { local: localListModel } );
|
|
}
|
|
return {
|
|
errCode: errCode,
|
|
errInfo: OO.getProp( errObj, 'error', 'info' )
|
|
};
|
|
}
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Create notification data config object for notification items from the
|
|
* given API data.
|
|
*
|
|
* @param {Object} apiData API data
|
|
* @return {Object} Notification config data object
|
|
*/
|
|
mw.echo.Controller.prototype.createNotificationData = function ( apiData ) {
|
|
var content = apiData[ '*' ] || {};
|
|
|
|
return {
|
|
type: apiData.section,
|
|
foreign: false,
|
|
source: 'local',
|
|
count: apiData.count,
|
|
read: !!apiData.read,
|
|
seen: !!apiData.read || apiData.timestamp.mw <= this.manager.getSeenTime(),
|
|
timestamp: apiData.timestamp.utcmw,
|
|
category: apiData.category,
|
|
content: {
|
|
header: content.header,
|
|
compactHeader: content.compactHeader,
|
|
body: content.body
|
|
},
|
|
iconURL: content.iconUrl,
|
|
iconType: content.icon,
|
|
primaryUrl: OO.getProp( content.links, 'primary', 'url' ),
|
|
secondaryUrls: OO.getProp( content.links, 'secondary' ) || [],
|
|
bundledIds: apiData.bundledIds,
|
|
bundledNotifications: apiData.bundledNotifications
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Mark all items within a given list model as read.
|
|
*
|
|
* NOTE: This method is strictly for list models, and will not work for
|
|
* group list models. To mark items as read in the xwiki model, whether
|
|
* it is pre-populated or not, please see #markEntireCrossWikiItemAsRead
|
|
*
|
|
* @param {string} [modelName] Symbolic name for the model
|
|
* @param {boolean} [isRead=true]
|
|
* @return {jQuery.Promise} Promise that is resolved when all items
|
|
* were marked as read.
|
|
*/
|
|
mw.echo.Controller.prototype.markEntireListModelRead = function ( modelName, isRead ) {
|
|
var i, items, item,
|
|
itemIds = [],
|
|
model = this.manager.getNotificationModel( modelName || 'local' );
|
|
|
|
if ( !model ) {
|
|
// Model doesn't exist
|
|
return $.Deferred().reject();
|
|
}
|
|
|
|
// Default to true
|
|
isRead = isRead === undefined ? true : isRead;
|
|
|
|
items = model.getItems();
|
|
for ( i = 0; i < items.length; i++ ) {
|
|
item = items[ i ];
|
|
if ( item.isRead() !== isRead ) {
|
|
itemIds.push( item.getId() );
|
|
}
|
|
}
|
|
|
|
return this.markItemsRead( itemIds, model.getName(), isRead );
|
|
};
|
|
|
|
/**
|
|
* Mark all local notifications as read
|
|
*
|
|
* @return {jQuery.Promise} Promise that is resolved when all
|
|
* local notifications have been marked as read.
|
|
*/
|
|
mw.echo.Controller.prototype.markLocalNotificationsRead = function () {
|
|
var itemIds = [];
|
|
|
|
this.manager.getLocalNotifications().forEach( function ( notification ) {
|
|
if ( !notification.isRead() ) {
|
|
itemIds = itemIds.concat( notification.getAllIds() );
|
|
notification.toggleRead( true );
|
|
}
|
|
} );
|
|
|
|
this.manager.getUnreadCounter().estimateChange( -itemIds.length );
|
|
return this.api.markItemsRead( itemIds, 'local', true ).then( this.refreshUnreadCount.bind( this ) );
|
|
};
|
|
|
|
/**
|
|
* Fetch notifications from the cross-wiki sources.
|
|
*
|
|
* @return {jQuery.Promise} Promise that is resolved when all items
|
|
* from the cross-wiki sources are populated into the cross-wiki
|
|
* model.
|
|
*/
|
|
mw.echo.Controller.prototype.fetchCrossWikiNotifications = function () {
|
|
var controller = this,
|
|
xwikiModel = this.manager.getNotificationModel( 'xwiki' );
|
|
|
|
if ( !xwikiModel ) {
|
|
// There is no xwiki notifications model, so we can't
|
|
// fetch into it
|
|
return $.Deferred().reject().promise();
|
|
}
|
|
|
|
return this.api.fetchNotificationGroups( xwikiModel.getSourceNames(), this.manager.getTypeString() )
|
|
.then(
|
|
function ( groupList ) {
|
|
var i, notifData, listModel, group, groupItems,
|
|
items = [];
|
|
|
|
for ( group in groupList ) {
|
|
listModel = xwikiModel.getItemBySource( group );
|
|
groupItems = groupList[ group ];
|
|
|
|
items = [];
|
|
for ( i = 0; i < groupItems.length; i++ ) {
|
|
notifData = controller.createNotificationData( groupItems[ i ] );
|
|
items.push(
|
|
new mw.echo.dm.NotificationItem( groupItems[ i ].id, $.extend( notifData, {
|
|
modelName: 'xwiki',
|
|
source: group,
|
|
bundled: true,
|
|
foreign: true
|
|
} ) )
|
|
);
|
|
}
|
|
// Add items
|
|
listModel.setItems( items );
|
|
}
|
|
},
|
|
function ( errCode, errObj ) {
|
|
return {
|
|
errCode: errCode,
|
|
errInfo: errCode === 'http' ?
|
|
mw.msg( 'echo-api-failure-cross-wiki' ) :
|
|
OO.getProp( errObj, 'error', 'info' )
|
|
};
|
|
}
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Mark local items as read in the API.
|
|
*
|
|
* @param {string[]|string} itemIds An array of item IDs, or a single item ID, to mark as read
|
|
* @param {string} modelName The name of the model that these items belong to
|
|
* @param {boolean} [isRead=true] The read state of the item; true for marking the
|
|
* item as read, false for marking the item as unread
|
|
* @return {jQuery.Promise} A promise that is resolved when the operation
|
|
* is complete, with the number of unread notifications still remaining
|
|
* for the set type of this controller, in the given source.
|
|
*/
|
|
mw.echo.Controller.prototype.markItemsRead = function ( itemIds, modelName, isRead ) {
|
|
var items,
|
|
model = this.manager.getNotificationModel( modelName ),
|
|
readState = this.manager.getFiltersModel().getReadState(),
|
|
allIds = [];
|
|
|
|
itemIds = Array.isArray( itemIds ) ? itemIds : [ itemIds ];
|
|
|
|
// Default to true
|
|
isRead = isRead === undefined ? true : isRead;
|
|
|
|
items = model.findByIds( itemIds );
|
|
|
|
// If we are only looking at specific read state,
|
|
// then we need to make sure the items are removed
|
|
// from the visible list, because they no longer
|
|
// correspond with the chosen state filter
|
|
if ( readState === 'read' && !isRead ) {
|
|
model.discardItems( items );
|
|
} else if ( readState === 'unread' && isRead ) {
|
|
model.discardItems( items );
|
|
// TODO: We should also find a way to update the pagination
|
|
// here properly. Do we pull more items from the next page
|
|
// when items are cleared? Do we set some threshhold for
|
|
// removed items where if it is reached, we update the list
|
|
// to reflect the new pagination? etc.
|
|
}
|
|
|
|
items.forEach( function ( notification ) {
|
|
allIds = allIds.concat( notification.getAllIds() );
|
|
if ( readState === 'all' ) {
|
|
notification.toggleRead( isRead );
|
|
}
|
|
} );
|
|
|
|
// Update pagination count
|
|
this.manager.updateCurrentPageItemCount();
|
|
|
|
this.manager.getUnreadCounter().estimateChange( isRead ? -allIds.length : allIds.length );
|
|
|
|
return this.api.markItemsRead( allIds, model.getSource(), isRead ).then( this.refreshUnreadCount.bind( this ) );
|
|
};
|
|
|
|
/**
|
|
* Mark cross-wiki items as read in the API.
|
|
*
|
|
* @param {string[]|string} itemIds An array of item IDs, or a single item ID, to mark as read
|
|
* @param {string} source The name for the source list that these items belong to
|
|
* @return {jQuery.Promise} A promise that is resolved when the operation
|
|
* is complete, with the number of unread notifications still remaining
|
|
* for the set type of this controller, in the given source.
|
|
*/
|
|
mw.echo.Controller.prototype.markCrossWikiItemsRead = function ( itemIds, source ) {
|
|
var sourceModel,
|
|
notifs,
|
|
xwikiModel = this.manager.getNotificationModel( 'xwiki' );
|
|
|
|
if ( !xwikiModel ) {
|
|
return $.Deferred().reject().promise();
|
|
}
|
|
this.manager.getUnreadCounter().estimateChange( -itemIds.length );
|
|
|
|
itemIds = Array.isArray( itemIds ) ? itemIds : [ itemIds ];
|
|
|
|
sourceModel = xwikiModel.getList().getGroupByName( source );
|
|
notifs = sourceModel.findByIds( itemIds );
|
|
sourceModel.discardItems( notifs );
|
|
|
|
return this.api.markItemsRead( itemIds, source, true )
|
|
.then( this.refreshUnreadCount.bind( this ) );
|
|
};
|
|
|
|
/**
|
|
* Mark all cross-wiki notifications from all sources as read
|
|
*
|
|
* @return {jQuery.Promise} Promise that is resolved when all notifications
|
|
* are marked as read
|
|
*/
|
|
mw.echo.Controller.prototype.markEntireCrossWikiItemAsRead = function () {
|
|
var controller = this,
|
|
xwikiModel = this.manager.getNotificationModel( 'xwiki' );
|
|
|
|
if ( !xwikiModel ) {
|
|
return $.Deferred().reject().promise();
|
|
}
|
|
|
|
return this.api.fetchNotificationGroups( xwikiModel.getSourceNames(), this.manager.getTypeString() )
|
|
.then( function ( groupList ) {
|
|
var i, listModel, group, groupItems,
|
|
promises = [],
|
|
idArray = [],
|
|
itemCounter = 0;
|
|
|
|
for ( group in groupList ) {
|
|
listModel = xwikiModel.getItemBySource( group );
|
|
groupItems = groupList[ group ];
|
|
|
|
idArray = [];
|
|
for ( i = 0; i < groupItems.length; i++ ) {
|
|
idArray = idArray.concat( groupItems[ i ].id ).concat( groupItems[ i ].bundledIds || [] );
|
|
}
|
|
itemCounter += idArray.length;
|
|
|
|
// Mark items as read in the API
|
|
promises.push(
|
|
controller.markCrossWikiItemsRead( idArray, listModel.getName() )
|
|
);
|
|
}
|
|
|
|
// Synchronously remove this model from the widget
|
|
controller.removeCrossWikiItem();
|
|
|
|
return mw.echo.api.NetworkHandler.static.waitForAllPromises( promises );
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Remove the entire cross-wiki model.
|
|
*/
|
|
mw.echo.Controller.prototype.removeCrossWikiItem = function () {
|
|
this.manager.removeNotificationModel( 'xwiki' );
|
|
};
|
|
|
|
/**
|
|
* Refresh the unread notifications counter
|
|
*
|
|
* @return {jQuery.Promise} A promise that is resolved when the counter
|
|
* is updated with the actual unread count from the server.
|
|
*/
|
|
mw.echo.Controller.prototype.refreshUnreadCount = function () {
|
|
return this.manager.getUnreadCounter().update();
|
|
};
|
|
|
|
/**
|
|
* Update seenTime for the given source
|
|
*
|
|
* @return {jQuery.Promise} A promise that is resolved when the
|
|
* seenTime was updated for all given types.
|
|
*/
|
|
mw.echo.Controller.prototype.updateSeenTime = function ( source ) {
|
|
var controller = this;
|
|
|
|
return this.api.updateSeenTime( this.getTypes(), source )
|
|
.then( function ( time ) {
|
|
controller.manager.getSeenTimeModel().setSeenTimeForSource( source, time );
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Update local seen time
|
|
*
|
|
* @return {jQuery.Promise} A promise that is resolved when the
|
|
* seenTime was updated for all given types.
|
|
*/
|
|
mw.echo.Controller.prototype.updateLocalSeenTime = function () {
|
|
return this.updateSeenTime( 'local' );
|
|
};
|
|
|
|
/**
|
|
* Update seenTime for the currently selected source
|
|
*
|
|
* @return {jQuery.Promise} A promise that is resolved when the
|
|
* seenTime was updated for all given types.
|
|
*/
|
|
mw.echo.Controller.prototype.updateSeenTimeForCurrentSource = function () {
|
|
var currSource = this.manager.getFiltersModel().getSourcePagesModel().getCurrentSource();
|
|
|
|
return this.updateSeenTime( currSource );
|
|
};
|
|
/**
|
|
* Get the types associated with the controller and model
|
|
*
|
|
* @return {string[]} Notification types
|
|
*/
|
|
mw.echo.Controller.prototype.getTypes = function () {
|
|
return this.manager.getTypes();
|
|
};
|
|
|
|
/**
|
|
* Return a string representation of the notification type.
|
|
* It could be 'alert', 'message' or, if both are set, 'all'
|
|
*
|
|
* @return {string} String representation of notifications type
|
|
*/
|
|
mw.echo.Controller.prototype.getTypeString = function () {
|
|
return this.manager.getTypeString();
|
|
};
|
|
} )( mediaWiki, jQuery );
|