From a8502ae1c429ece6980f8eb7b064eab4894c2365 Mon Sep 17 00:00:00 2001 From: Vinoth Kannan Date: Thu, 27 Aug 2020 23:04:45 +0530 Subject: [PATCH] FEATURE: add dismiss unread topics button when filtered by tag. (#10547) --- .../discourse/app/controllers/tags-show.js | 25 ++++++++++++++-- .../app/mixins/bulk-topic-selection.js | 9 ++---- .../javascripts/discourse/app/models/topic.js | 15 +++++++--- .../discourse/app/routes/discovery.js | 1 + .../discourse/app/routes/tags-show.js | 29 ++++++++++++++++++- .../discourse/app/templates/tags/show.hbs | 20 +++++++++---- app/controllers/topics_controller.rb | 5 ++++ config/locales/client.en.yml | 10 ++----- spec/requests/topics_controller_spec.rb | 20 +++++++++++++ 9 files changed, 105 insertions(+), 29 deletions(-) diff --git a/app/assets/javascripts/discourse/app/controllers/tags-show.js b/app/assets/javascripts/discourse/app/controllers/tags-show.js index 42d6bceefc1..a2eb9af26ec 100644 --- a/app/assets/javascripts/discourse/app/controllers/tags-show.js +++ b/app/assets/javascripts/discourse/app/controllers/tags-show.js @@ -7,6 +7,7 @@ import NavItem from "discourse/models/nav-item"; import FilterModeMixin from "discourse/mixins/filter-mode"; import { queryParams } from "discourse/controllers/discovery-sortable"; import bootbox from "bootbox"; +import showModal from "discourse/lib/show-modal"; export default Controller.extend(BulkTopicSelection, FilterModeMixin, { application: controller(), @@ -88,7 +89,7 @@ export default Controller.extend(BulkTopicSelection, FilterModeMixin, { @discourseComputed("navMode", "list.topics.length", "loading") footerMessage(navMode, listTopicsLength, loading) { - if (loading || listTopicsLength !== 0) { + if (loading) { return; } @@ -97,13 +98,29 @@ export default Controller.extend(BulkTopicSelection, FilterModeMixin, { tag: this.get("tag.id") }); } else { - return I18n.t(`tagging.topics.bottom.${navMode}`, { + return I18n.t(`topics.bottom.tag`, { tag: this.get("tag.id") }); } }, + isFilterPage: function(filter, filterType) { + if (!filter) { + return false; + } + return filter.match(new RegExp(filterType + "$", "gi")) ? true : false; + }, + + @discourseComputed("list.filter", "list.topics.length") + showDismissRead(filter, topicsLength) { + return this.isFilterPage(filter, "unread") && topicsLength > 0; + }, + actions: { + dismissReadPosts() { + showModal("dismiss-read", { title: "topics.bulk.dismiss_read" }); + }, + changeSort(order) { if (order === this.order) { this.toggleProperty("ascending"); @@ -122,7 +139,9 @@ export default Controller.extend(BulkTopicSelection, FilterModeMixin, { refresh() { return this.store - .findFiltered("topicList", { filter: "tags/" + this.get("tag.id") }) + .findFiltered("topicList", { + filter: this.get("list.filter") + }) .then(list => { this.set("list", list); this.resetSelected(); diff --git a/app/assets/javascripts/discourse/app/mixins/bulk-topic-selection.js b/app/assets/javascripts/discourse/app/mixins/bulk-topic-selection.js index cc2dfc1d55b..e1c67993b74 100644 --- a/app/assets/javascripts/discourse/app/mixins/bulk-topic-selection.js +++ b/app/assets/javascripts/discourse/app/mixins/bulk-topic-selection.js @@ -21,7 +21,7 @@ export default Mixin.create({ this.selected.clear(); }, - dismissRead(operationType, categoryOptions) { + dismissRead(operationType, options) { let operation; if (operationType === "posts") { operation = { type: "dismiss_posts" }; @@ -36,12 +36,7 @@ export default Mixin.create({ if (this.selected.length > 0) { promise = Topic.bulkOperation(this.selected, operation); } else { - promise = Topic.bulkOperationByFilter( - "unread", - operation, - this.get("category.id"), - categoryOptions - ); + promise = Topic.bulkOperationByFilter("unread", operation, options); } promise.then(result => { diff --git a/app/assets/javascripts/discourse/app/models/topic.js b/app/assets/javascripts/discourse/app/models/topic.js index 145fd2a2a5c..5cbaf1449fb 100644 --- a/app/assets/javascripts/discourse/app/models/topic.js +++ b/app/assets/javascripts/discourse/app/models/topic.js @@ -800,14 +800,21 @@ Topic.reopenClass({ }); }, - bulkOperationByFilter(filter, operation, categoryId, options) { + bulkOperationByFilter(filter, operation, options) { let data = { filter, operation }; - if (options && options.includeSubcategories) { - data.include_subcategories = true; + if (options) { + if (options.categoryId) { + data.category_id = options.categoryId; + } + if (options.includeSubcategories) { + data.include_subcategories = true; + } + if (options.tagName) { + data.tag_name = options.tagName; + } } - if (categoryId) data.category_id = categoryId; return ajax("/topics/bulk", { type: "PUT", data diff --git a/app/assets/javascripts/discourse/app/routes/discovery.js b/app/assets/javascripts/discourse/app/routes/discovery.js index 43f030d9abd..32bf3b6c77c 100644 --- a/app/assets/javascripts/discourse/app/routes/discovery.js +++ b/app/assets/javascripts/discourse/app/routes/discovery.js @@ -75,6 +75,7 @@ export default DiscourseRoute.extend(OpenComposer, { dismissRead(operationType) { const controller = this.controllerFor("discovery/topics"); controller.send("dismissRead", operationType, { + categoryId: controller.get("category.id"), includeSubcategories: !controller.noSubcategories }); } diff --git a/app/assets/javascripts/discourse/app/routes/tags-show.js b/app/assets/javascripts/discourse/app/routes/tags-show.js index 1b264249920..fdbd0baf7cd 100644 --- a/app/assets/javascripts/discourse/app/routes/tags-show.js +++ b/app/assets/javascripts/discourse/app/routes/tags-show.js @@ -6,7 +6,10 @@ import { filterQueryParams, findTopicList } from "discourse/routes/build-topic-route"; -import { queryParams } from "discourse/controllers/discovery-sortable"; +import { + resetParams, + queryParams +} from "discourse/controllers/discovery-sortable"; import PermissionType from "discourse/models/permission-type"; import Category from "discourse/models/category"; import FilterModeMixin from "discourse/mixins/filter-mode"; @@ -207,6 +210,30 @@ export default DiscourseRoute.extend(FilterModeMixin, { } }, + dismissReadTopics(dismissTopics) { + const operationType = dismissTopics ? "topics" : "posts"; + this.send("dismissRead", operationType); + }, + + dismissRead(operationType) { + const controller = this.controllerFor("tags-show"); + let options = { + tagName: controller.get("tag.id") + }; + const categoryId = controller.get("category.id"); + + if (categoryId) { + options = $.extend({}, options, { + categoryId: categoryId, + includeSubcategories: !controller.noSubcategories + }); + } + + controller.send("dismissRead", operationType, options); + }, + + resetParams, + didTransition() { this.controllerFor("tags.show")._showFooter(); return true; diff --git a/app/assets/javascripts/discourse/app/templates/tags/show.hbs b/app/assets/javascripts/discourse/app/templates/tags/show.hbs index e30edee3cfb..dded4a10840 100644 --- a/app/assets/javascripts/discourse/app/templates/tags/show.hbs +++ b/app/assets/javascripts/discourse/app/templates/tags/show.hbs @@ -82,13 +82,21 @@ changeSort=(action "changeSort") }} {{/discovery-topics-list}} - {{else}} - {{/if}} + {{/unless}} {{conditional-loading-spinner condition=list.loadingMore}} diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 583d7ebeedb..3db2290855f 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -856,6 +856,11 @@ class TopicsController < ApplicationController topics = topics.where('category_id = ?', params[:category_id]) end end + + if params[:tag_name].present? + topics = topics.joins(:tags).where("tags.name": params[:tag_name]) + end + topic_ids = topics.pluck(:id) else raise ActionController::ParameterMissing.new(:topic_ids) diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index c833c9361da..072638439e5 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -2166,6 +2166,7 @@ en: new: "There are no more new topics." unread: "There are no more unread topics." category: "There are no more %{category} topics." + tag: "There are no more %{tag} topics." top: "There are no more top topics." bookmarks: "There are no more bookmarked topics." @@ -2256,6 +2257,7 @@ en: bumped_at_title_MF: "{FIRST_POST}: {CREATED_AT}\n{LAST_POST}: {BUMPED_AT}" browse_all_categories: Browse all categories + browse_all_tags: Browse all tags view_latest_topics: view latest topics suggest_create_topic: Why not create a topic? @@ -3388,14 +3390,6 @@ en: latest: "There are no latest topics." bookmarks: "You have no bookmarked topics yet." top: "There are no top topics." - bottom: - latest: "There are no more latest topics." - posted: "There are no more posted topics." - read: "There are no more read topics." - new: "There are no more new topics." - unread: "There are no more unread topics." - top: "There are no more top topics." - bookmarks: "There are no more bookmarked topics." invite: custom_message: "Make your invite a little bit more personal by writing a custom message." diff --git a/spec/requests/topics_controller_spec.rb b/spec/requests/topics_controller_spec.rb index 17a896bac93..34ffad5d68a 100644 --- a/spec/requests/topics_controller_spec.rb +++ b/spec/requests/topics_controller_spec.rb @@ -2505,6 +2505,26 @@ RSpec.describe TopicsController do expect(TopicUser.get(post1.topic, post1.user).last_read_post_number).to eq(2) end + it "can mark tag topics unread" do + tag = Fabricate(:tag) + TopicTag.create!( + topic_id: topic.id, + tag_id: tag.id + ) + + post1 = create_post(user: user, topic_id: topic.id) + create_post(topic_id: topic.id) + + put "/topics/bulk.json", params: { + tag_name: tag.name, + filter: 'unread', + operation: { type: 'dismiss_posts' } + } + + expect(response.status).to eq(200) + expect(TopicUser.get(post1.topic, post1.user).last_read_post_number).to eq(2) + end + it "can find unread" do # mark all unread muted put "/topics/bulk.json", params: {