unread_ops: Use /messages/flags/narrow to mark stream/topic as read.

This commit refactors the original mark_all_as_read in unread_ops to
bulk_mark_mesages_as_read to include marking stream/topic as read.
The unread_ops API reamins the same to mark stream/topic as read but the
underlying implementation now uses a different endpoint. A new function
mark_all_as_read has been added so that the unread_ops API remains the
same.

Fixes #27372.
This commit is contained in:
shubham 2024-01-13 19:44:18 +07:00 committed by Tim Abbott
parent af7cfb677f
commit 664f29b4f1
1 changed files with 37 additions and 19 deletions

View File

@ -1,4 +1,5 @@
import $ from "jquery"; import $ from "jquery";
import _ from "lodash";
import render_confirm_mark_all_as_read from "../templates/confirm_dialog/confirm_mark_all_as_read.hbs"; import render_confirm_mark_all_as_read from "../templates/confirm_dialog/confirm_mark_all_as_read.hbs";
@ -36,6 +37,10 @@ const FOLLOWUP_BATCH_SIZE = 1000;
// case after a server-initiated reload. // case after a server-initiated reload.
let window_focused = document.hasFocus && document.hasFocus(); let window_focused = document.hasFocus && document.hasFocus();
// Since there's a database index on is:unread, it's a fast
// search query and thus worth including here as an optimization.),
const all_unread_messages_narrow = [{operator: "is", operand: "unread", negated: false}];
export function is_window_focused() { export function is_window_focused() {
return window_focused; return window_focused;
} }
@ -51,7 +56,7 @@ export function confirm_mark_all_as_read() {
}); });
} }
export function mark_all_as_read(args = {}) { function bulk_mark_messages_as_read(narrow, args = {}) {
args = { args = {
// We use an anchor of "oldest", not "first_unread", because // We use an anchor of "oldest", not "first_unread", because
// "first_unread" will be the oldest non-muted unread message, // "first_unread" will be the oldest non-muted unread message,
@ -73,9 +78,7 @@ export function mark_all_as_read(args = {}) {
num_after: args.num_after, num_after: args.num_after,
op: "add", op: "add",
flag: "read", flag: "read",
// Since there's a database index on is:unread, it's a fast narrow: JSON.stringify(narrow),
// search query and thus worth including here as an optimization.
narrow: JSON.stringify([{operator: "is", operand: "unread", negated: false}]),
}; };
channel.post({ channel.post({
url: "/json/messages/flags/narrow", url: "/json/messages/flags/narrow",
@ -104,7 +107,8 @@ export function mark_all_as_read(args = {}) {
loading_indicator_displayed = true; loading_indicator_displayed = true;
} }
mark_all_as_read({ bulk_mark_messages_as_read(narrow, {
...args,
anchor: data.last_processed_id, anchor: data.last_processed_id,
messages_read_till_now, messages_read_till_now,
num_after: FOLLOWUP_BATCH_SIZE, num_after: FOLLOWUP_BATCH_SIZE,
@ -126,7 +130,7 @@ export function mark_all_as_read(args = {}) {
loading_indicator_displayed = false; loading_indicator_displayed = false;
} }
if (unread.old_unreads_missing) { if (_.isEqual(narrow, all_unread_messages_narrow) && unread.old_unreads_missing) {
// In the rare case that the user had more than // In the rare case that the user had more than
// 50K total unreads on the server, the client // 50K total unreads on the server, the client
// won't have known about all of them; this was // won't have known about all of them; this was
@ -148,7 +152,7 @@ export function mark_all_as_read(args = {}) {
} else if (xhr.responseJSON?.code === "RATE_LIMIT_HIT") { } else if (xhr.responseJSON?.code === "RATE_LIMIT_HIT") {
// If we hit the rate limit, just continue without showing any error. // If we hit the rate limit, just continue without showing any error.
const milliseconds_to_wait = 1000 * xhr.responseJSON["retry-after"]; const milliseconds_to_wait = 1000 * xhr.responseJSON["retry-after"];
setTimeout(() => mark_all_as_read(args), milliseconds_to_wait); setTimeout(() => bulk_mark_messages_as_read(narrow, args), milliseconds_to_wait);
} else { } else {
// TODO: Ideally this would be a ui_report.error(); // TODO: Ideally this would be a ui_report.error();
// the user needs to know that our operation failed. // the user needs to know that our operation failed.
@ -446,20 +450,34 @@ export function mark_current_list_as_read(options) {
notify_server_messages_read(message_lists.current.all_messages(), options); notify_server_messages_read(message_lists.current.all_messages(), options);
} }
export function mark_stream_as_read(stream_id, cont) { export function mark_stream_as_read(stream_id) {
channel.post({ bulk_mark_messages_as_read(
url: "/json/mark_stream_as_read", [
data: {stream_id}, {operator: "is", operand: "unread", negated: false},
success: cont, {operator: "stream", operand: stream_id},
}); ],
{
stream_id,
},
);
} }
export function mark_topic_as_read(stream_id, topic, cont) { export function mark_topic_as_read(stream_id, topic) {
channel.post({ bulk_mark_messages_as_read(
url: "/json/mark_topic_as_read", [
data: {stream_id, topic_name: topic}, {operator: "is", operand: "unread", negated: false},
success: cont, {operator: "stream", operand: stream_id},
}); {operator: "topic", operand: topic},
],
{
stream_id,
topic,
},
);
}
export function mark_all_as_read() {
bulk_mark_messages_as_read(all_unread_messages_narrow);
} }
export function mark_pm_as_read(user_ids_string) { export function mark_pm_as_read(user_ids_string) {