Skip to content

Commit

Permalink
compose: Decrease jank on message-input focus
Browse files Browse the repository at this point in the history
By always calling setFocusState with message: true.

This piece of React state is meant to track when the topic input is
focused, when the message input is focused, and (with the
true-to-false transition debounced) when either is focused.

So if the message input is focused and we don't set that state (as
has sometimes been the case until now), it's not working as
intended. Fix that by making this setFocusState call unconditional,
like it is in handleTopicFocus.

This makes a visible improvement in the situation described by this
comment:

  // We weren't showing the topic input when the user tapped on the input
  // to focus it, but we're about to show it.  Focus that, if the user
  // hasn't already selected a topic.

Before, focusState.either was being set later than it should be; it
would only happen following that automatic topic focus, when
handleTopicFocus was called. Since focusState.either flows into
canSelectTopic, and canSelectTopic controls whether the topic input
is visible, the topic input was appearing a frame or two later than
it should -- sometimes even after the topic autocomplete appeared.

Now, focusState.either is correctly set right when the message input
is focused, eliminating that delay and so giving a less janky feel.
  • Loading branch information
chrisbobbe committed Apr 25, 2023
1 parent 2c1ca7f commit 15d97db
Showing 1 changed file with 2 additions and 3 deletions.
5 changes: 2 additions & 3 deletions src/compose/ComposeBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,18 +484,17 @@ const ComposeBox: React$AbstractComponent<Props, ImperativeHandle> = forwardRef(
);

const handleMessageFocus = useCallback(() => {
setFocusState(state => ({ ...state, message: true, either: true }));
if (
!isEditing
&& isStreamNarrow(narrow)
&& !focusState.either
&& !focusState.either // not affected by setFocusState above; React state is set asynchronously
&& topicInputState.value === ''
) {
// We weren't showing the topic input when the user tapped on the input
// to focus it, but we're about to show it. Focus that, if the user
// hasn't already selected a topic.
topicInputRef.current?.focus();
} else {
setFocusState(state => ({ ...state, message: true, either: true }));
}
}, [isEditing, narrow, focusState.either, topicInputState.value, topicInputRef]);

Expand Down

0 comments on commit 15d97db

Please sign in to comment.