[Payment due @mkhutornyi] Fix thread RHP not closing when parent message deleted from search pages - #94293
Conversation
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a1afc6a8d8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| } else if (Navigation.isActiveRoute(ROUTES.REPORT_WITH_ID.getRoute(reportAction.childReportID)) && !isDeletedParentAction) { | ||
| } else if ( | ||
| (Navigation.isActiveRoute(ROUTES.REPORT_WITH_ID.getRoute(reportAction.childReportID)) || | ||
| Navigation.isActiveRoute(ROUTES.SEARCH_REPORT.getRoute({reportID: reportAction.childReportID}))) && |
There was a problem hiding this comment.
Handle search thread routes with action IDs
When a thread is opened from a search result that deep-links to a specific action, the active path is search/view/:reportID/:reportActionID (Search builds those routes with reportActionID). Navigation.isActiveRoute() compares cleaned paths exactly, so comparing only SEARCH_REPORT.getRoute({reportID: reportAction.childReportID}) does not match search/view/<child>/<action>, and deleting the parent message leaves that search-opened thread RHP on screen instead of calling goBack().
Useful? React with 👍 / 👎.
|
It's a followup to #92543 |
2634fa7 to
b0de97c
Compare
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppandroid.movAndroid: mWeb ChromeiOS: HybridAppios.moviOS: mWeb SafariMacOS: Chrome / Safariweb.mov |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b0de97ceb7
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(reportID)); | ||
| } else if (Navigation.isActiveRoute(ROUTES.REPORT_WITH_ID.getRoute(reportAction.childReportID)) && !isDeletedParentAction) { | ||
| Navigation.goBack(undefined); | ||
| } else if (!isDeletedParentAction) { |
There was a problem hiding this comment.
Allow search thread cleanup for deleted parent actions
When the deleted message is the thread parent that this change is trying to handle, isDeletedParentAction is true because deleteReportComment() sets it from ReportActionsUtils.isThreadParentMessage() for actions with visible child replies or whose childReportID matches the current thread report. This guard therefore skips all of the new SEARCH_REPORT route checks, so deleting a parent message from a search-opened thread still never calls Navigation.goBack() and leaves the RHP open in that scenario.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Thanks for the note, but this is intentional behavior. isDeletedParentAction is true only when the deleted message has visible child replies (childVisibleActionCount > 0), meaning the thread still exists and remains accessible — navigating away in that case would be wrong. The new SEARCH_REPORT checks only need to fire when the thread is fully gone (isDeletedParentAction = false), which is exactly what this code does
|
🤖 Review — the navigation fix is logically correct, but it ships without a test for the new path. Verdict: The change correctly closes the thread RHP for search-opened threads. One blocking gap (missing test) and one optional cleanup. 1. No unit test for the new search-route behavior 🔴The only test change is adding the 2.
|
mkhutornyi
left a comment
There was a problem hiding this comment.
Please check AI reviews above. Otherwise LGTM
|
🎯 @mkhutornyi, thanks for reviewing and testing this PR! 🎉 A payment issue will be created for your review once this PR is deployed to production. If payment is not needed (e.g., regression PR review fix etc), react with 👎 to this comment to prevent the payment issue from being created. |
e789567 to
a19e28e
Compare
|
tests failing |
a19e28e to
7c58ac9
Compare
|
@mkhutornyi It should be ok now :) |
|
@codex review |
|
🤖 Review — both items from my previous review are resolved. LGTM. Verdict: The refactor and the new tests address the earlier feedback. No blocking issues.
Type-safety note (not a concern)The comparison Next Steps: Reply with |
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
🤖 Regression scan — no real regression risk found. The change strictly adds a navigation path; the existing one is preserved. Verdict: Safe. The new I checked the three ways this could have regressed:
One low-priority edge worth a reviewer's eye
Next Steps: Reply with |
|
🚧 grgia has triggered a test Expensify/App build. You can view the workflow run here. |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/grgia in version: 9.4.21-2 🚀
|
|
🚀 Deployed to production by https://github.com/mountiny in version: 9.4.21-9 🚀
Bundle Size Analysis (Sentry): |
|
🤖 Payment issue created: #94833 |
| } else if (Navigation.isActiveRoute(ROUTES.REPORT_WITH_ID.getRoute(reportAction.childReportID)) && !isDeletedParentAction) { | ||
| Navigation.goBack(undefined); |
There was a problem hiding this comment.
@MelvinBot Which PR first introduced this logic? Trying to find offending PR
There was a problem hiding this comment.
The else if branch that navigates back when the deleted action's childReportID is the active route was first introduced in #58889 ("fix: header shows skeleton, message is empty" by nkdengineer, merged 2025-03-23, fixing #58134).
- Added the branch:
ROUTES.REPORT_WITH_ID.getRoute(reportAction.childReportID)check +goBack(commiteb215dab1aa) - Same PR then tweaked the
goBackargs:goBack(undefined, {shouldPopToTop: true})→goBack(undefined)(commitd2cea8ba7aa)
Before that PR the block only had the first if (navigate back from REPORT_WITH_ID.getRoute(reportID, reportActionID)), so #58889 is where the child-report goBack logic originated. This PR (#94293) later refactored that same branch to also handle the SEARCH_REPORT route.
Blame evidence
Blame of the pre-#94293 version of src/libs/actions/Report/index.ts:3157-3158:
eb215dab1aae (nkdengineer 2025-03-21) } else if (Navigation.isActiveRoute(ROUTES.REPORT_WITH_ID.getRoute(reportAction.childReportID)) && !isDeletedParentAction) {
d2cea8ba7aa6 (nkdengineer 2025-03-21) Navigation.goBack(undefined);
Both commits merged via #58889.
cc: @mkhutornyi
Explanation of Change
When a parent message with a thread is deleted, the thread RHP should auto-close. This worked when the thread was opened from a regular report view, but not from search pages (
SEARCH_REPORTroute). Added a check for the search report route indeleteReportCommentsoNavigation.goBack()fires in both cases.Screen.Recording.2026-06-23.at.12.28.55.mov
Fixed Issues
$ #92543 (comment)
PROPOSAL:
Tests
Open the Search page and find a message that has a thread (reply in conversation).
Tap the message to open the thread RHP from search.
Delete the parent message (e.g. from the message action menu).
Verify that the thread RHP closes automatically and you return to the search results.
Open a report directly (non-search) and open a thread RHP for a message.
Delete the parent message.
Verify the thread RHP still closes correctly (regression check for the existing path).
Offline tests
N/A
QA Steps
Same as tests.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)Avatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari