FIX: mark topics in sub categories as unread when dismissing parent

Previously we would only dismiss the parent category and leave the
child categories unread
This commit is contained in:
Sam Saffron 2019-06-27 13:26:07 +10:00
parent 79d657203d
commit 5bc5c02af6
6 changed files with 54 additions and 14 deletions

View File

@ -18,7 +18,7 @@ export default Ember.Mixin.create({
this.selected.clear(); this.selected.clear();
}, },
dismissRead(operationType) { dismissRead(operationType, categoryOptions) {
let operation; let operation;
if (operationType === "posts") { if (operationType === "posts") {
operation = { type: "dismiss_posts" }; operation = { type: "dismiss_posts" };
@ -36,7 +36,8 @@ export default Ember.Mixin.create({
promise = Discourse.Topic.bulkOperationByFilter( promise = Discourse.Topic.bulkOperationByFilter(
"unread", "unread",
operation, operation,
this.get("category.id") this.get("category.id"),
categoryOptions
); );
} }

View File

@ -733,8 +733,13 @@ Topic.reopenClass({
}); });
}, },
bulkOperationByFilter(filter, operation, categoryId) { bulkOperationByFilter(filter, operation, categoryId, options) {
const data = { filter, operation }; let data = { filter, operation };
if (options && options.includeSubcategories) {
data.include_subcategories = true;
}
if (categoryId) data.category_id = categoryId; if (categoryId) data.category_id = categoryId;
return ajax("/topics/bulk", { return ajax("/topics/bulk", {
type: "PUT", type: "PUT",

View File

@ -60,12 +60,15 @@ export default Discourse.Route.extend(OpenComposer, {
}, },
dismissReadTopics(dismissTopics) { dismissReadTopics(dismissTopics) {
var operationType = dismissTopics ? "topics" : "posts"; const operationType = dismissTopics ? "topics" : "posts";
this.controllerFor("discovery/topics").send("dismissRead", operationType); this.send("dismissRead", operationType);
}, },
dismissRead(operationType) { dismissRead(operationType) {
this.controllerFor("discovery/topics").send("dismissRead", operationType); const controller = this.controllerFor("discovery/topics");
controller.send("dismissRead", operationType, {
includeSubcategories: !controller.noSubcategories
});
} }
} }
}); });

View File

@ -779,7 +779,17 @@ class TopicsController < ApplicationController
elsif params[:filter] == 'unread' elsif params[:filter] == 'unread'
tq = TopicQuery.new(current_user) tq = TopicQuery.new(current_user)
topics = TopicQuery.unread_filter(tq.joined_topic_user, current_user.id, staff: guardian.is_staff?).listable_topics topics = TopicQuery.unread_filter(tq.joined_topic_user, current_user.id, staff: guardian.is_staff?).listable_topics
topics = topics.where('category_id = ?', params[:category_id]) if params[:category_id]
if params[:category_id]
if params[:include_subcategories]
topics = topics.where(<<~SQL, category_id: params[:category_id])
category_id in (select id FROM categories WHERE parent_category_id = :category_id) OR
category_id = :category_id
SQL
else
topics = topics.where('category_id = ?', params[:category_id])
end
end
topic_ids = topics.pluck(:id) topic_ids = topics.pluck(:id)
else else
raise ActionController::ParameterMissing.new(:topic_ids) raise ActionController::ParameterMissing.new(:topic_ids)

View File

@ -68,12 +68,12 @@ class TopicsBulkAction
end end
def dismiss_posts def dismiss_posts
sql = " sql = <<~SQL
UPDATE topic_users tu UPDATE topic_users tu
SET highest_seen_post_number = t.highest_post_number , last_read_post_number = highest_post_number SET highest_seen_post_number = t.highest_post_number , last_read_post_number = highest_post_number
FROM topics t FROM topics t
WHERE t.id = tu.topic_id AND tu.user_id = :user_id AND t.id IN (:topic_ids) WHERE t.id = tu.topic_id AND tu.user_id = :user_id AND t.id IN (:topic_ids)
" SQL
DB.exec(sql, user_id: @user.id, topic_ids: @topic_ids) DB.exec(sql, user_id: @user.id, topic_ids: @topic_ids)
@changed_ids.concat @topic_ids @changed_ids.concat @topic_ids

View File

@ -2039,6 +2039,27 @@ RSpec.describe TopicsController do
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
it "can mark sub-categories unread" do
# TODO do we want to skip category definition by default in fabricator
category = Fabricate(:category, skip_category_definition: true)
sub = Fabricate(:category, parent_category_id: category.id, skip_category_definition: true)
topic.update!(category_id: sub.id)
post1 = create_post(user: user, topic_id: topic.id)
create_post(topic_id: topic.id)
put "/topics/bulk.json", params: {
category_id: category.id,
include_subcategories: true,
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 it "can find unread" do
# mark all unread muted # mark all unread muted
put "/topics/bulk.json", params: { put "/topics/bulk.json", params: {