Closed kbecciv closed 11 months ago
When clicking "Esc" multiple times, the attachment preview glitches.
The root cause here is buried quite deep and required a lot of debugging, so I'll try to be as detailed as possible here.
When we are hiding the attachments modal, we try to focus the composer, which causes the onScroll
event on the FlatList
inside the AttachmentCarousel
. This causes an avalanche effect of bugs.
This same RCA can be easier reproduced here: https://github.com/Expensify/App/issues/29109
In ComposerWithSuggestions, we are trying to focus the Composer
right after we hide the modal:
However, since the modal dismissal is an animated process, it's not happening right away. So we are, in fact, focusing on the composer when the modal is still open. The focus action fires a scroll event, which is then captured by the FlatList inside the AttachmentsCarousel (since FlatList is a combination of a VirtualizedList and a ScrollView).
Here's the call stack that comes all the way back to the ComposerWithSuggestions:
This, as a result, causes the onViewableItemsChanged
of the FlatList, which causes glitchy change of the image in this issue, and the endless redirection loop in https://github.com/Expensify/App/issues/29109.
First, we need to call the composer focus on modal hide with delay:
- focus();
+ focus(true);
}, [focus, prevIsFocused, prevIsModalVisible, isFocused, modal.isVisible, isNextModalWillOpenRef]);
Second, the focusWithDelay
relies on ComposerFocusManager.isReadyToFocus()
:
This is, in fact, barely useful since the ComposerFocusManager.resetReadyToFocus()
is called only in one place, and it's on Android:
We should set the composer as "not ready to focus" every time a modal is open, and set it back to "ready to focus" when the modal is dismissed.
For this, we need to add the following prop to the ReactNativeModal
component (it was by mistake removed in https://github.com/Expensify/App/pull/25672):
+ const handleModalWillShow = () => {
+ ComposerFocusManager.resetReadyToFocus();
+ };
...
return (
<ReactNativeModal
onBackdropPress={handleBackdropPress}
// Note: Escape key on web/desktop will trigger onBackButtonPress callback
// eslint-disable-next-line react/jsx-props-no-multi-spaces
onBackButtonPress={onClose}
+ onModalWillShow={handleModalWillShow}
onModalShow={handleShowModal}
propagateSwipe={propagateSwipe}
....
This solution alone would be enough to solve the current issue. However, if we want to fix both this and https://github.com/Expensify/App/issues/29109 in one take, we should make the following change:
Third, we need to correctly handle setting back the composer to "Ready to focus".
Currently, the ComposerFocusManager.setReadyToFocus()
is called in 2 places in BaseModal
:
Calling it in the handleDismissModal
was preferred because it's called finally, after the onModalHide
. But this specific method - Modal.onDismiss
- is not called in case of a non-fullscreen modal, and it's not called on navigating back via browser navigation.
The non-fullscreen case is already handled in hideModal
, but since the Attachment modal is full-screen, the "go-back" navigation will not call the ComposerFocusManager.setReadyToFocus()
at all, so the composer will not be focused on closing the attachment preview by navigating back.
That's why my suggestion is to move the ComposerFocusManager.setReadyToFocus()
fully into hideModal
:
Remove handleDismissModal
and make this change:
- const handleDismissModal = () => {
- ComposerFocusManager.setReadyToFocus();
- };
...
const hideModal = useCallback(
(callHideCallback = true) => {
if (shouldSetModalVisibility) {
Modal.setModalVisibility(false);
}
if (callHideCallback) {
onModalHide();
}
Modal.onModalDidClose();
- if (!fullscreen) {
ComposerFocusManager.setReadyToFocus();
- }
},
[shouldSetModalVisibility, onModalHide, fullscreen],
);
....
return (
<ReactNativeModal
onBackdropPress={handleBackdropPress}
// Note: Escape key on web/desktop will trigger onBackButtonPress callback
// eslint-disable-next-line react/jsx-props-no-multi-spaces
onBackButtonPress={onClose}
+ onModalWillShow={handleModalWillShow}
- onDismiss={handleDismissModal}
As a result, we will have both issues fixed, as it solves the actual root cause, and is not a workaround compared to some existing proposals:
https://github.com/Expensify/App/assets/12595293/61f76d19-60c4-4776-afb5-31f6d45d0f3a
Optionally, we could only call the ComposerFocusManager.setReadyToFocus()
for the attachment modal here:
https://github.com/Expensify/App/blob/7fb66cdd840ba14f5c958dd60fc1bb4f75d58bab/src/pages/home/report/ReportAttachments.js#L33
But I don't see any major reason against step 3 of this proposal, as it will be more versatile.
@abdulrahuman5196 @Christinadobrzyn this issue is now 4 weeks old and preventing us from maintaining WAQ, can you:
Thanks!
Current assignee @abdulrahuman5196 is eligible for the Internal assigner, not assigning anyone new.
@abdulrahuman5196, @Christinadobrzyn Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!
Will review the new proposals today
The latest proposals have much information which needs dive deep. Will review again tomorrow.
@abdulrahuman5196 I have answered your question about the root cause and found a related bug, in my comment
Still investigating. Will close over the weekend.
Thank you everyone for the root cause analysis.
Status so far: I was able to review the root cause which is onViewableItemsChanged
of flatlist getting called causing this issue.
I am have checked couple of proposals. Need to do some different platform testing on some of the proposals, before providing more info. Will post here once that is done.
Still investigating. Will provide update sooner
RE-Reviewing now
From investigation, the proposal by @pradeepmdk here https://github.com/Expensify/App/issues/27237#issuecomment-1751743967 seems simpler fixes which is aiming to fix in the attachment component itself which is good compared to other proposals so far. I tried 1st option and it didn't work for me. Just reducing the flicker time IMO.
2nd option is one I am more inclined for now. But it is showing loading indicator when closing the attachment modal.
https://github.com/Expensify/App/assets/46707890/f9590752-1735-4e54-8206-e43afd407e21
@pradeepmdk Could you check on these concerns and update the proposal if possible to fix the concerns?
@abdulrahuman5196 I hate to be this kind of person, but: The 2nd proposal by @pradeepmdk looks more like a local workaround that doesn't solve a quite similar issue with the same root cause: https://github.com/Expensify/App/issues/29109
On the other hand, while being more complex, my proposal https://github.com/Expensify/App/issues/27237#issuecomment-1753912527 fixes the actual root cause and resolves both this issue (without causing the loading indicator) and https://github.com/Expensify/App/issues/29109.
@abdulrahuman5196 I agree with @paultsimura, I think proposal from @pradeepmdk doesn't address the root cause or doesn't catch the real root cause. I mean what is causing the onViewableItemsChanged
to be triggered.
And I have replied to your question about the root cause, Do you have any opinion about my answer of the root cause?
and I found another bug and it's possible solution to fix it. So there is two bugs about attachment preview which we can solve here.
Thank you...
@abdulrahuman5196 i updated propsoal. and i agree with @paultsimura my solution not solved https://github.com/Expensify/App/issues/29109 because when we press back button https://github.com/Expensify/App/blob/389d7b0c4b96c6f2a2295055c685791d35b65252/src/components/AttachmentModal.js#L370 it's not triggering. so now the decision with to you but @paultsimura proposes solving both issues.
but waitForInteraction: true,
worked on initially but now not working I am not sure what happened now ๐
and one more thing but all are saying https://github.com/Expensify/App/blob/389d7b0c4b96c6f2a2295055c685791d35b65252/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions.js#L481 focus on immediately cause this issue. then this issue is always there, right? if we have more images then when navigating between images then no issues on here only thing before navigating images we are facing issues. any idea on this? ref: (from staging no issues)
https://github.com/Expensify/App/assets/16595846/38574fa3-2d3b-4243-bce7-8c85da009b3e
@abdulrahuman5196 so basically the root cause is when user pressing the second esc: the focus change to composer -> react native modal catch focus event and check whether the focused element is outside modal -> focused element is outside modal -> react native modal trap focus will focus the last element of the modal to prevent the focused element is outside of the modal -> the last rendered image of attachment preview is focused -> onViewableChange triggered. Here is the code that catch the focus event in trap focus of react native modal:
for detailed explanation you can see my answer of root cause and also I found the other bug and provide a solution for it. Thank you...
Hi folks thanks for the detailed discussion. Just to note simpler fixes are not always workaround fixes. But anyways since the proposal couldn't fix the loading indicator issue and other similar issue we have to drop it.
The proposals left currently to re-review are
1) @ilkeruyanik proposal here https://github.com/Expensify/App/issues/27237#issuecomment-1746045280 : I am not aligned on this since the proposal is still attempting to present multiple dismissModal by using stored values. But anyways will compare with other proposals as well.
2) @tsa321 's proposal here https://github.com/Expensify/App/issues/27237#issuecomment-1746060535 Could you kindly update the proposal if it doesn't included all the changes you have mentioned.
3) @paultsimura 's proposal here https://github.com/Expensify/App/issues/27237#issuecomment-1753912527 Need to fresh check this one.
Will work on the action items here https://github.com/Expensify/App/issues/27237#issuecomment-1779814093 today.
~Re-reviewing now~
@abdulrahuman5196, @Christinadobrzyn Huh... This is 4 days overdue. Who can take care of this?
Still on this phase going back and forth testing - https://github.com/Expensify/App/issues/27237#issuecomment-1779814093. Will update in a day.
Hi @abdulrahuman5196 just checking to see if there's any update based on the testing. Thanks!
Hi, Will review today just back from weekend
hi @abdulrahuman5196 can you provide an update for us? Thanks!
Sorry for dragging on. Still investigating proposal. Will cover over weekend or reach out for another C+ on monday.
@abdulrahuman5196 If you want help from another C+, I will be happy to help you cause I have been following this issue from the start.
Sure. Let me check over this weekend, if not will forward.
All the 3 pending proposals are working well. Let me compare them and come back with results.
@paultsimura 's proposal here https://github.com/Expensify/App/issues/27237#issuecomment-1753912527 looks good and work well. It is better than other proposal IMO. Reason being, the main root cause is that onViewableItemsChanged
is being called incorrectly from FlatList during our usage. But its not worth some upstream fix and since fix at our end is relatively small in all proposals. And another reason I think of is that if we add Navigation.dismissModal
in future in another place, we don't have to do any extra checks specific to this issue.
And I think we can just implement the First change proposed, I think some of the other changes proposed have been already implemented with some other PRs.
๐ ๐ ๐ C+ Reviewed
Triggered auto assignment to @hayata-suenaga, see https://stackoverflow.com/c/expensify/questions/7972 for more details.
Thank you, the PR will be ready today.
I'm going ooo until Monday Nov 27th so going to assign another BZ teammate to monitor this until I'm back. Thanks!
Status - reviewing PR! ๐
Triggered auto assignment to @miljakljajic (Bug
), see https://stackoverflow.com/c/expensify/questions/14418 for more details.
Platforms
in OP are โ
)@abdulrahuman5196 the proposal by @paultsimura is almost match my proposal, I describe the root cause first and the solution for the other bug which is similar to @paultsimura proposal, but I posted it first: https://github.com/Expensify/App/issues/27237#issuecomment-1751632831
adding focus(true) parameter and other additional lines in basemodal to fix this issue and the other issue is my original proposal, you can see it in my answer of your question about root cause...
Could you explain why you doesn't choose my proposal / optional solution? As I propose similar to @paultsimura solution but I am first.
@tsa321 let me check if you had proposed the solution first.
Cc: @paultsimura do share if you have thoughts
@abdulrahuman5196 please check https://github.com/Expensify/App/issues/27237#issuecomment-1751632831
in the last section, start with:
And another bug: If we press back button ...
I have posted the solution on 8 oct for the And another bug: If we press back button...
section...
I had added more detail in my original proposal to use this solution...
Looking at the proposals
@tsa321 edit the original proposal to include focus code suggestions only 3 weeks back https://github.com/Expensify/App/issues/27237#issuecomment-1746060535
Whereas @paultsimura had the suggestion on his original proposal in Oct 10 itself https://github.com/Expensify/App/issues/27237#issuecomment-1753912527 that let to my decision.
But seems @tsa321 suggested the solution as part of analysis replies here https://github.com/Expensify/App/issues/27237#issuecomment-1751632831 which happened at Oct 8, 2 days before @paultsimura 's solution.
So if we consider only main proposals @paultsimura would be one to choose. But I am not sure if we would consider replies and conversations which has code change suggestions as a valid proposals
@tsa321 / @paultsimura let me know if I got the timelines in any way wrongly.
@hayata-suenaga do you have any suggestions here?
And note for contributors: We have guideline to update original proposal everytime you think of a solution is worth mentioning to avoid this type of concerns.
@abdulrahuman5196 I am sorry, at that time I have just waiting for your reply on my answer of root cause and then I will update the proposal accordingly...
@abdulrahuman5196 I agree that the proposal of @tsa321 was not updated on time. Because of this, I did not even see those suggested changes before posting my proposal.
But in order not to make a decision based only on this, here are a couple more thoughts:
Setting focus(true)
is, in fact, only a partial solution, because without my third proposed change (which I still think we should implement), we have an issue: when clicking the browser "back" button, the composer does not get focused similar to clicking "x" or "esc".
Third, we need to correctly handle setting back the composer to "Ready to focus".
https://github.com/Expensify/App/assets/12595293/594e7d75-1e0d-4cc8-817b-be699d33b027
@tsa321 did not include it in their original discussion but added it in the modified proposal after mine was posted, meaning they considered it valuable enough to be included in the proposal, but missed this change in the discussion.
Here is the behavior with the fix applied:
@paultsimura but the general idea is similar, the root cause is at the focus() and need to add parameter true
and for the detailed implementation need more testing... and of course we need to reset and set the ready state accordingly to works...
and Also let consider the root cause section to consider which proposal gives more proper and correct explanation of the root cause...
I'd just like to add that in the past, I had a similar situation when my proposal was rejected because as was originally added in a discussion. The reason was that "You should be confident about the proposed solution, so when you have it, it should be reflected in the proposal".
To me, it seems logical that when some new idea comes to mind, it should be reflected in the proposal, otherwise waiting for some extra response before updating the proposal means that the Contributor is not sure about the proposed solution and doesn't want to risk putting it in the proposal before an extra confirmation.
I would prefer to avoid going back and forth further here because it can lead to some personal confrontations. I'll let @abdulrahuman5196 and @hayata-suenaga make the further decision taking into account the timing and these 2 comments: https://github.com/Expensify/App/issues/27237#issuecomment-1817412283 https://github.com/Expensify/App/issues/27237#issuecomment-1817417013
I'm going ooo until Monday Nov 27th so going to assign another BZ teammate to monitor this until I'm back. Thanks!
Status: working on PR
Triggered auto assignment to @trjExpensify (Bug
), see https://stackoverflow.com/c/expensify/questions/14418 for more details.
Platforms
in OP are โ
)I still agree with @abdulrahuman5196 that @paultsimura should take the PR considering the timeline and they updated their proposal.
However, I really want to appreciate everyone who suggested proposals. Thank you so much everyone ๐
Thanks. To keep things relatively fair for all, I'd like to offer $250 of my bounty to @tsa321 when the issue gets fixed.
Wow thank you @paultsimura, That is really nice of you
Back from ooo - I'll take this back. Thanks for watching Tom!
If you havenโt already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!
Action Performed:
multiple times
, observe that preview closes, reopens with different image and closesExpected Result:
App should close preview on ESC click (note you need to press Esc multiple times)
Actual Result:
App glitches on closing preview on ESC click
Workaround:
Unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
Version Number: 1.3.61-1 Reproducible in staging?: y Reproducible in production?: y If this was caught during regression testing, add the test name, ID and link from TestRail: Email or phone of affected tester (no customers): Logs: https://stackoverflow.com/c/expensify/questions/4856 Notes/Photos/Videos: Any additional supporting documentation
https://github.com/Expensify/App/assets/93399543/1c6168d6-ff13-4892-892f-4a98015c026a
https://github.com/Expensify/App/assets/93399543/9e5b35a2-db33-474a-957e-6fe952084b2e
Expensify/Expensify Issue URL: Issue reported by: @dhanashree-sawant Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1693558112570809
View all open jobs on GitHub
Upwork Automation - Do Not Edit