-
Notifications
You must be signed in to change notification settings - Fork 3.5k
The central page page is not rendered when resized to narrow and then to wide view again #53466
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| import {useEffect} from 'react'; | ||
| import useResponsiveLayout from '@hooks/useResponsiveLayout'; | ||
| import navigationRef from '@libs/Navigation/navigationRef'; | ||
|
|
||
| /** | ||
| * This hook resets the navigation root state when changing the layout size, resetting the state calls the getRehydredState method in CustomRouter.ts. | ||
| * When the screen size is changed, it is necessary to check whether the application displays the content correctly. | ||
| * When the app is opened on a small layout and the user resizes it to wide, a second screen has to be present in the navigation state to fill the space. | ||
| */ | ||
| function useNavigationResetRootOnLayoutChange() { | ||
| const {shouldUseNarrowLayout} = useResponsiveLayout(); | ||
|
|
||
| useEffect(() => { | ||
| if (!navigationRef.isReady()) { | ||
| return; | ||
| } | ||
| navigationRef.resetRoot(navigationRef.getRootState()); | ||
| }, [shouldUseNarrowLayout]); | ||
| } | ||
|
|
||
| export default useNavigationResetRootOnLayoutChange; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,95 @@ | ||||||||||||||||
| import {NavigationContainer} from '@react-navigation/native'; | ||||||||||||||||
| import {render, renderHook} from '@testing-library/react-native'; | ||||||||||||||||
| import React from 'react'; | ||||||||||||||||
| import useResponsiveLayout from '@hooks/useResponsiveLayout'; | ||||||||||||||||
| import type ResponsiveLayoutResult from '@hooks/useResponsiveLayout/types'; | ||||||||||||||||
| import getIsNarrowLayout from '@libs/getIsNarrowLayout'; | ||||||||||||||||
| import createResponsiveStackNavigator from '@libs/Navigation/AppNavigator/createResponsiveStackNavigator'; | ||||||||||||||||
| import BottomTabNavigator from '@libs/Navigation/AppNavigator/Navigators/BottomTabNavigator'; | ||||||||||||||||
| import useNavigationResetRootOnLayoutChange from '@libs/Navigation/AppNavigator/useNavigationResetRootOnLayoutChange'; | ||||||||||||||||
| import navigationRef from '@libs/Navigation/navigationRef'; | ||||||||||||||||
| import type {AuthScreensParamList} from '@libs/Navigation/types'; | ||||||||||||||||
| import ProfilePage from '@pages/settings/Profile/ProfilePage'; | ||||||||||||||||
| import NAVIGATORS from '@src/NAVIGATORS'; | ||||||||||||||||
| import SCREENS from '@src/SCREENS'; | ||||||||||||||||
|
|
||||||||||||||||
| const RootStack = createResponsiveStackNavigator<AuthScreensParamList>(); | ||||||||||||||||
|
|
||||||||||||||||
| jest.mock('@hooks/useResponsiveLayout', () => jest.fn()); | ||||||||||||||||
| jest.mock('@libs/getIsNarrowLayout', () => jest.fn()); | ||||||||||||||||
|
|
||||||||||||||||
| jest.mock('@pages/settings/InitialSettingsPage'); | ||||||||||||||||
| jest.mock('@pages/settings/Profile/ProfilePage'); | ||||||||||||||||
| jest.mock('@libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar'); | ||||||||||||||||
|
|
||||||||||||||||
| const DEFAULT_USE_RESPONSIVE_LAYOUT_VALUE: ResponsiveLayoutResult = { | ||||||||||||||||
| shouldUseNarrowLayout: true, | ||||||||||||||||
| isSmallScreenWidth: true, | ||||||||||||||||
| isInNarrowPaneModal: false, | ||||||||||||||||
| isExtraSmallScreenHeight: false, | ||||||||||||||||
| isMediumScreenWidth: false, | ||||||||||||||||
| isLargeScreenWidth: false, | ||||||||||||||||
| isExtraSmallScreenWidth: false, | ||||||||||||||||
| isSmallScreen: false, | ||||||||||||||||
| onboardingIsMediumOrLargerScreenWidth: false, | ||||||||||||||||
| }; | ||||||||||||||||
|
|
||||||||||||||||
| const INITIAL_STATE = { | ||||||||||||||||
| routes: [ | ||||||||||||||||
| { | ||||||||||||||||
| name: NAVIGATORS.BOTTOM_TAB_NAVIGATOR, | ||||||||||||||||
| state: { | ||||||||||||||||
| index: 1, | ||||||||||||||||
| routes: [{name: SCREENS.HOME}, {name: SCREENS.SETTINGS.ROOT}], | ||||||||||||||||
| }, | ||||||||||||||||
| }, | ||||||||||||||||
| ], | ||||||||||||||||
| }; | ||||||||||||||||
|
|
||||||||||||||||
| const mockedGetIsNarrowLayout = getIsNarrowLayout as jest.MockedFunction<typeof getIsNarrowLayout>; | ||||||||||||||||
| const mockedUseResponsiveLayout = useResponsiveLayout as jest.MockedFunction<typeof useResponsiveLayout>; | ||||||||||||||||
|
|
||||||||||||||||
| describe('Resize screen', () => { | ||||||||||||||||
| it('Should display the settings profile after resizing the screen with the settings page opened to the wide layout', () => { | ||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A great test case! As described, it ensures that when resizing the screen on the App/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts Lines 365 to 367 in f9ec4fa
As for the App/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/CustomFullScreenRouter.tsx Lines 51 to 54 in f9ec4fa
If needed, maybe similar test case could be added for them as well? I’m not a test expert, so not entirely sure. :)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it's a good point :) We're going to add this test in our PR including nav refactor as it contains many changes related to this code. I believe we can go ahead with this PR for now :)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same, I think we can keep on adding more test cases in future, but its good for this PR |
||||||||||||||||
| // Given the initialized navigation on the narrow layout with the settings screen | ||||||||||||||||
| mockedGetIsNarrowLayout.mockReturnValue(true); | ||||||||||||||||
| mockedUseResponsiveLayout.mockReturnValue({...DEFAULT_USE_RESPONSIVE_LAYOUT_VALUE, shouldUseNarrowLayout: true}); | ||||||||||||||||
|
|
||||||||||||||||
| const {rerender} = renderHook(() => useNavigationResetRootOnLayoutChange()); | ||||||||||||||||
|
|
||||||||||||||||
| render( | ||||||||||||||||
| <NavigationContainer | ||||||||||||||||
| ref={navigationRef} | ||||||||||||||||
| initialState={INITIAL_STATE} | ||||||||||||||||
| > | ||||||||||||||||
| <RootStack.Navigator> | ||||||||||||||||
| <RootStack.Screen | ||||||||||||||||
| name={NAVIGATORS.BOTTOM_TAB_NAVIGATOR} | ||||||||||||||||
| component={BottomTabNavigator} | ||||||||||||||||
| /> | ||||||||||||||||
|
|
||||||||||||||||
| <RootStack.Screen | ||||||||||||||||
| name={SCREENS.SETTINGS.PROFILE.ROOT} | ||||||||||||||||
| component={ProfilePage} | ||||||||||||||||
| /> | ||||||||||||||||
| </RootStack.Navigator> | ||||||||||||||||
| </NavigationContainer>, | ||||||||||||||||
| ); | ||||||||||||||||
|
|
||||||||||||||||
| const rootStateBeforeResize = navigationRef.current?.getRootState(); | ||||||||||||||||
|
|
||||||||||||||||
| expect(rootStateBeforeResize?.routes.at(0)?.name).toBe(NAVIGATORS.BOTTOM_TAB_NAVIGATOR); | ||||||||||||||||
| expect(rootStateBeforeResize?.routes.at(1)).toBeUndefined(); | ||||||||||||||||
|
|
||||||||||||||||
| // When resizing the screen to the wide layout | ||||||||||||||||
| mockedGetIsNarrowLayout.mockReturnValue(false); | ||||||||||||||||
| mockedUseResponsiveLayout.mockReturnValue({...DEFAULT_USE_RESPONSIVE_LAYOUT_VALUE, shouldUseNarrowLayout: false}); | ||||||||||||||||
| rerender({}); | ||||||||||||||||
|
|
||||||||||||||||
| const rootStateAfterResize = navigationRef.current?.getRootState(); | ||||||||||||||||
|
|
||||||||||||||||
| // Then the settings profile page should be displayed on the screen | ||||||||||||||||
| expect(rootStateAfterResize?.routes.at(0)?.name).toBe(NAVIGATORS.BOTTOM_TAB_NAVIGATOR); | ||||||||||||||||
| expect(rootStateAfterResize?.routes.at(1)?.name).toBe(SCREENS.SETTINGS.PROFILE.ROOT); | ||||||||||||||||
| }); | ||||||||||||||||
| }); | ||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a comment description of what this is used for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to start setting this up for more unit tests in the navigation are too @WojtekBoman @adamgrzybowski