UX: Update the reviewable count before the message bus

UX: Update the reviewable count before the message bus

In certain edge cases, the message bus won’t send the message to the user about the updated review count and it can go out of sync.

This patch synchronizes the review count every time:

  1. The user visits the “Needs Review” page

  2. Every time the user performs an action

diff --git a/app/assets/javascripts/discourse/components/reviewable-item.js.es6 b/app/assets/javascripts/discourse/components/reviewable-item.js.es6
index 60a1faa..ffce8c8 100644
--- a/app/assets/javascripts/discourse/components/reviewable-item.js.es6
+++ b/app/assets/javascripts/discourse/components/reviewable-item.js.es6
@@ -48,9 +48,14 @@ export default Ember.Component.extend({
         }
       )
         .then(result => {
-          this.attrs.remove(
-            result.reviewable_perform_result.remove_reviewable_ids
-          );
+          let performResult = result.reviewable_perform_result;
+
+          // "fast track" to update the current user's reviewable count before the message bus finds out.
+          if (performResult.reviewable_count !== undefined) {
+            this.currentUser.set("reviewable_count", result.reviewable_count);
+          }
+
+          this.attrs.remove(performResult.remove_reviewable_ids);
         })
         .catch(popupAjaxError)
         .finally(() => this.set("updating", false));
diff --git a/app/assets/javascripts/discourse/routes/review-index.js.es6 b/app/assets/javascripts/discourse/routes/review-index.js.es6
index 8c47007..f925075 100644
--- a/app/assets/javascripts/discourse/routes/review-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/review-index.js.es6
@@ -9,6 +9,12 @@ export default Discourse.Route.extend({
 
   setupController(controller, model) {
     let meta = model.resultSetMeta;
+
+    // "fast track" to update the current user's reviewable count before the message bus finds out.
+    if (meta.reviewable_count !== undefined) {
+      this.currentUser.set("reviewable_count", meta.reviewable_count);
+    }
+
     controller.setProperties({
       reviewables: model,
       type: meta.type,
diff --git a/app/controllers/reviewables_controller.rb b/app/controllers/reviewables_controller.rb
index 04e7623..274e4ba 100644
--- a/app/controllers/reviewables_controller.rb
+++ b/app/controllers/reviewables_controller.rb
@@ -42,7 +42,8 @@ class ReviewablesController < ApplicationController
         result
       end,
       meta: filters.merge(
-        total_rows_reviewables: total_rows, types: meta_types, reviewable_types: Reviewable.types
+        total_rows_reviewables: total_rows, types: meta_types, reviewable_types: Reviewable.types,
+        reviewable_count: Reviewable.list_for(current_user).count
       )
     }
     if (offset + PER_PAGE) < total_rows
diff --git a/app/serializers/reviewable_perform_result_serializer.rb b/app/serializers/reviewable_perform_result_serializer.rb
index 813bc5f..d48964a 100644
--- a/app/serializers/reviewable_perform_result_serializer.rb
+++ b/app/serializers/reviewable_perform_result_serializer.rb
@@ -7,7 +7,8 @@ class ReviewablePerformResultSerializer < ApplicationSerializer
     :created_post_id,
     :created_post_topic_id,
     :remove_reviewable_ids,
-    :version
+    :version,
+    :reviewable_count
   )
 
   def success
@@ -37,4 +38,8 @@ class ReviewablePerformResultSerializer < ApplicationSerializer
   def include_created_post_topic_id?
     object.created_post_topic.present?
   end
+
+  def reviewable_count
+    Reviewable.list_for(scope.user).count
+  end
 end
diff --git a/spec/requests/reviewables_controller_spec.rb b/spec/requests/reviewables_controller_spec.rb
index 9362b37..bf06100 100644
--- a/spec/requests/reviewables_controller_spec.rb
+++ b/spec/requests/reviewables_controller_spec.rb
@@ -64,6 +64,9 @@ describe ReviewablesController do
 
         expect(json['users'].any? { |u| u['id'] == reviewable.created_by_id }).to eq(true)
         expect(json['users'].any? { |u| u['id'] == reviewable.target_created_by_id }).to eq(true)
+
+        expect(json['meta']['reviewable_count']).to eq(1)
+        expect(json['meta']['status']).to eq("pending")
       end
 
       it "supports filtering by score" do
@@ -274,6 +277,7 @@ describe ReviewablesController do
         expect(json['reviewable_perform_result']['transition_to']).to eq('approved')
         expect(json['reviewable_perform_result']['transition_to_id']).to eq(Reviewable.statuses[:approved])
         expect(json['reviewable_perform_result']['remove_reviewable_ids']).to eq([reviewable.id])
+        expect(json['reviewable_perform_result']['reviewable_count']).to eq(1)
 
         expect(reviewable.reload.version).to eq(1)
         expect(other_reviewable.reload.version).to eq(0)

GitHub sha: cbc311e4

This commit has been mentioned on Discourse Meta. There might be relevant details there: