mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-11-23 23:44:53 +00:00
Implement subject+talk and null+user page grouping
Make it optional through the unpgrouppages parameter, so that generic usage of the unreadnotificationpages API is still possible. In the front-end, store which display title maps to what set of titles, and pass in the full set rather than just the display title when filtering by a page. Bug: T137502 Change-Id: I443ca00ff5e5d36fd6910101226358942e6aa8ee
This commit is contained in:
parent
9e206ef8f5
commit
4e64643eb7
|
@ -261,6 +261,7 @@
|
|||
"apihelp-query+notifications-example-1": "List notifications",
|
||||
"apihelp-query+notifications-example-2": "List notifications, grouped by section, with counts",
|
||||
"apihelp-query+unreadnotificationpages-description": "Get pages for which there are unread notifications for the current user.",
|
||||
"apihelp-query+unreadnotificationpages-param-grouppages": "Group talk pages together with their subject page, and group notifications not associated with a page together with the current user's user page.",
|
||||
"apihelp-query+unreadnotificationpages-param-limit": "The maximum number of pages to return.",
|
||||
"apihelp-query+unreadnotificationpages-param-wikis": "List of wikis to fetch pages with unread notifications from (defaults to only current wiki).",
|
||||
"apihelp-query+unreadnotificationpages-example-1": "List pages with (their amount of) unread notifications"
|
||||
|
|
|
@ -253,6 +253,7 @@
|
|||
"apihelp-query+notifications-example-1": "{{doc-apihelp-example|query+notifications}}",
|
||||
"apihelp-query+notifications-example-2": "{{doc-apihelp-example|query+notifications}}",
|
||||
"apihelp-query+unreadnotificationpages-description": "{{doc-apihelp-description|query+unreadnotificationpages}}",
|
||||
"apihelp-query+unreadnotificationpages-param-grouppages": "{{doc-apihelp-param|query+unreadnotificationpages|grouppages}}",
|
||||
"apihelp-query+unreadnotificationpages-param-limit": "{{doc-apihelp-param|query+unreadnotificationpages|limit}}",
|
||||
"apihelp-query+unreadnotificationpages-param-wikis": "{{doc-apihelp-param|query+unreadnotificationpages|wikis}}",
|
||||
"apihelp-query+unreadnotificationpages-example-1": "{{doc-apihelp-example|query+unreadnotificationpages}}"
|
||||
|
|
|
@ -28,8 +28,8 @@ class ApiEchoUnreadNotificationPages extends ApiCrossWikiBase {
|
|||
$params = $this->extractRequestParams();
|
||||
|
||||
$result = array();
|
||||
if ( in_array( wfWikiID(), $this->getRequestedWikis() ) ) {
|
||||
$result[wfWikiID()] = $this->getFromLocal( $params['limit'] );
|
||||
if ( in_array( wfWikiId(), $this->getRequestedWikis() ) ) {
|
||||
$result[wfWikiID()] = $this->getFromLocal( $params['limit'], $params['grouppages'] );
|
||||
}
|
||||
|
||||
if ( $this->getRequestedForeignWikis() ) {
|
||||
|
@ -47,10 +47,14 @@ class ApiEchoUnreadNotificationPages extends ApiCrossWikiBase {
|
|||
|
||||
/**
|
||||
* @param int $limit
|
||||
* @param bool $groupPages
|
||||
* @return array
|
||||
*/
|
||||
protected function getFromLocal( $limit ) {
|
||||
protected function getFromLocal( $limit, $groupPages ) {
|
||||
$dbr = MWEchoDbFactory::newFromDefault()->getEchoDb( DB_SLAVE );
|
||||
// If $groupPages is true, we need to fetch all pages and apply the ORDER BY and LIMIT ourselves
|
||||
// after grouping.
|
||||
$extraOptions = $groupPages ? array() : array( 'ORDER BY' => 'count DESC', 'LIMIT' => $limit );
|
||||
$rows = $dbr->select(
|
||||
array( 'echo_event', 'echo_notification' ),
|
||||
array( 'event_page_id', 'count' => 'COUNT(*)' ),
|
||||
|
@ -63,9 +67,7 @@ class ApiEchoUnreadNotificationPages extends ApiCrossWikiBase {
|
|||
__METHOD__,
|
||||
array(
|
||||
'GROUP BY' => 'event_page_id',
|
||||
'ORDER BY' => 'count DESC',
|
||||
'LIMIT' => $limit,
|
||||
),
|
||||
) + $extraOptions,
|
||||
array( 'echo_notification' => array( 'INNER JOIN', 'notification_event = event_id' ) )
|
||||
);
|
||||
|
||||
|
@ -73,17 +75,75 @@ class ApiEchoUnreadNotificationPages extends ApiCrossWikiBase {
|
|||
return array();
|
||||
}
|
||||
|
||||
$pages = array();
|
||||
$nullCount = 0;
|
||||
$pageCounts = array();
|
||||
foreach ( $rows as $row ) {
|
||||
$pages[$row->event_page_id] = $row->count;
|
||||
if ( $row->event_page_id !== null ) {
|
||||
$pageCounts[$row->event_page_id] = intval( $row->count );
|
||||
} else {
|
||||
$nullCount = intval( $row->count );
|
||||
}
|
||||
}
|
||||
|
||||
$titles = Title::newFromIDs( array_keys( $pageCounts ) );
|
||||
|
||||
$groupCounts = array();
|
||||
foreach ( $titles as $title ) {
|
||||
if ( $groupPages ) {
|
||||
// If $title is a talk page, add its count to its subject page's count
|
||||
$pageName = $title->getSubjectPage()->getPrefixedText();
|
||||
} else {
|
||||
$pageName = $title->getPrefixedText();
|
||||
}
|
||||
|
||||
$count = $pageCounts[$title->getArticleId()];
|
||||
if ( isset( $groupCounts[$pageName] ) ) {
|
||||
$groupCounts[$pageName] += $count;
|
||||
} else {
|
||||
$groupCounts[$pageName] = $count;
|
||||
}
|
||||
}
|
||||
|
||||
$userPageName = $this->getUser()->getUserPage()->getPrefixedText();
|
||||
if ( $nullCount > 0 && $groupPages ) {
|
||||
// Add the count for NULL (not associated with any page) to the count for the user page
|
||||
if ( isset( $groupCounts[$userPageName] ) ) {
|
||||
$groupCounts[$userPageName] += $nullCount;
|
||||
} else {
|
||||
$groupCounts[$userPageName] = $nullCount;
|
||||
}
|
||||
}
|
||||
|
||||
arsort( $groupCounts );
|
||||
if ( $groupPages ) {
|
||||
$groupCounts = array_slice( $groupCounts, 0, $limit );
|
||||
}
|
||||
|
||||
$result = array();
|
||||
$titles = Title::newFromIDs( array_keys( $pages ) );
|
||||
foreach ( $titles as $title ) {
|
||||
foreach ( $groupCounts as $pageName => $count ) {
|
||||
if ( $groupPages ) {
|
||||
$title = Title::newFromText( $pageName );
|
||||
$pages = array( $title->getSubjectPage()->getPrefixedText(), $title->getTalkPage()->getPrefixedText() );
|
||||
if ( $pageName === $userPageName ) {
|
||||
$pages[] = null;
|
||||
}
|
||||
$pageDescription = array(
|
||||
'ns' => $title->getNamespace(),
|
||||
'title' => $title->getPrefixedText(),
|
||||
'unprefixed' => $title->getText(),
|
||||
'pages' => $pages,
|
||||
);
|
||||
} else {
|
||||
$pageDescription = array( 'title' => $pageName );
|
||||
}
|
||||
$result[] = $pageDescription + array(
|
||||
'count' => $count,
|
||||
);
|
||||
}
|
||||
if ( !$groupPages && $nullCount > 0 ) {
|
||||
$result[] = array(
|
||||
'title' => $title->getPrefixedText(),
|
||||
'count' => $pages[$title->getArticleID()],
|
||||
'title' => null,
|
||||
'count' => $nullCount,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -112,9 +172,13 @@ class ApiEchoUnreadNotificationPages extends ApiCrossWikiBase {
|
|||
global $wgEchoMaxUpdateCount;
|
||||
|
||||
return parent::getAllowedParams() + array(
|
||||
'grouppages' => array(
|
||||
ApiBase::PARAM_TYPE => 'boolean',
|
||||
ApiBase::PARAM_DFLT => false,
|
||||
),
|
||||
'limit' => array(
|
||||
ApiBase::PARAM_TYPE => 'limit',
|
||||
ApiBase::PARAM_DFLT => 20,
|
||||
ApiBase::PARAM_DFLT => 10,
|
||||
ApiBase::PARAM_MIN => 1,
|
||||
ApiBase::PARAM_MAX => $wgEchoMaxUpdateCount,
|
||||
ApiBase::PARAM_MAX2 => $wgEchoMaxUpdateCount,
|
||||
|
|
|
@ -68,7 +68,8 @@
|
|||
var params = {
|
||||
action: 'query',
|
||||
meta: 'unreadnotificationpages',
|
||||
uselang: this.userLang
|
||||
uselang: this.userLang,
|
||||
unpgrouppages: true
|
||||
};
|
||||
|
||||
if ( !sources || sources === '*' ) {
|
||||
|
|
|
@ -132,7 +132,7 @@
|
|||
{
|
||||
continue: continueValue,
|
||||
readState: filters.getReadState(),
|
||||
titles: filters.getSourcePagesModel().getCurrentPage()
|
||||
titles: filters.getSourcePagesModel().getGroupedPagesForCurrentTitle()
|
||||
}
|
||||
)
|
||||
.then( function ( data ) {
|
||||
|
|
|
@ -123,12 +123,32 @@
|
|||
* Get all pages in a source
|
||||
*
|
||||
* @param {string} source Symbolic name of the source
|
||||
* @return {Object[]} Page definitions in this source
|
||||
* @return {Object} Page definitions in this source
|
||||
*/
|
||||
mw.echo.dm.SourcePagesModel.prototype.getSourcePages = function ( source ) {
|
||||
return this.sources[ source ] && this.sources[ source ].pages;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of page titles associated with one group title.
|
||||
*
|
||||
* @param {string} source Symbolic name of the source
|
||||
* @param {string} title Group title
|
||||
* @return {string[]} Page titles
|
||||
*/
|
||||
mw.echo.dm.SourcePagesModel.prototype.getGroupedPagesForTitle = function ( source, title ) {
|
||||
return OO.getProp( this.sources, source, 'pages', title, 'pages' ) || [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of page titles associated with the current group title.
|
||||
*
|
||||
* @return {string[]} Page titles
|
||||
*/
|
||||
mw.echo.dm.SourcePagesModel.prototype.getGroupedPagesForCurrentTitle = function () {
|
||||
return this.getGroupedPagesForTitle( this.getCurrentSource(), this.getCurrentPage() );
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset the data
|
||||
*/
|
||||
|
@ -144,11 +164,17 @@
|
|||
* @param {Object} details Details object
|
||||
*/
|
||||
mw.echo.dm.SourcePagesModel.prototype.setSourcePagesDetails = function ( source, details ) {
|
||||
var i, page;
|
||||
this.sources[ source ] = {
|
||||
title: details.source.title,
|
||||
base: details.source.base,
|
||||
totalCount: details.totalCount,
|
||||
pages: details.pages
|
||||
pages: {}
|
||||
};
|
||||
|
||||
for ( i = 0; i < details.pages.length; i++ ) {
|
||||
page = details.pages[ i ];
|
||||
this.sources[ source ].pages[ page.title ] = page;
|
||||
}
|
||||
};
|
||||
} )( mediaWiki );
|
||||
|
|
|
@ -72,21 +72,18 @@
|
|||
* Populate the widget from the model
|
||||
*/
|
||||
mw.echo.ui.PageFilterWidget.prototype.populateDataFromModel = function () {
|
||||
var i, title, widget,
|
||||
var title, widget, isUserPage,
|
||||
optionWidgets = [],
|
||||
sourcePages = this.model.getSourcePages( this.source );
|
||||
|
||||
for ( i = 0; i < sourcePages.length; i++ ) {
|
||||
for ( title in sourcePages ) {
|
||||
isUserPage = sourcePages[ title ].ns === mw.config.get( 'wgNamespaceIds' ).user;
|
||||
widget = new mw.echo.ui.PageNotificationsOptionWidget( {
|
||||
label: sourcePages[ i ].title,
|
||||
title: sourcePages[ i ].title,
|
||||
// TODO: Pages that are a user page should
|
||||
// have a user icon
|
||||
icon: 'article',
|
||||
unreadCount: sourcePages[ i ].count,
|
||||
// TODO: When we group pages, this should be
|
||||
// an array of titles
|
||||
data: sourcePages[ i ].title,
|
||||
label: isUserPage ? sourcePages[ title ].unprefixed : title,
|
||||
title: isUserPage ? sourcePages[ title ].unprefixed : title,
|
||||
icon: isUserPage ? 'userAvatar' : 'article',
|
||||
unreadCount: sourcePages[ title ].count,
|
||||
data: title,
|
||||
classes: [ 'mw-echo-ui-pageFilterWidget-page' ]
|
||||
} );
|
||||
optionWidgets.push( widget );
|
||||
|
|
Loading…
Reference in a new issue