-
-
Notifications
You must be signed in to change notification settings - Fork 676
UserItem: Remove UserItemRaw hack #5508
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
Conversation
|
Yeah, I agree. Can we try shrinking the user avatars down to the size of the icons? That would also shrink the height of the user rows, letting us show more of them at a time. |
|
Sure, seems like a fine direction to try -- thanks! |
gnprice
left a comment
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 @chrisbobbe for fixing this! Generally looks great; comments below.
| getUsersAndWildcards(state.users), | ||
| [ | ||
| // TODO: Refactor so we don't make these fake user objects. | ||
| { user_id: makeUserId(-1), full_name: 'all', email: '(Notify everyone)' }, | ||
| { user_id: makeUserId(-2), full_name: 'everyone', email: '(Notify everyone)' }, | ||
| ...state.users, |
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.
outboxActions [nfc]: Inline getUsersAndWildcards call
We're about to remove this hacky function's only caller; inline it
here, making sure to keep a comment that says we don't like the
hack.
"only other caller", perhaps? Seems like there was this caller and also another one.
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've updated this commit to inline the function at both callers and remove the function.
| const shouldMatch = [ | ||
| { user_id: -1, full_name: 'all', email: '(Notify everyone)' }, | ||
| someGuyUser, | ||
| ]; |
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.
Huh, it's interesting that these test cases only had one wildcard in the expected results, not two, while the logic we're deleting in getUsersAndWildcards was adding two pseudo-users. The search query in this test case is just '', matching everything. How does the old code pick just one of the two wildcard pseudo-users?
… Oh. I see. It's this:
const candidates = getUniqueUsers([...startWith, ...contains, ...matchesEmail]);… where:
export const getUniqueUsers = (
users: $ReadOnlyArray<AutocompleteOption>,
): $ReadOnlyArray<AutocompleteOption> => uniqby(users, 'email');… and it's relying on the fact that the two pseudo-users have the same very fake "email" value as each other, namely "(Notify everyone)". Yikes. Great to be deleting that.
I guess we still need the getUniqueUsers call, because the other thing it's doing is deduping users that matched several different ways.
Though one thing we can now do is switch it to use the user ID rather than email… no, better: it should just use === on the user objects.
src/common/UserAvatarWithPresence.js
Outdated
| // Callers don't make sure that the user is one we actually have data | ||
| // for: e.g., we're helping identify a PM narrow by showing one of the | ||
| // PM recipients, but that recipient's user record doesn't exist because | ||
| // it was deleted after the conversation started. | ||
| // TODO: Instead of null, show a legible placeholder so the user knows | ||
| // how to interpret the lack of data. Or make callers do that, and | ||
| // insist that userId refers to a real user, so we can use | ||
| // getUserForId instead of tryGetUserForId. |
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.
Same remark as here: #5531 (comment)
| export const serverCanonicalStringOf = englishCanonicalStringOf; | ||
|
|
||
| export const descriptionOf = ( |
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: can drop exports
| export const getFilteredSuggestions = ( | ||
| query: string, | ||
| destinationNarrow: Narrow, | ||
| _: GetText, | ||
| ): $ReadOnlyArray<WildcardMentionType> => | ||
| Array.from(WildcardMentionType.members()).filter(type => |
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.
The old code would return just one of @-all or @-everyone, if both matched. That seems helpful, since they're synonyms.
I guess web shows both of them, plus @-stream (which I think is also a synonym -- user docs seem to not mention it.) Still, taking up multiple spots in the autocomplete list -- especially on a mobile screen -- seems unhelpful and worth avoiding.
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, I can have it take the first match in [all, everyone, stream]. Is that a good order, or should we take the first match in [stream, all, everyone] or something else? (We'd exclude "stream" when the destination narrow isn't a stream or topic narrow, of course.)
If I change the code so it just shows one match, I see an odd thing where "all" shows up as the only wildcard-mention suggestion, when my actual query was "stream". That's because "all" matches by its descriptionOf(type, …), which is _('Notify stream'). We should probably prevent that by removing the description search.
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.
Sounds good to me.
The help center mentions @-all, sometimes also @-everyone, and never @-stream that I can see:
https://zulip.com/help/mention-a-user-or-group
https://zulip.com/help/pm-mention-alert-notifications
So I think the right order of preference is [all, everyone, stream].
| /* $FlowFixMe[prop-missing] - Type query_matches_source_attrs. In | ||
| particular, find a way to require `source` to have string values at | ||
| the keys given in `match_attrs`. */ | ||
| typeahead.query_matches_source_attrs( |
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 probably the right answer here is actually to dissolve this typeahead.query_matches_source_attrs function. It's over-abstracted already, and the trickiness of its type isn't even the biggest improvement the code would get by getting rid of it.
I wrote up a longer discussion showing how the call sites would improve, then realized that would be best turned into a quick PR to actually make said changes:
zulip/zulip#23375
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! I've published that change to NPM and my next revision uses typeahead.query_matches_string instead of typeahead.query_matches_source_attrs.
05b6cfe to
60715e9
Compare
|
Thanks for the reviews! Revision pushed. Here's the "after" photo for this revision, and I expect |
gnprice
left a comment
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 for the revision! I've just read all the changes except in the one main commit:
e49119c PeopleAutocomplete: Stop using fake user-like objects for wildcard mentions
Everything looks good except (that one commit I haven't read yet and) one comment below, which calls for some more refactoring in the emoji data.
Looking at the list of commits, I think this series would be good to break out as its own quick PR:
cddc2f9 UserGroupItem [nfc]: Inline styles.listItem here
70d50de UserItem [nfc]: Inline globalStyles.listItem here
0fe1cd7 UserItem [nfc]: Remove repetition in styles.wrapper
03c99c5 people autocomplete: Make users and user groups more uniform
05668e3 PeopleAutocomplete: Give user and user-group items 48+ px touch target
It looks all ready to merge, and it has a bit of a different job from the rest of the branch -- it's making the layout/design improvements to the autocomplete popup that were discussed above at #5508 (comment) .
| getActiveImageEmojiById, | ||
| emojis => | ||
| Object.keys(emojis).map(id => ({ | ||
| reaction_type: 'realm_emoji', | ||
| emoji_type: 'image', |
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 will be inaccurate in the case of the Zulip extra emoji :zulip:, where the reaction_type should be zulip_extra_emoji. This doesn't currently have a practical effect, because typeahead.get_emoji_matcher only looks to see if the reaction type is unicode_emoji or not; but it could in the future, because realm_emoji vs. zulip_extra_emoji have completely different meanings for emoji_code.
Looking at how this data is built up, I think a good solution would be:
- The objects we get from
getActiveImageEmojiByIdshould have areaction_typeproperty. - Similarly for the objects we pass around between the other selectors in this file.
- The type we have for those is
ImageEmojiType, which is defined inmodelTypesand used to describe parts of the API. So we can split that type:- The existing definition can be better named
RealmEmoji. In the API, it's always used for a realm emoji, not a Zulip extra emoji. (See 9d78140, which in retrospect should have made this split instead of renaming.) - Then
ImageEmojican be the name of a type that just addsreaction_type: ReactionTypeto that. - (In emojiSelectors we're already creating new objects anyway, to parse
source_url. So we might as well addreaction_typewhile we're at it.)
- The existing definition can be better named
The changes to add reaction_type can happen in a commit or two of their own prior to taking the shared upgrade. The inexact object type in typeahead.js.flow reflects the fact that the shared code isn't bothered by additional properties.
60715e9 to
7745673
Compare
|
Thanks for the review! Revision pushed, but this one isn't for review; I'm just pausing after separating out that other PR before doing the data fix you point to in #5508 (comment). I've taken the following screenshots at this point, since I don't expect them to be affected by that fix. Before/after: |
With ImageEmoji being the same as RealmEmoji except for an added reaction_type property. See discussion: zulip#5508 (comment)
7745673 to
f853559
Compare
|
OK, and now I've pushed a fix for the emoji data issue you pointed out. Thanks; this is ready for review. 🙂 |
gnprice
left a comment
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 for the revision! Looks good -- small comments below.
| export type EmojiForShared = {| emoji_type: EmojiType, emoji_name: string, emoji_code: string |}; | ||
| export type EmojiForShared = {| | ||
| reaction_type: ReactionType, |
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 change, and the other changes it drives, should be possible to put in a commit that comes before the @zulip/shared upgrade, so that the latter is purely a dependency upgrade.
That's reflected in the inexact object type in that library's type definitions:
#5508 (comment)
| @@ -0,0 +1,198 @@ | |||
| /* @flow strict-local */ | |||
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.
PeopleAutocomplete: Stop using fake user-like objects for wildcard mentions
As the comments point out, we've been using a hack where we make
fake "user" objects for wildcard mentions @all and @everyone, so we
can enlist UserItemRaw to show items for these in the people
autocomplete.
nit: do disarm these @-mentions so that GitHub doesn't interpret them:
https://github.com/zulip/zulip-mobile/blob/main/docs/style.md#mentioning-people
One convenient form is "@-all" / "@-everyone".
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.
- We now show "stream", not just "all" and "everyone", fixing #4325.
nit: https://github.com/zulip/zulip-mobile/blob/main/docs/style.md#fixes-format
(Fine to have it in prose here, but please also include the regular form -- makes it easier to spot when scanning the commit message)
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: do disarm these @-mentions so that GitHub doesn't interpret them
Ooh, good catch. These didn't cross my mind as problematic; I guess either GitHub recognizes "all" and "everyone" in some special way, or maybe I've accidentally at-mentioned people with those strings as their usernames (oops!).
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.
Yeah, I was curious and so I expanded those commits where they appear in the main PR page here on GitHub, and hovered on the mentions -- they do in fact get recognized as mentions, of these organizations:
https://github.com/all
https://github.com/everyone
The latter has a logo for its avatar, and a description:
We are Everyone, a digital communications agency based in Glasgow, Scotland.
Both of them appear to be ordinary non-special organizations, though as it happens not individuals.
| ), | ||
| }: Section<UserGroup>), | ||
| ({ | ||
| data: wildcardMentionForQuery != null ? [wildcardMentionForQuery] : [], |
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.
It looks like we're not actually using in this component the fact that there's just one of these, right?
In that case, likely simpler to have the helper function return the list, and have it just be an internal fact about that function that it only ever returns at most one item.
I'm not following the details of the discussion, so sorry if this was already mentioned, but the "all" looks shifted to the left compared to everything else in the "after" screenshot. |
Yeah, that part was fixed by #5551. I believe the "after" of this PR, now that #5551 is merged, will look just like it did in the previous revision: |
|
(FWIW @chrisbobbe for next time when splitting out part of a PR that's readier for merge, my suggestion would be: move that part to the start of the branch, send it as its own PR, but keep the main PR based on top of that so that the tip of the PR still has all the changes. At least in a case like this one where the split-out changes are needed in order to get the final screenshot to look right, or more generally where the changes in the main PR depend on those in the split-out PR.) |
Sure, in retrospect I think that would've made sense in this case. Although, this time you did say "break out" the commits as a new PR, in part because they had a "different job from the rest of the branch". 😛 |
With ImageEmoji being the same as RealmEmoji except for an added reaction_type property. See discussion: zulip#5508 (comment)
f853559 to
9d748a0
Compare
|
Thanks for the review! Revision pushed. |
|
OK, this all looks good! With just one commit-message nit: That last paragraph can just be deleted, I think -- it's describing a change that now occurs in the previous commit, and is described there. I guess the latter doesn't mention the specific zulip/zulip PR, so you could move that information there. I would say I'll just fix that up and merge, but this is a rare occasion when I have urgent work: #5545, where the server side is actively being iterated on right now and we want to get both server and client side merged tonight for tomorrow's Zulip Server 6.0 release. So instead, please merge at will after handling the above comment. |
With ImageEmoji being the same as RealmEmoji except for an added reaction_type property. See discussion: zulip#5508 (comment)
The relevant Flow definition in @zulip/shared's typeahead.js.flow will soon change, when we take a @zulip/shared upgrade, so that reaction_type will be required (see zulip/zulip#23412). There's no problem adding it to EmojiForShared before taking the upgrade, though, since the @zulip/shared definition is an inexact object, meaning it isn't bothered by additional properties.
This brings a nice change to the typeahead code: the overabstracted function query_matches_source_attrs is removed, and query_matches_string is exported instead: zulip/zulip#23375
@zulip/shared implemented this in zulip/zulip@21778, and it was released (with a needed Flow-type fix) in 0.0.16, which we just upgraded to in the previous commit. From reading code, I believe this doesn't change the emoji-matcher behavior that we offer to the user, so marking NFC.
Making sure to keep comments saying we don't like these hacky fake user objects.
We'll use this soon so we can follow the web app in describing @-all / @-everyone in the PeopleAutocomplete as "Notify stream" or "Notify recipients", according to the type of conversation narrow (topic or PM).
…ntions
As the comments point out, we've been using a hack where we make
fake "user" objects for wildcard mentions @-all and @-everyone, so
we can enlist UserItemRaw to show items for these in the people
autocomplete.
Clear out that hack and make a new UI component for showing wildcard
mentions in the autocomplete.
While we're at it, make some improvements:
- Show the Font Awesome bullhorn icon, like the web app.
- Re: the explanatory text, previously "(Notify everyone)":
- It now says "Notify stream" when composing a stream message, and
"Notify recipients" when composing a PM, following the web app.
- It doesn't have parentheses anymore. The web app uses them to
distinguish the explanatory text from the special string that
triggers the mention, as in "all (Notify stream)". We already do
that by putting the explanatory text on a new line, in a smaller
font.
- It's now wired up for translation.
- We now show "stream", not just "all" and "everyone", fixing zulip#4325.
- A wildcard mention will now show up if your search term matches
the translation of it in your chosen language.
- We now use shared code (`typeahead.query_matches_string`)
for match-modulo-diacritics logic.
Fixes: zulip#4325
This type saved us the trouble of faking every last boring detail of a whole UserOrBot object, in the world where we used fake user-like objects for wildcard mentions. We stopped using those in the previous commit, so we don't need this type anymore, and we can just say we're passing around whole UserOrBot objects because that's what we're doing.
9d748a0 to
2d73026
Compare
|
Done, thanks for the review! |
With ImageEmoji being the same as RealmEmoji except for an added reaction_type property. See discussion: zulip#5508 (comment)






Before this, we were co-opting
UserItemRawto represent wildcard mentions@alland@everyonein the people autocomplete, pretending that both of those was somehow a "user item".Stop doing that, and make a more dedicated UI for these, with some small improvements:
Screenshots below.
(edit: description updated to reflect current revision.)
Fixes: #4325