messages: Add spinner for messages sent on slow connections.

At times, it might get confusing for users who are on
slow connections if their messages has not been sent
even after 5s. Including a spinner that will only show
up after 5 seconds has elapsed will keep user informed
about their slow connection.

5s is set as minimum time because showing up a spinner
before than might be distracting for users on normal
connections.

Fixes: #19328.
This commit is contained in:
Lakshay Mittal
2023-03-18 00:24:09 +05:30
committed by Tim Abbott
parent 24d9d3d90c
commit e86fe4e57c
6 changed files with 78 additions and 0 deletions

View File

@@ -290,6 +290,9 @@ export function send_message(request = create_message_object()) {
if (locally_echoed) {
clear_compose_box();
// Schedule a timer to display a spinner when the message is
// taking a longtime to send.
setTimeout(() => echo.display_slow_send_loading_spinner(message), 5000);
}
}

View File

@@ -453,6 +453,17 @@ function abort_message(message) {
}
}
export function display_slow_send_loading_spinner(message) {
const $row = $(`div[zid="${message.id}"]`);
if (message.locally_echoed && !message.failed_request) {
$row.find(".slow-send-spinner").removeClass("hidden");
// We don't need to do anything special to ensure this gets
// cleaned up if the message is delivered, because the
// message's HTML gets replaced once the message is
// successfully sent.
}
}
export function initialize() {
function on_failed_action(selector, callback) {
$("#main_div").on("click", selector, function (e) {

View File

@@ -48,6 +48,10 @@ function hide_tooltip_if_reference_removed(
const callback = function (mutationsList) {
for (const mutation of mutationsList) {
for (const node of nodes_to_check_for_removal) {
// Hide instance if reference's class changes.
if (mutation.type === "attributes" && mutation.attributeName === "class") {
instance.hide();
}
// Hide instance if reference is in the removed node list.
if (Array.prototype.includes.call(mutation.removedNodes, node)) {
instance.hide();
@@ -185,6 +189,30 @@ export function initialize() {
e.currentTarget._tippy.destroy();
});
delegate("body", {
target: ".slow-send-spinner",
appendTo: () => document.body,
onShow(instance) {
instance.setContent(
$t({
defaultMessage:
"Your message is taking longer than expected to be sent. Sending…",
}),
);
const $elem = $(instance.reference);
// We need to check for removal of local class from message_row since
// .slow-send-spinner is not removed (hidden) from DOM when message is sent.
const target = $elem.parents(".message_row").get(0);
const config = {attributes: true, childList: false, subtree: false};
const nodes_to_check_for_removal = [$elem.get(0)];
hide_tooltip_if_reference_removed(target, config, instance, nodes_to_check_for_removal);
},
onHidden(instance) {
instance.destroy();
},
});
delegate("body", {
target: ".message_table .message_time",
appendTo: () => document.body,

View File

@@ -97,6 +97,17 @@ $time_column_max_width: 150px;
}
}
.slow-send-spinner {
display: none;
justify-self: end;
margin-right: 10px;
text-align: end;
grid-row-start: 1;
grid-column-start: 4;
position: relative;
top: $distance_of_text_elements_from_message_box_top;
}
.message_content {
grid-row-start: 1;
grid-column-start: 2;
@@ -159,6 +170,12 @@ $time_column_max_width: 150px;
margin-top: 1px;
}
.slow-send-spinner {
align-self: center;
position: unset;
margin-top: 1px;
}
.message_edit_notice {
align-self: center;
top: 2px;
@@ -203,6 +220,7 @@ $time_column_max_width: 150px;
& ~ .alert-msg,
& ~ .message_time,
& ~ .slow-send-spinner,
& ~ .message_controls {
grid-row: 1 / 3;
}
@@ -265,4 +283,9 @@ $time_column_max_width: 150px;
&.local .message_time {
opacity: 0;
}
/* Show the spinner only for messages that are still locally echoed. */
&.local .slow-send-spinner {
display: unset !important;
}
}

View File

@@ -929,6 +929,15 @@ td.pointer {
}
}
.messagebox-content .slow-send-spinner {
display: block;
font-size: 12px;
text-align: right;
opacity: 0.6;
color: var(--color-default-text);
animation: rotate 1s infinite linear;
}
/* The way this overrides the menus with a background-color and a high
z-index is kinda hacky, and requires some annoying color-matching,
but it works. */

View File

@@ -31,6 +31,10 @@
{{timestr}}
</a>
{{#if msg/locally_echoed}}
<span class="fa fa-circle-o-notch slow-send-spinner hidden"></span>
{{/if}}
{{> message_controls}}
{{#unless status_message}}