-
-
Notifications
You must be signed in to change notification settings - Fork 323
Add support for 'starred' typeaheads #794
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
Changes from all commits
8938c09
9e8513b
275ec11
a3be878
195bc42
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -164,30 +164,43 @@ def _stream_box_autocomplete(self, text: str, state: Optional[int] | |
| def generic_autocomplete(self, text: str, state: Optional[int] | ||
| ) -> Optional[str]: | ||
| autocomplete_map = OrderedDict([ | ||
| ('@_', self.autocomplete_mentions), | ||
| ('@_', self.autocomplete_users), | ||
| ('@_**', self.autocomplete_users), | ||
| ('@', self.autocomplete_mentions), | ||
| ('@*', self.autocomplete_groups), | ||
| ('@**', self.autocomplete_users), | ||
| ('#', self.autocomplete_streams), | ||
| ('#**', self.autocomplete_streams), | ||
| (':', self.autocomplete_emojis), | ||
| ]) | ||
|
|
||
| # Look in a reverse order to find the last autocomplete prefix used in | ||
| # the text. For instance, if text='@#example', use '#' as the prefix. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not related to this commit, but I think I should point out that the server does allow names to start with
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a bug I suppose, but I'm not sure what we can do unless we disable
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kaustubh-nair I added a FIXME to the code here for now. One option I just thought of might be to allow multiple different autocompletes - maybe |
||
| reversed_text = text[::-1] | ||
| for reverse_index, char in enumerate(reversed_text): | ||
| # Patch for silent mentions. | ||
| if (char == '_' and reverse_index + 1 < len(reversed_text) | ||
| and reversed_text[reverse_index + 1] == '@'): | ||
| char = '@_' | ||
|
|
||
| if char in autocomplete_map: | ||
| prefix = char | ||
| autocomplete_func = autocomplete_map[prefix] | ||
| prefix_index = max(text.rfind(prefix), 0) | ||
| break | ||
| else: | ||
| # Return text if it doesn't have any of the autocomplete prefixes. | ||
| # FIXME: Mentions can actually start with '#', and streams with | ||
| # anything; this implementation simply chooses the right-most | ||
| # match of the longest length | ||
| prefix_indices = { | ||
| prefix: text.rfind(prefix) | ||
| for prefix in autocomplete_map | ||
| } | ||
| found_prefix_indices = { | ||
| prefix: index | ||
| for prefix, index in prefix_indices.items() | ||
| if index > -1 | ||
| } | ||
| # Return text if it doesn't have any of the autocomplete prefixes. | ||
| if not found_prefix_indices: | ||
| return text | ||
|
|
||
| # Use latest longest matching prefix (so @_ wins vs @) | ||
| prefix_index = max(found_prefix_indices.values()) | ||
| prefix = max( | ||
neiljp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| (len(prefix), prefix) | ||
| for prefix, index in found_prefix_indices.items() | ||
| if index == prefix_index | ||
| )[1] | ||
| autocomplete_func = autocomplete_map[prefix] | ||
|
|
||
| # NOTE: The following block only executes if any of the autocomplete | ||
| # prefixes exist. | ||
| typeaheads, suggestions = ( | ||
|
|
@@ -222,11 +235,21 @@ def autocomplete_mentions(self, text: str, prefix_string: str | |
| ) -> Tuple[List[str], List[str]]: | ||
| # Handles user mentions (@ mentions and silent mentions) | ||
| # and group mentions. | ||
| groups = [group_name | ||
| for group_name in self.model.user_group_names | ||
| if match_group(group_name, text[1:])] | ||
| group_typeahead = format_string(groups, '@*{}*') | ||
|
|
||
| user_typeahead, user_names = self.autocomplete_users( | ||
| text, prefix_string | ||
| ) | ||
| group_typeahead, groups = self.autocomplete_groups( | ||
| text, prefix_string | ||
| ) | ||
|
|
||
| combined_typeahead = user_typeahead + group_typeahead | ||
| combined_names = user_names + groups | ||
|
|
||
| return combined_typeahead, combined_names | ||
|
|
||
| def autocomplete_users(self, text: str, prefix_string: str | ||
| ) -> Tuple[List[str], List[str]]: | ||
| users_list = self.view.users | ||
| matching_users = [user | ||
| for user in users_list | ||
|
|
@@ -241,12 +264,26 @@ def autocomplete_mentions(self, text: str, prefix_string: str | |
| reverse=True) | ||
|
|
||
| user_names = [user['full_name'] for user in sorted_matching_users] | ||
| user_typeahead = format_string(user_names, prefix_string + '**{}**') | ||
| extra_prefix = "{}{}".format( | ||
| '*' if prefix_string[-1] != '*' else '', | ||
| '*' if prefix_string[-2:] != '**' else '', | ||
| ) | ||
| user_typeahead = format_string(user_names, | ||
| prefix_string + extra_prefix + '{}**') | ||
|
|
||
| combined_typeahead = user_typeahead + group_typeahead | ||
| combined_names = user_names + groups | ||
| return user_typeahead, user_names | ||
|
|
||
| return combined_typeahead, combined_names | ||
| def autocomplete_groups(self, text: str, prefix_string: str | ||
| ) -> Tuple[List[str], List[str]]: | ||
| prefix_length = len(prefix_string) | ||
| groups = [group_name | ||
| for group_name in self.model.user_group_names | ||
| if match_group(group_name, text[prefix_length:])] | ||
|
|
||
| extra_prefix = '*' if prefix_string[-1] != '*' else '' | ||
| group_typeahead = format_string(groups, | ||
| prefix_string + extra_prefix + '{}*') | ||
| return group_typeahead, groups | ||
|
|
||
| def autocomplete_streams(self, text: str, prefix_string: str | ||
| ) -> Tuple[List[str], List[str]]: | ||
|
|
@@ -256,7 +293,9 @@ def autocomplete_streams(self, text: str, prefix_string: str | |
| stream_typeahead = format_string(streams, '#**{}**') | ||
| stream_data = list(zip(stream_typeahead, streams)) | ||
|
|
||
| matched_data = match_stream(stream_data, text[1:], | ||
| prefix_length = len(prefix_string) | ||
|
|
||
| matched_data = match_stream(stream_data, text[prefix_length:], | ||
| self.view.pinned_streams) | ||
| return matched_data | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
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.
[minor] The commit title says that
*is added for non-silent mentions for groups & users. However,**is being added for users as well.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 clarified this text 👍