mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-11-27 17:20:40 +00:00
Cross-wiki notifications integration
Bug: T121829 Change-Id: Ifb52ad5605a56d27e5951479326689242a49430e
This commit is contained in:
parent
5670a247f0
commit
63eef35026
10
Echo.php
10
Echo.php
|
@ -434,6 +434,16 @@ $wgEchoNotifications = array(
|
|||
'title-params' => array( 'agent' ),
|
||||
'icon' => 'site',
|
||||
),
|
||||
'foreign' => array(
|
||||
'presentation-model' => 'EchoForeignPresentationModel',
|
||||
'user-locators' => array(
|
||||
'EchoUserLocator::locateEventAgent'
|
||||
),
|
||||
'category' => 'foreign',
|
||||
'group' => 'positive',
|
||||
'section' => 'alert',
|
||||
'icon' => 'site',
|
||||
),
|
||||
);
|
||||
|
||||
// Enable new talk page messages alert for all logged in users by default
|
||||
|
|
|
@ -48,7 +48,9 @@ $wgAutoloadClasses += array(
|
|||
'EchoEventMapperTest' => __DIR__ . '/tests/phpunit/mapper/EventMapperTest.php',
|
||||
'EchoEventPresentationModel' => __DIR__ . '/includes/formatters/EventPresentationModel.php',
|
||||
'EchoExecuteFirstArgumentStub' => __DIR__ . '/tests/phpunit/mapper/NotificationMapperTest.php',
|
||||
'EchoForeignPresentationModel' => __DIR__ . '/includes/formatters/EchoForeignPresentationModel.php',
|
||||
'EchoFilteredSequentialIterator' => __DIR__ . '/includes/iterator/FilteredSequentialIterator.php',
|
||||
'EchoForeignNotifications' => __DIR__ . '/includes/ForeignNotifications.php',
|
||||
'EchoFlyoutFormatter' => __DIR__ . '/includes/formatters/EchoFlyoutFormatter.php',
|
||||
'EchoHTMLEmailDecorator' => __DIR__ . '/includes/EmailFormatter.php',
|
||||
'EchoHTMLEmailFormatter' => __DIR__ . '/includes/EmailFormatter.php',
|
||||
|
|
|
@ -136,6 +136,8 @@
|
|||
"echo-email-batch-body-intro-weekly": "Hi $1,\nHere's a summary of this week's activity on {{SITENAME}} for you.",
|
||||
"echo-email-batch-link-text-view-all-notifications": "View all notifications",
|
||||
"echo-rev-deleted-text-view": "This page revision has been suppressed.",
|
||||
"notification-header-foreign-alert": "More alerts from $3 {{PLURAL:$4|and one other wiki|and $4 other wikis|0=}}",
|
||||
"notification-header-foreign-message": "More messages from $3 {{PLURAL:$4|and one other wiki|and $4 other wikis|0=}}",
|
||||
"apihelp-echomarkread-description": "Mark notifications as read for the current user.",
|
||||
"apihelp-echomarkread-param-list": "A list of notification IDs to mark as read.",
|
||||
"apihelp-echomarkread-param-all": "If set, marks all of a user's notifications as read.",
|
||||
|
@ -153,6 +155,7 @@
|
|||
"apihelp-query+notifications-param-format": "If specified, notifications will be returned formatted this way.",
|
||||
"apihelp-query+notifications-param-limit": "The maximum number of notifications to return.",
|
||||
"apihelp-query+notifications-param-index": "If specified, a list of notification IDs, in order, will be returned.",
|
||||
"apihelp-query+notifications-param-noforn": "True to opt out of data about notifications on foreign wikis.",
|
||||
"apihelp-query+notifications-param-alertcontinue": "When more alert results are available, use this to continue.",
|
||||
"apihelp-query+notifications-param-alertunreadfirst": "Whether to show unread message notifications first.",
|
||||
"apihelp-query+notifications-param-messagecontinue": "When more message results are available, use this to continue.",
|
||||
|
|
|
@ -157,6 +157,8 @@
|
|||
"echo-email-batch-body-intro-weekly": "Introduction text for weekly email digest. Parameters:\n* $1 - a username\nSee also:\n* {{msg-mw|Echo-email-batch-body-intro-daily}}",
|
||||
"echo-email-batch-link-text-view-all-notifications": "The link text for the primary action in daily and weekly email digest",
|
||||
"echo-rev-deleted-text-view": "Short message displayed instead of edit content when revision text is suppressed.",
|
||||
"notification-header-foreign-alert": "Flyout-specific format for displaying notification header of having alert notifications on foreign wikis.\n\nParameters:\n* $1 - the formatted username of the current user.\n* $2 - the username for GENDER\n* $3 - 1 of the foreign wikis you have notifications on\n* $4 - the amount of remaining other wikis you have notifications on",
|
||||
"notification-header-foreign-message": "Flyout-specific format for displaying notification header of having message notifications on foreign wikis.\n\nParameters:\n* $1 - the formatted username of the current user.\n* $2 - the username for GENDER\n* $3 - 1 of the foreign wikis you have notifications on\n* $4 - the amount of remaining other wikis you have notifications on",
|
||||
"apihelp-echomarkread-description": "{{doc-apihelp-description|echomarkread}}",
|
||||
"apihelp-echomarkread-param-list": "{{doc-apihelp-param|echomarkread|list}}",
|
||||
"apihelp-echomarkread-param-all": "{{doc-apihelp-param|echomarkread|all}}",
|
||||
|
@ -174,6 +176,7 @@
|
|||
"apihelp-query+notifications-param-format": "{{doc-apihelp-param|query+notifications|format}}",
|
||||
"apihelp-query+notifications-param-limit": "{{doc-apihelp-param|query+notifications|limit}}",
|
||||
"apihelp-query+notifications-param-index": "{{doc-apihelp-param|query+notifications|index}}",
|
||||
"apihelp-query+notifications-param-noforn": "{{doc-apihelp-param|query+notifications|noforn}}",
|
||||
"apihelp-query+notifications-param-alertcontinue": "{{doc-apihelp-param|query+notifications|alertcontinue}}",
|
||||
"apihelp-query+notifications-param-alertunreadfirst": "{{doc-apihelp-param|query+notifications|alertunreadfirst}}",
|
||||
"apihelp-query+notifications-param-messagecontinue": "{{doc-apihelp-param|query+notifications|messagecontinue}}",
|
||||
|
|
146
includes/ForeignNotifications.php
Normal file
146
includes/ForeignNotifications.php
Normal file
|
@ -0,0 +1,146 @@
|
|||
<?php
|
||||
|
||||
class EchoForeignNotifications {
|
||||
/**
|
||||
* @var bool|EchoUnreadWikis
|
||||
*/
|
||||
protected $unreadWikis = false;
|
||||
|
||||
/**
|
||||
* @var array [(str) section => (int) count, ...]
|
||||
*/
|
||||
protected $counts = array( EchoAttributeManager::ALERT => 0, EchoAttributeManager::MESSAGE => 0 );
|
||||
|
||||
/**
|
||||
* @var array [(str) section => (string[]) wikis, ...]
|
||||
*/
|
||||
protected $wikis = array( EchoAttributeManager::ALERT => array(), EchoAttributeManager::MESSAGE => array() );
|
||||
|
||||
/**
|
||||
* @var array [(str) section => (MWTimestamp) timestamp, ...]
|
||||
*/
|
||||
protected $timestamps = array( EchoAttributeManager::ALERT => false, EchoAttributeManager::MESSAGE => false );
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $populated = false;
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct( User $user ) {
|
||||
if ( $user->getOption( 'echo-cross-wiki-notifications' ) ) {
|
||||
$this->unreadWikis = EchoUnreadWikis::newFromUser( $user );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $section Name of section or null for all
|
||||
* @return int
|
||||
*/
|
||||
public function getCount( $section = null ) {
|
||||
$this->populate();
|
||||
|
||||
if ( $section === null ) {
|
||||
return array_sum( $this->counts );
|
||||
}
|
||||
|
||||
return isset( $this->counts[$section] ) ? $this->counts[$section] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $section Name of section or null for all
|
||||
* @return MWTimestamp|false
|
||||
*/
|
||||
public function getTimestamp( $section = null ) {
|
||||
$this->populate();
|
||||
|
||||
if ( $section === null ) {
|
||||
$max = false;
|
||||
/** @var MWTimestamp $timestamp */
|
||||
foreach ( $this->timestamps as $timestamp ) {
|
||||
// $timestamp < $max = invert 0
|
||||
// $timestamp > $max = invert 1
|
||||
if ( $max === false || $timestamp->diff( $max )->invert === 1 ) {
|
||||
$max = $timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
return $timestamp;
|
||||
}
|
||||
|
||||
return isset( $this->timestamps[$section] ) ? $this->timestamps[$section] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $section Name of section or null for all
|
||||
* @return string[]
|
||||
*/
|
||||
public function getWikis( $section = null ) {
|
||||
$this->populate();
|
||||
|
||||
if ( $section === null ) {
|
||||
$all = array();
|
||||
foreach ( $this->wikis as $wikis ) {
|
||||
$all = array_merge( $all, $wikis );
|
||||
}
|
||||
|
||||
return array_unique( $all );
|
||||
}
|
||||
|
||||
return isset( $this->wikis[$section] ) ? $this->wikis[$section] : array();
|
||||
}
|
||||
|
||||
protected function populate() {
|
||||
if ( $this->populated ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $this->unreadWikis === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$unreadCounts = $this->unreadWikis->getUnreadCounts();
|
||||
if ( !$unreadCounts ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $unreadCounts as $wiki => $sections ) {
|
||||
// exclude current wiki
|
||||
if ( $wiki === wfWikiID() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $sections as $section => $data ) {
|
||||
if ( $data['count'] > 0 ) {
|
||||
$this->counts[$section] += $data['count'];
|
||||
$this->wikis[$section][] = $wiki;
|
||||
$this->timestamps[$section] = new MWTimestamp( $data['ts'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->populated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $wikis
|
||||
* @return array[] [(string) wiki => (array) data]
|
||||
*/
|
||||
public function getApiEndpoints( array $wikis ) {
|
||||
global $wgConf;
|
||||
|
||||
$data = array();
|
||||
foreach ( $wikis as $wiki ) {
|
||||
$data[$wiki] = array(
|
||||
'title' => $wiki,
|
||||
'url' => $wgConf->get( 'wgServer', $wiki ) .
|
||||
$wgConf->get( 'wgScriptPath', $wiki ) .
|
||||
'/api.php'
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -35,6 +35,11 @@ class MWEchoNotifUser {
|
|||
*/
|
||||
private $targetPageMapper;
|
||||
|
||||
/**
|
||||
* @var EchoForeignNotifications
|
||||
*/
|
||||
private $foreignNotifications;
|
||||
|
||||
/**
|
||||
* Usually client code doesn't need to initialize the object directly
|
||||
* because it could be obtained from factory method newFromUser()
|
||||
|
@ -56,6 +61,7 @@ class MWEchoNotifUser {
|
|||
$this->cache = $cache;
|
||||
$this->notifMapper = $notifMapper;
|
||||
$this->targetPageMapper = $targetPageMapper;
|
||||
$this->foreignNotifications = new EchoForeignNotifications( $user );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -150,7 +156,10 @@ class MWEchoNotifUser {
|
|||
* @return int
|
||||
*/
|
||||
public function getMessageCount( $cached = true, $dbSource = DB_SLAVE ) {
|
||||
return $this->getNotificationCount( $cached, $dbSource, EchoAttributeManager::MESSAGE );
|
||||
$count = $this->getNotificationCount( $cached, $dbSource, EchoAttributeManager::MESSAGE );
|
||||
$count += $this->foreignNotifications->getCount( EchoAttributeManager::MESSAGE );
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,7 +170,10 @@ class MWEchoNotifUser {
|
|||
* @return int
|
||||
*/
|
||||
public function getAlertCount( $cached = true, $dbSource = DB_SLAVE ) {
|
||||
return $this->getNotificationCount( $cached, $dbSource, EchoAttributeManager::ALERT );
|
||||
$count = $this->getNotificationCount( $cached, $dbSource, EchoAttributeManager::ALERT );
|
||||
$count += $this->foreignNotifications->getCount( EchoAttributeManager::ALERT );
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -256,10 +268,18 @@ class MWEchoNotifUser {
|
|||
*
|
||||
* @param boolean $cached Set to false to bypass the cache. (Optional. Defaults to true)
|
||||
* @param int $dbSource Use master or slave database to pull count (Optional. Defaults to DB_SLAVE)
|
||||
* @return int
|
||||
* @return bool|MWTimestamp
|
||||
*/
|
||||
public function getLastUnreadAlertTime( $cached = true, $dbSource = DB_SLAVE ) {
|
||||
return $this->getLastUnreadNotificationTime( $cached, $dbSource, EchoAttributeManager::ALERT );
|
||||
$time = $this->getLastUnreadNotificationTime( $cached, $dbSource, EchoAttributeManager::ALERT );
|
||||
|
||||
$foreignTime = $this->foreignNotifications->getTimestamp( EchoAttributeManager::ALERT );
|
||||
if ( $foreignTime !== false ) {
|
||||
$max = max( $time ? $time->getTimestamp( TS_MW ) : 0, $foreignTime->getTimestamp( TS_MW ) );
|
||||
$time = new MWTimestamp( $max );
|
||||
}
|
||||
|
||||
return $time;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -267,10 +287,18 @@ class MWEchoNotifUser {
|
|||
*
|
||||
* @param boolean $cached Set to false to bypass the cache. (Optional. Defaults to true)
|
||||
* @param int $dbSource Use master or slave database to pull count (Optional. Defaults to DB_SLAVE)
|
||||
* @return int
|
||||
* @return bool|MWTimestamp
|
||||
*/
|
||||
public function getLastUnreadMessageTime( $cached = true, $dbSource = DB_SLAVE ) {
|
||||
return $this->getLastUnreadNotificationTime( $cached, $dbSource, EchoAttributeManager::MESSAGE );
|
||||
$time = $this->getLastUnreadNotificationTime( $cached, $dbSource, EchoAttributeManager::MESSAGE );
|
||||
|
||||
$foreignTime = $this->foreignNotifications->getTimestamp( EchoAttributeManager::MESSAGE );
|
||||
if ( $foreignTime !== false ) {
|
||||
$max = max( $time ? $time->getTimestamp( TS_MW ) : 0, $foreignTime->getTimestamp( TS_MW ) );
|
||||
$time = new MWTimestamp( $max );
|
||||
}
|
||||
|
||||
return $time;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,10 +5,6 @@
|
|||
*
|
||||
*/
|
||||
class EchoUnreadWikis {
|
||||
|
||||
const ALERT = 'alert';
|
||||
const MESSAGE = 'message';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
@ -78,11 +74,11 @@ class EchoUnreadWikis {
|
|||
continue;
|
||||
}
|
||||
$wikis[$row->euw_wiki] = array(
|
||||
self::ALERT => array(
|
||||
EchoAttributeManager::ALERT => array(
|
||||
'count' => $row->euw_alerts,
|
||||
'ts' => $row->euw_alerts_ts,
|
||||
),
|
||||
self::MESSAGE => array(
|
||||
EchoAttributeManager::MESSAGE => array(
|
||||
'count' => $row->euw_messages,
|
||||
'ts' => $row->euw_messages_ts,
|
||||
),
|
||||
|
|
|
@ -18,6 +18,8 @@ class ApiEchoNotifications extends ApiQueryBase {
|
|||
$params = $this->extractRequestParams();
|
||||
$prop = $params['prop'];
|
||||
|
||||
$foreignNotifications = new EchoForeignNotifications( $user );
|
||||
|
||||
$result = array();
|
||||
if ( in_array( 'list', $prop ) ) {
|
||||
// Group notification results by section
|
||||
|
@ -27,6 +29,12 @@ class ApiEchoNotifications extends ApiQueryBase {
|
|||
$user, $section, $params['filter'], $params['limit'],
|
||||
$params[$section . 'continue'], $params['format'], $params[$section . 'unreadfirst']
|
||||
);
|
||||
|
||||
if ( $foreignNotifications->getCount( $section ) > 0 ) {
|
||||
// insert fake notification for foreign notifications
|
||||
$result[$section]['list'][-1] = $this->makeForeignNotification( $user, $params['format'], $foreignNotifications, $section );
|
||||
}
|
||||
|
||||
$this->getResult()->setIndexedTagName( $result[$section]['list'], 'notification' );
|
||||
// 'index' is built on top of 'list'
|
||||
if ( in_array( 'index', $prop ) ) {
|
||||
|
@ -41,6 +49,14 @@ class ApiEchoNotifications extends ApiQueryBase {
|
|||
$attributeManager->getUserEnabledEventsbySections( $user, 'web', $params['sections'] ),
|
||||
$params['filter'], $params['limit'], $params['continue'], $params['format']
|
||||
);
|
||||
|
||||
// insert fake notifications for foreign notifications
|
||||
foreach ( EchoAttributeManager::$sections as $i => $section ) {
|
||||
if ( $foreignNotifications->getCount( $section ) > 0 ) {
|
||||
$result['list'][-$i-1] = $this->makeForeignNotification( $user, $params['format'], $foreignNotifications, $section );
|
||||
}
|
||||
}
|
||||
|
||||
$this->getResult()->setIndexedTagName( $result['list'], 'notification' );
|
||||
// 'index' is built on top of 'list'
|
||||
if ( in_array( 'index', $prop ) ) {
|
||||
|
@ -48,12 +64,16 @@ class ApiEchoNotifications extends ApiQueryBase {
|
|||
$this->getResult()->setIndexedTagName( $result['index'], 'id' );
|
||||
}
|
||||
}
|
||||
|
||||
// add API endpoint for each of the wikis where notification data
|
||||
// can be queried from
|
||||
$result['sources'] = $foreignNotifications->getApiEndpoints( $foreignNotifications->getWikis() );
|
||||
}
|
||||
|
||||
if ( in_array( 'count', $prop ) ) {
|
||||
$result = array_merge_recursive(
|
||||
$result,
|
||||
$this->getPropcount( $user, $params['sections'], $params['groupbysection'] )
|
||||
$this->getPropCount( $user, $params['sections'], $params['groupbysection'], $foreignNotifications )
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -194,19 +214,22 @@ class ApiEchoNotifications extends ApiQueryBase {
|
|||
* @param User $user
|
||||
* @param string[] $sections
|
||||
* @param boolean $groupBySection
|
||||
* @param EchoForeignNotifications $foreignNotifications
|
||||
* @return array
|
||||
*/
|
||||
protected function getPropCount( User $user, array $sections, $groupBySection ) {
|
||||
protected function getPropCount( User $user, array $sections, $groupBySection, EchoForeignNotifications $foreignNotifications ) {
|
||||
$result = array();
|
||||
$notifUser = MWEchoNotifUser::newFromUser( $user );
|
||||
// Always get total count
|
||||
$rawCount = $notifUser->getNotificationCount();
|
||||
$rawCount += $foreignNotifications->getCount();
|
||||
$result['rawcount'] = $rawCount;
|
||||
$result['count'] = EchoNotificationController::formatNotificationCount( $rawCount );
|
||||
|
||||
if ( $groupBySection ) {
|
||||
foreach ( $sections as $section ) {
|
||||
$rawCount = $notifUser->getNotificationCount( /* $tryCache = */true, DB_SLAVE, $section );
|
||||
$rawCount += $foreignNotifications->getCount( $section );
|
||||
$result[$section]['rawcount'] = $rawCount;
|
||||
$result[$section]['count'] = EchoNotificationController::formatNotificationCount( $rawCount );
|
||||
}
|
||||
|
@ -232,6 +255,42 @@ class ApiEchoNotifications extends ApiQueryBase {
|
|||
return $result;
|
||||
}
|
||||
|
||||
protected function makeForeignNotification( User $user, $format, EchoForeignNotifications $foreignNotifications, $section ) {
|
||||
$wikis = $foreignNotifications->getWikis( $section );
|
||||
$count = $foreignNotifications->getCount( $section );
|
||||
|
||||
$row = new StdClass;
|
||||
$row->event_id = -1;
|
||||
$row->event_type = 'foreign';
|
||||
$row->event_variant = null;
|
||||
$row->event_agent_id = $user->getId();
|
||||
$row->event_agent_ip = null;
|
||||
$row->event_page_id = null;
|
||||
$row->event_page_namespace = null;
|
||||
$row->event_page_title = null;
|
||||
$row->event_extra = serialize( array(
|
||||
'section' => $section,
|
||||
'wikis' => $wikis,
|
||||
'count' => $count
|
||||
) );
|
||||
|
||||
$row->notification_user = $user->getId();
|
||||
$row->notification_timestamp = $foreignNotifications->getTimestamp( $section );
|
||||
$row->notification_read_timestamp = null;
|
||||
$row->notification_bundle_base = 1;
|
||||
$row->notification_bundle_hash = md5( 'bogus' );
|
||||
$row->notification_bundle_display_hash = md5( 'also-bogus' );
|
||||
|
||||
// format output like any other notification
|
||||
$notif = EchoNotification::newFromRow( $row );
|
||||
$output = EchoDataOutputFormatter::formatOutput( $notif, $format, $user, $this->getLanguage() );
|
||||
|
||||
// add cross-wiki-specific data
|
||||
$output['sources'] = $wikis;
|
||||
$output['count'] = $count;
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function getAllowedParams() {
|
||||
$sections = EchoAttributeManager::$sections;
|
||||
$params = array(
|
||||
|
@ -270,6 +329,7 @@ class ApiEchoNotifications extends ApiQueryBase {
|
|||
'special',
|
||||
),
|
||||
),
|
||||
'noforn' => false,
|
||||
'limit' => array(
|
||||
ApiBase::PARAM_TYPE => 'limit',
|
||||
ApiBase::PARAM_DFLT => 20,
|
||||
|
|
28
includes/formatters/EchoForeignPresentationModel.php
Normal file
28
includes/formatters/EchoForeignPresentationModel.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
class EchoForeignPresentationModel extends EchoEventPresentationModel {
|
||||
public function getIconType() {
|
||||
return 'site';
|
||||
}
|
||||
|
||||
public function getPrimaryLink() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getHeaderMessageKey() {
|
||||
$data = $this->event->getExtra();
|
||||
$section = $data['section'];
|
||||
|
||||
return "notification-header-{$this->type}-{$section}";
|
||||
}
|
||||
|
||||
public function getHeaderMessage() {
|
||||
$msg = parent::getHeaderMessage();
|
||||
|
||||
$data = $this->event->getExtra();
|
||||
$msg->params( reset( $data['wikis'] ) );
|
||||
$msg->numParams( count( $data['wikis'] ) - 1 );
|
||||
|
||||
return $msg;
|
||||
}
|
||||
}
|
|
@ -40,7 +40,7 @@
|
|||
* Fetch notifications from the API.
|
||||
*
|
||||
* @param {jQuery.Promise} [apiPromise] An existing promise querying the API for notifications.
|
||||
* This allows us to send an API request external to the DM and have the model
|
||||
* This allows us to send an API request foreign to the DM and have the model
|
||||
* handle the operation as if it asked for the request itself, updating all that
|
||||
* needs to be updated and emitting all proper events.
|
||||
* @return {jQuery.Promise} A promise that resolves with an object containing the
|
||||
|
|
|
@ -95,18 +95,18 @@
|
|||
*
|
||||
* @param {string} name Symbolic name
|
||||
* @param {Object} config Configuration details
|
||||
* @param {boolean} isExternal Is an external API
|
||||
* @param {boolean} isForeign Is a foreign API
|
||||
* @throws {Error} If no URL was given for a foreign API
|
||||
*/
|
||||
mw.echo.dm.NetworkHandler.prototype.addApiHandler = function ( name, config, isExternal ) {
|
||||
mw.echo.dm.NetworkHandler.prototype.addApiHandler = function ( name, config, isForeign ) {
|
||||
var apiConfig;
|
||||
|
||||
if ( !this.handlers[ name ] ) {
|
||||
apiConfig = $.extend( true, {}, { baseParams: this.baseParams, type: this.getType() }, config );
|
||||
|
||||
if ( isExternal ) {
|
||||
if ( isForeign ) {
|
||||
if ( !config.url ) {
|
||||
throw new Error( 'External APIs must have a valid url.' );
|
||||
throw new Error( 'Foreign APIs must have a valid url.' );
|
||||
}
|
||||
this.addCustomApiHandler( name, new mw.echo.dm.ForeignAPIHandler( config.url, apiConfig ) );
|
||||
} else {
|
||||
|
|
|
@ -54,8 +54,8 @@
|
|||
|
||||
// Create notification models for each source
|
||||
for ( source in this.sources ) {
|
||||
// Add external API handler
|
||||
this.networkHandler.addApiHandler( source, { url: this.sources[ source ].url }, true );
|
||||
// Add foreign API handler
|
||||
this.networkHandler.addApiHandler( source, { url: this.sources[ source ].url, baseParams: { notnoforn: 1, notfilter: '!read' } }, true );
|
||||
|
||||
// Create a notifications model
|
||||
item = new mw.echo.dm.NotificationsModel(
|
||||
|
@ -63,7 +63,7 @@
|
|||
{
|
||||
type: this.getType(),
|
||||
source: source,
|
||||
external: this.external,
|
||||
foreign: this.foreign,
|
||||
title: this.sources[ source ].title,
|
||||
removeReadNotifications: this.removeReadNotifications
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
* @cfg {boolean} [seen=false] State the seen state of the option
|
||||
* @cfg {string} [timestamp] Notification timestamp in Mediawiki timestamp format
|
||||
* @cfg {string} [primaryUrl] Notification primary link in raw url format
|
||||
* @cfg {boolean} [external=false] This notification is from an external source
|
||||
* @cfg {string} [source] The source this notification is coming from, if it is external
|
||||
* @cfg {boolean} [foreign=false] This notification is from a foreign source
|
||||
* @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:
|
||||
* {
|
||||
|
@ -55,7 +55,7 @@
|
|||
|
||||
this.category = config.category || '';
|
||||
this.type = config.type || 'alert';
|
||||
this.external = !!config.external;
|
||||
this.foreign = !!config.foreign;
|
||||
this.source = config.source || '';
|
||||
this.iconType = config.iconType;
|
||||
this.iconURL = config.iconURL;
|
||||
|
@ -146,11 +146,11 @@
|
|||
};
|
||||
|
||||
/**
|
||||
* Check whether this notification item is external
|
||||
* @return {boolean} Notification item is external
|
||||
* Check whether this notification item is foreign
|
||||
* @return {boolean} Notification item is foreign
|
||||
*/
|
||||
mw.echo.dm.NotificationItem.prototype.isExternal = function () {
|
||||
return this.external;
|
||||
mw.echo.dm.NotificationItem.prototype.isForeign = function () {
|
||||
return this.foreign;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* the source of the notification items for the network handler.
|
||||
* @cfg {number} [limit=25] Notification limit
|
||||
* @cfg {string} [userLang] User language
|
||||
* @cfg {boolean} [external] The model's source is external
|
||||
* @cfg {boolean} [foreign] The model's source is foreign
|
||||
* @cfg {boolean} [removeReadNotifications=false] Remove read notifications completely. This
|
||||
* means the model will only contain unread notifications. This is useful for
|
||||
* cross-wiki bundled notifications.
|
||||
|
@ -39,7 +39,7 @@
|
|||
|
||||
this.markingAllAsRead = false;
|
||||
this.removeReadNotifications = !!config.removeReadNotifications;
|
||||
this.external = !!config.external;
|
||||
this.foreign = !!config.foreign;
|
||||
|
||||
this.networkHandler = networkHandler;
|
||||
|
||||
|
@ -329,7 +329,7 @@
|
|||
this.emit( 'updateSeenTime' );
|
||||
|
||||
// Only update seenTime in the API locally
|
||||
if ( !this.isExternal() ) {
|
||||
if ( !this.isForeign() ) {
|
||||
promise = this.getApi().updateSeenTime( type );
|
||||
} else {
|
||||
promise = $.Deferred().resolve();
|
||||
|
@ -365,7 +365,7 @@
|
|||
|
||||
this.markingAllAsRead = true;
|
||||
for ( i = 0, len = items.length; i < len; i++ ) {
|
||||
if ( !items[ i ].isExternal() ) {
|
||||
if ( !items[ i ].isForeign() ) {
|
||||
items[ i ].toggleRead( true );
|
||||
items[ i ].toggleSeen( true );
|
||||
}
|
||||
|
@ -448,13 +448,13 @@
|
|||
iconURL: content.iconUrl,
|
||||
iconType: content.icon,
|
||||
type: model.getType(),
|
||||
external: model.isExternal(),
|
||||
foreign: model.isForeign(),
|
||||
source: model.getSource(),
|
||||
primaryUrl: OO.getProp( content.links, 'primary', 'url' ),
|
||||
secondaryUrls: OO.getProp( content.links, 'secondary' ) || []
|
||||
};
|
||||
|
||||
if ( notifData.type === 'external' ) {
|
||||
if ( notifData.type === 'foreign' ) {
|
||||
// Define sources
|
||||
sources = {};
|
||||
for ( s = 0; s < notifData.sources.length; s++ ) {
|
||||
|
@ -471,11 +471,11 @@
|
|||
// type. Some types don't have read messages, but
|
||||
// some do
|
||||
removeReadNotifications: true,
|
||||
// Override the external flag to 'true' for cross-wiki
|
||||
// Override the foreign flag to 'true' for cross-wiki
|
||||
// notifications.
|
||||
// For bundles that are not external (like regular
|
||||
// For bundles that are not foreign (like regular
|
||||
// bundles of notifications) this flag should be false
|
||||
external: true,
|
||||
foreign: true,
|
||||
count: notifData.count
|
||||
} )
|
||||
);
|
||||
|
@ -654,12 +654,12 @@
|
|||
};
|
||||
|
||||
/**
|
||||
* This model is external
|
||||
* This model is foreign
|
||||
*
|
||||
* @return {boolean} Model is external
|
||||
* @return {boolean} Model is foreign
|
||||
*/
|
||||
mw.echo.dm.NotificationsModel.prototype.isExternal = function () {
|
||||
return this.external;
|
||||
mw.echo.dm.NotificationsModel.prototype.isForeign = function () {
|
||||
return this.foreign;
|
||||
};
|
||||
|
||||
} )( mediaWiki, jQuery );
|
||||
|
|
Loading…
Reference in a new issue