compose: Track recent focus on recipient box.

This commit is contained in:
Karl Stolley 2025-10-27 12:50:59 -05:00 committed by Tim Abbott
parent 5bd538b8d6
commit cfad05e4e2
2 changed files with 50 additions and 8 deletions

View File

@ -599,6 +599,15 @@ export function initialize(): void {
});
$("textarea#compose-textarea").on("focus", () => {
// To shortcut a delay otherwise introduced when the topic
// input is blurred, we immediately update the topic's
// displayed text and compose-area placeholder when the
// compose textarea is focused. We only do this in channels
// that allow topics.
if (!stream_data.is_empty_topic_only_channel(compose_state.stream_id())) {
const $input = $<HTMLInputElement>("input#stream_message_recipient_topic");
compose_recipient.update_topic_displayed_text($input.val());
}
compose_recipient.update_compose_area_placeholder_text();
compose_fade.do_update_all();
if (narrow_state.narrowed_by_reply()) {
@ -637,20 +646,25 @@ export function initialize(): void {
composebox_typeahead.private_message_recipient_typeahead.lookup(false, true);
});
// To track delayed effects originating from the "blur" event
// and its use of setTimeout, we need to set up a variable to
// reference the timeout's ID across events.
let recipient_focused_timeout: ReturnType<typeof setTimeout>;
$("input#stream_message_recipient_topic").on("focus", () => {
// We don't want the `recently-focused` class removed via
// a setTimeout from the "blur" event, if we're suddenly
// focused again.
clearTimeout(recipient_focused_timeout);
const $compose_recipient = $("#compose-recipient");
const $input = $<HTMLInputElement>("input#stream_message_recipient_topic");
compose_recipient.update_topic_displayed_text($input.val(), true);
compose_recipient.update_compose_area_placeholder_text();
// When the topic input is focused, we no longer treat
// the recipient row as low attention, as we assume the user
// is doing something that requires keeping attention called
// to the recipient row
// to the recipient row.
compose_recipient.set_high_attention_recipient_row();
$("input#stream_message_recipient_topic").one("blur", () => {
compose_recipient.update_topic_displayed_text($input.val());
compose_recipient.update_compose_area_placeholder_text();
});
$compose_recipient.addClass("recently-focused");
});
$("input#stream_message_recipient_topic").on("input", () => {
@ -659,14 +673,41 @@ export function initialize(): void {
});
$("#private_message_recipient").on("focus", () => {
// We don't want the `.recently-focused` class removed via
// setTimeout from the "blur" event, if we're suddenly
// focused again.
clearTimeout(recipient_focused_timeout);
const $compose_recipient = $("#compose-recipient");
// When the DM input is focused, we no longer treat
// the recipient row as low attention, as we assume the user
// is doing something that requires keeping attention called
// to the recipient row
compose_recipient.set_high_attention_recipient_row();
$compose_recipient.addClass("recently-focused");
});
$("input#stream_message_recipient_topic, #private_message_recipient").on("blur", () => {
const $compose_recipient = $("#compose-recipient");
const $input = $<HTMLInputElement>("input#stream_message_recipient_topic");
// To correct for an edge case when clearing the topic box
// via the left sidebar, we do the following actions after a
// delay; these will not have an effect for DMs, and so can
// safely be referenced here. Note, too, that if focus shifts
// immediately from the topic box to the compose textarea,
// we update these things immediately so that no delay is
// apparent on the topic's displayed text or the placeholder
// in the empty compose textarea.
// Also, in case a user quickly opens and closes the compose
// box, we need to clear a previously set timeout before
// setting a new one. Otherwise, the compose box can open
// in a strange state displaying *general chat* and italicizing
// the topic input.
clearTimeout(recipient_focused_timeout);
recipient_focused_timeout = setTimeout(() => {
compose_recipient.update_topic_displayed_text($input.val());
compose_recipient.update_compose_area_placeholder_text();
$compose_recipient.removeClass("recently-focused");
}, 500);
compose_recipient.update_recipient_row_attention_level();
});

View File

@ -1241,9 +1241,10 @@ textarea.new_message_textarea {
interactions (e.g., Shift-Tabbing from the compose textarea
to the topic box) show instant changes, so we don't need to
accommodate them here, which we prevent by applying the
transitions only when focus isn't within the recipient row. */
transitions only when focus isn't within the recipient row,
or hasn't recently been within the topic box. */
#compose.compose-box-open {
.low-attention-recipient-row:hover:not(:focus-within) {
.low-attention-recipient-row:not(.recently-focused, :focus-within) {
#compose_select_recipient_widget,
#compose_recipient_box,
#compose-direct-recipient .pill-container {