Skip to content
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

[$250] Compose box - Browser's back arrow do not focus composer if first image preview open #42368

Open
1 of 6 tasks
lanitochka17 opened this issue May 18, 2024 · 26 comments
Open
1 of 6 tasks
Assignees
Labels
Bug Something is broken. Auto assigns a BugZero manager. External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review Weekly KSv2

Comments

@lanitochka17
Copy link

lanitochka17 commented May 18, 2024

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Version Number: 1.4.74-0
Reproducible in staging?: Y
Reproducible in production?: Y
If this was caught during regression testing, add the test name, ID and link from TestRail: N/A
Issue reported by: Applause - Internal Team

Action Performed:

Precondition: upload multiple images in chat

  1. Open the first uploaded image
  2. Click the "Back" button in the browser

Expected Result:

Composer gets focused

Actual Result:

Last uploaded image preview opened

Workaround:

Unknown

Platforms:

Which of our officially supported platforms is this issue occurring on?

  • Android: Native
  • Android: mWeb Chrome
  • iOS: Native
  • iOS: mWeb Safari
  • MacOS: Chrome / Safari
  • MacOS: Desktop

Screenshots/Videos

Add any screenshot/video evidence

Bug6481495_1715770820384.multiple_image.mp4

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~013929a859819a7038
  • Upwork Job ID: 1792347976114130945
  • Last Price Increase: 2024-05-27
  • Automatic offers:
    • DylanDylann | Contributor | 0
    • tsa321 | Contributor | 102496699
Issue OwnerCurrent Issue Owner: @thesahindia
@lanitochka17 lanitochka17 added Daily KSv2 Bug Something is broken. Auto assigns a BugZero manager. labels May 18, 2024
Copy link

melvin-bot bot commented May 18, 2024

Triggered auto assignment to @jliexpensify (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

@jliexpensify jliexpensify added the External Added to denote the issue can be worked on by a contributor label May 20, 2024
Copy link

melvin-bot bot commented May 20, 2024

Job added to Upwork: https://www.upwork.com/jobs/~013929a859819a7038

@melvin-bot melvin-bot bot changed the title Compose box - Browser's back arrow do not focus composer if first image preview open [$250] Compose box - Browser's back arrow do not focus composer if first image preview open May 20, 2024
@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label May 20, 2024
Copy link

melvin-bot bot commented May 20, 2024

Triggered auto assignment to Contributor-plus team member for initial proposal review - @thesahindia (External)

@jliexpensify
Copy link
Contributor

Can repro, adding External and probably fits into VSB best?

@tsa321
Copy link
Contributor

tsa321 commented May 20, 2024

Proposal

Please re-state the problem that we are trying to solve in this issue

Browser back button open other images when user opens first attachment image in attachment view (and won't close attachment view) and press the back button.

What is the root cause of the problem?

In here:

beforeRemove: () => {
// Clear search input (WorkspaceInvitePage) when modal is closed
SearchInputManager.searchInput = '';
Modal.setModalVisibility(false);
Modal.willAlertModalBecomeVisible(false);
},

When back button is pressed, the beforeRemove listener is called immediately even though the modal is not completely hidden yet. The code above will set modal visibility to false too early and will make:

const shouldAutoFocus =
!modal?.isVisible && isFocused && (shouldFocusInputOnScreenFocus || (isEmptyChat && !ReportActionsUtils.isTransactionThread(parentReportAction))) && shouldShowComposeInput;

shouldAutoFocus to be true. This will make RNMarkdownTextInput:

<RNMarkdownTextInput

autofocus to be true.
This will make composer immediately focused even though the modal is not completelly hidden(because there is some animation). The trap focuse in react native modal will detect if focus is outside modal and will make focus back to element inside the modal, and here will eventually make the image changes to other/ next images.
More context is in here:

#27237 (comment)

More info about image changes in attachment view

@DylanDylann Focus event catch by react native modal ModalFocusTrap is in here:

https://github.com/necolas/react-native-web/blob/54c14d64dabd175e8055e1dc92e9196c821f9b7d/packages/react-native-web/src/exports/Modal/ModalFocusTrap.js#L137

The function of this file based on the comment is to trap focus so the focus won't leave modal, if the focus is outside of modal, the trap focus will focus last element inside modal.

The code flow is: Composer focused (from autofocus of RNMarkdownTextInput)-> focus event triggered -> catch by trapFocus (which will try to focus child or last descendant element of the modal -> trap focus looping through descendant element -> until last element of the initial rendered image (initialNumToRender is 3 in AttachmentCarousel) list reached :
The trapFocus try to focus the element of the attachment list will cause onViewableItemsChanged will be executed because the focus will make the displayed image slide(changes), hence will execute handler in:

const onCarouselAttachmentChange = useCallback(
(attachment: Attachment) => {
const routeToNavigate = ROUTES.REPORT_ATTACHMENTS.getRoute(reportID, String(attachment.source));
Navigation.navigate(routeToNavigate);
},

which is navigate back to the attachment modal.

Focus event catch by react native modal ModalFocusTrap is in here:

https://github.com/necolas/react-native-web/blob/54c14d64dabd175e8055e1dc92e9196c821f9b7d/packages/react-native-web/src/exports/Modal/ModalFocusTrap.js#L137

The function of this file based on the comment is to trap focus so the focus won't leave modal, if the focus is outside of modal, the trap focus will focus last element inside modal.

The code flow is: Composer focused (from autofocus of RNMarkdownTextInput)-> focus event triggered -> catch by trapFocus (which will try to focus child or last descendant element of the modal -> trap focus looping through descendant element -> until last element of the initial rendered image (initialNumToRender is 3 in AttachmentCarousel) list reached :
The trapFocus try to focus the element of the attachment list will cause onViewableItemsChanged will be executed because the focus will make the displayed image slide(changes), hence will execute handler in:

const onCarouselAttachmentChange = useCallback(
(attachment: Attachment) => {
const routeToNavigate = ROUTES.REPORT_ATTACHMENTS.getRoute(reportID, String(attachment.source));
Navigation.navigate(routeToNavigate);
},

which is navigate back to the attachment modal.

What changes do you think we should make in order to solve the problem?

So basically we prevent set modal visibility too early, in here we should add a condition:

Modal.setModalVisibility(false);
Modal.willAlertModalBecomeVisible(false);

the code could be:

if (Modal.areAllModalsHidden()) {
    Modal.setModalVisibility(false);
    Modal.willAlertModalBecomeVisible(false);
}

This will check whether all modals is hidden completely.
Then the set of setModalVisibility and willAlertModalBecomeVisible are already exist in BaseModal - hideModal:

const hideModal = useCallback(

The modal already use it and so the if check above is sufficient to fix this issue.



To solve the closed issue that reappears above, in baseModal, we should call hide modal only in here:

<ModalContent onDismiss={handleDismissModal}>

so we add hideModal inside handleDismissModal then remove onModalHide and onDismiss property of ReactNativeModal. This is because many types of modal (whether the modal support onModalHide or not) used in the app and put the hideModal call in here will make sure the hideModal is executed once.

Result:
back.button.issue.fix.mp4
Fix result for the other issue that reappears:
other.issue.fix.result.mp4

@arjun-dureja
Copy link

arjun-dureja commented May 20, 2024

Proposal

Please re-state the problem that we are trying to solve in this issue.

When an image attachment is opened inside a chat, pressing the browser back button will result in another image displaying, rather than being navigated back to the chat.

What is the root cause of that problem?

Inside the AttachmentCarousel component, the updatePage function is unexpectedly being called when the browser back button is pressed (due to how onViewableItemsChanged works on FlatList). This causes onNavigate to be called with the first attachment in the viewable items, which then navigates the user to a different attachment.

What changes do you think we should make in order to solve the problem?

We should detect when the back button is pressed (potentially using a ref) and then return early inside the updatePage function. This will ensure that we're not unnecessarily fetching a different image and navigating the user to it. It will allow the user to go back to the chat

What alternative solutions did you explore? (Optional)

@CleverWolf1220
Copy link

Proposal

Please re-state the problem that we are trying to solve in this issue.

Compose box - Browser's back arrow do not focus composer if first image preview open

This issue is reproducible for video attachments as well.

What is the root cause of that problem?

In FlatList component of AttachmentCarousel, onViewableItemsChanged is called when pressing browser back button without user interection.

What changes do you think we should make in order to solve the problem?

We should add waitForInteraction: true in viewabilityConfig

What alternative solutions did you explore? (Optional)

Copy link

melvin-bot bot commented May 20, 2024

📣 @CleverWolf1220! 📣
Hey, it seems we don’t have your contributor details yet! You'll only have to do this once, and this is how we'll hire you on Upwork.
Please follow these steps:

  1. Make sure you've read and understood the contributing guidelines.
  2. Get the email address used to login to your Expensify account. If you don't already have an Expensify account, create one here. If you have multiple accounts (e.g. one for testing), please use your main account email.
  3. Get the link to your Upwork profile. It's necessary because we only pay via Upwork. You can access it by logging in, and then clicking on your name. It'll look like this. If you don't already have an account, sign up for one here.
  4. Copy the format below and paste it in a comment on this issue. Replace the placeholder text with your actual details.
    Screen Shot 2022-11-16 at 4 42 54 PM
    Format:
Contributor details
Your Expensify account email: <REPLACE EMAIL HERE>
Upwork Profile Link: <REPLACE LINK HERE>

@thesahindia
Copy link
Member

@jliexpensify, I won't be able to review this soon. Please reassign.

@DylanDylann
Copy link
Contributor

DylanDylann commented May 22, 2024

I would love to take over this issue as C+

@thesahindia thesahindia removed their assignment May 22, 2024
@melvin-bot melvin-bot bot removed the Help Wanted Apply this label when an issue is open to proposals by contributors label May 22, 2024
Copy link

melvin-bot bot commented May 22, 2024

📣 @DylanDylann 🎉 An offer has been automatically sent to your Upwork account for the Contributor role 🎉 Thanks for contributing to the Expensify app!

Offer link
Upwork job
Please accept the offer and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review 🧑‍💻
Keep in mind: Code of Conduct | Contributing 📖

@jliexpensify
Copy link
Contributor

jliexpensify commented May 22, 2024

All yours @DylanDylann!

EDIT: Still considering proposals!

@jliexpensify jliexpensify added the Help Wanted Apply this label when an issue is open to proposals by contributors label May 22, 2024
@DylanDylann
Copy link
Contributor

@tsa321 Could you detail this point? Which logic does that?

The trap focuse in react native modal will detect if focus is outside modal and will make focus back to element inside the modal, and here will eventually make the image changes to other/ next images.

@DylanDylann
Copy link
Contributor

DylanDylann commented May 24, 2024

@arjun-dureja Could you deep dive into this point and explain why the updatePage is called? Is there any reference, document that explain why onViewableItemsChanged is triggered?

due to how onViewableItemsChanged works on FlatList

cc @CleverWolf1220

@DylanDylann
Copy link
Contributor

@CleverWolf1220 Why waitForInteraction will resolve this problem?

@tsa321
Copy link
Contributor

tsa321 commented May 24, 2024

@DylanDylann Focus event catch by react native modal ModalFocusTrap is in here:

https://github.com/necolas/react-native-web/blob/54c14d64dabd175e8055e1dc92e9196c821f9b7d/packages/react-native-web/src/exports/Modal/ModalFocusTrap.js#L137

The function of this file based on the comment is to trap focus so the focus won't leave modal, if the focus is outside of modal, the trap focus will focus last element inside modal.

The code flow is: Composer focused (from autofocus of RNMarkdownTextInput)-> focus event triggered -> catch by trapFocus (which will try to focus child or last descendant element of the modal -> trap focus looping through descendant element -> until last element of the initial rendered image (initialNumToRender is 3 in AttachmentCarousel) list reached :
The trapFocus try to focus the element of the attachment list will cause onViewableItemsChanged will be executed because the focus will make the displayed image slide(changes), hence will execute handler in:

const onCarouselAttachmentChange = useCallback(
(attachment: Attachment) => {
const routeToNavigate = ROUTES.REPORT_ATTACHMENTS.getRoute(reportID, String(attachment.source));
Navigation.navigate(routeToNavigate);
},

which is navigate back to the attachment modal.

@melvin-bot melvin-bot bot added the Overdue label May 27, 2024
Copy link

melvin-bot bot commented May 27, 2024

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

Copy link

melvin-bot bot commented May 27, 2024

@jliexpensify, @DylanDylann Whoops! This issue is 2 days overdue. Let's get this updated quick!

@DylanDylann
Copy link
Contributor

Hi Melv, thanks for tagging me. I will complete my review today

@melvin-bot melvin-bot bot removed the Overdue label May 28, 2024
@CleverWolf1220
Copy link

@DylanDylann

@CleverWolf1220 Why waitForInteraction will resolve this problem?

Sorry for late response. I found that my proposal solves this issue but causes other problems.

@DylanDylann
Copy link
Contributor

@tsa321's proposal looks good to me. Let's go with them

🎀 👀 🎀 C+ reviewed

Copy link

melvin-bot bot commented May 28, 2024

Triggered auto assignment to @dangrous, see https://stackoverflow.com/c/expensify/questions/7972 for more details.

@dangrous
Copy link
Contributor

Ooh, that's complicated. I think this solution makes sense to me, but we should make sure to do a lot of testing on closing other modals, etc. to make sure this doesn't cause any regressions there.

Assigining @tsa321

@melvin-bot melvin-bot bot removed the Help Wanted Apply this label when an issue is open to proposals by contributors label May 28, 2024
Copy link

melvin-bot bot commented May 28, 2024

📣 @tsa321 🎉 An offer has been automatically sent to your Upwork account for the Contributor role 🎉 Thanks for contributing to the Expensify app!

Offer link
Upwork job
Please accept the offer and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review 🧑‍💻
Keep in mind: Code of Conduct | Contributing 📖

Copy link

melvin-bot bot commented Jun 7, 2024

⚠️ Looks like this issue was linked to a Deploy Blocker here

If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.

If a regression has occurred and you are the assigned CM follow the instructions here.

If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.

@jliexpensify
Copy link
Contributor

@DylanDylann there wasn't a regression, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something is broken. Auto assigns a BugZero manager. External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review Weekly KSv2
Projects
Status: No status
Development

No branches or pull requests

8 participants