From a64cb948ed9b954f715db2063cdacb41f177684a Mon Sep 17 00:00:00 2001 From: Krzysztof Kotlarek Date: Wed, 21 Jun 2023 13:42:30 +1000 Subject: [PATCH] FIX: update unread and new count for categories (#22145) There is a problem that unread and new count is not updated to reflecting topicTrackingState. It is because discourseComputed on Category is not working properly with topicTrackingState. Moving it to component level is making counter reliable. --- .../app/components/category-list-item.js | 10 ++++++ .../app/components/category-unread.hbs | 15 ++++---- .../app/components/parent-category-row.hbs | 2 ++ .../app/components/sub-category-item.hbs | 6 +++- .../discourse/app/models/category.js | 18 +++++----- .../app/widgets/hamburger-categories.js | 4 +-- .../discourse/app/widgets/hamburger-menu.js | 8 ++--- spec/system/category_topics_spec.rb | 22 ++++++++++++ .../page_objects/components/category_list.rb | 35 +++++++++++++++++++ 9 files changed, 94 insertions(+), 26 deletions(-) create mode 100644 spec/system/category_topics_spec.rb create mode 100644 spec/system/page_objects/components/category_list.rb diff --git a/app/assets/javascripts/discourse/app/components/category-list-item.js b/app/assets/javascripts/discourse/app/components/category-list-item.js index 468ce928c75..12e41368404 100644 --- a/app/assets/javascripts/discourse/app/components/category-list-item.js +++ b/app/assets/javascripts/discourse/app/components/category-list-item.js @@ -26,4 +26,14 @@ export default Component.extend({ (!isMutedCategory && listType === LIST_TYPE.MUTED) ); }, + + @discourseComputed("topicTrackingState.messageCount") + unreadTopicsCount() { + return this.category.unreadTopicsCount; + }, + + @discourseComputed("topicTrackingState.messageCount") + newTopicsCount() { + return this.category.newTopicsCount; + }, }); diff --git a/app/assets/javascripts/discourse/app/components/category-unread.hbs b/app/assets/javascripts/discourse/app/components/category-unread.hbs index 0021e01260f..459ccc57945 100644 --- a/app/assets/javascripts/discourse/app/components/category-unread.hbs +++ b/app/assets/javascripts/discourse/app/components/category-unread.hbs @@ -1,20 +1,17 @@ -{{#if this.category.unreadTopics}} +{{#if this.unreadTopicsCount}} {{i18n "filters.unread.lower_title_with_count" - count=this.category.unreadTopics + count=this.unreadTopicsCount }} {{/if}} -{{#if this.category.newTopics}} +{{#if this.newTopicsCount}} {{i18n - "filters.new.lower_title_with_count" - count=this.category.newTopics - }} + >{{i18n "filters.new.lower_title_with_count" count=this.newTopicsCount}} {{/if}} \ No newline at end of file diff --git a/app/assets/javascripts/discourse/app/components/parent-category-row.hbs b/app/assets/javascripts/discourse/app/components/parent-category-row.hbs index 8b521eef36f..151bf4d8f91 100644 --- a/app/assets/javascripts/discourse/app/components/parent-category-row.hbs +++ b/app/assets/javascripts/discourse/app/components/parent-category-row.hbs @@ -67,6 +67,8 @@ @category={{this.category}} @tagName="div" @class="unread-new" + @unreadTopicsCount={{this.unreadTopicsCount}} + @newTopicsCount={{this.newTopicsCount}} /> diff --git a/app/assets/javascripts/discourse/app/components/sub-category-item.hbs b/app/assets/javascripts/discourse/app/components/sub-category-item.hbs index a8d88651f1a..dadf3b9801d 100644 --- a/app/assets/javascripts/discourse/app/components/sub-category-item.hbs +++ b/app/assets/javascripts/discourse/app/components/sub-category-item.hbs @@ -3,7 +3,11 @@ {{category-link this.category hideParent="true"}} {{#unless this.hideUnread}} - + {{/unless}} {{/unless}} \ No newline at end of file diff --git a/app/assets/javascripts/discourse/app/models/category.js b/app/assets/javascripts/discourse/app/models/category.js index 5101056328d..8bb0f762d92 100644 --- a/app/assets/javascripts/discourse/app/models/category.js +++ b/app/assets/javascripts/discourse/app/models/category.js @@ -198,6 +198,14 @@ const Category = RestModel.extend({ return notificationLevel >= NotificationLevels.TRACKING; }, + get unreadTopicsCount() { + return this.topicTrackingState.countUnread({ categoryId: this.id }); + }, + + get newTopicsCount() { + return this.topicTrackingState.countNew({ categoryId: this.id }); + }, + save() { const id = this.id; const url = id ? `/categories/${id}` : "/categories"; @@ -310,16 +318,6 @@ const Category = RestModel.extend({ } }, - @discourseComputed("id", "topicTrackingState.messageCount") - unreadTopics(id) { - return this.topicTrackingState.countUnread({ categoryId: id }); - }, - - @discourseComputed("id", "topicTrackingState.messageCount") - newTopics(id) { - return this.topicTrackingState.countNew({ categoryId: id }); - }, - setNotification(notification_level) { User.currentProp( "muted_category_ids", diff --git a/app/assets/javascripts/discourse/app/widgets/hamburger-categories.js b/app/assets/javascripts/discourse/app/widgets/hamburger-categories.js index 8ef945c88b2..c48bbfb8e97 100644 --- a/app/assets/javascripts/discourse/app/widgets/hamburger-categories.js +++ b/app/assets/javascripts/discourse/app/widgets/hamburger-categories.js @@ -19,8 +19,8 @@ createWidget("hamburger-category", { this.attach("category-link", { category: c, allowUncategorized: true }), ]; - const unreadTotal = - parseInt(c.get("unreadTopics"), 10) + parseInt(c.get("newTopics"), 10); + const unreadTotal = c.unreadTopicsCount + c.newTopicsCount; + if (unreadTotal) { results.push( h( diff --git a/app/assets/javascripts/discourse/app/widgets/hamburger-menu.js b/app/assets/javascripts/discourse/app/widgets/hamburger-menu.js index b6ba869b6c8..67b3b9e7a93 100644 --- a/app/assets/javascripts/discourse/app/widgets/hamburger-menu.js +++ b/app/assets/javascripts/discourse/app/widgets/hamburger-menu.js @@ -198,12 +198,12 @@ export default createWidget("hamburger-menu", { .filter((c) => c.notification_level !== NotificationLevels.MUTED); categories = allCategories - .filter((c) => c.get("newTopics") > 0 || c.get("unreadTopics") > 0) + .filter((c) => c.newTopicsCount > 0 || c.unreadTopicsCount > 0) .sort((a, b) => { return ( - b.get("newTopics") + - b.get("unreadTopics") - - (a.get("newTopics") + a.get("unreadTopics")) + b.newTopicsCount + + b.unreadTopicsCount - + (a.unreadTopicsCount + a.newTopicsCount) ); }); diff --git a/spec/system/category_topics_spec.rb b/spec/system/category_topics_spec.rb new file mode 100644 index 00000000000..1544ac27cdc --- /dev/null +++ b/spec/system/category_topics_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +describe "Viewing top topics on categories page", type: :system, js: true do + fab!(:user) { Fabricate(:user) } + let(:category_list) { PageObjects::Components::CategoryList.new } + fab!(:category) { Fabricate(:category) } + fab!(:topic) { Fabricate(:topic, category: category) } + + it "displays and updates new counter" do + sign_in(user) + + visit("/categories") + + category_list.click_new_posts_badge(count: 1) + category_list.click_topic(topic) + category_list.click_logo + category_list.click_category_navigation + + expect(category_list).to have_category(category) + expect(category_list).to have_no_new_posts_badge + end +end diff --git a/spec/system/page_objects/components/category_list.rb b/spec/system/page_objects/components/category_list.rb new file mode 100644 index 00000000000..49e000bf7d7 --- /dev/null +++ b/spec/system/page_objects/components/category_list.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module PageObjects + module Components + class CategoryList < PageObjects::Components::Base + def has_category?(category) + page.has_css?("tr[data-category-id='#{category.id}']") + end + + def has_topic?(topic) + page.has_css?(topic_list_item_class(topic)) + end + + def has_no_new_posts_badge? + page.has_no_css?(".new-posts") + end + + def click_category_navigation + page.find(".nav-pills .categories").click + end + + def click_logo + page.find(".title a").click + end + + def click_new_posts_badge(count: 1) + page.find(".new-posts", text: "#{count} new").click + end + + def click_topic(topic) + page.find("a", text: topic.title).click + end + end + end +end