-
Notifications
You must be signed in to change notification settings - Fork 162
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
autocomplete: Implement new design for @-mention autocomplete items #995
base: main
Are you sure you want to change the base?
Conversation
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! Comments below.
In the Figma:
- The gap between the avatar photo and the text is 6px, not 8px
- The outer padding is top: 4, right: 8, bottom: 4, left: 4 (not top: 8, right: 16, bottom: 8, left: 16) Since left and right are unequal, we should use
EdgeInsetsDirectional
for this. - Please post screenshots showing the "…" effect when the name or metadata text are very long (not sure this is implemented in this revision)
- The avatar photo is a 36px rounded square with 4px border radius (not a 32px square with 3px border radius)
- Our designer doesn't want the "ink splash" effect on buttons. We should remove the
InkWell
widget and implement the on-pressed appearance specified here:
https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=3732-28939&node-type=symbol&m=dev
lib/widgets/theme.dart
Outdated
final Color contextMenuItemLabel; | ||
final Color contextMenuItemMeta; |
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.
Since these are variables in the Figma, they don't belong in this section, which is marked
// Not named variables in Figma; taken from older Figma drafts, or elsewhere.
They should appear alphabetically in the section at the top:
final Color background;
final Color bgCounterUnread;
final Color bgTopBar;
// [etc.]
When moving them there, please also update the other places these names appear in the class, such as the lerp
method.
lib/widgets/theme.dart
Outdated
@@ -167,6 +169,8 @@ class DesignVariables extends ThemeExtension<DesignVariables> { | |||
// TODO(design-dark) need proper dark-theme color (this is ad hoc) | |||
subscriptionListHeaderText: const HSLColor.fromAHSL(1.0, 240, 0.1, 0.75).toColor(), | |||
unreadCountBadgeTextForChannel: Colors.white.withValues(alpha: 0.9), | |||
contextMenuItemLabel: const Color(0xffDFE1E8), |
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.
I think we more often use lowercase letters in these.
lib/widgets/autocomplete.dart
Outdated
/// The given user's real email address, if known, for displaying in the UI. | ||
/// | ||
/// Returns null if self-user isn't able to see [user]'s real email address. | ||
String? _getDisplayEmailFor(User user, {required PerAccountStore store}) { |
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.
Yes, as you suggested in the PR description, we should avoid copy-pasting this complicated logic from somewhere else. If we have some complicated logic written twice, and it needs to be updated, there's a risk that we'll update one place and forget the other.
Maybe a good place for a reusable function is lib/api/model/model.dart, below the User
class? That refactor should be in an NFC prep commit.
lib/widgets/autocomplete.dart
Outdated
avatar = Avatar(userId: userId, size: 32, borderRadius: 3); | ||
label = PerAccountStoreWidget.of(context).users[userId]!.fullName; | ||
label = user!.fullName; | ||
metaData = _getDisplayEmailFor(user, store: store) ?? ''; |
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: Since "metadata" is one word, the variable should be called metadata
.
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.
Also, let's make it nullable, so String? metadata;
, so its empty value is null
instead of the empty string.
lib/widgets/autocomplete.dart
Outdated
switch (option) { | ||
case UserMentionAutocompleteResult(:var userId): | ||
final store = PerAccountStoreWidget.of(context); | ||
final user = store.users[userId]; |
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.
final user = store.users[userId]; | |
final user = store.users[userId]!; |
instead of putting the !
later, when we try to access .fullName
.
lib/widgets/autocomplete.dart
Outdated
Column( | ||
mainAxisSize: MainAxisSize.min, | ||
crossAxisAlignment: CrossAxisAlignment.start, | ||
children: [ | ||
Text(label, style: TextStyle(fontSize: 18, height: 1.1, color: designVariables.contextMenuItemLabel) //Creates a line height equavalent to ~20 | ||
.merge(weightVariableTextStyle(context, wght: 600))), | ||
Visibility( | ||
visible: metaData.isNotEmpty, | ||
child: Text(metaData, style: TextStyle(height: 1.14, color: designVariables.contextMenuItemMeta)), //Creates a line height equavalent to ~16 | ||
)])]))); |
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.
indentation and line lengths:
Column( | |
mainAxisSize: MainAxisSize.min, | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
Text(label, style: TextStyle(fontSize: 18, height: 1.1, color: designVariables.contextMenuItemLabel) //Creates a line height equavalent to ~20 | |
.merge(weightVariableTextStyle(context, wght: 600))), | |
Visibility( | |
visible: metaData.isNotEmpty, | |
child: Text(metaData, style: TextStyle(height: 1.14, color: designVariables.contextMenuItemMeta)), //Creates a line height equavalent to ~16 | |
)])]))); | |
Column( | |
mainAxisSize: MainAxisSize.min, | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
Text( | |
style: TextStyle( | |
fontSize: 18, | |
height: 1.1, // Creates a line height equavalent to ~20 | |
color: designVariables.contextMenuItemLabel, | |
) | |
.merge(weightVariableTextStyle(context, wght: 600)), | |
label), | |
Visibility( | |
visible: metaData.isNotEmpty, | |
child: Text( | |
style: TextStyle( | |
height: 1.14, // Creates a line height equavalent to ~16 | |
color: designVariables.contextMenuItemMeta, | |
), | |
metaData)), | |
]), | |
]))); |
lib/widgets/autocomplete.dart
Outdated
mainAxisSize: MainAxisSize.min, | ||
crossAxisAlignment: CrossAxisAlignment.start, | ||
children: [ | ||
Text(label, style: TextStyle(fontSize: 18, height: 1.1, color: designVariables.contextMenuItemLabel) //Creates a line height equavalent to ~20 |
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.
See other places where we set height
; here, we would express it as 20 / 18
.
lib/widgets/autocomplete.dart
Outdated
.merge(weightVariableTextStyle(context, wght: 600))), | ||
Visibility( | ||
visible: metaData.isNotEmpty, | ||
child: Text(metaData, style: TextStyle(height: 1.14, color: designVariables.contextMenuItemMeta)), //Creates a line height equavalent to ~16 |
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.
height: 16 / 14
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.
Also, this should have an explicit fontSize: 14
. Even if that matches the default, let's be explicit here.
lib/widgets/autocomplete.dart
Outdated
children: [ | ||
Text(label, style: TextStyle(fontSize: 18, height: 1.1, color: designVariables.contextMenuItemLabel) //Creates a line height equavalent to ~20 | ||
.merge(weightVariableTextStyle(context, wght: 600))), | ||
Visibility( |
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.
Instead of Visibility
, how about using Dart's "collection if" feature:
if (metaData.isNotEmpty) Text(/* … */),
, but combined with my earlier suggestions it would be
if (metadata != null) Text(/* … */),
Sure, this would be good to fix — please go ahead and add a commit with that fix if you think you already see how to do it, or start a thread in #mobile-team and we can discuss in more detail. |
Okay, thank you for the review, I will make the changes. |
If it's needed for the other work you're doing in this PR, then a commit in this PR is a good way to do it. If it's not related to what's in this PR, then a separate PR is best. |
Okay |
About the splash, I kept the inkwell widget, because a gesture detector doesn't show splashes, but I removed the sparkle effect, and left just the color change on tap. I also added a border radius in the splash as shown on the design, it's a bit difficult to see here but it is there. Would this work according to the design? screen-20241014-204642.mp4 |
Implemented new design for @-mention autocomplete items. Added new `contextMenuItemLabel` and `contextMenuItemMeta` color variables to `designVariables` class. Updated autocomplete tests. Fixes: zulip#913
If your code causes any noticeable differences from the design, please identify them and say why you think they are OK. This will shorten the path to deciding if the code will work. :) It looks like you haven't pushed your latest revision to GitHub. When it's ready for another review, please do that, and comment saying that it's ready for review. |
No, I haven't yet. That is because I have been facing some problems with the And I have looked at the test, and tried to do some searching as to why it might be failing, and I haven't succeeded. I did not see any obvious place where the avatar widget size was checked in the test. I also thought it might be because of an outdated golden test snapshot, but I could not find any references to a snapshot file. So I have been confused and stumped. I was just about to comment on that before seeing your comment, wondering if anyone can help point me in the right direction. |
If you push the code here, and then start a conversation in #mobile-dev-help with the test failure you're seeing, that will probably be the most efficient way to get help investigating it. |
Okay, I will do that |
Moved getDisplayEmailFor method which gets the user's real email address to lib/api/model/model.dart and refactored usages to remove duplication.
17aea85
to
e107e03
Compare
I have pushed my changes, please review |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
Thanks for starting that conversation. Here's a link, so people reading this will know the conversation is happening and where to find it: https://chat.zulip.org/#narrow/channel/516-mobile-dev-help/topic/ComposeAutocomplete.20test.20failure.20help/near/1963058 |
Hello everyone,
This PR implements the updated design for the @-mention autocomplete items as detailed in this Figma File
https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=3859-3131&m=dev
I added new
contextMenuItemLabel
andcontextMenuItemMeta
color variables to thedesignVariables
class from the design.I also had to manually set the line height to match the design exactly.
As Greg described here, the autocomplete item only shows the user's real email address when the user has allowed their email to be visible, if not it doesn't show anything. I used the
_getDisplayEmailFor()
method from the profile page to get the user's real email. I am not sure if it is a good idea to have a copy of the same method here, maybe we should find a way to not have multiple copies of the same method.I updated autocomplete tests to also check if the email(metaData) is also shown as the updated design now shows extra metadata.
I attempted to add another test to verify if the email is not shown when the user's
emailAddressVisibility != emailAddressVisibility.everyone
, while doing so I learned a bit more about how the app manages users and data, but to be honest I couldn't get it to work properly, and I did not want to massively change up the current test file. Still trying to wrap my head around that.This also leads me to a bug I think, which I discovered in the
example_data.dart
initialSnapshot
method where some of the arguments from theintialSnapshot
method aren't being passed down to the method, I think someone missed that when setting up the method.Please review when you can, thank you
Fixes: #913