-
Notifications
You must be signed in to change notification settings - Fork 310
msglist: Distinguish isBot: true
message senders with a bot marker
#605
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
msglist: Distinguish isBot: true
message senders with a bot marker
#605
Conversation
@@ -484,6 +487,22 @@ void main() { | |||
|
|||
debugNetworkImageHttpClientProvider = null; | |||
}); | |||
|
|||
testWidgets('Bot user is distinguished by showing an icon', (tester) async { | |||
prepareBoringImageHttpClient(); |
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.
In the test before this test, I noticed that there was a fake HttpClient
set, that could be replaced by calling this method that was factored out in #590.
testWidgets('Updates avatar on RealmUserUpdateEvent', (tester) async {
- final httpClient = FakeImageHttpClient();
- debugNetworkImageHttpClientProvider = () => httpClient;
- httpClient.request.response
- ..statusCode = HttpStatus.ok
- ..content = kSolidBlueAvatar;
+ prepareBoringImageHttpClient();
}
Is it ok if I add an additional [NFC] commit to this PR with the requested change, or should we just ignore it for now?
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.
Seems reasonable to me! 🙂
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, this looks mostly good! Small comments below.
lib/widgets/message_list.dart
Outdated
@@ -926,6 +928,10 @@ class MessageWithPossibleSender extends StatelessWidget { | |||
).merge(weightVariableTextStyle(context, wght: 600, | |||
wghtIfPlatformRequestsBold: 900)), | |||
overflow: TextOverflow.ellipsis)), | |||
if (messageSender?.isBot ?? false) ...[ | |||
const SizedBox(width: 8), | |||
const Icon(ZulipIcons.bot, size: 18, color: Colors.grey), |
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 match the color to what the web app uses.
I'm also curious how the 18px size is chosen, and the 8px distance from the user's name. To my eye I think those values might both want to be a bit smaller. What does the web app do?
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 should be fixed. Even on the webapp the bot icon isn't super prominent, and I have no idea why it's blurred.
I saw this comment on CZO, so I decided to go with a more prominent icon. Any recommendations from your side are most welcome!
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.
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.
Hmm. To me, that all looks good except the size; I think it looks too small now. The font size in the web app is smaller than in the mobile app, so maybe this icon should be scaled up according to that. Maybe try 15px?
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.
Applied the changes. Updated the description for the new images. Please have a look!
@@ -484,6 +487,22 @@ void main() { | |||
|
|||
debugNetworkImageHttpClientProvider = null; | |||
}); | |||
|
|||
testWidgets('Bot user is distinguished by showing an icon', (tester) async { | |||
prepareBoringImageHttpClient(); |
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.
Seems reasonable to me! 🙂
test/widgets/message_list_test.dart
Outdated
users: users, | ||
); | ||
|
||
tester.widget(find.byIcon(ZulipIcons.bot)); |
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 you check specifically that the icon appears next to the sender that is a bot, and also that an icon doesn't appear on the senders that are not bots?
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.
Sure thing!
Thanks for the review! A few comments above. |
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 @sm-sayedi for handling this, and @chrisbobbe for the review!
Other than the things Chris remarked on above, this all looks good to me, except a few nits below.
test/widgets/message_list_test.dart
Outdated
testWidgets('Bot user is distinguished by showing an icon', (tester) async { | ||
prepareBoringImageHttpClient(); | ||
|
||
final users = List.generate(3, (index) => eg.user(isBot: index == 0)); |
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 is probably clearer as a list literal with three explicit eg.user
calls: [eg.user(isBot: true), eg.user(isBot: false),
etc. Not much longer that way, and less logic for the reader to unpack.
lib/widgets/message_list.dart
Outdated
final message = item.message; | ||
final messageSender = | ||
PerAccountStoreWidget.of(context).users[message.senderId]; |
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: (two nits)
final message = item.message; | |
final messageSender = | |
PerAccountStoreWidget.of(context).users[message.senderId]; | |
final store = PerAccountStoreWidget.of(context); | |
final message = item.message; | |
final sender = store.users[message.senderId]; |
That way the result of PerAccountStoreWidget.of
goes into a store
local, like in most of our other build methods where it appears. The uniformity is mildly helpful; and this way also makes it maximally easy to add another bit of logic using the store later, without either duplicating the lookup or rewriting these lines.
Separately, most everything within this method is about the particular message message
, so a name "sender" communicates basically the same meaning as "message sender". Similarly the existing other locals include senderRow
and time
, without the added qualifier "message".
Oh and one other nit, in the commit message:
Let's make the prefix Similarly, s/users/message senders/ would further help pin down where in the UI we're talking about (and the resulting summary line is 68 columns, so there's room; summary lines can go a bit over 70). |
14697c4
to
2570ae4
Compare
Thanks for the review! Pushed the latest revision. PTAL! |
Sorry, I am not sure where to add this in the commit message! |
2570ae4
to
e0db6c1
Compare
check(nameFinder.evaluate().singleOrNull).isNotNull(); | ||
check(botFinder.evaluate().singleOrNull).isNotNull(); | ||
|
||
final userFinder = find.ancestor( |
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.
For a bot user, this evaluates to two results, and that's because there are two Row
s that satisfy this finder; one direct parent Row
and another, the parent of this parent Row
, both are for the same user. To make sure they're for the same user, the following two lines are added just before the finder:
check(nameFinder.evaluate().singleOrNull).isNotNull();
check(botFinder.evaluate().singleOrNull).isNotNull();
This makes sure the fullName
text for a user is only shown once on the screen. The bot icon is also checked for being shown just once, but that does not guarantee it belongs to the current user. That check is done by check(userFinder.evaluate()).isNotEmpty()
.
I hope this test is fine for checking if a bot icon is shown next to a user name.
isBot: true
users with a bot markerisBot: true
users with a bot marker
Ah, that was perhaps a bit cryptic of a way to put it. What I meant by "s/users/message senders/" was "replace 'users' with 'message senders'". (The |
e0db6c1
to
85051a3
Compare
isBot: true
users with a bot markerisBot: true
message senders with a bot marker
Thanks, just learned something new! Revision pushed! |
8038a39
to
f2cf926
Compare
Thanks for the revision! This all looks good to me except one more commit-message nit: For that first commit, the prefix should be Other than that I'll leave this for @chrisbobbe to re-review for the icon size and placement, and anything else he notices, and then merge. |
f2cf926
to
50d079c
Compare
Thanks for the review! Revision pushed. Now waiting for a review from your side @chrisbobbe! |
…Client` In the test ('Updates avatar on RealmUserUpdateEvent'), the code for setting a `FakeImageHttpClient` is replaced by the `prepareBoringImageHttpClient` function.
50d079c
to
8c0f9ae
Compare
Thanks, looks good to me! Merging. After this, there are still some places in the UI where we show the name of a bot user without making it clear it's a bot. For example, it would probably be helpful to show the bot icon next to a bot user's name on the profile page ( |
Sure, will do so. |
A bot icon is shown with the name of the bot users.
Fixes: #156