-
Notifications
You must be signed in to change notification settings - Fork 42
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
Inline conversation updates. Fixes #473. #688
Inline conversation updates. Fixes #473. #688
Conversation
Ok, so I've been looking into this. @creviera I may be missing something here, but AFAICT it already works in terms of In the
Note the line three from the bottom where the I'm probably misunderstanding what you're asking for here, but when I pretend to be a source via the local version of SD website, I don't even appear to have the opportunity to update or change the content of the message I (as a source) have sent. I.e. the content of I have a feeling I'm getting the wrong end of the stick here. ;-) |
Also fixes #635 |
Ah you are right. We already connect the securedrop-client/securedrop_client/gui/widgets.py Lines 1572 to 1581 in 15314ae
So you don't need to worry about updating the MessageWidget since it is a SpeechBubble widget which handles the signal by updating the text |
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.
just read through this diff, this approach so far makes sense to me!
viewport_height = self.scroll.viewport().height() | ||
|
||
if current_val + viewport_height > max_val: | ||
if self.reply_flag and max_val > 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.
ah, this is a nice way to handle the scrolling behavior
OK folks... this is ready to review now that all the tests pass. ;-) Something to bring to your attention:
Hurrah! 🎉 💬 |
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.
on_reply_sent
used to immediately add the reply to the conversation. This no longer happens because it was creating duplicate entries in the conversation view for the reply item. However, there needs to be some indication that the reply is in flight. I can easily add something to this PR (a spinner or some other such signal as we may agree/discuss with @ninavizz). Alternatively, this could be a new issue.
The current implementation of pending replies saves them to the draftreplies
table and then removes them from there when they have been successfully sent. In the GUI these pending replies show up as more transparent as you see here in the design: https://app.zeplin.io/project/5c807ea562f734bd2756b243/screen/5d5b183a152c905223e5fab0
See how we add a draft reply with a pending status to the local db before creating a job and sending it off to the server:
securedrop-client/securedrop_client/logic.py
Lines 787 to 799 in f391abe
reply_status = self.session.query(db.ReplySendStatus).filter_by( | |
name=db.ReplySendStatusCodes.PENDING.value).one() | |
draft_reply = db.DraftReply( | |
uuid=reply_uuid, | |
timestamp=datetime.utcnow(), | |
source_id=source.id, | |
journalist_id=self.api.token_journalist_uuid, | |
file_counter=source.interaction_count, | |
content=message, | |
send_status_id=reply_status.id, | |
) | |
self.session.add(draft_reply) | |
self.session.commit() |
And here you'll see how we delete the draft reply and add a non-draft reply within the SendReplyJob:
securedrop-client/securedrop_client/api_jobs/uploads.py
Lines 59 to 65 in 6be344c
update_draft_replies(session, source.id, draft_timestamp, | |
draft_file_counter, new_file_counter) | |
# Delete draft, add reply to replies table. | |
session.add(reply_db_object) | |
session.delete(draft_reply_db_object) | |
session.commit() |
Hopefully this points you to the code and design docs you need to see why we have this feature and how it should work.
@creviera your comments about |
Hmmm... not sure why the tests failed. They work for me locally. Investigating. |
OK... looked into the CI fail. Not sure what's going on since the tests are supposed to be isolated from each other and the test is exactly the same as |
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 see pending replies show up now! I haven't looked at why your test is failing yet, but it looks like the ConversationView widgets are missing their spacing and sometimes overlap when the GUI is updated, see:
I wonder if this is a layout spacing issue or perhaps the index logic that determines where we need to start redrawing widgets has a bug in it. I can take a closer look later today.
@creviera hmm... I didn't encounter the spacing issue while testing (highly likely to be my oversight). Feel free to bat it back in my court -- happy to fix up my own mistaikes. ;-) |
@eloquence that is, indeed, the case (wrt #635) |
@creviera OK... I've been able to reproduce and fix all the bugs you mention except the final one (which I've not been able to reproduce, despite no end of redrawing, rescaling, maximising, minimizing, sending of messages and so on). The actual fix itself was very simple and addressed a bug where the widget was drawn over or mistakenly deleted if in a failed-to-send state. I've also added a test to ensure this case is explicitly checked. Also, thanks for sharing that really cute trick for making SD server randomly fail. That helped a LOT. 👍 |
Also, trying to figure out how to properly test with a |
amazing! will test and verify |
I tested all the following bugs, which no longer occur:
Nice work! |
Note: once you rebase, we can merge |
Rebased. 👍 |
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 don't have an STR yet, but I'm seeing a new issue where existing speech bubbles are getting added to the conversation view more than once. It looks like whenever I send a reply that fails, then existing successful messages and replies are added again to the conversation. This might happen only when resizing the window. I will try to create an STR to repro but here you can see that the "This is a test submission without markup!" and "This is a test submission with markup..." have been copied multiple times:
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 am unable to repro the repeating messages and replies. Since it has only happened once for me, I will create an issue in case someone else runs into this.
looks like this needs another rebase |
Rebased. |
looks like you need to rebase onto --- a/securedrop_client/gui/widgets.py
+++ b/securedrop_client/gui/widgets.py
@@@ -2483,10 -2436,16 +2517,21 @@@ class ConversationView(QWidget)
"""
Add a message from the source.
"""
++<<<<<<< HEAD
+ conversation_item = MessageWidget(message.uuid, str(message), self.controller.message_ready)
+ self.conversation_layout.addWidget(conversation_item, alignment=Qt.AlignLeft)
++=======
+ if message.content is not None:
+ content = message.content
+ else:
+ content = '<Message not yet available>'
- def add_reply(self, reply: Union[DraftReply, Reply]) -> None:
+ conversation_item = MessageWidget(message.uuid, content, self.controller.message_ready, index)
+ self.conversation_layout.insertWidget(index, conversation_item, alignment=Qt.AlignLeft)
+ self.current_messages[message.uuid] = conversation_item
++>>>>>>> A working PoC which requires feedback and tests. Fixes #473.
+
+ def add_reply(self, reply: Union[DraftReply, Reply], index) -> None:
"""
Add a reply from a journalist to the source.
""" |
01bd4ef
to
8d3c507
Compare
@creviera OK... some careful git unpicking and a rebase later... I've had to force push. Please check. |
Fix freedomofpress#61 to supercede freedomofpress#685. Make on_reply_sent work properly without duplicate entries.
8d3c507
to
abac2cc
Compare
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.
all pr comments were addressed and bugs fixed. time to merge!
Description
Fixes #473.
Fixes #635.
Fixes #691.
This is proof of concept ensures we're not deleting and recreating messages in a conversation each time a new message is added to the conversation or an update occurs.
It also handles cases where the messages are re-ordered after an update, and makes it possible to inline-update further attributes of messages as they change through time.
It was also an opportunity for me to deep-dive back into the guts of the application and figure out how it all fits together again..! 🔬 👀 🐍 What you see is my stab at a simple and flexible solution.
The comments / annotations in the code should explain what's going on. Please take a look and, as always, I welcome ideas, constructive criticism and other feedback. Assuming, via discussion of the PR, we settle on the approach, I can pick this up again on Monday (my next FPF day) and make it into a "proper" PR with tests and other essentials.
Thanks in advance for your contributions..! 👍
Test Plan
To be done.
Checklist
If these changes modify code paths involving cryptography, the opening of files in VMs or network (via the RPC service) traffic, Qubes testing in the staging environment is required. For fine tuning of the graphical user interface, testing in any environment in Qubes is required. Please check as applicable: