Sbisson has uploaded a new change for review.

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

Change subject: [WIP] Stop counting notifications objects on the client
......................................................................

[WIP] Stop counting notifications objects on the client

Rely on the server to get the current unread notification count.

Bug: T129726
Change-Id: I9af4defc00dd491ed2b355eb4e85073476e08ce7
---
M modules/api/mw.echo.api.EchoApi.js
M modules/ooui/mw.echo.ui.NotificationBadgeWidget.js
M modules/viewmodel/mw.echo.dm.NotificationsModel.js
3 files changed, 61 insertions(+), 35 deletions(-)


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

diff --git a/modules/api/mw.echo.api.EchoApi.js 
b/modules/api/mw.echo.api.EchoApi.js
index 9366b16..4adfe59 100644
--- a/modules/api/mw.echo.api.EchoApi.js
+++ b/modules/api/mw.echo.api.EchoApi.js
@@ -85,7 +85,9 @@
         *  for that type in the given source
         */
        mw.echo.api.EchoApi.prototype.markItemsRead = function ( itemIds, 
source, isRead ) {
-               return this.network.getApiHandler( source ).markItemsRead( 
itemIds, isRead );
+               return this.network.getApiHandler( source ).markItemsRead( 
itemIds, isRead ).then( function ( response ) {
+                       return response.query.echomarkread;
+               } );
        };
 
        /**
diff --git a/modules/ooui/mw.echo.ui.NotificationBadgeWidget.js 
b/modules/ooui/mw.echo.ui.NotificationBadgeWidget.js
index d78a798..e3f05f0 100644
--- a/modules/ooui/mw.echo.ui.NotificationBadgeWidget.js
+++ b/modules/ooui/mw.echo.ui.NotificationBadgeWidget.js
@@ -235,6 +235,9 @@
                        this.updateIcon( !!unseenCount );
                }
 
+               if ( isNaN( unreadCount ) ) {
+                       return;
+               }
                // Update badge count
                if ( !this.markReadWhenSeen || !this.popup.isVisible() || 
unreadCount < this.currentUnreadCountInBadge ) {
                        wgEchoMaxNotificationCount = mw.config.get( 
'wgEchoMaxNotificationCount' );
diff --git a/modules/viewmodel/mw.echo.dm.NotificationsModel.js 
b/modules/viewmodel/mw.echo.dm.NotificationsModel.js
index a176080..3b99375 100644
--- a/modules/viewmodel/mw.echo.dm.NotificationsModel.js
+++ b/modules/viewmodel/mw.echo.dm.NotificationsModel.js
@@ -49,7 +49,6 @@
 
                // Store references to unseen and unread notifications
                this.unseenNotifications = new mw.echo.dm.NotificationList();
-               this.unreadNotifications = new mw.echo.dm.NotificationList();
 
                // Events
                this.aggregate( {
@@ -176,7 +175,8 @@
         * @fires unreadChange
         */
        mw.echo.dm.NotificationsModel.prototype.onItemRead = function ( item, 
isRead ) {
-               var id = item && item.getId();
+               var model = this,
+                       id = item && item.getId();
 
                // Update unread status and emit events
                if ( isRead ) {
@@ -184,25 +184,21 @@
                        // because the API takes a single request to mark all 
notifications
                        // as read, and we don't need to send multiple 
individual requests.
                        if ( !this.markingAllAsRead ) {
-                               this.toggleItemsReadInApi( id, isRead );
+                               this.decrementUnreadCount();
+                               this.toggleItemsReadInApi( id, isRead ).then( 
function ( data ) {
+                                       model.setUnreadCount( data[ 
model.getType() ].rawcount, false );
+                               } );
                        }
                        if ( this.removeReadNotifications ) {
                                // Remove this notification from the model
                                this.removeItems( [ item ] );
                        }
-                       // Remove the item from the counter after all other 
operations
-                       // finished, since some of the operations check if 
there are any
-                       // unread notifications to begin with.
-                       this.unreadNotifications.removeItems( [ item ] );
+
                } else {
-                       this.toggleItemsReadInApi( id, isRead );
-                       this.unreadNotifications.addItems( [ item ] );
-               }
-
-               this.emit( 'unreadChange', this.unreadNotifications.getItems() 
);
-
-               if ( this.unreadNotifications.isEmpty() ) {
-                       this.emit( 'allRead' );
+                       this.incrementUnreadCount();
+                       this.toggleItemsReadInApi( id, isRead ).then( function 
( data ) {
+                               model.setUnreadCount( data[ model.getType() 
].rawcount, false );
+                       } );
                }
 
                if ( !this.countUnreadTalkPageNotifications() ) {
@@ -232,7 +228,7 @@
        
mw.echo.dm.NotificationsModel.prototype.countUnreadTalkPageNotifications = 
function () {
                var i, len,
                        talk = 0,
-                       items = this.unreadNotifications.getItems();
+                       items = this.getItems();
 
                for ( i = 0, len = items.length; i < len; i++ ) {
                        if ( items[ i ].getCategory() === 'edit-user-talk' ) {
@@ -267,7 +263,34 @@
         * @return {number} Number of unread notifications
         */
        mw.echo.dm.NotificationsModel.prototype.getUnreadCount = function () {
-               return this.unreadNotifications.getNotificationCount();
+               return this.unreadCount;
+       };
+
+       mw.echo.dm.NotificationsModel.prototype.decrementUnreadCount = function 
( count ) {
+               count = count || 1;
+               return this.setUnreadCount( Math.max( 0, this.unreadCount - 
count ), true );
+       };
+
+       mw.echo.dm.NotificationsModel.prototype.incrementUnreadCount = function 
() {
+               return this.setUnreadCount( Math.min( 100, this.unreadCount + 1 
), true );
+       };
+
+       mw.echo.dm.NotificationsModel.prototype.setUnreadCount = function ( 
unreadCount, estimation ) {
+               var MAX = 99;
+               if ( estimation && this.unreadCount > MAX ) {
+                       // we don't really know how many there is
+                       return;
+               }
+
+               if ( this.unreadCount !== unreadCount ) {
+                       if ( estimation ) {
+                               console.log('estimating unread count to', 
unreadCount);
+                       } else {
+                               console.log( 'actual unread count is', 
unreadCount );
+                       }
+                       this.unreadCount = unreadCount;
+                       this.emit( 'unreadChange' );
+               }
        };
 
        /**
@@ -357,8 +380,9 @@
         * @fires empty
         */
        mw.echo.dm.NotificationsModel.prototype.markAllRead = function () {
-               var i, len,
-                       items = this.unreadNotifications.getItems(),
+               var model = this,
+                       i, len, item,
+                       items = this.getItems(),
                        itemIds = [],
                        length = items.length;
 
@@ -382,17 +406,19 @@
 
                this.markingAllAsRead = true;
                for ( i = 0, len = items.length; i < len; i++ ) {
+                       item = items[ i ];
                        // Skip items that are foreign if we are in automatic 
'mark all as read'
-                       if ( !items[ i ].isForeign() ) {
-                               items[ i ].toggleRead( true );
-                               items[ i ].toggleSeen( true );
-                               this.unreadNotifications.removeItems( [ items[ 
i ] ] );
+                       if ( !item.isForeign() && !item.isRead() ) {
+                               item.toggleRead( true );
+                               item.toggleSeen( true );
                                itemIds.push( items[ i ].getId() );
                        }
                }
                this.markingAllAsRead = false;
-
-               return this.api.markItemsRead( itemIds, this.getSource(), 
this.getType() );
+               this.decrementUnreadCount( itemIds.length );
+               return this.api.markItemsRead( itemIds, this.getSource(), true 
).then( function(data){
+                       model.setUnreadCount( data[ model.getType() ].rawcount 
);
+               } );
        };
 
        /**
@@ -425,10 +451,6 @@
        mw.echo.dm.NotificationsModel.prototype.toggleItemsReadInApi = function 
( itemIds, isRead ) {
                itemIds = $.isArray( itemIds ) ? itemIds : [ itemIds ];
 
-               if ( isRead && !this.unreadNotifications.getItemCount() ) {
-                       return $.Deferred().resolve( 0 ).promise();
-               }
-
                return this.api.markItemsRead( itemIds, this.getSource(), 
isRead );
        };
 
@@ -460,6 +482,10 @@
         */
        mw.echo.dm.NotificationsModel.prototype.fetchNotifications = function ( 
isForced ) {
                var model = this;
+
+               this.fetchUnreadCountFromApi().then( function ( count ) {
+                       model.setUnreadCount( count, false );
+               } );
 
                // Rebuild the notifications promise either when it is null or 
when
                // it exists in a failed state
@@ -575,9 +601,6 @@
                var i, len;
 
                for ( i = 0, len = items.length; i < len; i++ ) {
-                       if ( !items[ i ].isRead() ) {
-                               this.unreadNotifications.addItems( [ items[ i ] 
] );
-                       }
                        if ( !items[ i ].isSeen() ) {
                                this.unseenNotifications.addItems( [ items[ i ] 
] );
                        }
@@ -596,7 +619,6 @@
                var i, len;
 
                for ( i = 0, len = items.length; i < len; i++ ) {
-                       this.unreadNotifications.removeItems( [ items[ i ] ] );
                        this.unseenNotifications.removeItems( [ items[ i ] ] );
                }
 
@@ -612,7 +634,6 @@
         * Update the unread and unseen tracking lists when we clear items
         */
        mw.echo.dm.NotificationsModel.prototype.clearItems = function () {
-               this.unreadNotifications.clearItems();
                this.unseenNotifications.clearItems();
 
                // Parent

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9af4defc00dd491ed2b355eb4e85073476e08ce7
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Echo
Gerrit-Branch: master
Gerrit-Owner: Sbisson <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to