Mark bundled notifications as read

In the current bundling system, only the
bundle base is mark as read. It leaves all
the non-base bundled notifications without
a read_timestamp. They would all appear
as read in the new bundling system.

With this change, all notifications in
a bundled are update with a read_timestamp
when the bundle is read.

The implementation of this change is
somewhat temporary as the new bundling
system brings changes to the models
and controller.

Bug: T136368
Change-Id: I70b71d722d8d62cbdd1adc004293030ef900ac94
This commit is contained in:
Stephane Bisson 2016-06-02 10:00:48 -04:00
parent 45013bb676
commit aa578a44a1
4 changed files with 43 additions and 8 deletions

View file

@ -21,6 +21,11 @@ class EchoModelFormatter extends EchoEventFormatter {
$link['url'] = wfExpandUrl( $link['url'] );
}
$bundledIds = $model->getBundledIds();
if ( $bundledIds ) {
$data[ 'bundledIds' ] = $bundledIds;
}
return $data;
}
}

View file

@ -172,6 +172,20 @@ abstract class EchoEventPresentationModel implements JsonSerializable {
return $this->bundledEvents;
}
/**
* Get the ids of the bundled notifications or false if it's not bundled
*
* @return int[]|bool
*/
public function getBundledIds() {
if ( $this->isBundled() ) {
return array_map( function ( EchoEvent $event ) {
return $event->getId();
}, $this->getBundledEvents() );
}
return false;
}
/**
* This method returns true when there are bundled notifications, even if they are all
* in the same group according to getBundleGrouping(). For presentation purposes, you may

View file

@ -267,7 +267,8 @@
iconURL: content.iconUrl,
iconType: content.icon,
primaryUrl: OO.getProp( content.links, 'primary', 'url' ),
secondaryUrls: OO.getProp( content.links, 'secondary' ) || []
secondaryUrls: OO.getProp( content.links, 'secondary' ) || [],
bundledIds: content.bundledIds
};
};
@ -283,7 +284,7 @@
* were marked as read.
*/
mw.echo.Controller.prototype.markEntireListModelRead = function ( modelName ) {
var i, items,
var i, items, item,
itemIds = [],
model = this.manager.getNotificationModel( modelName || 'local' );
@ -294,8 +295,9 @@
items = model.getItems();
for ( i = 0; i < items.length; i++ ) {
if ( !items[ i ].isRead() ) {
itemIds.push( items[ i ].getId() );
item = items[ i ];
if ( !item.isRead() ) {
itemIds = itemIds.concat( item.getAllIds() );
}
}
@ -389,18 +391,20 @@
* for the set type of this controller, in the given source.
*/
mw.echo.Controller.prototype.markItemsRead = function ( itemIds, modelSource, isRead ) {
var allIds = [];
itemIds = Array.isArray( itemIds ) ? itemIds : [ itemIds ];
// Default to true
isRead = isRead === undefined ? true : isRead;
this.manager.getNotificationModel( modelSource ).findByIds( itemIds ).forEach( function ( notification ) {
allIds = allIds.concat( notification.getAllIds() );
notification.toggleRead( isRead );
} );
this.manager.getUnreadCounter().estimateChange( isRead ? -itemIds.length : itemIds.length );
this.manager.getUnreadCounter().estimateChange( isRead ? -allIds.length : allIds.length );
return this.api.markItemsRead( itemIds, modelSource, isRead ).then( this.refreshUnreadCount.bind( this ) );
return this.api.markItemsRead( allIds, modelSource, isRead ).then( this.refreshUnreadCount.bind( this ) );
};
/**
@ -459,7 +463,7 @@
idArray = [];
for ( i = 0; i < groupItems.length; i++ ) {
idArray.push( groupItems[ i ].id );
idArray = idArray.concat( groupItems[ i ].id ).concat( groupItems[ i ][ '*' ].bundledIds || [] );
}
itemCounter += idArray.length;
@ -467,8 +471,8 @@
promises.push(
controller.markCrossWikiItemsRead( idArray, listModel.getSource() )
);
}
// Synchronously remove this model from the widget
controller.removeCrossWikiItem();

View file

@ -24,6 +24,7 @@
* @cfg {string} [primaryUrl] Notification primary link in raw url format
* @cfg {boolean} [foreign=false] This notification is from a foreign source
* @cfg {boolean} [bundled=false] This notification is part of a bundle
* @cfg {number[]} [bundledIds] IDs of notifications bundled with this one
* @cfg {string} [source] The source this notification is coming from, if it is foreign
* @cfg {Object[]} [secondaryUrls] An array of objects defining the secondary URLs
* for this notification. The secondary URLs are expected to have this structure:
@ -70,6 +71,7 @@
this.timestamp = config.timestamp || fallbackMWDate;
this.setPrimaryUrl( config.primaryUrl );
this.setSecondaryUrls( config.secondaryUrls );
this.bundledIds = config.bundledIds;
};
/* Initialization */
@ -280,4 +282,14 @@
mw.echo.dm.NotificationItem.prototype.getSource = function () {
return this.source;
};
/**
* Get the all ids contained in this notification
*
* @return {number[]}
*/
mw.echo.dm.NotificationItem.prototype.getAllIds = function () {
return [ this.getId() ].concat( this.bundledIds || [] );
};
} )( mediaWiki, jQuery );