mirror of
https://github.com/discourse/discourse.git
synced 2026-08-04 18:33:28 -05:00
FIX: update PM tracking state when marking messages as unread (#36258)
When marking a private message as unread via "destroy_timings", two issues prevented old PMs from appearing in the Unread list: 1. PostTiming.destroy_for used Topic.listable_topics which excludes PMs, so first_unread_pm_at was never updated. Now it explicitly handles PMs by calling set_minimum_first_unread_pm! 2. The client-side PM tracking state wasn't notified of the change. Unlike regular topics which sync state on navigation, PM tracking relies on MessageBus for updates. Added publish_read call to notify the client. Internal ref - t/155983
This commit is contained in:
@@ -341,6 +341,19 @@ class TopicsController < ApplicationController
|
||||
|
||||
last_notification.update!(read: false) if last_notification
|
||||
|
||||
topic = Topic.find_by(id: topic_id)
|
||||
|
||||
if topic&.private_message?
|
||||
topic_user = TopicUser.find_by(user: current_user, topic:)
|
||||
|
||||
PrivateMessageTopicTrackingState.publish_read(
|
||||
topic_id,
|
||||
topic_user&.last_read_post_number,
|
||||
current_user,
|
||||
topic_user&.notification_level,
|
||||
)
|
||||
end
|
||||
|
||||
render body: nil
|
||||
end
|
||||
|
||||
|
||||
@@ -108,9 +108,15 @@ class PostTiming < ActiveRecord::Base
|
||||
|
||||
Post.where(topic_id: topic_ids).update_all("reads = reads - 1")
|
||||
|
||||
date = Topic.listable_topics.where(id: topic_ids).minimum(:updated_at)
|
||||
topics = Topic.where(id: topic_ids)
|
||||
|
||||
set_minimum_first_unread!(user_id: user_id, date: date) if date
|
||||
if (date = topics.listable_topics.minimum(:updated_at))
|
||||
set_minimum_first_unread!(user_id:, date:)
|
||||
end
|
||||
|
||||
topics.private_messages.find_each do |topic|
|
||||
set_minimum_first_unread_pm!(topic:, user_id:, date: topic.updated_at)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -226,4 +226,30 @@ RSpec.describe PostTiming do
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".destroy_for" do
|
||||
it "updates first unread for a user correctly when topic is a pm" do
|
||||
post = Fabricate(:private_message_post)
|
||||
post.topic.update!(updated_at: 10.minutes.ago)
|
||||
PostTiming.process_timings(post.user, post.topic_id, 1, [[post.post_number, 100]])
|
||||
|
||||
PostTiming.destroy_for(post.user.id, [post.topic_id])
|
||||
|
||||
expect(post.user.user_stat.reload.first_unread_pm_at).to eq_time(post.topic.updated_at)
|
||||
end
|
||||
|
||||
it "updates first unread for a user correctly when topic is a group pm" do
|
||||
topic = Fabricate(:private_message_topic, updated_at: 10.minutes.ago)
|
||||
post = Fabricate(:post, topic:)
|
||||
user = Fabricate(:user)
|
||||
group = Fabricate(:group)
|
||||
group.add(user)
|
||||
topic.allowed_groups << group
|
||||
PostTiming.process_timings(user, topic.id, 1, [[post.post_number, 100]])
|
||||
|
||||
PostTiming.destroy_for(user.id, [topic.id])
|
||||
|
||||
expect(GroupUser.find_by(user:, group:).first_unread_pm_at).to eq_time(topic.updated_at)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1489,6 +1489,34 @@ RSpec.describe TopicsController do
|
||||
}.from([1, 1]).to([0, 0])
|
||||
end
|
||||
end
|
||||
|
||||
context "for private messages" do
|
||||
fab!(:pm_post, :private_message_post)
|
||||
fab!(:pm_topic) { pm_post.topic }
|
||||
fab!(:pm_user) { pm_topic.user }
|
||||
|
||||
before do
|
||||
sign_in(pm_user)
|
||||
TopicUser.create!(
|
||||
topic: pm_topic,
|
||||
user: pm_user,
|
||||
last_read_post_number: 1,
|
||||
notification_level: TopicUser.notification_levels[:watching],
|
||||
)
|
||||
PostTiming.create!(topic: pm_topic, user: pm_user, post_number: 1, msecs: 1000)
|
||||
end
|
||||
|
||||
it "publishes a message to update the client-side tracking state" do
|
||||
messages =
|
||||
MessageBus.track_publish(PrivateMessageTopicTrackingState.user_channel(pm_user.id)) do
|
||||
delete "/t/#{pm_topic.id}/timings.json"
|
||||
end
|
||||
|
||||
expect(messages.size).to eq(1)
|
||||
expect(messages.first.data["message_type"]).to eq("read")
|
||||
expect(messages.first.data["topic_id"]).to eq(pm_topic.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#mute/unmute" do
|
||||
|
||||
Reference in New Issue
Block a user