Fix some notification badge related issue

* In some languages like persian, the number 0 is represented as '.', we can't compare
  '.' with either 0 or '0' to detect the no-notification status of the badge

* The markread API doesn't respect uselang param, it would return 0 instead of . in a url with uselang=fa

Note: we need to provide raw and formatted count in the API since client side javascript
      doesn't provide fancy function like $wgLang->formatNum()

bug: 54575

Change-Id: I0a49828253ec346ed27c5b9a976f8bdff4e1fa90
This commit is contained in:
bsitu 2013-09-24 17:18:02 -07:00
parent 70bbd32eea
commit 3b3ed1e3bc
6 changed files with 67 additions and 42 deletions

View file

@ -152,6 +152,16 @@ $wgResourceModules += array(
),
'targets' => array( 'desktop', 'mobile' ),
),
'ext.echo.desktop' => $echoResourceTemplate + array(
'scripts' => 'desktop/ext.echo.desktop.js',
'dependencies' => array(
'ext.echo.base',
'mediawiki.api',
'mediawiki.Uri',
'mediawiki.jqueryMsg',
'mediawiki.user',
),
),
'ext.echo.overlay' => $echoResourceTemplate + array(
'scripts' => array(
'overlay/ext.echo.overlay.js',
@ -162,12 +172,8 @@ $wgResourceModules += array(
'monobook' => 'overlay/ext.echo.overlay.monobook.css',
),
'dependencies' => array(
'ext.echo.base',
'mediawiki.api',
'mediawiki.Uri',
'ext.echo.desktop',
'mediawiki.util',
'mediawiki.jqueryMsg',
'mediawiki.user',
),
'messages' => array(
'echo-overlay-title',
@ -185,12 +191,8 @@ $wgResourceModules += array(
),
'styles' => 'special/ext.echo.special.css',
'dependencies' => array(
'ext.echo.base',
'mediawiki.api',
'mediawiki.Uri',
'ext.echo.desktop',
'mediawiki.ui',
'mediawiki.jqueryMsg',
'mediawiki.user',
),
'messages' => array(
'echo-load-more-error',

View file

@ -29,7 +29,13 @@ class ApiEchoMarkRead extends ApiBase {
}
}
$result = array( 'result' => 'success', 'count' => $notifUser->getFormattedNotificationCount() );
$rawCount = $notifUser->getNotificationCount();
$result = array(
'result' => 'success',
'rawcount' => $rawCount,
'count' => EchoNotificationController::formatNotificationCount( $rawCount ),
);
$this->getResult()->addValue( 'query', $this->getModuleName(), $result );
}
@ -45,6 +51,7 @@ class ApiEchoMarkRead extends ApiBase {
'token' => array(
ApiBase::PARAM_REQUIRED => true,
),
'uselang' => null
);
}
@ -53,6 +60,7 @@ class ApiEchoMarkRead extends ApiBase {
'list' => 'A list of notification IDs to mark as read',
'all' => "If set to true, marks all of a user's notifications as read",
'token' => 'edit token',
'uselang' => 'the desired language to format the output'
);
}

View file

@ -50,7 +50,9 @@ class ApiEchoNotifications extends ApiQueryBase {
}
if ( in_array( 'count', $prop ) ) {
$result['count'] = $notifUser->getFormattedNotificationCount();
$rawCount = $notifUser->getNotificationCount();
$result['rawcount'] = $rawCount;
$result['count'] = EchoNotificationController::formatNotificationCount( $rawCount );
}
if ( in_array( 'index', $prop ) ) {

View file

@ -0,0 +1,20 @@
( function ( $, mw ) {
'use strict';
// Functions that are only available to echo desktop version
mw.echo.desktop = {
/**
* Append uselang param to API get/post data if applicable
* @param apiData {Object}
*/
appendUseLang: function ( apiData ) {
var curUri = new mw.Uri();
if ( curUri.query.uselang !== undefined ) {
apiData.uselang = curUri.query.uselang;
}
return apiData;
}
};
} )( jQuery, mediaWiki );

View file

@ -4,12 +4,15 @@
mw.echo.overlay = {
updateCount: function ( newCount ) {
/**
* @param newCount formatted count
* @param rawCount unformatted count
*/
updateCount: function ( newCount, rawCount ) {
var $badge = $( '.mw-echo-notifications-badge' );
$badge.text( newCount );
// newCount could be '99+' or another string.
// Checking for number as well just to be paranoid.
if ( newCount !== '0' && newCount !== 0 ) {
if ( rawCount !== '0' && rawCount !== 0 ) {
$badge.addClass( 'mw-echo-unread-notifications' );
} else {
$badge.removeClass( 'mw-echo-unread-notifications' );
@ -24,7 +27,6 @@
$prefLink = $( '#pt-preferences a' ),
count = 0,
apiData,
curUri = new mw.Uri(),
api = new mw.Api( { ajax: { cache: false } } );
// Set notification limit based on height of the window
@ -44,14 +46,11 @@
'notprop' : 'index|list|count'
};
if ( curUri.query.uselang !== undefined ) {
apiData.uselang = curUri.query.uselang;
}
api.get( apiData ).done( function ( result ) {
api.get( mw.echo.desktop.appendUseLang( apiData ) ).done( function ( result ) {
var notifications = result.query.notifications,
unread = [],
unreadTotalCount = result.query.notifications.count,
unreadRawTotalCount = result.query.notifications.rawcount,
$title = $( '<div class="mw-echo-overlay-title"></div>' ),
$ul = $( '<ul class="mw-echo-notifications"></ul>' ),
titleText = '',
@ -60,7 +59,7 @@
$markReadButton;
if ( unreadTotalCount !== undefined ) {
mw.echo.overlay.updateCount( unreadTotalCount );
mw.echo.overlay.updateCount( unreadTotalCount, unreadRawTotalCount );
}
$ul.css( 'max-height', notificationLimit * 95 + 'px' );
$.each( notifications.index, function ( index, id ) {
@ -123,7 +122,7 @@
} );
if ( notifications.index.length > 0 ) {
if ( isNaN( unreadTotalCount ) || unreadTotalCount > unread.length ) {
if ( unreadRawTotalCount > unread.length ) {
titleText = mw.msg( 'echo-overlay-title-overflow', unread.length, unreadTotalCount );
overflow = true;
} else {
@ -139,14 +138,14 @@
.text( mw.msg( 'echo-mark-all-as-read' ) )
.click( function ( e ) {
e.preventDefault();
api.post( {
api.post( mw.echo.desktop.appendUseLang( {
'action' : 'echomarkread',
'all' : true,
'token': mw.user.tokens.get( 'editToken' )
} ).done( function ( result ) {
} ) ).done( function ( result ) {
if ( result.query.echomarkread.count !== undefined ) {
count = result.query.echomarkread.count;
mw.echo.overlay.updateCount( count );
mw.echo.overlay.updateCount( count, result.query.echomarkread.rawcount );
// Reset header to 'Notifications'
$( '#mw-echo-overlay-title-text').msg( 'echo-overlay-title' );
}
@ -158,9 +157,7 @@
// 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']
if ( overflow && unreadRawTotalCount < mw.echo.overlay.configuration['max-notification-count']
) {
// Add the 'mark all as read' button to the title area
$title.append( $markReadButton );
@ -239,14 +236,14 @@
// only need to mark as read if there is unread item
if ( unread.length > 0 ) {
api.post( {
api.post( mw.echo.desktop.appendUseLang( {
'action' : 'echomarkread',
'list' : unread.join( '|' ),
'token': mw.user.tokens.get( 'editToken' )
} ).done( function ( result ) {
} ) ).done( function ( result ) {
if ( result.query.echomarkread.count !== undefined ) {
count = result.query.echomarkread.count;
mw.echo.overlay.updateCount( count );
mw.echo.overlay.updateCount( count, result.query.echomarkread.rawcount );
}
} );
}

View file

@ -58,7 +58,7 @@
* Load more notification records.
*/
loadMore: function () {
var api = new mw.Api( { ajax: { cache: false } } ), curUri = new mw.Uri(),
var api = new mw.Api( { ajax: { cache: false } } ),
notifications, data, container, $li, that = this, unread = [], apiData;
apiData = {
@ -70,11 +70,7 @@
'notlimit': mw.config.get( 'wgEchoDisplayNum' )
};
if ( curUri.query.uselang !== undefined ) {
apiData.uselang = curUri.query.uselang;
}
api.get( apiData ).done( function ( result ) {
api.get( mw.echo.desktop.appendUseLang( apiData ) ).done( function ( result ) {
container = $( '#mw-echo-special-container' );
notifications = result.query.notifications;
unread = [];
@ -128,16 +124,16 @@
markAsRead: function ( unread ) {
var api = new mw.Api(), that = this;
api.post( {
api.post( mw.echo.desktop.appendUseLang( {
'action' : 'echomarkread',
'list' : unread.join( '|' ),
'token': mw.user.tokens.get( 'editToken' )
} ).done( function ( result ) {
} ) ).done( function ( result ) {
// update the badge if the link is enabled
if ( result.query.echomarkread.count !== undefined &&
$( '#pt-notifications').length && typeof mw.echo.overlay === 'object'
) {
mw.echo.overlay.updateCount( result.query.echomarkread.count );
mw.echo.overlay.updateCount( result.query.echomarkread.count, result.query.echomarkread.rawcount );
}
that.onSuccess();
} ).fail( function () {