toggle_resolve_topic: Display spinner while request is in progress.

We replace the check icon for "Mark as resolved/unresolved" with
a spinner while the request is still ongoing.

This helps to prevent double-clicking and reduce possible
race conditions.

Fixes #26190.
This commit is contained in:
Prakhar Pratyush 2023-09-16 13:10:07 +05:30 committed by Tim Abbott
parent 72b3a53864
commit 8d29ad7325
4 changed files with 34 additions and 4 deletions

View File

@ -401,7 +401,7 @@ export function initialize() {
const $recipient_row = $(e.target).closest(".recipient_row");
const message_id = rows.id_for_recipient_row($recipient_row);
const topic_name = $(e.target).attr("data-topic-name");
message_edit.toggle_resolve_topic(message_id, topic_name);
message_edit.toggle_resolve_topic(message_id, topic_name, false, $recipient_row);
});
$("body").on("click", ".message_header .on_hover_topic_unresolve", (e) => {
@ -409,7 +409,7 @@ export function initialize() {
const $recipient_row = $(e.target).closest(".recipient_row");
const message_id = rows.id_for_recipient_row($recipient_row);
const topic_name = $(e.target).attr("data-topic-name");
message_edit.toggle_resolve_topic(message_id, topic_name);
message_edit.toggle_resolve_topic(message_id, topic_name, false, $recipient_row);
});
// Mute topic in a unmuted stream

View File

@ -598,6 +598,14 @@ export function start($row, edit_box_open_callback) {
});
}
function show_toggle_resolve_topic_spinner($row) {
const $spinner = $row.find(".toggle_resolve_topic_spinner");
loading.make_indicator($spinner);
$spinner.css({width: "18px"});
$row.find(".on_hover_topic_resolve, .on_hover_topic_unresolve").hide();
$row.find(".toggle_resolve_topic_spinner").show();
}
function get_resolve_topic_time_limit_error_string(time_limit, time_limit_unit, topic_is_resolved) {
if (topic_is_resolved) {
if (time_limit_unit === "minute") {
@ -682,7 +690,12 @@ function handle_resolve_topic_failure_due_to_time_limit(topic_is_resolved) {
});
}
export function toggle_resolve_topic(message_id, old_topic_name, report_errors_in_global_banner) {
export function toggle_resolve_topic(
message_id,
old_topic_name,
report_errors_in_global_banner,
$row,
) {
let new_topic_name;
const topic_is_resolved = resolved_topic.is_resolved(old_topic_name);
if (topic_is_resolved) {
@ -691,6 +704,10 @@ export function toggle_resolve_topic(message_id, old_topic_name, report_errors_i
new_topic_name = resolved_topic.resolve_name(old_topic_name);
}
if ($row) {
show_toggle_resolve_topic_spinner($row);
}
const request = {
propagate_mode: "change_all",
topic: new_topic_name,
@ -701,7 +718,13 @@ export function toggle_resolve_topic(message_id, old_topic_name, report_errors_i
channel.patch({
url: "/json/messages/" + message_id,
data: request,
success() {
const $spinner = $row.find(".toggle_resolve_topic_spinner");
loading.destroy_indicator($spinner);
},
error(xhr) {
const $spinner = $row.find(".toggle_resolve_topic_spinner");
loading.destroy_indicator($spinner);
if (xhr.responseJSON) {
if (xhr.responseJSON.code === "MOVE_MESSAGES_TIME_LIMIT_EXCEEDED") {
handle_resolve_topic_failure_due_to_time_limit(topic_is_resolved);

View File

@ -2482,7 +2482,13 @@ div.topic_edit_spinner {
vertical-align: middle;
}
div.topic_edit_spinner .loading_indicator_spinner {
div.toggle_resolve_topic_spinner {
margin-top: -12px;
padding-left: 9px;
}
div.topic_edit_spinner .loading_indicator_spinner,
div.toggle_resolve_topic_spinner .loading_indicator_spinner {
width: 14px;
height: 14px;

View File

@ -55,6 +55,7 @@
{{else}}
<i class="fa fa-check on_hover_topic_resolve recipient_bar_icon hidden-for-spectators" data-topic-name="{{topic}}" data-tippy-content="{{t 'Mark as resolved' }}" role="button" tabindex="0" aria-label="{{t 'Mark as resolved' }}"></i>
{{/if}}
<div class="toggle_resolve_topic_spinner" style="display: none"></div>
{{/if}}
{{#if development}}