Skip to content
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

[Navigation Reboot] Swap the DrawerNavigator for the ResponsiveNavigator #16581

Merged
merged 74 commits into from
Apr 22, 2023

Conversation

adamgrzybowski
Copy link
Contributor

@adamgrzybowski adamgrzybowski commented Mar 27, 2023

Details

This PR is a part of the navigation rework issue. Changes introduced here are related to the three issues listed below.

Motivation for changes should be included in this design DOC but I will include a short summary in the description.

  • Update RHP to be encapsulated in another navigator
    Putting all RHP screens into one stack navigator makes it easier to implement a responsive navigator and planned navigation patterns. Fewer cases to consider.

  • Create the ResponsiveNavigator
    This navigator has two main differences from the regular StackNavigator.

    1. It displays the regular StackView or custom ThreePaneView depending on the size of the screen.
    2. The Router of this navigator copies the behavior of StackNavigator and additionally ensures that there is at least one report route on the stack if the screen is big.
  • Remove the drawer navigator
    All other changes included here should be related to migrating from the DrawerNavigator to the ResponsiveNavigator or the new navigation patterns that this migration enables. e.g. The user can push more than one report screen on the stack.

If you can't find explanations for changes in the design DOC, feel free to ask questions! I will answer or update the description.

Fixed Issues

$ #15848
$ #15851
$ #15852

PROPOSAL: GH_LINK_ISSUE(COMMENT)

Tests

  • Verify that no errors appear in the JS console

Offline tests

QA Steps

  • 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 / Chrome
    • iOS / native
    • iOS / Safari
    • MacOS / Chrome / Safari
    • MacOS / Desktop
  • 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 verified the translation was requested/reviewed 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 correct English and approved by marketing by adding the Waiting for Copy label for a copy review on the original GH to get the correct copy.
    • 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.js 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 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(themeColors.componentBG)
  • 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 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 author checklist, including those that don't apply to this PR.

Screenshots/Videos

Web
web.mov
Mobile Web - Chrome
androidweb.mov
Mobile Web - Safari
iosweb.mov
Desktop
desktop.mov
iOS
ios.mp4
Android
android.mov

@parasharrajat
Copy link
Member

Please ping us when ready for testing.

@mountiny
Copy link
Contributor

I think this is kinda ready for testing but in limited scope.

@adamgrzybowski would you be bale to describe what should bre ready to be tested here or give some guidance for the team once ready? Thanks!

@parasharrajat
Copy link
Member

Let's add as many as possible details to the PR description bcz this is a big change and many will revert to it in the future.

@adamgrzybowski
Copy link
Contributor Author

Hi! I think it's a good time to start some testing and look for what is missing. As you may notice, this may be a bit unusual because work is still in progress and we are assuming that there are bugs here.

That's why I need your help! Those are quite big changes. It would be hard for me to check every place where something could break after this refactor and continue development in the meantime.

The parts that you should focus on are related to the navigation, especially actions around the report screen and the report list. But it would be great to do some general testing.

The part that you shouldn't really focus on now is navigating between screens in the right modal e.g. /settings -> /settings/profile. This part is yet to be done in other PR.

There are a few issues that I am aware but I am still working on them:

  • Lag after opening a report from the report list (there should be a loader here)
  • Using /concierge page to navigate to the report.
  • When using the back button it's possible that highlighting the current report on the sidebar won't update.

Have in mind that the pattern of navigation has changed a little and now there is a possibility to push multiple report screens on the stack

I see a request about the details in the PR but I guess it would be best to fill it in when removing the draft status

Thanks for your help! Let me know if you need some more information.

cc: @parasharrajat @mountiny

@mountiny
Copy link
Contributor

Thanks! C+ could yu try to test push notifications too?

@aimane-chnaif
Copy link
Contributor

C+ could yu try to test push notifications too?

not locally. pretty annoying that we need to release build every time for testing push notification in android.
Even no way of testing iOS from Ready for Build build unless we have udids registered.

@mountiny
Copy link
Contributor

@parasharrajat yes, thanks!

@OSBotify
Copy link
Contributor

OSBotify commented Jun 6, 2023

🚀 Deployed to staging by https://github.com/mountiny in version: 1.3.25-1 🚀

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

@isagoico
Copy link

isagoico commented Jun 6, 2023

@mountiny @adamgrzybowski Hello! Any QA needed for this PR?

@mountiny
Copy link
Contributor

mountiny commented Jun 6, 2023

@isagoico its all part of that one bigger PR, full regression is required to catch anything odd

@OSBotify
Copy link
Contributor

OSBotify commented Jun 8, 2023

🚀 Deployed to production by https://github.com/roryabraham in version: 1.3.25-8 🚀

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

Comment on lines -125 to -129
<SidebarScreen
navigation={navigation}
onLayout={this.trackAppStartTiming}
reportIDFromRoute={reportIDFromRoute}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

The removal of reportIDFromRoute caused a regression #20703. We added a HOC withCurrentReportId that provides currentReportId that's meant to be a replacement of reportIDFromRoute but we didn't replace all the occurrences of that old prop.

return (
<NavigationContainer
key={props.isSmallScreenWidth ? 'small' : 'big'}
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

I don't know if we have to focus on all resizing issues. cc: @mountiny

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't see an alternative solution for now. Remounting is necessary to make this architecture work. Those are drawbacks of solutions that let us simplify the logic when the screen is not resized

Copy link
Contributor

Choose a reason for hiding this comment

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

This is being actively worked on now by @adamgrzybowski and we will solve this by using css styles for the layout and we wont remount the navigators.

const updateSavedNavigationStateAndLogRoute = (state) => {
navigationStateRef.current = state;
props.updateCurrentReportId(state);
parseAndLogRoute(state);
Copy link
Contributor

Choose a reason for hiding this comment

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

✋ Coming from #20825

Salute for all experts for this navigation reboot 🫡

The state can be undefined and it's crashed the app when we try to use the navigation state in other methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@@ -2,8 +2,9 @@
import _ from 'underscore';
import React, {forwardRef, Component} from 'react';
import PropTypes from 'prop-types';
import {FlatList, View} from 'react-native';
Copy link
Contributor

Choose a reason for hiding this comment

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

This caused a minor type console error - #20591

name={SCREENS.REPORT}

// We do it this way to avoid adding this to url
initialParams={{openOnAdminRoom: openOnAdminRoom ? 'true' : undefined}}
Copy link
Contributor

@mollfpr mollfpr Nov 8, 2023

Choose a reason for hiding this comment

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

✋ Coming from #28262

This is causing a console error because the type of openOnAdminRoom is boolean or undefined.

useFocusEffect(() => {
if (_.has(props.session, 'authToken')) {
// Pop the concierge loading page before opening the concierge report.
Navigation.goBack();
Copy link
Contributor

Choose a reason for hiding this comment

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

This line caused a bug where the keyboard appears for a brief moment. More info on #35239

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

Successfully merging this pull request may close these issues.