Catrope has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/273569

Change subject: [WIP] In cross-wiki notifications, sort wikis by timestamp of 
most recent notification
......................................................................

[WIP] In cross-wiki notifications, sort wikis by timestamp of most recent 
notification

Also make the wiki mentioned in the message be the one with the
most recent notification.

ForeignNotifications tracks timestamps per wiki per section,
and exposes these through getWikiTimestamp(). ApiEchoNotifications
adds these timestamps to the sources manifest, and also sorts
the list of wikis by timestamp (it'd be nicer to do this in
ForeignPresentationModel instead, but then we'd have to create a new
ForeignNotifications instance which causes a duplicated DB query).

NotificationsModel receives the timestamp for its wiki as its
fallback timestamp, and makes getTimestamp() return this value
during the pre-population phase. This causes its parent to
automatically sort it correctly.

Change-Id: Ie083fbb1ccaf74fbe804633d87ef03c9e71b120f
---
M includes/ForeignNotifications.php
M includes/api/ApiEchoNotifications.php
M modules/viewmodel/mw.echo.dm.NotificationGroupItem.js
M modules/viewmodel/mw.echo.dm.NotificationsModel.js
4 files changed, 44 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Echo 
refs/changes/69/273569/1

diff --git a/includes/ForeignNotifications.php 
b/includes/ForeignNotifications.php
index d75fcba..ccf18ab 100644
--- a/includes/ForeignNotifications.php
+++ b/includes/ForeignNotifications.php
@@ -22,6 +22,11 @@
        protected $timestamps = array( EchoAttributeManager::ALERT => false, 
EchoAttributeManager::MESSAGE => false );
 
        /**
+        * @var array [(str) wiki => [ (str) section => (MWTimestamp) 
timestamp, ...], ...]
+        */
+       protected $wikiTimestamps = array();
+
+       /**
         * @var bool
         */
        protected $populated = false;
@@ -92,6 +97,25 @@
                return isset( $this->wikis[$section] ) ? $this->wikis[$section] 
: array();
        }
 
+       public function getWikiTimestamp( $wiki, $section = null ) {
+               $this->populate();
+               if ( !isset( $this->wikiTimestamps[$wiki] ) ) {
+                       return false;
+               }
+               if ( $section === null ) {
+                       $max = false;
+                       foreach ( $this->wikiTimestamps[$wiki] as $section => 
$ts ) {
+                               // $ts < $max = invert 0
+                               // $ts > $max = invert 1
+                               if ( $max === false || $ts->diff( $max 
)->invert === 1 ) {
+                                       $max = $ts;
+                               }
+                       }
+                       return $max;
+               }
+               return isset( $this->wikiTimestamps[$wiki][$section] ) ? 
$this->wikiTimestamps[$wiki][$section] : false;
+       }
+
        protected function populate() {
                if ( $this->populated ) {
                        return;
@@ -118,6 +142,8 @@
                                        $this->wikis[$section][] = $wiki;
 
                                        $timestamp = new MWTimestamp( 
$data['ts'] );
+                                       $this->wikiTimestamps[$wiki][$section] 
= $timestamp;
+
                                        // We need $this->timestamp[$section] 
to be the max timestamp
                                        // across all wikis.
                                        // $timestamp < 
$this->timestamps[$section] = invert 0
diff --git a/includes/api/ApiEchoNotifications.php 
b/includes/api/ApiEchoNotifications.php
index 4353134..33d08a3 100644
--- a/includes/api/ApiEchoNotifications.php
+++ b/includes/api/ApiEchoNotifications.php
@@ -89,6 +89,11 @@
                        // can be queried from
                        if ( $foreignNotifications ) {
                                $result['sources'] = 
$foreignNotifications->getApiEndpoints( $foreignNotifications->getWikis() );
+                               // Add timestamp information
+                               foreach ( $result['sources'] as $wiki => &$data 
) {
+                                       // FIXME: getWikiTimestamp() needs 
$section but we don't have that here
+                                       $data['ts'] = 
$foreignNotifications->getWikiTimestamp( $wiki )->getTimestamp( TS_MW );
+                               }
                        }
                }
 
@@ -285,6 +290,13 @@
                $wikis = $foreignNotifications->getWikis( $section );
                $count = $foreignNotifications->getCount( $section );
 
+               // Sort wikis by timestamp, in descending order (newest first)
+               usort( $wikis, function ( $a, $b ) use ( $foreignNotifications, 
$section ) {
+                       $aTimestamp = $foreignNotifications->getWikiTimestamp( 
$a, $section ) ?: new MWTimestamp( 0 );
+                       $bTimestamp = $foreignNotifications->getWikiTimestamp( 
$b, $section ) ?: new MWTimestamp( 0 );
+                       return $bTimestamp->getTimestamp( TS_UNIX ) - 
$aTimestamp->getTimestamp( TS_UNIX );
+               } );
+
                $row = new StdClass;
                $row->event_id = -1;
                $row->event_type = 'foreign';
diff --git a/modules/viewmodel/mw.echo.dm.NotificationGroupItem.js 
b/modules/viewmodel/mw.echo.dm.NotificationGroupItem.js
index b8e617a..4c34e7b 100644
--- a/modules/viewmodel/mw.echo.dm.NotificationGroupItem.js
+++ b/modules/viewmodel/mw.echo.dm.NotificationGroupItem.js
@@ -65,7 +65,8 @@
                                        source: source,
                                        foreign: this.foreign,
                                        title: this.sources[ source ].title,
-                                       removeReadNotifications: 
this.removeReadNotifications
+                                       removeReadNotifications: 
this.removeReadNotifications,
+                                       timestamp: this.sources[ source ].ts
                                }
                        );
                        items.push( item );
diff --git a/modules/viewmodel/mw.echo.dm.NotificationsModel.js 
b/modules/viewmodel/mw.echo.dm.NotificationsModel.js
index 79f3715..d9e708d 100644
--- a/modules/viewmodel/mw.echo.dm.NotificationsModel.js
+++ b/modules/viewmodel/mw.echo.dm.NotificationsModel.js
@@ -18,6 +18,8 @@
         *  the source of the notification items for the network handler.
         * @cfg {number} [limit=25] Notification limit
         * @cfg {string} [userLang] User language
+        * @cfg {number} [timestamp] Timestamp (in MW format) to return from 
#getTimestamp when
+        *  there are no items; use this if the timestamp is known ahead of 
time (before population).
         * @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
@@ -36,6 +38,7 @@
                this.source = config.source || 'local';
                this.id = config.id || this.source;
                this.title = config.title || '';
+               this.fallbackTimestamp = config.timestamp;
 
                this.markingAllAsRead = false;
                this.autoMarkReadInProcess = false;
@@ -682,7 +685,7 @@
 
                // This is a sorted list, so the top (first) item is also the 
'latest'
                // item for this purpose.
-               return items[ 0 ] && items[ 0 ].getTimestamp();
+               return ( items[ 0 ] && items[ 0 ].getTimestamp() ) || 
this.fallbackTimestamp;
        };
 
        /**

-- 
To view, visit https://gerrit.wikimedia.org/r/273569
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie083fbb1ccaf74fbe804633d87ef03c9e71b120f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Echo
Gerrit-Branch: master
Gerrit-Owner: Catrope <roan.katt...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to