-
Notifications
You must be signed in to change notification settings - Fork 42
Refactor extract conversation FileWidget #1369
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
Refactor extract conversation FileWidget #1369
Conversation
The FileWidget is only ever used as part of a conversation, and the new package structure reflects that. I only touched the related files and I grouped them around domain concepts and features.
The packages provide namespacing, and class names don't need to be globally unique. Simpler names also make easier to highlight the parallels between different packages.
|
||
def test_class_name_matches_css_object_name_for_export_dialog(export_dialog): | ||
assert "ExportDialog" == export_dialog.__class__.__name__ | ||
def test_preferred_name_matches_css_object_name_for_export_dialog(export_dialog): | ||
assert "ExportDialog" in export_dialog.passphrase_form.objectName() |
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.
These two specific assertions are not met anymore. I decided not to touch the stylesheet in order to keep the changes scoped (they're large already 😬).
Eventually, I think that breaking the stylesheet into smaller files that follow the package structure would make maintenance easier, and also would make redundant the need to have global matching names for Python classes and QSS names.
Until then, PrintDialog
and ExportDialog
seems to me that they remain the most appropriate QSS names for conversation.ExportDialog
and conversation.PrintDialog
(even though they are called export.Dialog
and print.Dialog
as an implementaiton detail of the conversation
package.) Does this make sense?
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 convention, enforced by these tests, is to use the class name as the object name in the CSS to make it easier to find the relevant code. For now, let's stick to this convention and rename the CSS objects to match the new class names. This will make it cleaner when you're ready to move the relevant CSS code to the new project structure.
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 direction of this PR is great! I just have one main concern, which is that this change, left as is, breaks a couple conventions:
- tests should exist in a test structure that mirrors the project structure, e.g. tests that test
securedrop_client/gui/dialogs.py
need to go intests/gui/test_dialogs.py
, nottests/gui/test_widgets.py
- CSS object names should match the Python classes they are used in
If you refactor one class at a time, you can migrate the relevant tests so that you don't break these conventions, and it's still small enough for the reviewer.
Also, regarding CSS, were you thinking of doing something like this eventually?
styles/gui
├── auth
│ └── dialog.css
├── buttons.css
├── conversation
│ └── print
│ └── dialog.css
├── dialogs.css
└── ...
Or would you move the CSS files into the project structure like this:
securedrop_client/gui
├── __init__.py
├── auth
│ ├── __init__.py
│ └── dialog.py
│ └── dialog.css
├── buttons.py
├── buttons.css
├── conversation
│ ├── __init__.py
│ ├── export
│ │ ├── __init__.py
│ │ └── dialog.py
│ ├── file.py
│ └── print
│ ├── __init__.py
│ └── dialog.py
├── dialogs.py
├── dialogs.css
└── ...
Or keep it flat:
styles
├── auth_dialog.css
├── print_dialog.css
├── dialogs.css
└── ...
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 can add those changes 👍
Regarding the stylesheets location, I have a strong preference for the second layout you described, where the all the parts of a given component are grouped together, for a few reasons:
- That option splits concerns by component, which in our case closely aligns with the domain boundaries (e.g.
auth
,conversation
,source
, "conversation export feature", "source deletion feature" are concepts that are shared by the team beyond the code.) - That option also makes clear the fact that components are scoped to themselves. Because all the files are grouped together it makes less likely that dependencies will be drawn from unrelated places.
- I find the separation by language just as arbitrary and not very convenient in practice when I work with components. After all, QSS and Python code do indeed change together (we even have tests to check object names and QSS names are in sync!). YMMV (Support material - that entire side deck is interesting IMHO)
What do you think @creviera? (and @rocodes @Er1kkkaaa!)
Note: this thread is relevant to #303
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 agree with your points. 🚀
Since there's a lot of code moving around, it might make sense to break this up into multiple commits or PRs scoped to moving one class/file at a time, e.g. move ModalDialog
and any associated css and tests from widgets.py
, test_widgets.py
, and some-name.css into dialogs.py
, test_dialogs.py
, and dialog.css
. This should make both of our lives much easier during the migration and review of the migration. Otherwise, I'm down for a slower review where I piece it all together in the diffs.
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 there's a lot of code moving around, it might make sense to break this up into multiple commits or PRs scoped to moving one class/file at a time [...]
Yes! I was thinking the same, I'll "re-package" this PR (and #1373) into one-class-at-a-time chunks. 👍
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 road mapping purposes, I'll proceed as follows:
-
misc
(removing all class definitions fromgui/__init__.py
) Remove component definitions from package __init__ file #1377 -
auth
(currently is the smaller package) -
actions
(made possible by ☝️ if I remember correctly) -
conversation/file
-
conversation/export
-
conversation/print
I'm not 100% sure about the end of the sequence, but I'll update when we get there.
@gonzalo-bulnes should we close this PR since you're breaking it up now? |
@creviera The review plan here is:
Happy to 🍐 on this (you review, I rebase the branches as we go).
|
I'll close this PR, as the updated checklist is done now 🙂 Note that nor all the moves were actually performed (initial intent), but I think those can be performed as we go. |
Description
This is preliminary work relevant to #1354. This PR moves (but doesn't otherwise modify) the widgets involved in drawing the files (
FileWidget
) in the conversation timeline. Providing user feedback while downloading the files will expand on existingFileWidget
behavior, and it will be easier to manage change in a small file than it would be inwidgets.py
.Goal: Make clearer which widgets depend on which, and package together the ones that are likely to change together. For the package names, I went for "domain concepts" (e.g. Source, Conversation, authentication...) and features (e.g. export, print...). The idea is that the domain should only change slowly (stability is good) and features can be added or removed all at once, so it's nice when they're relatively independent and clearly identified. Naming is hard and YMMV, please comment what you think!! 🙂
Package structure at this point
Closes #1340
Test Plan
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:
If these changes add or remove files other than client code, the AppArmor profile may need to be updated. Please check as applicable:
If these changes modify the database schema, you should include a database migration. Please check as applicable:
main
and confirmed that the migration applies cleanlymain
and would like the reviewer to do so