FIX: PMs displaying outdated unread counts when read status is processing (#19217)

When a client "reads" a post, we do no immediately send the data of the
post for processing on the server. Instead, read posts data is batched
together and sent to the server for processing at regular intervals. On
the server side, processing of read posts data is done in the
background. As such, there is a small window of delay before a post is
marked as read by a user on the server side.

If a client reads a topic and loads the messages topic list before the
server has processed the read post, the unread posts count for the topic
which the client just read will appear to be incorrect/outdated.

As part of tracking a post as read, we are already tracking the highest
read post number for the last read topic by the client. Therefore, we
can use this information to correct the highest post read number in the
scenario that was described above. This solution is the same as what
we've been doing for the regular topics list.
This commit is contained in:
Alan Guo Xiang Tan 2022-11-29 05:55:48 +08:00 committed by GitHub
parent 07bc3ba139
commit f14189eb3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 3 deletions

View File

@ -1,5 +1,6 @@
import DiscourseRoute from "discourse/routes/discourse";
import ViewingActionType from "discourse/mixins/viewing-action-type";
import { setTopicList } from "discourse/lib/topic-list-tracker";
export default DiscourseRoute.extend(ViewingActionType, {
renderTemplate() {
@ -7,6 +8,8 @@ export default DiscourseRoute.extend(ViewingActionType, {
},
setupController(controller, model) {
setTopicList(model);
const userActionType = this.userActionType;
this.controllerFor("user").set("userActionType", userActionType);
this.controllerFor("user-activity").set("userActionType", userActionType);

View File

@ -139,6 +139,7 @@ export default class ScreenTrack extends Service {
const highestRead = parseInt(Object.keys(timings).lastObject, 10);
const cachedHighestRead = this.highestReadFromCache(topicId);
if (!cachedHighestRead || cachedHighestRead < highestRead) {
setHighestReadCache(topicId, highestRead);
}

View File

@ -12,6 +12,11 @@ import {
import { fixturesByUrl } from "discourse/tests/helpers/create-pretender";
import selectKit from "../helpers/select-kit-helper";
import { cloneJSON } from "discourse-common/lib/object";
import { NotificationLevels } from "discourse/lib/notification-levels";
import {
resetHighestReadCache,
setHighestReadCache,
} from "discourse/lib/topic-list-tracker";
acceptance(
"User Private Messages - user with no group messages",
@ -92,9 +97,22 @@ function testUserPrivateMessagesWithGroupMessages(needs, customUserProps) {
return helper.response({
topic_list: {
topics: [
{ id: 1, posters: [] },
{ id: 2, posters: [] },
{ id: 3, posters: [] },
{
id: 1,
posters: [],
notification_level: NotificationLevels.TRACKING,
unread_posts: 1,
last_read_post_number: 1,
highest_post_number: 2,
},
{
id: 2,
posters: [],
},
{
id: 3,
posters: [],
},
],
},
});
@ -546,6 +564,22 @@ function testUserPrivateMessagesWithGroupMessages(needs, customUserProps) {
);
});
test("viewing messages when highest read cache has been set for a topic", async function (assert) {
try {
setHighestReadCache(1, 2);
await visit("/u/charlie/messages");
assert.strictEqual(
query(".topic-post-badges").textContent.trim(),
"",
"does not display unread posts count badge"
);
} finally {
resetHighestReadCache();
}
});
test("viewing messages", async function (assert) {
await visit("/u/charlie/messages");
@ -555,6 +589,12 @@ function testUserPrivateMessagesWithGroupMessages(needs, customUserProps) {
"displays the right topic list"
);
assert.strictEqual(
query(`tr[data-topic-id="1"] .topic-post-badges`).textContent.trim(),
"1",
"displays the right unread posts count badge"
);
await visit("/u/charlie/messages/group/awesome_group");
assert.strictEqual(