-
-
Notifications
You must be signed in to change notification settings - Fork 250
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
Add support for Polls Widget on ZT. #1551
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.
@rsashank This update looks good, and being able to see the poll votes is useful. This looks fine in a separate popup for now 👍
Having polls update via events would be the obvious next step here, though we may want to focus on merging the todo PR first to make integrating this easier?
zulipterminal/core.py
Outdated
voter_names = [] | ||
for voter_id in voter_ids: | ||
user_info = self.model.get_user_info(voter_id) | ||
if user_info: | ||
voter_names.append(user_info["full_name"]) |
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.
Is this new data structure code here, instead of the new view class, since it accesses the model, or for some other reason?
In any case, user_name_from_id
would be a lighter-weight function to use, if only accessing the name.
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, I included it here since I'm accessing the model.
Got it, updated with user_name_from_id
.
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.
You addressed the latter point, but I'm not sure why the conversion into the format required for the popup occurs here, rather than in the popup code itself?
(this was my first point 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.
Oops my bad, I had a response written that I forgot to submit as a review.
Added process_poll_widget function to process submessages containing a poll widget. Returns the question of the poll along with options and their voters in a dict.
SHOW_POLL_VOTES : 'v' to check votes for a given poll.
Takes poll_question and options as an input and displays voters for each option.
Creates an instance of PollResultsView class and shows the popup.
This prevents an empty-title popup in the Poll Results view.
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.
@rsashank Thanks for the update - this looks rather close to being ready 🎉 I tested this manually and had to remind myself why the poll updates were working even though you didn't add them in this PR! 😮
Generally, there are a few nits I noticed similar to the other PR and to avoid duplication, a few improvements to the popup, and some small possible restructuring.
The main point left to discuss is probably the key to use - or where to connect the popup to. That's not critical before merging, though I'm often wary of accepting a new hotkey unless we know it's "safe" and won't impact things later. It's easy enough to change in a later commit, but since we're not currently releasing regularly then in principle anyone may use this and start using the hotkey!
If the latter becomes a sticking point, we can certainly merge the main part first, and leave the popup part to another PR (or similar).
poll_widget = ( | ||
f"<strong>Poll\n{poll_question}</strong>" | ||
if poll_question | ||
else "No poll question provided. Please add one via the web app." |
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: For this line and one further below, we might consider using a fixed string common to both cases, and adding a TODO comment which relates to the lack of this feature so far (in ZT).
if not self.poll_question: | ||
# If no poll question is provided, set a message to display | ||
# in Poll Results popup. | ||
self.poll_question = "No poll question provided." |
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 can do this last commit as part of an earlier commit when you first write this code, ie. setting a variable. This same text is used directly above, so that will avoid duplication. When you do the adding of the self.
prefix, the variable will already be available.
@@ -1185,4 +1186,6 @@ def keypress(self, size: urwid_Size, key: str) -> Optional[str]: | |||
self.model.controller.show_emoji_picker(self.message) | |||
elif is_command_key("MSG_SENDER_INFO", key): | |||
self.model.controller.show_msg_sender_info(self.message["sender_id"]) | |||
elif is_command_key("SHOW_POLL_VOTES", key) and self.widget_type == "poll": |
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 no options, the popup operates but shows no data - maybe we should just skip the popup if there is no extra data to show?
|
||
|
||
@pytest.mark.parametrize( | ||
"submessage, expected_poll_question, expected_options", |
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: plural, as in other PR.
"canned,1": {"option": "No", "votes": []}, | ||
"32159,1": {"option": "Maybe", "votes": [32159]}, | ||
}, | ||
id="poll_widget_with_multiple_voters", |
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: This test is known to be a poll_widget already, as with other PR.
self, | ||
controller: Any, | ||
poll_question: str, | ||
poll_options: Dict[str, Dict[str, Any]], |
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 type seems inaccurate? This is one benefit of defining more complex data types that you're passing around, even if via typeddicts, since you can refer to them as a name and update them in one place.
voters_display = ( | ||
"\n".join(map(str, voter_names)) | ||
if voter_names | ||
else f"{INVALID_MARKER} No votes yet" |
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 does make it stand out better 👍
|
||
options_with_names[option_key] = { | ||
"option": option_text, | ||
"votes": voter_names if voter_names else [], |
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: Is this conditional necessary?
def show_poll_vote( | ||
self, | ||
poll_question: str, | ||
options: Dict[str, Dict[str, Any]], |
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.
Assuming this is poll_options, this type is different again?
elif self.widget_type == "poll": | ||
self.poll_question, self.poll_options = process_poll_widget( |
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: You've added self.widget_type, but not initialized the others earlier in this commit.
What does this PR do, and why?
Add support to view polls
External discussion & connections
Polls - Widget Support #T986 #T1477
How did you test this?
Self-review checklist for each commit
Visual changes