diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index d700e268ff647..f820f27b98b7b 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -185,12 +185,25 @@ const closeRHPFlow = (ref = navigationRef) => originalCloseRHPFlow(ref); /** * Close the side panel on narrow layout when navigating to a different screen. */ -function closeSidePanelOnNarrowScreen() { +function closeSidePanelOnNarrowScreen(route: Route) { const isExtraLargeScreenWidth = Dimensions.get('window').width > variables.sidePanelResponsiveWidthBreakpoint; if (!sidePanelNVP?.openNarrowScreen || isExtraLargeScreenWidth) { return; } + + // Split "r/:reportID/attachment/add" by ":reportID" to get the prefix "r/" and suffix "/attachment/add" + const addAttachmentPrefix = ROUTES.REPORT_ADD_ATTACHMENT.route.split(':reportID').at(0) ?? ''; + const addAttachmentSuffix = ROUTES.REPORT_ADD_ATTACHMENT.route.split(':reportID').at(1) ?? ''; + const attachmentPreviewRoute = ROUTES.REPORT_ATTACHMENTS.route; + const isAddingAttachment = typeof route === 'string' && route.startsWith(addAttachmentPrefix) && route.includes(addAttachmentSuffix); + const isPreviewingAttachment = typeof route === 'string' && route.startsWith(attachmentPreviewRoute); + // If the user is navigating to an attachment route (previewing or adding), keep the side panel open + // so they still have access to the chat. + if (isAddingAttachment || isPreviewingAttachment) { + return; + } + SidePanelActions.closeSidePanel(true); } @@ -308,7 +321,7 @@ function navigate(route: Route, options?: LinkToOptions) { const targetRoute = route.startsWith(CONST.SAML_REDIRECT_URL) ? ROUTES.HOME : route; linkTo(navigationRef.current, targetRoute, options); - closeSidePanelOnNarrowScreen(); + closeSidePanelOnNarrowScreen(route); } /** * When routes are compared to determine whether the fallback route passed to the goUp function is in the state, diff --git a/tests/navigation/NavigateTests.tsx b/tests/navigation/NavigateTests.tsx index bcc56f8657409..636b5995178e2 100644 --- a/tests/navigation/NavigateTests.tsx +++ b/tests/navigation/NavigateTests.tsx @@ -1,6 +1,7 @@ import {act, render} from '@testing-library/react-native'; import React from 'react'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; +import SidePanelActions from '@libs/actions/SidePanel'; import getIsNarrowLayout from '@libs/getIsNarrowLayout'; import Navigation from '@libs/Navigation/Navigation'; import navigationRef from '@libs/Navigation/navigationRef'; @@ -9,6 +10,7 @@ import NAVIGATORS from '@src/NAVIGATORS'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; import TestNavigationContainer from '../utils/TestNavigationContainer'; +import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; jest.mock('@hooks/useResponsiveLayout', () => jest.fn()); jest.mock('@libs/getIsNarrowLayout', () => jest.fn()); @@ -246,5 +248,97 @@ describe('Navigate', () => { expect(lastSplitAfterNavigate?.name).toBe(NAVIGATORS.RIGHT_MODAL_NAVIGATOR); expect(lastSplitAfterNavigate?.state?.routes.at(-1)?.name).toBe(SCREENS.RIGHT_MODAL.SETTINGS); }); + + it.each([ROUTES.REPORT_ADD_ATTACHMENT.getRoute('1'), ROUTES.REPORT_ATTACHMENTS.getRoute()])( + 'does not close the side panel when navigating to attachment routes (%s)', + async (route) => { + // Given the initialized navigation on the narrow layout with the reports split navigator + render( + , + ); + + const closeSidePanelSpy = jest.spyOn(SidePanelActions, 'closeSidePanel'); + + // Open side panel on narrow screen + act(() => { + SidePanelActions.openSidePanel(true); + }); + await waitForBatchedUpdates(); + + // When navigate to an attachment route + act(() => { + Navigation.navigate(route); + }); + + // Then side panel should remain open + expect(closeSidePanelSpy).not.toHaveBeenCalled(); + }, + ); + + it('closes the side panel when navigating to workspaces list', async () => { + // Given the initialized navigation on the narrow layout with the reports split navigator + render( + , + ); + + const closeSidePanelSpy = jest.spyOn(SidePanelActions, 'closeSidePanel'); + + // Open side panel on narrow screen + act(() => { + SidePanelActions.openSidePanel(true); + }); + await waitForBatchedUpdates(); + + // When navigate to a non-attachment route + act(() => { + Navigation.navigate(ROUTES.WORKSPACES_LIST.getRoute()); + }); + + // Then side panel should close on narrow screen + expect(closeSidePanelSpy).toHaveBeenCalledWith(true); + expect(closeSidePanelSpy).toHaveBeenCalledTimes(1); + }); }); });