-
Notifications
You must be signed in to change notification settings - Fork 308
msglist: When initial message fetch comes up empty, auto-focus compose box #1544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
msglist: When initial message fetch comes up empty, auto-focus compose box #1544
Conversation
…e box This is part of our plan to streamline the new-DM UI: when you start a new DM conversation with no history, we should auto-focus the content input in the compose box. Fixes: zulip#1543
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, LGTM!
@override void requestFocusIfUnfocused() { | ||
if (topicFocusNode.hasFocus || contentFocusNode.hasFocus) return; | ||
if (topicInteractionStatus.value == ComposeTopicInteractionStatus.notEditingNotChosen) { | ||
topicFocusNode.requestFocus(); | ||
} else { | ||
contentFocusNode.requestFocus(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function could also be useful for #1448.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Looks good; some small comments below.
/// A convenience method to encapsulate choosing the topic or content input | ||
/// when both exist (see [StreamComposeBoxController.requestFocusIfUnfocused]). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I'd think of a "convenience method" as doing something the caller could have perfectly reasonably done for itself, but which just makes it a bit easier or shorter at the caller. Because this is encapsulating meaningful logic of its own (at least in the subclass implementation), I wouldn't call it a "convenience method".
/// A convenience method to encapsulate choosing the topic or content input | |
/// when both exist (see [StreamComposeBoxController.requestFocusIfUnfocused]). | |
/// This encapsulates choosing the topic or content input | |
/// when both exist (see [StreamComposeBoxController.requestFocusIfUnfocused]). |
if (topicInteractionStatus.value == ComposeTopicInteractionStatus.notEditingNotChosen) { | ||
topicFocusNode.requestFocus(); | ||
} else { | ||
contentFocusNode.requestFocus(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make this a switch
— seems like one wants to explicitly think through each of the values of ComposeTopicInteractionStatus in order to understand this logic.
check(controller).isA<StreamComposeBoxController>() | ||
.topicFocusNode.hasFocus.isFalse(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can make this check a bit stronger, verifying focus doesn't go to the content input either:
check(controller).isA<StreamComposeBoxController>() | |
.topicFocusNode.hasFocus.isFalse(); | |
check(controller).isA<StreamComposeBoxController>() | |
..topicFocusNode.hasFocus.isFalse() | |
..contentFocusNode.hasFocus.isFalse(); |
await prepareComposeBox(tester, | ||
narrow: DmNarrow.withUser(user.userId, selfUserId: store.selfUserId), | ||
messages: [eg.dmMessage(from: user, to: [store.selfUser])]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
store
is set up by prepareComposeBox
itself, so these end up using the state left behind by the previous test case. You can see the effect by running the case in isolation:
$ flutter test test/widgets/compose_box_test.dart --name DmNarrow
00:06 +0: auto focus DmNarrow, non-empty fetch
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following LateError was thrown running a test:
LateInitializationError: Local 'store' has not been initialized.
When the exception was thrown, this was the stack:
#0 LateError._throwLocalNotInitialized (dart:_internal-patch/internal_patch.dart:214:5)
#1 main.<anonymous closure>.<anonymous closure> (file:///home/greg/z/flutterz/test/widgets/compose_box_test.dart)
[…]
Looks like prepareComposeBox
takes a selfUser
argument, so that can be used to control this.
This is part of our plan to streamline the new-DM UI: when you start a new DM conversation with no history, we should auto-focus the content input in the compose box.
Fixes: #1543