-
Notifications
You must be signed in to change notification settings - Fork 241
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 file viewer #7270
Refactor file viewer #7270
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.
@ch-iv great work! The code in this component is quite thorny, and you've done a good job teasing it apart. I've left a few comments on how you can streamline further (with a bit more aggressive refactoring).
One thing to watch out for as you are doing manual tests of your code is to make sure in the grading view that annotations are correctly rendered as files are switched, when switching between viewers of different types (e.g., pdf -> text) and between different files that use the same viewer.
}); | ||
} | ||
}); | ||
this.setFileUrl(submission_file_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.
Similar to my comment on your other PR, this function calls setState
, which isn't synchronous. As you probably noticed, in the current implementation of setFileUrl
, all of the URL-creation code is synchronous except the heic
/heif
image formats, which currently require a separate request to be made.
You can try doing the following:
- Move the heic/heif handling into the
ImageViewer
component, where it more logically belongs - Change
this.setFileUrl
tothis.getFileUrl
and just (synchronously) return a URL, and then use that to set the initial url in thesetState
call on line 114 - Ideally set the
type
state in that initial call (L114) as well, so that you don't need the if branch code on Lines 122-124 - See also my comment on the plaintext/binary branch a bit further below
if (response.ok) { | ||
return response.text(); | ||
} | ||
const delimiter = this.props.selectedFileURL.includes("?") ? "&" : "?"; |
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 delimiter-handling part is quite awkward; I believe you're running into this because you're trying to unify the handling of multiple different URLs.
Rather than insert this here, please modify how the URLs are originally generated to include these query parameters directly. (I assume this will involve a few different locations, because of the different places this component is used.)
return response.text(); | ||
} | ||
const delimiter = this.props.selectedFileURL.includes("?") ? "&" : "?"; | ||
fetch( |
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.
Okay, so a larger change you can make (which I'd support) is to move the content fetching here into the TextViewer
and BinaryViewer
components. This will make the different viewer components more uniform in how they fetch data, and help simplify the FileViewer
code.
Pull Request Test Coverage Report for Build 12455551235Details
💛 - Coveralls |
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.
Nice work, @ch-iv! In addition to the inline comments, you can go ahead and remove all traces of the get_file
method. This includes the controller method, the routes.rb
file, the submission_policy.rb
file, and any related tests.
|
||
return ( | ||
<React.Fragment> | ||
<div style={{display: this.state.loading || this.state.errorMessage ? "none" : "block"}}> |
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 extra div is causing a rendering problem with the PDF viewer (height collapsing).
Fixing CSS is a bit tricky; instead of wrapping in a div, you can pass a display
prop to each viewer, and use that to control the display of each component.
this.display_annotations(); | ||
this.adjustPictureSize(); | ||
this.rotateImage(); | ||
if (this.props.url && this.props.url !== prevProps.url) { |
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.
Oh, sorry I realized that only the setImageURL
should be guarded in this way. The this.display_annotations
/this.adjustPictureSize
/this.rotateImage
should always trigger, otherwise the annotations won't show up properly. (Test in UI by creating an annotation and changing the zoom/rotation.)
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.
Thank you, @ch-iv!
Proposed Changes
This PR refactors the
FileViewer
component and some of the adjacent components. The changes include:/get_file
endpointFileViewer
to theImageViewer
These changes make the structure of the file viewer more logical and easier to change in the future. This also introduces a small frontend performance improvement by doing one less http request.
Screenshots of your changes (if applicable)
Associated documentation repository pull request (if applicable)
Type of Change
(Write an
X
or a brief description next to the type or types that best describe your changes.)Checklist
(Complete each of the following items for your pull request. Indicate that you have completed an item by changing the
[ ]
into a[x]
in the raw text, or by clicking on the checkbox in the rendered description on GitHub.)Before opening your pull request:
After opening your pull request:
Questions and Comments
(Include any questions or comments you have regarding your changes.)