Add 'Mark all as read' button to overlay

Button is only shown if there are more unread notifications than
fit in the overlay.

To avoid performance issues, this version only works for cases where
the number of unread notifications is less than the maximum count
(99 currently). Otherwise the button to mark all as read isn't
displayed (it's also limited on the server-side for good measure).

Bug: 47092
Change-Id: Ifcb0a436e2b31062741c441cca239d35ddefa0e1
This commit is contained in:
kaldari 2013-04-16 18:00:21 -07:00
parent 057e86286d
commit 9448c6cab0
9 changed files with 116 additions and 5 deletions

View file

@ -143,6 +143,7 @@ $1',
'echo-overlay-link' => 'All notifications',
'echo-overlay-title' => 'Notifications',
'echo-overlay-title-overflow' => 'Notifications (showing $1 of $2 unread)',
'echo-mark-all-as-read' => 'Mark all as read',
// Special page
'echo-date-today' => 'Today',
@ -440,6 +441,7 @@ The new notification count next to notification link, for example: 99+
* $1 - the number of unread notifications being shown
* $2 - the total number of unread notifications that exist
{{Identical|Notification}}',
'echo-mark-all-as-read' => 'Text for button that marks all unread notifications as read. Keep this short as possible.',
'echo-date-today' => "The header text for today's notification section",
'echo-date-yesterday' => "The header text for yesterday's notification section",
'echo-date-header' => '{{optional}}

View file

@ -129,6 +129,7 @@ $wgResourceModules += array(
'mediawiki.jqueryMsg',
'jquery.badge',
'ext.echo.icons',
'mediawiki.ui',
),
'messages' => array(
'echo-link-new',
@ -137,6 +138,7 @@ $wgResourceModules += array(
'echo-overlay-title-overflow',
'echo-overlay-link',
'echo-none',
'echo-mark-all-as-read',
),
),
'ext.echo.special' => $echoResourceTemplate + array(

View file

@ -620,7 +620,7 @@ class EchoHooks {
* @return bool true in all cases
*/
public static function makeGlobalVariablesScript( &$vars, OutputPage $outputPage ) {
global $wgEchoShowFullNotificationsLink, $wgEchoHelpPage;
global $wgEchoShowFullNotificationsLink, $wgEchoHelpPage, $wgEchoMaxNotificationCount;
$user = $outputPage->getUser();
// Provide info for the Overlay
@ -631,6 +631,7 @@ class EchoHooks {
'notifications-link-full' => $wgEchoShowFullNotificationsLink,
'timestamp' => $timestamp->getTimestamp( TS_UNIX ),
'notification-count' => EchoNotificationController::getFormattedNotificationCount( $user ),
'max-notification-count' => $wgEchoMaxNotificationCount,
);
$vars['wgEchoHelpPage'] = $wgEchoHelpPage;
}

View file

@ -14,6 +14,8 @@ class ApiEchoNotifications extends ApiQueryBase {
$params = $this->extractRequestParams();
if ( count( $params['markread'] ) ) {
EchoNotificationController::markRead( $user, $params['markread'] );
} elseif ( $params['markallread'] ) {
EchoNotificationController::markAllRead( $user );
}
$prop = $params['prop'];
@ -161,6 +163,10 @@ class ApiEchoNotifications extends ApiQueryBase {
'markread' => array(
ApiBase::PARAM_ISMULTI => true,
),
'markallread' => array(
ApiBase::PARAM_REQUIRED => false,
ApiBase::PARAM_TYPE => 'boolean'
),
'format' => array(
ApiBase::PARAM_TYPE => array(
'text',
@ -188,6 +194,7 @@ class ApiEchoNotifications extends ApiQueryBase {
return array(
'prop' => 'Details to request.',
'markread' => 'A list of notification IDs to mark as read',
'markallread' => "If set to true, marks all of a user's notifications as read",
'format' => 'If specified, notifications will be returned formatted this way.',
'index' => 'If specified, a list of notification IDs, in order, will be returned.',
'limit' => 'The maximum number of notifications to return.',

View file

@ -161,6 +161,25 @@ class EchoNotificationController {
self::resetNotificationCount( $user, DB_MASTER );
}
/**
* @param $user User to mark all notifications read for
* @return boolean
*/
public static function markAllRead( $user ) {
global $wgEchoBackend, $wgEchoMaxNotificationCount;
$notificationCount = self::getNotificationCount( $user );
// Only update all the unread notifications if it isn't a huge number.
// TODO: Implement batched jobs it's over the maximum.
if ( $notificationCount <= $wgEchoMaxNotificationCount ) {
$wgEchoBackend->markAllRead( $user );
self::resetNotificationCount( $user, DB_MASTER );
return true;
} else {
return false;
}
}
/**
* Recalculates the number of notifications that a user has.
*

View file

@ -227,6 +227,23 @@ class MWDbEchoBackend extends MWEchoBackend {
);
}
/**
* @param $user User
*/
public function markAllRead( $user ) {
$this->dbw->update(
'echo_notification',
array( 'notification_read_timestamp' => $this->dbw->timestamp( wfTimestampNow() ) ),
array(
'notification_user' => $user->getId(),
'notification_read_timestamp' => NULL,
'notification_bundle_base' => 1,
),
__METHOD__,
array( 'LIMIT' => 500 )
);
}
/**
* @param $user User object to check notifications for
* @param $dbSource string use master or slave storage to pull count

View file

@ -115,6 +115,12 @@ abstract class MWEchoBackend {
*/
abstract public function markRead( $user, $eventIDs );
/**
* Mark all unread notifications as read for a user
* @param $user User
*/
abstract public function markAllRead( $user );
/**
* Retrieves number of unread notifications that a user has.
* @param $user User object to check notifications for

View file

@ -58,9 +58,12 @@
.mw-echo-overlay-title {
/*border-bottom: 1px solid #A7D7F9;*/
font-size: 13px;
padding: 15px 15px 15px 60px;
line-height: 15px;
height: 15px;
padding: 15px 15px 15px 28px;
border-bottom: 1px solid #DDDDDD;
font-weight: bold;
position: relative;
}
#mw-echo-overlay-footer {
@ -113,3 +116,13 @@
border-bottom: 1px solid #DDDDDD;
padding: 15px 15px 10px 60px;
}
#mw-echo-mark-read-button {
position: absolute;
bottom: 12px;
right: 15px;
padding: 1px 8px;
font-size: 11px;
line-height: 15px;
font-weight: normal;
}

View file

@ -58,7 +58,9 @@
$title = $( '<div class="mw-echo-overlay-title"></div>' ),
$ul = $( '<ul class="mw-echo-notifications"></ul>' ),
titleText = '',
$overlayFooter;
overflow = false,
$overlayFooter,
$markReadButton;
$ul.css( 'max-height', notificationLimit * 95 + 'px' );
$.each( notifications.index, function( index, id ) {
@ -84,15 +86,57 @@
} );
if ( notifications.index.length > 0 ) {
if ( unreadTotalCount > unread.length ) {
if ( isNaN( unreadTotalCount ) || unreadTotalCount > unread.length ) {
titleText = mw.msg( 'echo-overlay-title-overflow', unread.length, unreadTotalCount );
overflow = true;
} else {
titleText = mw.msg( 'echo-overlay-title' );
}
} else {
titleText = mw.msg( 'echo-none' );
}
$title.text( titleText );
$markReadButton = $( '<button/>' )
.addClass( 'mw-ui-button' )
.attr( 'id', 'mw-echo-mark-read-button' )
.text( mw.msg( 'echo-mark-all-as-read' ) )
.click( function( e ) {
e.preventDefault();
Api.get( {
'action' : 'query',
'meta' : 'notifications',
'notmarkallread' : true,
'notprop' : 'count'
}, {
'ok' : function( result ) {
if ( result.query.notifications.count !== undefined ) {
count = result.query.notifications.count;
mw.echo.overlay.updateCount( count );
// Reset header to 'Notifications'
$( '#echo-overlay-title-text').text( mw.msg( 'echo-overlay-title' ) );
}
}
} );
} );
// If there are more unread notifications than can fit in the overlay,
// but fewer than the maximum count, show the 'mark all as read' button.
// The only reason we limit it to the maximum is to prevent expensive
// database updates. If the count is more than the maximum, it could
// be thousands.
if ( overflow &&
!isNaN( unreadTotalCount ) &&
unreadTotalCount < mw.echo.overlay.configuration['max-notification-count']
) {
// Add the 'mark all as read' button to the title area
$title.append( $markReadButton );
}
// Add the header to the title area
$( '<div/>' )
.attr( 'id', 'echo-overlay-title-text' )
.text( titleText )
.appendTo( $title );
// Insert the title area into the overlay
$title.appendTo( $overlay );
if ( $ul.find( 'li' ).length ) {