From 7597ba70aedc34683783c1ca9006fd52849c423a Mon Sep 17 00:00:00 2001 From: gijoe0295 Date: Wed, 26 Jun 2024 00:12:58 +0700 Subject: [PATCH 1/4] fix: context menu actions do not refocus composer for comment linking --- src/libs/Navigation/isReportOpenInRHP.ts | 10 ++++++++++ src/libs/Navigation/linkTo/index.ts | 3 ++- src/libs/ReportActionComposeFocusManager.ts | 11 +++++++---- 3 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 src/libs/Navigation/isReportOpenInRHP.ts diff --git a/src/libs/Navigation/isReportOpenInRHP.ts b/src/libs/Navigation/isReportOpenInRHP.ts new file mode 100644 index 000000000000..72c34f1aff14 --- /dev/null +++ b/src/libs/Navigation/isReportOpenInRHP.ts @@ -0,0 +1,10 @@ +import type {NavigationState} from '@react-navigation/native'; +import NAVIGATORS from '@src/NAVIGATORS'; +import SCREENS from '@src/SCREENS'; + +const isReportOpenInRHP = (state: NavigationState | undefined): boolean => { + const lastRoute = state?.routes?.at(-1); + return !!(lastRoute?.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR && lastRoute?.state?.routes?.some((route) => route?.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT)); +}; + +export default isReportOpenInRHP; diff --git a/src/libs/Navigation/linkTo/index.ts b/src/libs/Navigation/linkTo/index.ts index 90e52d02163c..959886e0a691 100644 --- a/src/libs/Navigation/linkTo/index.ts +++ b/src/libs/Navigation/linkTo/index.ts @@ -3,6 +3,7 @@ import type {NavigationContainerRef, NavigationState, PartialState} from '@react import {findFocusedRoute} from '@react-navigation/native'; import {omitBy} from 'lodash'; import getIsNarrowLayout from '@libs/getIsNarrowLayout'; +import isReportOpenInRHP from '@libs/Navigation/isReportOpenInRHP'; import extractPolicyIDsFromState from '@libs/Navigation/linkingConfig/extractPolicyIDsFromState'; import isCentralPaneName from '@libs/NavigationUtils'; import shallowCompare from '@libs/ObjectUtils'; @@ -68,7 +69,7 @@ export default function linkTo(navigation: NavigationContainerRef route?.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT); + const isReportInRhpOpened = isReportOpenInRHP(rootState); // If action type is different than NAVIGATE we can't change it to the PUSH safely if (action?.type === CONST.NAVIGATION.ACTION_TYPE.NAVIGATE) { diff --git a/src/libs/ReportActionComposeFocusManager.ts b/src/libs/ReportActionComposeFocusManager.ts index 0765f5f0ba75..116a9e47c07f 100644 --- a/src/libs/ReportActionComposeFocusManager.ts +++ b/src/libs/ReportActionComposeFocusManager.ts @@ -1,8 +1,10 @@ import React from 'react'; import type {MutableRefObject} from 'react'; import type {TextInput} from 'react-native'; -import ROUTES from '@src/ROUTES'; -import Navigation from './Navigation/Navigation'; +import SCREENS from '@src/SCREENS'; +import getTopmostRouteName from './Navigation/getTopmostRouteName'; +import isReportOpenInRHP from './Navigation/isReportOpenInRHP'; +import {navigationRef} from './Navigation/Navigation'; type FocusCallback = (shouldFocusForNonBlurInputOnTapOutside?: boolean) => void; @@ -31,8 +33,9 @@ function onComposerFocus(callback: FocusCallback | null, isMainComposer = false) * Request focus on the ReportActionComposer */ function focus(shouldFocusForNonBlurInputOnTapOutside?: boolean) { - /** Do not trigger the refocusing when the active route is not the report route, */ - if (!Navigation.isActiveRoute(ROUTES.REPORT_WITH_ID.getRoute(Navigation.getTopmostReportId() ?? '-1'))) { + /** Do not trigger the refocusing when the active route is not the report screen */ + const navigationState = navigationRef.current?.getState(); + if (!navigationState || (!isReportOpenInRHP(navigationState) && getTopmostRouteName(navigationState) !== SCREENS.REPORT)) { return; } From 45ed4c9a1d93357c0a17bc8f9e1fac6c4550f0d4 Mon Sep 17 00:00:00 2001 From: gijoe0295 Date: Wed, 26 Jun 2024 03:18:14 +0700 Subject: [PATCH 2/4] do not return focus on focus trap deactivate when composer is refocused --- src/components/FocusTrap/FocusTrapForModal/index.web.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/components/FocusTrap/FocusTrapForModal/index.web.tsx b/src/components/FocusTrap/FocusTrapForModal/index.web.tsx index be5da8c49a78..00dcedd32aa2 100644 --- a/src/components/FocusTrap/FocusTrapForModal/index.web.tsx +++ b/src/components/FocusTrap/FocusTrapForModal/index.web.tsx @@ -1,6 +1,7 @@ import FocusTrap from 'focus-trap-react'; import React from 'react'; import sharedTrapStack from '@components/FocusTrap/sharedTrapStack'; +import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager'; import type FocusTrapForModalProps from './FocusTrapForModalProps'; function FocusTrapForModal({children, active}: FocusTrapForModalProps) { @@ -12,6 +13,12 @@ function FocusTrapForModal({children, active}: FocusTrapForModalProps) { clickOutsideDeactivates: true, initialFocus: false, fallbackFocus: document.body, + setReturnFocus: (element) => { + if (ReportActionComposeFocusManager.isFocused()) { + return false; + } + return element; + }, }} > {children} From 43d6d8cd66875d8668ee52b7c5699ed94f267dff Mon Sep 17 00:00:00 2001 From: gijoe0295 Date: Wed, 26 Jun 2024 05:02:33 +0700 Subject: [PATCH 3/4] handle search report case --- src/libs/Navigation/isReportOpenInRHP.ts | 9 ++++++++- src/libs/ReportActionComposeFocusManager.ts | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libs/Navigation/isReportOpenInRHP.ts b/src/libs/Navigation/isReportOpenInRHP.ts index 72c34f1aff14..51e8a95bb66b 100644 --- a/src/libs/Navigation/isReportOpenInRHP.ts +++ b/src/libs/Navigation/isReportOpenInRHP.ts @@ -4,7 +4,14 @@ import SCREENS from '@src/SCREENS'; const isReportOpenInRHP = (state: NavigationState | undefined): boolean => { const lastRoute = state?.routes?.at(-1); - return !!(lastRoute?.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR && lastRoute?.state?.routes?.some((route) => route?.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT)); + if (!lastRoute) { + return false; + } + const params = lastRoute.params; + if (params && 'screen' in params && typeof params.screen === 'string' && params.screen === SCREENS.RIGHT_MODAL.SEARCH_REPORT) { + return true; + } + return !!(lastRoute.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR && lastRoute.state?.routes?.some((route) => route?.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT)); }; export default isReportOpenInRHP; diff --git a/src/libs/ReportActionComposeFocusManager.ts b/src/libs/ReportActionComposeFocusManager.ts index 116a9e47c07f..2dfa81d89a20 100644 --- a/src/libs/ReportActionComposeFocusManager.ts +++ b/src/libs/ReportActionComposeFocusManager.ts @@ -4,7 +4,7 @@ import type {TextInput} from 'react-native'; import SCREENS from '@src/SCREENS'; import getTopmostRouteName from './Navigation/getTopmostRouteName'; import isReportOpenInRHP from './Navigation/isReportOpenInRHP'; -import {navigationRef} from './Navigation/Navigation'; +import navigationRef from './Navigation/navigationRef'; type FocusCallback = (shouldFocusForNonBlurInputOnTapOutside?: boolean) => void; @@ -34,7 +34,7 @@ function onComposerFocus(callback: FocusCallback | null, isMainComposer = false) */ function focus(shouldFocusForNonBlurInputOnTapOutside?: boolean) { /** Do not trigger the refocusing when the active route is not the report screen */ - const navigationState = navigationRef.current?.getState(); + const navigationState = navigationRef.getState(); if (!navigationState || (!isReportOpenInRHP(navigationState) && getTopmostRouteName(navigationState) !== SCREENS.REPORT)) { return; } From a12f4428c88dfff00a9c4da1052300a18cb59024 Mon Sep 17 00:00:00 2001 From: gijoe0295 Date: Wed, 26 Jun 2024 05:45:00 +0700 Subject: [PATCH 4/4] fix perf-test --- tests/perf-test/SidebarLinks.perf-test.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/perf-test/SidebarLinks.perf-test.tsx b/tests/perf-test/SidebarLinks.perf-test.tsx index 4caa22d062d4..0bd2e83f4e72 100644 --- a/tests/perf-test/SidebarLinks.perf-test.tsx +++ b/tests/perf-test/SidebarLinks.perf-test.tsx @@ -20,6 +20,11 @@ jest.mock('../../src/libs/Navigation/Navigation', () => ({ isNavigationReady: jest.fn(() => Promise.resolve()), isDisplayedInModal: jest.fn(() => false), })); +jest.mock('../../src/libs/Navigation/navigationRef', () => ({ + getState: () => ({ + routes: [], + }), +})); jest.mock('@components/Icon/Expensicons'); jest.mock('@react-navigation/native');