-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Report Attachments Modal Route #20167
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
Report Attachments Modal Route #20167
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.
This PR is ready for code review
I'll be able to continue and add testing steps and check all platforms tomorrow ✅
src/ROUTES.js
Outdated
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 think I can remove the changes here and in linking which would disable deep linking, but also prevent me from using the global Navigation object in ImageRenderer (I'll post a similar note there)
Right now if we refresh the page or copy paste the URL while we have the attachment carousel open, it would load the page with the attachment carousel open
The question is, do we want to deliberately not allow this? It can be used as a feature linking to specific attachments
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 can be replaced by a call to useNavigation and then navigation.navigate('Report_Attachment', {.reportID, source })
Everywhere else we use Navigation.navigate and ROUTES so I've opted for the same approach here, but this allows deep linking and link sharing and this feature might be unwanted
|
@NikkiWines @rushatgabhane One of you needs to copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
The Carousel already updates the parent component this way, when attachments change Updating it here allows the parent component to not need `isAuthenticated` and `originalFileName` for the initial image source provided, since they are obtained here as well
|
@kidroca @NikkiWines sorry i was out sick and couldn't review the PR in time. |
|
@NikkiWines I'll be taking this over. Please assign this to me. |
|
@kidroca Can you please resolve conflicts? |
|
Yes, I'll look into it tonight |
Otherwise, when closing the modal there's a blank screen displayed briefly It seems the previous screen does not stay underneath the modal unless it's on the root
ff20435 to
3d5bc85
Compare
kidroca
left a comment
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.
Please be aware that a significant overhaul to the navigation structure in the main branch, introduced some merge conflicts. I've managed to resolve these conflicts, but in the process, I found it necessary to implement some additional changes to ensure seamless integration and functionality.
All merge conflicts have been successfully resolved ✅
| <RootStack.Screen | ||
| name={SCREENS.REPORT_ATTACHMENTS} | ||
| options={{ | ||
| headerShown: false, | ||
| presentation: 'transparentModal', | ||
| }} | ||
| getComponent={() => { | ||
| const ReportAttachments = require('../../../pages/home/report/ReportAttachments').default; | ||
| return ReportAttachments; | ||
| }} | ||
| listeners={modalScreenListeners} | ||
| /> |
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.
Utilizing RootStack.Screen proved to be the only viable solution for overlaying the modal over the opened chat. I tested alternative navigators such as CENTRAL_PANE_NAVIGATOR, FULL_SCREEN_NAVIGATOR, and RIGHT_MODAL_NAVIGATOR. However, these alternatives resulted in a blank screen beneath the modal. This undesired outcome was visible for at least half a second during the modal's closing transition.
Sample Behavior When Not Using RootStack
Please refer to the following link for a demonstration of this behavior without the use of RootStack:
Android.Emulator.-.Pixel_2_API_29_5554.2023-06-14.16-28-43.mp4
Sample Behavior When Using RootStack
For comparison, the following link shows the preferred outcome achieved when utilizing RootStack:
Android.Emulator.-.Pixel_2_API_29_5554.2023-06-14.16-31-27.mp4
| if (lastRoute.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR || lastRoute.name === NAVIGATORS.FULL_SCREEN_NAVIGATOR) { | ||
| // if we are not in the target report, we need to navigate to it after dismissing the modal | ||
| if (targetReportID && targetReportID !== getTopmostReportId(rootState)) { | ||
| const state = getStateFromPath(ROUTES.getReportRoute(targetReportID)); | ||
|
|
||
| const action = getActionFromState(state, linkingConfig.config); | ||
| action.type = 'REPLACE'; | ||
| navigationRef.current.dispatch(action); | ||
| } else { | ||
| navigationRef.current.dispatch(StackActions.pop()); | ||
| switch (lastRoute.name) { | ||
| case NAVIGATORS.RIGHT_MODAL_NAVIGATOR: | ||
| case NAVIGATORS.FULL_SCREEN_NAVIGATOR: | ||
| case SCREENS.REPORT_ATTACHMENTS: | ||
| // if we are not in the target report, we need to navigate to it after dismissing the modal | ||
| if (targetReportID && targetReportID !== getTopmostReportId(rootState)) { | ||
| const state = getStateFromPath(ROUTES.getReportRoute(targetReportID)); | ||
|
|
||
| const action = getActionFromState(state, linkingConfig.config); | ||
| action.type = 'REPLACE'; | ||
| navigationRef.current.dispatch(action); | ||
| } else { | ||
| navigationRef.current.dispatch(StackActions.pop()); | ||
| } | ||
| break; | ||
| default: { | ||
| Log.hmmm('[Navigation] dismissModal failed because there is no modal stack to dismiss'); |
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 found it necessary to introduce an extra OR condition in our logic. For better readability and understanding of the flow, I decided to convert this structure into a switch statement.
|
@kidroca Can you please resolve the conflicts again? |
|
@allroundexperts just dropping a friendly note that you should review the code without waiting for @kidroca to resolve the conflicts. Especially if the conflicts are something trivial.
|
Thanks @rushatgabhane! |
# Conflicts: # src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.js # src/libs/Navigation/Navigation.js
|
@allroundexperts @rushatgabhane The updates introduced in PR #20338 have led to a new merge conflict that isn't straightforward to resolve. In these changes, the The approach from my PR, which depended on receiving only the report ID as a string, is no longer compatible: App/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.js Lines 57 to 58 in 3d5bc85
To address this, I propose adjusting the logic so that we continue to pass only the |
|
Conflicts resolved ✅ Screenshots / videos updated |
allroundexperts
left a comment
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 is looking good. All yours @NikkiWines!
NikkiWines
left a comment
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.
Looks good and tests well - Going to add @chiragsalian as a reviewer for a third set of eyes since he helped review the proposal
| const reportID = _.get(props, ['route', 'params', 'reportID']); | ||
| const report = ReportUtils.getReport(reportID); | ||
| const source = decodeURI(_.get(props, ['route', 'params', 'source'])); |
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.
NAB: these can all be used inline instead of declared separately
chiragsalian
left a comment
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.
Code LGTM and seems to work well. There is a feature freeze atm so i won't be merging this PR but i had one question, shouldn't we update the attachment URL when the user switches between attachments? I'm a little concerned that it could be confusing for a user seeing the same attachment URL while switching between multiple attachments
I had the same question @chiragsalian. I agree that it is confusing for the user. |
|
I appreciate the thought of changing the URL to provide feedback to the user when they switch attachments. This could indeed be helpful, especially in scenarios where the same attachment might be uploaded multiple times consecutively. However, I am unsure about the overall benefit of this change. Only a small portion of the URL (around 5-10 digits we see) would vary between different attachments, while the majority of the URL would remain the same. This might not provide a significant difference in feedback to the user. If we decide to proceed with this change, I would suggest implementing it as a separate pull request. This way, it would be easier to review and test independently. |
|
Feature freeze is over! @kidroca might be good just to pull |
|
Hmm sure i am fine with a separate pull request to make things easier to review/test.
Yeah no matter how small the change i like URLs to match what the user sees. Its always possible one chat report to another has just 1 different digit, but it is still valuable to keep the URL up to date imo. |
|
I'll go ahead and merge this PR to get it out the door soon. If something is wrong with it QA should hopefully catch problems. I'll mention in the issue that we'll be updating the URL realtime as a follow up. |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by https://github.com/chiragsalian in version: 1.3.36-0 🚀
|
|
@Julesssss
If this PR did break downloads it should have been caught I'll take a look for a potential cause as I'm already working on another carousel update |
|
Thanks for looking, what you said makes sense 👍 This is just occuring on staging, so it might not have shown up anyway during testing. |
|
We have a blocker (a relatively trivial one, IMO) that was introduced in this last release and since this PR is the only one that has to do with attachments, I'm wonder if didn't introduce this bug. |
|
@deetergp, you've made a valid point. Prior to this, I was unaware of the existing functionality that relied upon a specific hierarchy to restrict drag and drop actions over attachments. It's plausible that by altering this hierarchy, I unintentionally introduced the issue at hand. |
|
🚀 Deployed to production by https://github.com/Julesssss in version: 1.3.36-5 🚀
|
| function ReportAttachments(props) { | ||
| const reportID = _.get(props, ['route', 'params', 'reportID']); | ||
| const report = ReportUtils.getReport(reportID); | ||
| const source = decodeURI(_.get(props, ['route', 'params', 'source'])); |
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 source can be a number (viewing assets in native) but the decoded uri is always a string which makes the image fail to load. We needed to preserve the type of the passed source. (Coming from #31138)
|
We missed handling a case for inaccessible report images. When the user opens a link to attachment where the user does not have access to the report, the attachment modal keeps on loading. #23374 |

Details
In this PR, I have made several enhancements to the existing code to improve the handling of report attachments. Key changes include the addition of a new modal screen
src/pages/home/report/ReportAttachments.js, modifyingAttachmentModalto make the passing ofchildrenoptional, and the addition of adefaultOpenprop toAttachmentModal. A new route,REPORT_ATTACHMENT, has also been introduced.Changes:
src/ROUTES.js:
A new route named
REPORT_ATTACHMENThas been added. It is structured asr/:reportID/attachment?source=...and has an associated getter function for generating this URL with the required parameters.src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.js:
The AttachmentModal component usage has been replaced with navigation to the new
REPORT_ATTACHMENTroute.src/libs/Navigation/AppNavigator/AuthScreens.js:
The new
Report_Attachmentsscreen has been registered in the application's authenticated screens.src/libs/Navigation/linkingConfig.js:
The
Report_Attachmentsscreen has been added to the linking configuration, enabling it to be opened via URL schemes or deep linking.src/components/AttachmentCarousel/index.js:
Use
onNavigateto update the parent modal's state with additional information about the selected attachment - file name and auth requirementssrc/components/AttachmentModal.js:
The
childrenprop is now optional, and a newdefaultOpenprop has been added, which determines whether the modal should be open by default.src/pages/home/report/ReportAttachments.js:
This new file creates the ReportAttachments component, which returns an
AttachmentModalthat's set todefaultOpen. It takes areportIDandsourceas parameters from the route, and on modal hide, it dismisses the modal.Fixed Issues
$ #18451
PROPOSAL: #18451 (comment)
Tests
Test 1: Verify Existing Functionality is Unaltered
Objective: To ensure that the implemented changes haven't affected the existing functionality.
Expected Outcomes:
Note: This PR does not address existing known issues such as the carousel occasionally displaying the wrong image (as detailed in #18150 (comment)).
Test 2: Verify the issue with deleting an image is resolved
Objective: To ensure that the main issue with deleting attachments is resolved
Expected Outcomes:
Offline tests
N/A
Opening an attachment while offline should have the same behavior as it did before - the attachment appears to load indefinitely. We can close the attachment view and return to the chat.
QA Steps
Test 1: Verify Existing Functionality is Unaltered
Objective: To ensure that the implemented changes haven't affected the existing functionality.
Expected Outcomes:
Note: This PR does not address existing known issues such as the carousel occasionally displaying the wrong image (as detailed in #18150 (comment)).
Test 2: Verify the issue with deleting an image is resolved
Objective: To ensure that the main issue with deleting attachments is resolved
Expected Outcomes:
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)myBool && <MyComponent />.src/languages/*files and using the translation methodWaiting for Copylabel for a copy review on the original GH to get the correct copy.STYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)/** comment above it */thisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor)thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG))Avataris modified, I verified thatAvataris working as expected in all cases)ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Web
Screen.Recording.2023-06-06.at.21.23.53.mov
Mobile Web - Chrome
2023-06-21_22-06-18.mp4
Mobile Web - Safari
Screen.Recording.2023-06-06.at.21.27.54.mov
Desktop
Screen.Recording.2023-06-06.at.21.27.54.mov
iOS
Screen.Recording.2023-06-06.at.21.23.53.mov
Android
2023-06-21_22-10-18.mp4