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: {