Skip to content

Migrate InteractionManager - batch 1 - #88603

Merged
roryabraham merged 27 commits into
Expensify:mainfrom
software-mansion-labs:mrejdak/migrate-interactionmanager
May 14, 2026
Merged

roryabraham merged 27 commits into
Expensify:mainfrom
software-mansion-labs:mrejdak/migrate-interactionmanager

Conversation

@mrejdak

@mrejdak mrejdak commented Apr 23, 2026 •

Copy link
Copy Markdown
Contributor

Explanation of Change

Batch 1 of InteractionManager migration

Fixed Issues

$ #71913
$ #83061
PROPOSAL:

Tests

‎WorkspaceCompanyCardsSettingsPage.tsx‎

  1. Open a workspace with company cards set up
  2. Go to "Company Cards" tab
  3. Press Settings -> Remove card feed
  4. Verify that the confirmation modal displays correctly
  5. Press Delete
  6. Verify that the modal closes correctly and the navigation happens after the closing animation has finished

WorkspaceExpensifyCardDetailsPage.tsx‎

  1. Open a workspace with a virtual Expensify card issued to a member
  2. Go to "Expensify Card" tab
  3. Click to view details of a member with an issued card
  4. Scroll down and press Deactivate card
  5. Verify that the confirmation modal displays correctly
  6. Press Deactivate
  7. Verify that the modal closes correctly and the navigation happens after the closing animation has finished

AvatarCropModal.tsx

  1. Go to Account tab
  2. Click Profile and press the edit avatar icon
  3. Press Edit and select "Upload photo"
  4. Upload a new photo and verify that the avatar crop modal is displayed correctly
  5. Press Upload -> Save and verify that both modals closed correctly

AutoSubmitModal.tsx

  1. Go to https://dev.new.expensify.com:8082/auto-submit
  2. Verify that the modal displays correctly
  3. Press Got it and verify that it closes correctly

FeatureTrainingModal.tsx

  1. Go to https://dev.new.expensify.com:8082/track-training
  2. Verify that the modal displays correctly
  3. Press Got it and verify that it closes correctly

useFilesValidation.ts

  • On mobile:
  1. Press the + button and select Create expense
  2. Press the image icon and select Choose file
  3. Try to upload a file with a wrong extension (e.g. ".txt")
  4. Verify that the "Invalid file type" modal is displayed correctly
  5. Press Close and verify that it closes correctly
  • On web:
  1. Drag and drop a file with a wrong extension (e.g. ".txt")
  2. Repeat steps 4. and 5. from the mobile flow above

PopoverReportActionContextMenu.tsx

  1. Open a chat room
  2. Send any message
  3. Long-press on it (press the ... on web)
  4. Select Delete from the options displayed
  5. Verify that the confirmation modal is displayed correctly
  6. Press Delete and verify that it closes correctly and that the message is removed after the modal disappears

IOURequestStepDescription.tsx (Web)

  1. Open a report with a single expense
  2. Click on Description
  3. Change the description and press the back button
  4. When the Discard changes modal opens, press Cancel and verify that the input focuses back correctly.

IOURequestStepMerchant.tsx (Web)

  1. Open a report with a single expense
  2. Click on Merchant
  3. Change the merchant and press the back button
  4. When the Discard changes modal opens, press Cancel and verify that the input focuses back correctly.

AttachmentModalContainer/index.native.tsx (mobile)

  1. Open 1:1 chat with variety of attachments sent
    2 Tap on attachment preview to open larger preview
  2. Tap < button on the left side of the preview to navigate back to the chat
  3. Repeat with a few other attachments
  4. Verify that the preview closes correctly and no part of the previous attachment remains visible on the side of the screen

ContactMethodDetailsPage.tsx

  1. Go to Account tab and press Profile and then Contact methods
  2. Add a new contact method (e.g. email), but don't validate it
  3. Select the not validated option from the list and verify that the magic code input is correctly auto-focused
  4. Type in 1-2 numbers, so a different cell of the magic code input is focused
  5. Press the ... button and select "Remove"
  6. Verify that the the keyboard dismisses (mobile) before confirmation modals is shown
  7. Select Cancel and verify that the modal closes first and that the input cell focuses back correctly
  8. Repeat steps 5 and 6
  9. Select Yes, continue and verify that the modal closes before navigating back

WorkspaceCategoriesPage.tsx

  1. Go to Workspaces tab
  2. Open a workspace and press Categories
  3. Select at least two categories (checkboxes on web, longpress on mobile) and from the dropdown menu select Delete categories
  4. Press Delete and verify that the modal closes correctly, the categories are removed and there that are no categories selected

PolicyDistanceRatesPage.tsx

  1. Open a workspace with distance rates enabled and more than two added
  2. Select at least two distance rates (checkboxes on web, longpress on mobile) and from the dropdown menu select Delete rates
  3. Press Delete and verify that the modal closes correctly, the distance rates are removed and there that are no distance rates selected

WorkspacePerDiemPage.tsx

  1. Open a workspace with multiple Per Diem options imported
  2. Open the Per Diem tab and select at least two rows
  3. From the dropdown menu select Delete rates -> Delete
  4. Verify that the confirmation modal closes correctly, the rates are removed and there are no selected rates left

ReportFieldsListValuesPage.tsx

  1. Open a workspace with report fields enabled
  2. Create a new list-type report field with multiple list values
  3. Click on the new report field and then on the 'List Values' to edit them
  4. Select at least two of them and from the dropdown menu select Delete values -> Delete
  5. Verify that the confirmation modal closes correctly, the values are removed and there are no selected values left

WorkspaceTagsPage.tsx

  1. Open a workspace with multiple single-level tags added
  2. Go to Tags and select at least two tags (but not all of them)
  3. From the dropdown menu select Delete tags -> Delete
  4. Verify that the confirmation modal closes correctly, the tags are removed and there are no selected tags left
  5. Select the remaining tags and repeat step 3.
  6. Verify that the selection mode is off

WorkspaceTaxesPage.tsx

  1. Open a workspace with taxes enabled
  2. Add multiple custom tax rates
  3. Select at least two of them
  4. From the dropdown menu select Delete rates -> Delete
  5. Verify that the confirmation modal closes correctly, the rates are removed and there are no selected rates left

WorkspaceWorkflowsApprovalsEditPage.tsx‎

  1. Open a workspace with workflows enabled
  2. Create a new approver workflow if there isn't one already
  3. Select the approver workflow to edit it
  4. Edit the member list and save changes
  5. Verify that after saving changes, navigation completes before the value is updated
  6. Select the approver workflow again
  7. Select Delete -> Delete
  8. Verify that the modal closes correctly before navigating back and that the workflow is removed after the navigation completes

WorkspaceMembersPage.tsx

  1. Open a workspace with multiple members
  2. Go to Members and select at least two
  3. From the dropdown menu select Remove members and then Remove
  4. Verify that the confirmation modal closes correctly, the members are removed and there are no selected members left

WorkspacesListPage.tsx

  1. Create 8-10 workspaces and scroll down (so that some are off-screen)
  2. Press ... on the last one and select Duplicate workspace
  3. Name the duplicated workspace "AAA workspace" so that it will end up on top of the list
  4. Press Next and verify that the list correctly scrolls to the new workspace

ReportParticipantsPage.tsx

  1. Create a group chat with >12 people (so that search bar appears)
  2. Type a query into the search-member bar and select some members that appear as the search result
  3. From the dropdown menu select Remove members and then Remove
  4. Verify that the modal closes correctly, the members are removed, the search phrase is cleared and there are no selected members left

RoomMembersPage.tsx

  1. Create a #room with >12 people (so that search bar appears)
  2. Repeat steps 2-4 from the test above
  • Verify that no errors appear in the JS console

Offline tests

N/A

QA Steps

Same as Tests

  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
      • If any non-english text was added/modified, I used JaimeGPT to get English > Spanish translation. I then posted it in #expensify-open-source and it was approved by an internal Expensify engineer. Link to Slack message:
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.ts or at the top of the file that uses the constant) are defined as such
  • I verified that if a function's arguments changed that all usages have also been updated correctly
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native
Android: mWeb Chrome
iOS: Native

‎WorkspaceCompanyCardsSettingsPage.tsx‎

batch1_remove_card_feed.mov

WorkspaceExpensifyCardDetailsPage.tsx‎

batch1_deactivate_card.mov

AvatarCropModal.tsx

batch1_avatar_crop.mov

useFilesValidation.ts

batch1_file_validation.mov

PopoverReportActionContextMenu.tsx

batch1_popover_remove_comment.mov

AttachmentModalContainer/index.native.tsx (mobile)

batch1_attachment_modal_container.mov

ContactMethodDetailsPage.tsx

batch1_contact_details.mov

WorkspaceCategoriesPage.tsx

batch1_workspace_categories.mov

PolicyDistanceRatesPage.tsx

batch1_distance_rates.mov

WorkspacePerDiemPage.tsx

batch1_per_diem.mov

ReportFieldsListValuesPage.tsx

batch1_report_field_list.mov

WorkspaceTagsPage.tsx

batch1_tags.mov

WorkspaceTaxesPage.tsx

batch1_taxes.mov

WorkspaceWorkflowsApprovalsEditPage.tsx‎

batch1_approver_workflow.mov
batch1_approver_workflow_del.mov

WorkspaceMembersPage.tsx

batch1_members.mov

WorkspacesListPage.tsx

batch1_workspace_list.mov

ReportParticipantsPage.tsx

batch1_group_chat.mov

RoomMembersPage.tsx

batch1_room_members.mov
iOS: mWeb Safari
MacOS: Chrome / Safari

AvatarCropModal.tsx

batch1_avatar_crop_web.mov

AutoSubmitModal.tsx

batch1_auto_submit.mov

FeatureTrainingModal.tsx

batch1_track_training.mov

useFilesValidation.ts

batch1_file_validation__web.mov

PopoverReportActionContextMenu.tsx

batch1_popover_remove_comment_web.mov

IOURequestStepDescription.tsx (Web)

batch1_IOU_description_web.mov

IOURequestStepMerchant.tsx (Web)

batch1_IOU_merchant_web.mov

ContactMethodDetailsPage.tsx

batch1_contract_details_web.mov

WorkspaceCategoriesPage.tsx

batch1_workspace_categories_web.mov

PolicyDistanceRatesPage.tsx

batch1_distance_rates_web.mov

WorkspacePerDiemPage.tsx

batch1_per_diem_web.mov

ReportFieldsListValuesPage.tsx

batch1_report_field_list_web.mov

WorkspaceTagsPage.tsx

batch1_tags_web.mov

WorkspaceTaxesPage.tsx

batch1_taxes_web.mov

WorkspaceWorkflowsApprovalsEditPage.tsx‎

batch1_approver_workflow_web.mov
batch1_approver_workflow_del_web.mov

WorkspaceMembersPage.tsx

batch1_members_web.mov

WorkspacesListPage.tsx

batch1_workspace_list_web.mov

ReportParticipantsPage.tsx

batch1_group_chat_web.mov

RoomMembersPage.tsx

batch1_room_members_web.mov

@codecov

codecov Bot commented Apr 29, 2026 •

Copy link
Copy Markdown

@mrejdak mrejdak changed the title Mrejdak/migrate interactionmanager Migrate InteractionManager - batch 1 Apr 30, 2026
Comment thread src/components/AutoSubmitModal.tsx Resolved
Comment on lines +422 to +425
if (pendingCloseRef.current) {
pendingCloseRef.current = false;
pendingCloseModalAction();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this ref here? Why can't we trigger the action when shouldCloseOnConfirm is true? 🤔

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ref is there so that we can check whether the modal was closed using the closeModal callback.
shouldCloseOnConfirm only indicates whether modal should be closed after pressing submit, while the action should trigger anytime the modal closes via the closeModal (which is called either by pressing submit with shouldCloseOnConfirm = true or by user closing the modal e.g. with a backdrop press).
There are two cases which don't use closeModal and should not trigger the action - when the modal is closed by switching the isModalDisabled flag and by pressing help button with shouldCallOnHelpWhenModalHidden = true.
In both cases, the value of shouldCloseOnConfirm does not affect the outcome.

Comment on lines +322 to +318
InteractionManager.runAfterInteractions(() => {
validateCodeFormRef.current?.focus?.();
});
validateCodeFormRef.current?.focus?.();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it safe to remove this? from what I see in the ScreenWrapper code, it's wrapped in setTimeout, not our TransitionTracker :/

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the ScreenWrapper waits for the transitionEnd of the entry transition, the setTimeout is only a fallback for iOS where the transitionEnd doesn't trigger sometimes (according to the comment). So from what I understand the difference is that transition tracker guards against all events, while ScreenWrapper only waits for the entry transition end. However, I just noticed that this change is not a part of this batch, but the batch 8 (Input Focus usages), so I'll revert it for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change belong to the current batch? Also, are you sure requestAnimationFrame can be used instead of InteractionManager here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, WorkspacesListPage.tsx belongs to the current batch (it's on the list), but I'm also not sure if requestAnimationFrame works correctly here 🤔

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, the requestAnimationFrame doesn't work here as I thought 😅 - I'll change it to transitiontracker directly

Comment on lines +328 to +327
// eslint-disable-next-line @typescript-eslint/no-deprecated
InteractionManager.runAfterInteractions(() => {
onClose?.();
});
onClose?.();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure it won't break anything? It was added here to fix RHP error

@mrejdak mrejdak May 6, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested it and could not reproduce the referenced error - the current flow of editing photo differs as well from the one that had the rhp error, the flow is now split between two modals (cropping and saving) which I believe is also the reason why the bug is not present anymore

@collectioneur collectioneur left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I second @war-in comments. Otherwise, great job on this 😄

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, WorkspacesListPage.tsx belongs to the current batch (it's on the list), but I'm also not sure if requestAnimationFrame works correctly here 🤔

@mrejdak
mrejdak marked this pull request as ready for review May 11, 2026 12:27
@mrejdak
mrejdak requested review from a team as code owners May 11, 2026 12:27
@melvin-bot
melvin-bot Bot requested review from Pujan92 and trjExpensify and removed request for a team and Pujan92 May 11, 2026 12:27
@Pujan92

Pujan92 commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

Reviewer Checklist

  • I have verified the author checklist is complete (all boxes are checked off).
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I included screenshots or videos for tests on all platforms
  • I verified tests pass on all platforms & I tested again on:
    • Android: HybridApp
    • Android: mWeb Chrome
    • iOS: HybridApp
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that the left part of a conditional rendering a React component is a boolean and NOT a string, e.g. myBool && <MyComponent />.
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar have been tested & I retested again)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

Screenshots/Videos

Android: HybridApp
Android: mWeb Chrome
iOS: HybridApp
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2026-05-14.at.21.43.14.mov
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2026-05-14.at.21.47.47.mov
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2026-05-14.at.21.49.15.mov
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2026-05-14.at.21.52.52.mov
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2026-05-14.at.21.54.01.mov
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2026-05-14.at.21.56.26.mov
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2026-05-14.at.21.55.56.mov
iOS: mWeb Safari
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2026-05-14.at.22.11.44.mov
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2026-05-14.at.22.13.34.mov
MacOS: Chrome / Safari
Screen.Recording.2026-05-13.at.23.10.48.mov
Screen.Recording.2026-05-13.at.23.56.51.mov
Screen.Recording.2026-05-14.at.21.37.43.mov
Screen.Recording.2026-05-14.at.21.38.39.mov
Screen.Recording.2026-05-14.at.21.39.15.mov

InteractionManager.runAfterInteractions(() => {
onClose?.();
});
onClose?.();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need to use this inside TransitionTracker.runAfterTransitions callback?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was previously added to fix an error with RHP that @war-in linked above. The current flow differs from the one shown in the issue (it's now split between two modals), which I believe is what fixed the bug, as I've tested and couldn't reproduce it.

@Pujan92

Pujan92 commented May 14, 2026

Copy link
Copy Markdown
Contributor

@mrejdak Plz fix the conflicts

@Pujan92 Pujan92 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@melvin-bot
melvin-bot Bot requested a review from roryabraham May 14, 2026 16:32
@Pujan92

Pujan92 commented May 14, 2026

Copy link
Copy Markdown
Contributor

@mrejdak lint is failing and conflicts again 😢

@Pujan92

Pujan92 commented May 14, 2026

Copy link
Copy Markdown
Contributor

@roryabraham can you plz trigger adhoc build here

@mrejdak

mrejdak commented May 14, 2026

Copy link
Copy Markdown
Contributor Author

@mrejdak lint is failing and conflicts again 😢

Done!

"../../src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/TransparentOverlay.tsx" "no-restricted-syntax" 1
"../../src/components/AutoCompleteSuggestions/AutoCompleteSuggestionsPortal/TransparentOverlay/TransparentOverlay.tsx" "react-hooks/refs" 1
"../../src/components/AutoCompleteSuggestions/index.tsx" "react-hooks/set-state-in-effect" 1
"../../src/components/AutoSubmitModal.tsx" "@typescript-eslint/no-deprecated/InteractionManager.runAfterInteractions" 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrejdak in future, you should not need to manually tighten eslint.seatbelt.tsv. It will happen automatically on merge, and if you let it happen that way then you'll avoid having to resolve conflicts in the ratchet file.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will keep that in mind, thanks!

@roryabraham
roryabraham merged commit fdb50e6 into Expensify:main May 14, 2026
38 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🚧 @roryabraham has triggered a test Expensify/App build. You can view the workflow run here.

@OSBotify

Copy link
Copy Markdown
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/roryabraham in version: 9.3.74-7 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

Bundle Size Analysis (Sentry):

@MelvinBot

Copy link
Copy Markdown
Contributor

After reviewing the changes in this PR, no help site updates are required.

This PR is a purely internal code refactoring (Batch 1 of InteractionManager migration). It replaces InteractionManager.runAfterInteractions calls with alternative patterns across ~39 files. The changes affect modal closing timing, navigation sequencing, and animation handling — but introduce no user-facing changes to features, UI labels, workflows, or behavior.

No new features were added, no existing feature names or settings were changed, and no user-facing flows were modified.

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to production by https://github.com/Beamanator in version: 9.3.74-7 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

@jponikarchuk

Copy link
Copy Markdown

Deploy Blocker #90866 was identified to be related to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants