Merge "Filter notifications by read state in Special:Notifications"

This commit is contained in:
jenkins-bot 2016-05-27 21:35:41 +00:00 committed by Gerrit Code Review
commit 5d30e4cfac
8 changed files with 194 additions and 1 deletions

View file

@ -164,6 +164,7 @@ $wgResourceModules += array(
'mw.echo.js',
'model/mw.echo.dm.js',
'model/mw.echo.dm.PaginationModel.js',
'model/mw.echo.dm.FiltersModel.js',
'model/mw.echo.dm.ModelManager.js',
'model/mw.echo.dm.SortedList.js',
'model/mw.echo.dm.NotificationItem.js',
@ -275,6 +276,7 @@ $wgResourceModules += array(
'scripts' => array(
'ui/mw.echo.ui.DatedSubGroupListWidget.js',
'ui/mw.echo.ui.DatedNotificationsWidget.js',
'ui/mw.echo.ui.ReadStateButtonSelectWidget.js',
'ui/mw.echo.ui.NotificationsInboxWidget.js',
'special/ext.echo.special.js',
),
@ -289,6 +291,9 @@ $wgResourceModules += array(
),
'messages' => array(
'echo-load-more-error',
'notification-inbox-filter-read',
'notification-inbox-filter-unread',
'notification-inbox-filter-all',
'echo-more-info',
'echo-feedback',
'echo-specialpage-section-markread',

View file

@ -193,6 +193,9 @@
"notification-timestamp-ago-years": "{{PLURAL:$1|$1yr}}",
"notification-timestamp-today": "Today",
"notification-timestamp-yesterday": "Yesterday",
"notification-inbox-filter-read": "Read",
"notification-inbox-filter-unread": "Unread",
"notification-inbox-filter-all": "All",
"echo-email-subject-default": "New notification at {{SITENAME}}",
"echo-email-body-default": "You have a new notification at {{SITENAME}}:\n\n$1",
"echo-email-batch-body-default": "You have a new notification.",

View file

@ -184,6 +184,9 @@
"notification-timestamp-ago-years": "Label for the amount of time since a notification has arrived in the case where it is in order of years. This should be a very short string. $1 - Number of years",
"notification-timestamp-today": "Label for a group of notifications that arrived today.",
"notification-timestamp-yesterday": "Label for a group of notifications that arrived yesterday.",
"notification-inbox-filter-read": "Label for the button that shows only read notification.",
"notification-inbox-filter-unread": "Label for the button that shows only unread notification.",
"notification-inbox-filter-all": "Label for the button that shows all notification.",
"echo-email-subject-default": "Default subject for Echo e-mail notifications",
"echo-email-body-default": "Default message content for Echo email notifications. Parameters:\n* $1 - a plain text description of the notification",
"echo-email-batch-body-default": "Default message for Echo e-mail digest notifications",

View file

@ -16,6 +16,18 @@
/* Initialization */
OO.initClass( mw.echo.Controller );
/**
* Update a filter value
*
* @param {string} filter Filter name
* @param {string} value Filter value
*/
mw.echo.Controller.prototype.setFilter = function ( filter, value ) {
if ( filter === 'readState' ) {
this.manager.getFiltersModel().setReadState( value );
}
};
/**
* Fetch the next page by date
*
@ -61,13 +73,15 @@
mw.echo.Controller.prototype.fetchLocalNotificationsByDate = function ( page ) {
var controller = this,
pagination = this.manager.getPaginationModel(),
filters = this.manager.getFiltersModel(),
continueValue = pagination.getPageContinue( page || pagination.getCurrPageIndex() );
return this.api.fetchNotifications(
this.manager.getTypeString(),
'local',
true,
continueValue
continueValue,
filters.getReadState()
)
.then( function ( data ) {
var i, notifData, newNotifData, date, itemModel, symbolicName,

View file

@ -0,0 +1,64 @@
( function ( mw ) {
/**
* Filters model for displaying filtered notification list.
*
* @class
* @mixins OO.EventEmitter
*
* @constructor
* @param {Object} config Configuration object
* @cfg {string} [readState='all'] Notifications read state. Allowed
* values are 'all', 'read' or 'unread'.
*/
mw.echo.dm.FiltersModel = function MwEchoDmFiltersModel( config ) {
config = config || {};
// Mixin constructor
OO.EventEmitter.call( this );
this.readState = 'all';
if ( config.readState ) {
this.setReadState( config.readState );
}
};
/* Initialization */
OO.initClass( mw.echo.dm.FiltersModel );
OO.mixinClass( mw.echo.dm.FiltersModel, OO.EventEmitter );
/* Events */
/**
* @event update
*
* The filters have been updated
*/
/* Methods */
/**
* Set the read state filter
*
* @param {string} readState Notifications read state
*/
mw.echo.dm.FiltersModel.prototype.setReadState = function ( readState ) {
var allowed = [ 'all', 'read', 'unread' ];
if (
this.readState !== readState &&
allowed.indexOf( readState ) > -1
) {
this.readState = readState;
this.emit( 'update' );
}
};
/**
* Get the read state filter
*
* @return {string} Notifications read state
*/
mw.echo.dm.FiltersModel.prototype.getReadState = function () {
return this.readState;
};
} )( mediaWiki );

View file

@ -38,6 +38,7 @@
this.notificationModels = {};
this.paginationModel = new mw.echo.dm.PaginationModel();
this.filtersModel = new mw.echo.dm.FiltersModel();
// Properties
this.seenTime = mw.config.get( 'wgEchoSeenTime' ) || {};
@ -133,6 +134,15 @@
return this.paginationModel;
};
/**
* Get the filters model
*
* @return {mw.echo.dm.FiltersModel} Filters model
*/
mw.echo.dm.ModelManager.prototype.getFiltersModel = function () {
return this.filtersModel;
};
/**
* Remove a model from the manager
*

View file

@ -55,12 +55,17 @@
} );
this.bottomPaginationButtons = this.createPaginationButtons();
// Filter by read state
this.readStateSelectWidget = new mw.echo.ui.ReadStateButtonSelectWidget();
// Events
this.topPaginationButtons.connect( this, { choose: 'onPaginationChoose' } );
this.bottomPaginationButtons.connect( this, { choose: 'onPaginationChoose' } );
this.topPaginationStart.connect( this, { click: 'onPaginationStart' } );
this.bottomPaginationStart.connect( this, { click: 'onPaginationStart' } );
this.readStateSelectWidget.connect( this, { filter: 'onReadStateFilter' } );
this.manager.connect( this, { update: 'updatePaginationLabel' } );
this.manager.getFiltersModel().connect( this, { update: 'updateReadStateSelectWidget' } );
this.disablePagination();
// Initialization
@ -73,6 +78,9 @@
$( '<div>' )
.addClass( 'mw-echo-ui-notificationsInboxWidget-toolbar-row' )
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationsInboxWidget-toolbar-readState' )
.append( this.readStateSelectWidget.$element ),
$( '<div>' )
.addClass( 'mw-echo-ui-notificationsInboxWidget-toolbar-top-placeholder' ),
$( '<div>' )
@ -106,6 +114,7 @@
)
);
this.updateReadStateSelectWidget();
this.populateNotifications();
};
@ -116,6 +125,15 @@
/* Methods */
/**
* Respond to filters update
*/
mw.echo.ui.NotificationsInboxWidget.prototype.updateReadStateSelectWidget = function () {
this.readStateSelectWidget
.getItemFromData( this.manager.getFiltersModel().getReadState() )
.setSelected( true );
};
/**
* Respond to pagination start button click event
*/
@ -137,6 +155,16 @@
}
};
/**
* Respond to read state filter event
*
* @param {string} readState Read state 'all', 'read' or 'unread'
*/
mw.echo.ui.NotificationsInboxWidget.prototype.onReadStateFilter = function ( readState ) {
this.controller.setFilter( 'readState', readState );
this.populateNotifications();
};
/**
* Create a set of pagination buttons
*
@ -178,6 +206,8 @@
this.topPaginationLabel.toggle( !isDisabled );
this.bottomPaginationLabel.toggle( !isDisabled );
this.readStateSelectWidget.setDisabled( isDisabled );
};
/**

View file

@ -0,0 +1,64 @@
( function ( $, mw ) {
/**
* A select widget for notification read state: 'all', 'read' or 'unread'
*
* @class
* @extends OO.ui.ButtonSelectWidget
*
* @constructor
* @param {Object} [config] Configuration object
*/
mw.echo.ui.ReadStateButtonSelectWidget = function MwEchoUiReadStateButtonSelectWidget( config ) {
config = config || {};
// Parent
mw.echo.ui.ReadStateButtonSelectWidget.parent.call( this, $.extend( config, {
items: [
new OO.ui.ButtonOptionWidget( {
data: 'all',
label: mw.msg( 'notification-inbox-filter-all' )
} ),
new OO.ui.ButtonOptionWidget( {
data: 'read',
label: mw.msg( 'notification-inbox-filter-read' )
} ),
new OO.ui.ButtonOptionWidget( {
data: 'unread',
label: mw.msg( 'notification-inbox-filter-unread' )
} )
]
} ) );
this.connect( this, { choose: 'onChoose' } );
this.$element
.addClass( 'mw-echo-ui-readStateButtonSelectWidget' );
};
/* Initialization */
OO.inheritClass( mw.echo.ui.ReadStateButtonSelectWidget, OO.ui.ButtonSelectWidget );
/* Events */
/**
* @event filter
* @param {string} readState The chosen read state
*/
/* Methods */
/**
* Respond to choose event
*
* @param {OO.ui.ButtonOptionWidget} item Chosen item
* @fires filter
*/
mw.echo.ui.ReadStateButtonSelectWidget.prototype.onChoose = function ( item ) {
var data = item && item.getData();
if ( data ) {
this.emit( 'filter', data );
}
};
} )( jQuery, mediaWiki );