diff --git a/contributingGuides/NAVIGATION.md b/contributingGuides/NAVIGATION.md index 32d3919efbe4..8467b97c29fb 100644 --- a/contributingGuides/NAVIGATION.md +++ b/contributingGuides/NAVIGATION.md @@ -1,6 +1,6 @@ # Overview -The navigation in the App consists of a top-level Stack Navigator (called `RootStack`) with each of its `Screen` components handling different high-level flow. All those flows can be seen in `AuthScreens.js` file. +The navigation in the App consists of a top-level Stack Navigator (called `RootStack`) with each of its `Screen` components handling different high-level flow. All those flows can be seen in `AuthScreens.tsx` file. ## Terminology @@ -20,11 +20,11 @@ Navigation Actions - User actions correspond to resulting navigation actions tha ## Adding RHP flows -Most of the time, if you want to add some of the flows concerning one of your reports, e.g. `Money Request` from a user, you will most probably use `RightModalNavigator.js` and `ModalStackNavigators.js` file: +Most of the time, if you want to add some of the flows concerning one of your reports, e.g. `Money Request` from a user, you will most probably use `RightModalNavigator.tsx` and `ModalStackNavigators.tsx` file: -- Since each of those flows is kind of a modal stack, if you want to add a page to the existing flow, you should just add a page to the correct stack in `ModalStackNavigators.js`. +- Since each of those flows is kind of a modal stack, if you want to add a page to the existing flow, you should just add a page to the correct stack in `ModalStackNavigators.tsx`. -- If you want to create new flow, add a `Screen` in `RightModalNavigator.js` and make new modal in `ModalStackNavigators.js` with chosen pages. +- If you want to create new flow, add a `Screen` in `RightModalNavigator.tsx` and make new modal in `ModalStackNavigators.tsx` with chosen pages. When creating RHP flows, you have to remember a couple things: @@ -196,4 +196,4 @@ The action for the first step created with `getMinimalAction` looks like this: ``` ### Deeplinking -There is no minimal action for deeplinking directly to the `Profile` screen. But because the `Settings_root` is not on the stack, pressing UP will reset the params for navigators to the correct ones. \ No newline at end of file +There is no minimal action for deeplinking directly to the `Profile` screen. But because the `Settings_root` is not on the stack, pressing UP will reset the params for navigators to the correct ones. diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 1bc06e231448..9cd55b41455b 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -416,6 +416,7 @@ type OnyxValues = { [ONYXKEYS.IS_LOADING_PAYMENT_METHODS]: boolean; [ONYXKEYS.IS_LOADING_REPORT_DATA]: boolean; [ONYXKEYS.IS_TEST_TOOLS_MODAL_OPEN]: boolean; + [ONYXKEYS.IS_LOADING_APP]: boolean; [ONYXKEYS.WALLET_TRANSFER]: OnyxTypes.WalletTransfer; [ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID]: string; [ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT]: boolean; @@ -428,6 +429,7 @@ type OnyxValues = { [ONYXKEYS.MAPBOX_ACCESS_TOKEN]: OnyxTypes.MapboxAccessToken; [ONYXKEYS.ONYX_UPDATES_FROM_SERVER]: OnyxTypes.OnyxUpdatesFromServer; [ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT]: number; + [ONYXKEYS.DEMO_INFO]: OnyxTypes.DemoInfo; [ONYXKEYS.MAX_CANVAS_AREA]: number; [ONYXKEYS.MAX_CANVAS_HEIGHT]: number; [ONYXKEYS.MAX_CANVAS_WIDTH]: number; diff --git a/src/SCREENS.ts b/src/SCREENS.ts index f4cbcf4f2564..c0d3df82e228 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -2,6 +2,7 @@ * This is a file containing constants for all of the screen names. In most cases, we should use the routes for * navigation. But there are situations where we may need to access screen names directly. */ +import DeepValueOf from './types/utils/DeepValueOf'; const PROTECTED_SCREENS = { HOME: 'Home', @@ -22,6 +23,25 @@ const SCREENS = { WORKSPACES: 'Settings_Workspaces', SECURITY: 'Settings_Security', STATUS: 'Settings_Status', + PROFILE: 'Settings_Profile', + PRONOUNS: 'Settings_Pronouns', + DISPLAY_NAME: 'Settings_Display_Name', + TIMEZONE: 'Settings_Timezone', + TIMEZONE_SELECT: 'Settings_Timezone_Select', + CONTACT_METHODS: 'Settings_ContactMethods', + CONTACT_METHOD_DETAILS: 'Settings_ContactMethodDetails', + NEW_CONTACT_METHOD: 'Settings_NewContactMethod', + SHARE_CODE: 'Settings_Share_Code', + ABOUT: 'Settings_About', + APP_DOWNLOAD_LINKS: 'Settings_App_Download_Links', + LOUNGE_ACCESS: 'Settings_Lounge_Access', + + PERSONAL_DETAILS_INITIAL: 'Settings_PersonalDetails_Initial', + PERSONAL_DETAILS_LEGAL_NAME: 'Settings_PersonalDetails_LegalName', + PERSONAL_DETAILS_DATE_OF_BIRTH: 'Settings_PersonalDetails_DateOfBirth', + PERSONAL_DETAILS_ADDRESS: 'Settings_PersonalDetails_Address', + PERSONAL_DETAILS_ADDRESS_COUNTRY: 'Settings_PersonalDetails_Address_Country', + WALLET: 'Settings_Wallet', WALLET_DOMAIN_CARD: 'Settings_Wallet_DomainCard', WALLET_CARD_GET_PHYSICAL: { @@ -30,15 +50,166 @@ const SCREENS = { ADDRESS: 'Settings_Card_Get_Physical_Address', CONFIRM: 'Settings_Card_Get_Physical_Confirm', }, + WALLET_TRANSFER_BALANCE: 'Settings_Wallet_Transfer_Balance', + WALLET_CHOOSE_TRANSFER_ACCOUNT: 'Settings_Wallet_Choose_Transfer_Account', + WALLET_ENABLE_PAYMENTS: 'Settings_Wallet_EnablePayments', + WALLET_CARD_ACTIVATE: 'Settings_Wallet_Card_Activate', + WALLET_REPORT_VIRTUAL_CARD_FRAUD: 'Settings_Wallet_ReportVirtualCardFraud', + WALLET_CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS: 'Settings_Wallet_Cards_Digital_Details_Update_Address', + + ADD_DEBIT_CARD: 'Settings_Add_Debit_Card', + ADD_BANK_ACCOUNT: 'Settings_Add_Bank_Account', + PREFERENCES_PRIORITY_MODE: 'Settings_Preferences_PriorityMode', + PREFERENCES_LANGUAGE: 'Settings_Preferences_Language', + PREFERENCES_THEME: 'Settings_Preferences_Theme', + CLOSE: 'Settings_Close', + STATUS_SET: 'Settings_Status_Set', + TWO_FACTOR_AUTH: 'Settings_TwoFactorAuth', + REPORT_CARD_LOST_OR_DAMAGED: 'Settings_ReportCardLostOrDamaged', }, SAVE_THE_WORLD: { ROOT: 'SaveTheWorld_Root', }, + RIGHT_MODAL: { + SETTINGS: 'Settings', + NEW_CHAT: 'NewChat', + SEARCH: 'Search', + DETAILS: 'Details', + PROFILE: 'Profile', + REPORT_DETAILS: 'Report_Details', + REPORT_SETTINGS: 'Report_Settings', + REPORT_WELCOME_MESSAGE: 'Report_WelcomeMessage', + PARTICIPANTS: 'Participants', + MONEY_REQUEST: 'MoneyRequest', + NEW_TASK: 'NewTask', + TEACHERS_UNITE: 'TeachersUnite', + TASK_DETAILS: 'Task_Details', + ENABLE_PAYMENTS: 'EnablePayments', + SPLIT_DETAILS: 'SplitDetails', + ADD_PERSONAL_BANK_ACCOUNT: 'AddPersonalBankAccount', + WALLET_STATEMENT: 'Wallet_Statement', + FLAG_COMMENT: 'Flag_Comment', + EDIT_REQUEST: 'EditRequest', + SIGN_IN: 'SignIn', + PRIVATE_NOTES: 'Private_Notes', + ROOM_MEMBERS: 'RoomMembers', + ROOM_INVITE: 'RoomInvite', + REFERRAL: 'Referral', + }, SIGN_IN_WITH_APPLE_DESKTOP: 'AppleSignInDesktop', SIGN_IN_WITH_GOOGLE_DESKTOP: 'GoogleSignInDesktop', DESKTOP_SIGN_IN_REDIRECT: 'DesktopSignInRedirect', SAML_SIGN_IN: 'SAMLSignIn', + + MONEY_REQUEST: { + ROOT: 'Money_Request', + AMOUNT: 'Money_Request_Amount', + PARTICIPANTS: 'Money_Request_Participants', + CONFIRMATION: 'Money_Request_Confirmation', + CURRENCY: 'Money_Request_Currency', + DATE: 'Money_Request_Date', + DESCRIPTION: 'Money_Request_Description', + CATEGORY: 'Money_Request_Category', + TAG: 'Money_Request_Tag', + MERCHANT: 'Money_Request_Merchant', + WAYPOINT: 'Money_Request_Waypoint', + EDIT_WAYPOINT: 'Money_Request_Edit_Waypoint', + DISTANCE: 'Money_Request_Distance', + RECEIPT: 'Money_Request_Receipt', + }, + + IOU_SEND: { + ADD_BANK_ACCOUNT: 'IOU_Send_Add_Bank_Account', + ADD_DEBIT_CARD: 'IOU_Send_Add_Debit_Card', + ENABLE_PAYMENTS: 'IOU_Send_Enable_Payments', + }, + + REPORT_SETTINGS: { + ROOT: 'Report_Settings_Root', + ROOM_NAME: 'Report_Settings_Room_Name', + NOTIFICATION_PREFERENCES: 'Report_Settings_Notification_Preferences', + WRITE_CAPABILITY: 'Report_Settings_Write_Capability', + }, + + NEW_TASK: { + ROOT: 'NewTask_Root', + TASK_ASSIGNEE_SELECTOR: 'NewTask_TaskAssigneeSelector', + TASK_SHARE_DESTINATION_SELECTOR: 'NewTask_TaskShareDestinationSelector', + DETAILS: 'NewTask_Details', + TITLE: 'NewTask_Title', + DESCRIPTION: 'NewTask_Description', + }, + + TASK: { + TITLE: 'Task_Title', + DESCRIPTION: 'Task_Description', + ASSIGNEE: 'Task_Assignee', + }, + + PRIVATE_NOTES: { + VIEW: 'PrivateNotes_View', + LIST: 'PrivateNotes_List', + EDIT: 'PrivateNotes_Edit', + }, + + REPORT_DETAILS: { + ROOT: 'Report_Details_Root', + SHARE_CODE: 'Report_Details_Share_Code', + }, + + WORKSPACE: { + INITIAL: 'Workspace_Initial', + SETTINGS: 'Workspace_Settings', + CARD: 'Workspace_Card', + REIMBURSE: 'Workspace_Reimburse', + RATE_AND_UNIT: 'Workspace_RateAndUnit', + BILLS: 'Workspace_Bills', + INVOICES: 'Workspace_Invoices', + TRAVEL: 'Workspace_Travel', + MEMBERS: 'Workspace_Members', + INVITE: 'Workspace_Invite', + INVITE_MESSAGE: 'Workspace_Invite_Message', + CURRENCY: 'Workspace_Settings_Currency', + }, + + EDIT_REQUEST: { + ROOT: 'EditRequest_Root', + CURRENCY: 'EditRequest_Currency', + }, + + I_KNOW_A_TEACHER: 'I_Know_A_Teacher', + INTRO_SCHOOL_PRINCIPAL: 'Intro_School_Principal', + I_AM_A_TEACHER: 'I_Am_A_Teacher', + + ENABLE_PAYMENTS_ROOT: 'EnablePayments_Root', + ADD_PERSONAL_BANK_ACCOUNT_ROOT: 'AddPersonalBankAccount_Root', + REIMBURSEMENT_ACCOUNT_ROOT: 'Reimbursement_Account_Root', + WALLET_STATEMENT_ROOT: 'WalletStatement_Root', + SIGN_IN_ROOT: 'SignIn_Root', + DETAILS_ROOT: 'Details_Root', + PROFILE_ROOT: 'Profile_Root', + REPORT_WELCOME_MESSAGE_ROOT: 'Report_WelcomeMessage_Root', + REPORT_PARTICIPANTS_ROOT: 'ReportParticipants_Root', + ROOM_MEMBERS_ROOT: 'RoomMembers_Root', + ROOM_INVITE_ROOT: 'RoomInvite_Root', + SEARCH_ROOT: 'Search_Root', + NEW_CHAT_ROOT: 'NewChat_Root', + FLAG_COMMENT_ROOT: 'FlagComment_Root', + + SPLIT_DETAILS: { + ROOT: 'SplitDetails_Root', + EDIT_REQUEST: 'SplitDetails_Edit_Request', + EDIT_CURRENCY: 'SplitDetails_Edit_Currency', + }, + + REIMBURSEMENT_ACCOUNT: 'ReimbursementAccount', + GET_ASSISTANCE: 'GetAssistance', + REFERRAL_DETAILS: 'Referral_Details', + KEYBOARD_SHORTCUTS: 'KeyboardShortcuts', } as const; +type Screen = DeepValueOf; + export default SCREENS; export {PROTECTED_SCREENS}; +export type {Screen}; diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.tsx similarity index 83% rename from src/libs/Navigation/AppNavigator/AuthScreens.js rename to src/libs/Navigation/AppNavigator/AuthScreens.tsx index de334635da54..a78b38728136 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.js +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -1,9 +1,6 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; import React, {memo, useEffect, useRef} from 'react'; import {View} from 'react-native'; -import Onyx, {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; +import Onyx, {OnyxEntry, withOnyx} from 'react-native-onyx'; import useWindowDimensions from '@hooks/useWindowDimensions'; import KeyboardShortcut from '@libs/KeyboardShortcut'; import getCurrentUrl from '@libs/Navigation/currentUrl'; @@ -12,6 +9,7 @@ import NetworkConnection from '@libs/NetworkConnection'; import * as Pusher from '@libs/Pusher/pusher'; import PusherConnectionManager from '@libs/PusherConnectionManager'; import * as SessionUtils from '@libs/SessionUtils'; +import type {AuthScreensParamList} from '@navigation/types'; import DemoSetupPage from '@pages/DemoSetupPage'; import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; import DesktopSignInRedirectPage from '@pages/signin/DesktopSignInRedirectPage'; @@ -31,32 +29,52 @@ import NAVIGATORS from '@src/NAVIGATORS'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; +import * as OnyxTypes from '@src/types/onyx'; +import type {SelectedTimezone, Timezone} from '@src/types/onyx/PersonalDetails'; import createCustomStackNavigator from './createCustomStackNavigator'; import defaultScreenOptions from './defaultScreenOptions'; import getRootNavigatorScreenOptions from './getRootNavigatorScreenOptions'; import CentralPaneNavigator from './Navigators/CentralPaneNavigator'; import RightModalNavigator from './Navigators/RightModalNavigator'; -const loadReportAttachments = () => require('../../../pages/home/report/ReportAttachments').default; -const loadSidebarScreen = () => require('../../../pages/home/sidebar/SidebarScreen').default; -const loadValidateLoginPage = () => require('../../../pages/ValidateLoginPage').default; -const loadLogOutPreviousUserPage = () => require('../../../pages/LogOutPreviousUserPage').default; -const loadConciergePage = () => require('../../../pages/ConciergePage').default; +type AuthScreensProps = { + /** Session of currently logged in user */ + session: OnyxEntry; + + /** The report ID of the last opened public room as anonymous user */ + lastOpenedPublicRoomID: OnyxEntry; + + /** Opt-in experimental mode that prevents certain Onyx keys from persisting to disk */ + isUsingMemoryOnlyKeys: OnyxEntry; + + /** The last Onyx update ID was applied to the client */ + lastUpdateIDAppliedToClient: OnyxEntry; -let timezone; -let currentAccountID; -let isLoadingApp; + /** Information about any currently running demos */ + demoInfo: OnyxEntry; +}; + +const loadReportAttachments = () => require('../../../pages/home/report/ReportAttachments').default as React.ComponentType; +const loadSidebarScreen = () => require('../../../pages/home/sidebar/SidebarScreen').default as React.ComponentType; +const loadValidateLoginPage = () => require('../../../pages/ValidateLoginPage').default as React.ComponentType; +const loadLogOutPreviousUserPage = () => require('../../../pages/LogOutPreviousUserPage').default as React.ComponentType; +const loadConciergePage = () => require('../../../pages/ConciergePage').default as React.ComponentType; + +let timezone: Timezone | null; +let currentAccountID = -1; +let isLoadingApp = false; Onyx.connect({ key: ONYXKEYS.SESSION, - callback: (val) => { + callback: (value) => { // When signed out, val hasn't accountID - if (!_.has(val, 'accountID')) { + if (!(value && 'accountID' in value)) { timezone = null; return; } - currentAccountID = val.accountID; + currentAccountID = value.accountID ?? -1; + if (Navigation.isActiveRoute(ROUTES.SIGN_IN_MODAL)) { // This means sign in in RHP was successful, so we can dismiss the modal and subscribe to user events Navigation.dismissModal(); @@ -67,17 +85,17 @@ Onyx.connect({ Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, - callback: (val) => { - if (!val || timezone) { + callback: (value) => { + if (!value || timezone) { return; } - timezone = lodashGet(val, [currentAccountID, 'timezone'], {}); - const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; + timezone = value?.[currentAccountID]?.timezone ?? {}; + const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone as SelectedTimezone; // If the current timezone is different than the user's timezone, and their timezone is set to automatic // then update their timezone. - if (_.isObject(timezone) && timezone.automatic && timezone.selected !== currentTimezone) { + if (timezone?.automatic && timezone?.selected !== currentTimezone) { timezone.selected = currentTimezone; PersonalDetails.updateAutomaticTimezone({ automatic: true, @@ -89,12 +107,12 @@ Onyx.connect({ Onyx.connect({ key: ONYXKEYS.IS_LOADING_APP, - callback: (val) => { - isLoadingApp = val; + callback: (value) => { + isLoadingApp = !!value; }, }); -const RootStack = createCustomStackNavigator(); +const RootStack = createCustomStackNavigator(); // We want to delay the re-rendering for components(e.g. ReportActionCompose) // that depends on modal visibility until Modal is completely closed and its focused // When modal screen is focused, update modal visibility in Onyx @@ -109,40 +127,7 @@ const modalScreenListeners = { }, }; -const propTypes = { - /** Session of currently logged in user */ - session: PropTypes.shape({ - email: PropTypes.string.isRequired, - }), - - /** The report ID of the last opened public room as anonymous user */ - lastOpenedPublicRoomID: PropTypes.string, - - /** Opt-in experimental mode that prevents certain Onyx keys from persisting to disk */ - isUsingMemoryOnlyKeys: PropTypes.bool, - - /** The last Onyx update ID was applied to the client */ - lastUpdateIDAppliedToClient: PropTypes.number, - - /** Information about any currently running demos */ - demoInfo: PropTypes.shape({ - money2020: PropTypes.shape({ - isBeginningDemo: PropTypes.bool, - }), - }), -}; - -const defaultProps = { - isUsingMemoryOnlyKeys: false, - session: { - email: null, - }, - lastOpenedPublicRoomID: null, - lastUpdateIDAppliedToClient: null, - demoInfo: {}, -}; - -function AuthScreens({isUsingMemoryOnlyKeys, lastUpdateIDAppliedToClient, session, lastOpenedPublicRoomID, demoInfo}) { +function AuthScreens({lastUpdateIDAppliedToClient, session, lastOpenedPublicRoomID, demoInfo, isUsingMemoryOnlyKeys = false}: AuthScreensProps) { const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); const screenOptions = getRootNavigatorScreenOptions(isSmallScreenWidth, styles); @@ -158,8 +143,8 @@ function AuthScreens({isUsingMemoryOnlyKeys, lastUpdateIDAppliedToClient, sessio const searchShortcutConfig = CONST.KEYBOARD_SHORTCUTS.SEARCH; const chatShortcutConfig = CONST.KEYBOARD_SHORTCUTS.NEW_CHAT; const currentUrl = getCurrentUrl(); - const isLoggingInAsNewUser = SessionUtils.isLoggingInAsNewUser(currentUrl, session.email); - const shouldGetAllData = isUsingMemoryOnlyKeys || SessionUtils.didUserLogInDuringSession() || isLoggingInAsNewUser; + const isLoggingInAsNewUser = !!session?.email && SessionUtils.isLoggingInAsNewUser(currentUrl, session.email); + const shouldGetAllData = !!isUsingMemoryOnlyKeys || SessionUtils.didUserLogInDuringSession() || isLoggingInAsNewUser; // Sign out the current user if we're transitioning with a different user const isTransitioning = currentUrl.includes(ROUTES.TRANSITION_BETWEEN_APPS); if (isLoggingInAsNewUser && isTransitioning) { @@ -202,7 +187,7 @@ function AuthScreens({isUsingMemoryOnlyKeys, lastUpdateIDAppliedToClient, sessio App.redirectThirdPartyDesktopSignIn(); // Check if we should be running any demos immediately after signing in. - if (lodashGet(demoInfo, 'money2020.isBeginningDemo', false)) { + if (demoInfo?.money2020?.isBeginningDemo) { Navigation.navigate(ROUTES.MONEY2020, CONST.NAVIGATION.TYPE.FORCED_UP); } if (lastOpenedPublicRoomID) { @@ -265,15 +250,7 @@ function AuthScreens({isUsingMemoryOnlyKeys, lastUpdateIDAppliedToClient, sessio return ( - + true); -export default withOnyx({ +export default withOnyx({ session: { key: ONYXKEYS.SESSION, }, diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js deleted file mode 100644 index be803e62a98b..000000000000 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ /dev/null @@ -1,264 +0,0 @@ -import {CardStyleInterpolators, createStackNavigator} from '@react-navigation/stack'; -import React, {useMemo} from 'react'; -import _ from 'underscore'; -import useThemeStyles from '@styles/useThemeStyles'; -import SCREENS from '@src/SCREENS'; - -/** - * Create a modal stack navigator with an array of sub-screens. - * - * @param {Object} screens key/value pairs where the key is the name of the screen and the value is a functon that returns the lazy-loaded component - * @returns {Function} - */ -function createModalStackNavigator(screens) { - const ModalStackNavigator = createStackNavigator(); - - function ModalStack() { - const styles = useThemeStyles(); - - const defaultSubRouteOptions = useMemo( - () => ({ - cardStyle: styles.navigationScreenCardStyle, - headerShown: false, - cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS, - }), - [styles], - ); - - return ( - - {_.map(screens, (getComponent, name) => ( - - ))} - - ); - } - - ModalStack.displayName = 'ModalStack'; - - return ModalStack; -} - -const MoneyRequestModalStackNavigator = createModalStackNavigator({ - Money_Request: () => require('../../../pages/iou/MoneyRequestSelectorPage').default, - Money_Request_Amount: () => require('../../../pages/iou/steps/NewRequestAmountPage').default, - Money_Request_Participants: () => require('../../../pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage').default, - Money_Request_Confirmation: () => require('../../../pages/iou/steps/MoneyRequestConfirmPage').default, - Money_Request_Currency: () => require('../../../pages/iou/IOUCurrencySelection').default, - Money_Request_Date: () => require('../../../pages/iou/MoneyRequestDatePage').default, - Money_Request_Description: () => require('../../../pages/iou/MoneyRequestDescriptionPage').default, - Money_Request_Category: () => require('../../../pages/iou/MoneyRequestCategoryPage').default, - Money_Request_Tag: () => require('../../../pages/iou/MoneyRequestTagPage').default, - Money_Request_Merchant: () => require('../../../pages/iou/MoneyRequestMerchantPage').default, - IOU_Send_Add_Bank_Account: () => require('../../../pages/AddPersonalBankAccountPage').default, - IOU_Send_Add_Debit_Card: () => require('../../../pages/settings/Wallet/AddDebitCardPage').default, - IOU_Send_Enable_Payments: () => require('../../../pages/EnablePayments/EnablePaymentsPage').default, - Money_Request_Waypoint: () => require('../../../pages/iou/NewDistanceRequestWaypointEditorPage').default, - Money_Request_Edit_Waypoint: () => require('../../../pages/iou/MoneyRequestEditWaypointPage').default, - Money_Request_Distance: () => require('../../../pages/iou/NewDistanceRequestPage').default, - Money_Request_Receipt: () => require('../../../pages/EditRequestReceiptPage').default, -}); - -const SplitDetailsModalStackNavigator = createModalStackNavigator({ - SplitDetails_Root: () => require('../../../pages/iou/SplitBillDetailsPage').default, - SplitDetails_Edit_Request: () => require('../../../pages/EditSplitBillPage').default, - SplitDetails_Edit_Currency: () => require('../../../pages/iou/IOUCurrencySelection').default, -}); - -const DetailsModalStackNavigator = createModalStackNavigator({ - Details_Root: () => require('../../../pages/DetailsPage').default, -}); - -const ProfileModalStackNavigator = createModalStackNavigator({ - Profile_Root: () => require('../../../pages/ProfilePage').default, -}); - -const ReportDetailsModalStackNavigator = createModalStackNavigator({ - Report_Details_Root: () => require('../../../pages/ReportDetailsPage').default, - Report_Details_Share_Code: () => require('../../../pages/home/report/ReportDetailsShareCodePage').default, -}); - -const ReportSettingsModalStackNavigator = createModalStackNavigator({ - Report_Settings_Root: () => require('../../../pages/settings/Report/ReportSettingsPage').default, - Report_Settings_Room_Name: () => require('../../../pages/settings/Report/RoomNamePage').default, - Report_Settings_Notification_Preferences: () => require('../../../pages/settings/Report/NotificationPreferencePage').default, - Report_Settings_Write_Capability: () => require('../../../pages/settings/Report/WriteCapabilityPage').default, -}); - -const TaskModalStackNavigator = createModalStackNavigator({ - Task_Title: () => require('../../../pages/tasks/TaskTitlePage').default, - Task_Description: () => require('../../../pages/tasks/TaskDescriptionPage').default, - Task_Assignee: () => require('../../../pages/tasks/TaskAssigneeSelectorModal').default, -}); - -const ReportWelcomeMessageModalStackNavigator = createModalStackNavigator({ - Report_WelcomeMessage_Root: () => require('../../../pages/ReportWelcomeMessagePage').default, -}); - -const ReportParticipantsModalStackNavigator = createModalStackNavigator({ - ReportParticipants_Root: () => require('../../../pages/ReportParticipantsPage').default, -}); - -const RoomMembersModalStackNavigator = createModalStackNavigator({ - RoomMembers_Root: () => require('../../../pages/RoomMembersPage').default, -}); - -const RoomInviteModalStackNavigator = createModalStackNavigator({ - RoomInvite_Root: () => require('../../../pages/RoomInvitePage').default, -}); - -const SearchModalStackNavigator = createModalStackNavigator({ - Search_Root: () => require('../../../pages/SearchPage').default, -}); - -const NewChatModalStackNavigator = createModalStackNavigator({ - NewChat_Root: () => require('../../../pages/NewChatSelectorPage').default, -}); - -const NewTaskModalStackNavigator = createModalStackNavigator({ - NewTask_Root: () => require('../../../pages/tasks/NewTaskPage').default, - NewTask_TaskAssigneeSelector: () => require('../../../pages/tasks/TaskAssigneeSelectorModal').default, - NewTask_TaskShareDestinationSelector: () => require('../../../pages/tasks/TaskShareDestinationSelectorModal').default, - NewTask_Details: () => require('../../../pages/tasks/NewTaskDetailsPage').default, - NewTask_Title: () => require('../../../pages/tasks/NewTaskTitlePage').default, - NewTask_Description: () => require('../../../pages/tasks/NewTaskDescriptionPage').default, -}); - -const NewTeachersUniteNavigator = createModalStackNavigator({ - [SCREENS.SAVE_THE_WORLD.ROOT]: () => require('../../../pages/TeachersUnite/SaveTheWorldPage').default, - I_Know_A_Teacher: () => require('../../../pages/TeachersUnite/KnowATeacherPage').default, - Intro_School_Principal: () => require('../../../pages/TeachersUnite/ImTeacherPage').default, - I_Am_A_Teacher: () => require('../../../pages/TeachersUnite/ImTeacherPage').default, -}); - -const SettingsModalStackNavigator = createModalStackNavigator({ - [SCREENS.SETTINGS.ROOT]: () => require('../../../pages/settings/InitialSettingsPage').default, - Settings_Share_Code: () => require('../../../pages/ShareCodePage').default, - [SCREENS.SETTINGS.WORKSPACES]: () => require('../../../pages/workspace/WorkspacesListPage').default, - Settings_Profile: () => require('../../../pages/settings/Profile/ProfilePage').default, - Settings_Pronouns: () => require('../../../pages/settings/Profile/PronounsPage').default, - Settings_Display_Name: () => require('../../../pages/settings/Profile/DisplayNamePage').default, - Settings_Timezone: () => require('../../../pages/settings/Profile/TimezoneInitialPage').default, - Settings_Timezone_Select: () => require('../../../pages/settings/Profile/TimezoneSelectPage').default, - Settings_PersonalDetails_Initial: () => require('../../../pages/settings/Profile/PersonalDetails/PersonalDetailsInitialPage').default, - Settings_PersonalDetails_LegalName: () => require('../../../pages/settings/Profile/PersonalDetails/LegalNamePage').default, - Settings_PersonalDetails_DateOfBirth: () => require('../../../pages/settings/Profile/PersonalDetails/DateOfBirthPage').default, - Settings_PersonalDetails_Address: () => require('../../../pages/settings/Profile/PersonalDetails/AddressPage').default, - Settings_PersonalDetails_Address_Country: () => require('../../../pages/settings/Profile/PersonalDetails/CountrySelectionPage').default, - Settings_ContactMethods: () => require('../../../pages/settings/Profile/Contacts/ContactMethodsPage').default, - Settings_ContactMethodDetails: () => require('../../../pages/settings/Profile/Contacts/ContactMethodDetailsPage').default, - Settings_NewContactMethod: () => require('../../../pages/settings/Profile/Contacts/NewContactMethodPage').default, - [SCREENS.SETTINGS.PREFERENCES]: () => require('../../../pages/settings/Preferences/PreferencesPage').default, - Settings_Preferences_PriorityMode: () => require('../../../pages/settings/Preferences/PriorityModePage').default, - Settings_Preferences_Language: () => require('../../../pages/settings/Preferences/LanguagePage').default, - // Will be uncommented as part of https://github.com/Expensify/App/issues/21670 - // Settings_Preferences_Theme: () => require('../../../pages/settings/Preferences/ThemePage').default, - Settings_Close: () => require('../../../pages/settings/Security/CloseAccountPage').default, - [SCREENS.SETTINGS.SECURITY]: () => require('../../../pages/settings/Security/SecuritySettingsPage').default, - Settings_About: () => require('../../../pages/settings/AboutPage/AboutPage').default, - Settings_App_Download_Links: () => require('../../../pages/settings/AppDownloadLinks').default, - Settings_Lounge_Access: () => require('../../../pages/settings/Profile/LoungeAccessPage').default, - Settings_Wallet: () => require('../../../pages/settings/Wallet/WalletPage').default, - Settings_Wallet_Cards_Digital_Details_Update_Address: () => require('../../../pages/settings/Profile/PersonalDetails/AddressPage').default, - Settings_Wallet_DomainCard: () => require('../../../pages/settings/Wallet/ExpensifyCardPage').default, - Settings_Wallet_ReportVirtualCardFraud: () => require('../../../pages/settings/Wallet/ReportVirtualCardFraudPage').default, - Settings_Wallet_Card_Activate: () => require('../../../pages/settings/Wallet/ActivatePhysicalCardPage').default, - [SCREENS.SETTINGS.WALLET_CARD_GET_PHYSICAL.NAME]: () => require('../../../pages/settings/Wallet/Card/GetPhysicalCardName').default, - [SCREENS.SETTINGS.WALLET_CARD_GET_PHYSICAL.PHONE]: () => require('../../../pages/settings/Wallet/Card/GetPhysicalCardPhone').default, - [SCREENS.SETTINGS.WALLET_CARD_GET_PHYSICAL.ADDRESS]: () => require('../../../pages/settings/Wallet/Card/GetPhysicalCardAddress').default, - [SCREENS.SETTINGS.WALLET_CARD_GET_PHYSICAL.CONFIRM]: () => require('../../../pages/settings/Wallet/Card/GetPhysicalCardConfirm').default, - Settings_Wallet_Transfer_Balance: () => require('../../../pages/settings/Wallet/TransferBalancePage').default, - Settings_Wallet_Choose_Transfer_Account: () => require('../../../pages/settings/Wallet/ChooseTransferAccountPage').default, - Settings_Wallet_EnablePayments: () => require('../../../pages/EnablePayments/EnablePaymentsPage').default, - Settings_Add_Debit_Card: () => require('../../../pages/settings/Wallet/AddDebitCardPage').default, - Settings_Add_Bank_Account: () => require('../../../pages/AddPersonalBankAccountPage').default, - [SCREENS.SETTINGS.STATUS]: () => require('../../../pages/settings/Profile/CustomStatus/StatusPage').default, - Settings_Status_Set: () => require('../../../pages/settings/Profile/CustomStatus/StatusSetPage').default, - Workspace_Initial: () => require('../../../pages/workspace/WorkspaceInitialPage').default, - Workspace_Settings: () => require('../../../pages/workspace/WorkspaceSettingsPage').default, - Workspace_Settings_Currency: () => require('../../../pages/workspace/WorkspaceSettingsCurrencyPage').default, - Workspace_Card: () => require('../../../pages/workspace/card/WorkspaceCardPage').default, - Workspace_Reimburse: () => require('../../../pages/workspace/reimburse/WorkspaceReimbursePage').default, - Workspace_RateAndUnit: () => require('../../../pages/workspace/reimburse/WorkspaceRateAndUnitPage').default, - Workspace_Bills: () => require('../../../pages/workspace/bills/WorkspaceBillsPage').default, - Workspace_Invoices: () => require('../../../pages/workspace/invoices/WorkspaceInvoicesPage').default, - Workspace_Travel: () => require('../../../pages/workspace/travel/WorkspaceTravelPage').default, - Workspace_Members: () => require('../../../pages/workspace/WorkspaceMembersPage').default, - Workspace_Invite: () => require('../../../pages/workspace/WorkspaceInvitePage').default, - Workspace_Invite_Message: () => require('../../../pages/workspace/WorkspaceInviteMessagePage').default, - ReimbursementAccount: () => require('../../../pages/ReimbursementAccount/ReimbursementAccountPage').default, - GetAssistance: () => require('../../../pages/GetAssistancePage').default, - Settings_TwoFactorAuth: () => require('../../../pages/settings/Security/TwoFactorAuth/TwoFactorAuthPage').default, - Settings_ReportCardLostOrDamaged: () => require('../../../pages/settings/Wallet/ReportCardLostPage').default, - KeyboardShortcuts: () => require('../../../pages/KeyboardShortcutsPage').default, -}); - -const EnablePaymentsStackNavigator = createModalStackNavigator({ - EnablePayments_Root: () => require('../../../pages/EnablePayments/EnablePaymentsPage').default, -}); - -const AddPersonalBankAccountModalStackNavigator = createModalStackNavigator({ - AddPersonalBankAccount_Root: () => require('../../../pages/AddPersonalBankAccountPage').default, -}); - -const ReimbursementAccountModalStackNavigator = createModalStackNavigator({ - ReimbursementAccount_Root: () => require('../../../pages/ReimbursementAccount/ReimbursementAccountPage').default, -}); - -const WalletStatementStackNavigator = createModalStackNavigator({ - WalletStatement_Root: () => require('../../../pages/wallet/WalletStatementPage').default, -}); - -const FlagCommentStackNavigator = createModalStackNavigator({ - FlagComment_Root: () => require('../../../pages/FlagCommentPage').default, -}); - -const EditRequestStackNavigator = createModalStackNavigator({ - EditRequest_Root: () => require('../../../pages/EditRequestPage').default, - EditRequest_Currency: () => require('../../../pages/iou/IOUCurrencySelection').default, -}); - -const PrivateNotesModalStackNavigator = createModalStackNavigator({ - PrivateNotes_View: () => require('../../../pages/PrivateNotes/PrivateNotesViewPage').default, - PrivateNotes_List: () => require('../../../pages/PrivateNotes/PrivateNotesListPage').default, - PrivateNotes_Edit: () => require('../../../pages/PrivateNotes/PrivateNotesEditPage').default, -}); - -const SignInModalStackNavigator = createModalStackNavigator({ - SignIn_Root: () => require('../../../pages/signin/SignInModal').default, -}); -const ReferralModalStackNavigator = createModalStackNavigator({ - Referral_Details: () => require('../../../pages/ReferralDetailsPage').default, -}); - -export { - MoneyRequestModalStackNavigator, - SplitDetailsModalStackNavigator, - DetailsModalStackNavigator, - ProfileModalStackNavigator, - ReportDetailsModalStackNavigator, - TaskModalStackNavigator, - ReportSettingsModalStackNavigator, - ReportWelcomeMessageModalStackNavigator, - ReportParticipantsModalStackNavigator, - SearchModalStackNavigator, - NewChatModalStackNavigator, - NewTaskModalStackNavigator, - SettingsModalStackNavigator, - EnablePaymentsStackNavigator, - AddPersonalBankAccountModalStackNavigator, - ReimbursementAccountModalStackNavigator, - WalletStatementStackNavigator, - FlagCommentStackNavigator, - EditRequestStackNavigator, - PrivateNotesModalStackNavigator, - NewTeachersUniteNavigator, - SignInModalStackNavigator, - RoomMembersModalStackNavigator, - RoomInviteModalStackNavigator, - ReferralModalStackNavigator, -}; diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx new file mode 100644 index 000000000000..163423036362 --- /dev/null +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx @@ -0,0 +1,294 @@ +import {ParamListBase} from '@react-navigation/routers'; +import {CardStyleInterpolators, createStackNavigator, StackNavigationOptions} from '@react-navigation/stack'; +import React, {useMemo} from 'react'; +import type { + AddPersonalBankAccountNavigatorParamList, + DetailsNavigatorParamList, + EditRequestNavigatorParamList, + EnablePaymentsNavigatorParamList, + FlagCommentNavigatorParamList, + MoneyRequestNavigatorParamList, + NewChatNavigatorParamList, + NewTaskNavigatorParamList, + ParticipantsNavigatorParamList, + PrivateNotesNavigatorParamList, + ProfileNavigatorParamList, + ReferralDetailsNavigatorParamList, + ReimbursementAccountNavigatorParamList, + ReportDetailsNavigatorParamList, + ReportSettingsNavigatorParamList, + ReportWelcomeMessageNavigatorParamList, + RoomInviteNavigatorParamList, + RoomMembersNavigatorParamList, + SearchNavigatorParamList, + SettingsNavigatorParamList, + SignInNavigatorParamList, + SplitDetailsNavigatorParamList, + TaskDetailsNavigatorParamList, + TeachersUniteNavigatorParamList, + WalletStatementNavigatorParamList, +} from '@navigation/types'; +import useThemeStyles from '@styles/useThemeStyles'; +import SCREENS from '@src/SCREENS'; +import type {Screen} from '@src/SCREENS'; + +type Screens = Partial React.ComponentType>>; + +/** + * Create a modal stack navigator with an array of sub-screens. + * + * @param screens key/value pairs where the key is the name of the screen and the value is a functon that returns the lazy-loaded component + */ +function createModalStackNavigator(screens: Screens): React.ComponentType { + const ModalStackNavigator = createStackNavigator(); + + function ModalStack() { + const styles = useThemeStyles(); + + const defaultSubRouteOptions = useMemo( + (): StackNavigationOptions => ({ + cardStyle: styles.navigationScreenCardStyle, + headerShown: false, + cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS, + }), + [styles], + ); + + return ( + + {Object.keys(screens as Required).map((name) => ( + )[name as Screen]} + /> + ))} + + ); + } + + ModalStack.displayName = 'ModalStack'; + + return ModalStack; +} + +const MoneyRequestModalStackNavigator = createModalStackNavigator({ + [SCREENS.MONEY_REQUEST.ROOT]: () => require('../../../pages/iou/MoneyRequestSelectorPage').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.AMOUNT]: () => require('../../../pages/iou/steps/NewRequestAmountPage').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.PARTICIPANTS]: () => require('../../../pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.CONFIRMATION]: () => require('../../../pages/iou/steps/MoneyRequestConfirmPage').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.CURRENCY]: () => require('../../../pages/iou/IOUCurrencySelection').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.DATE]: () => require('../../../pages/iou/MoneyRequestDatePage').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.DESCRIPTION]: () => require('../../../pages/iou/MoneyRequestDescriptionPage').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.CATEGORY]: () => require('../../../pages/iou/MoneyRequestCategoryPage').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.TAG]: () => require('../../../pages/iou/MoneyRequestTagPage').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.MERCHANT]: () => require('../../../pages/iou/MoneyRequestMerchantPage').default as React.ComponentType, + [SCREENS.IOU_SEND.ADD_BANK_ACCOUNT]: () => require('../../../pages/AddPersonalBankAccountPage').default as React.ComponentType, + [SCREENS.IOU_SEND.ADD_DEBIT_CARD]: () => require('../../../pages/settings/Wallet/AddDebitCardPage').default as React.ComponentType, + [SCREENS.IOU_SEND.ENABLE_PAYMENTS]: () => require('../../../pages/EnablePayments/EnablePaymentsPage').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.WAYPOINT]: () => require('../../../pages/iou/NewDistanceRequestWaypointEditorPage').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.EDIT_WAYPOINT]: () => require('../../../pages/iou/MoneyRequestEditWaypointPage').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.DISTANCE]: () => require('../../../pages/iou/NewDistanceRequestPage').default as React.ComponentType, + [SCREENS.MONEY_REQUEST.RECEIPT]: () => require('../../../pages/EditRequestReceiptPage').default as React.ComponentType, +}); + +const SplitDetailsModalStackNavigator = createModalStackNavigator({ + [SCREENS.SPLIT_DETAILS.ROOT]: () => require('../../../pages/iou/SplitBillDetailsPage').default as React.ComponentType, + [SCREENS.SPLIT_DETAILS.EDIT_REQUEST]: () => require('../../../pages/EditSplitBillPage').default as React.ComponentType, + [SCREENS.SPLIT_DETAILS.EDIT_CURRENCY]: () => require('../../../pages/iou/IOUCurrencySelection').default as React.ComponentType, +}); + +const DetailsModalStackNavigator = createModalStackNavigator({ + [SCREENS.DETAILS_ROOT]: () => require('../../../pages/DetailsPage').default as React.ComponentType, +}); + +const ProfileModalStackNavigator = createModalStackNavigator({ + [SCREENS.PROFILE_ROOT]: () => require('../../../pages/ProfilePage').default as React.ComponentType, +}); + +const ReportDetailsModalStackNavigator = createModalStackNavigator({ + [SCREENS.REPORT_DETAILS.ROOT]: () => require('../../../pages/ReportDetailsPage').default as React.ComponentType, + [SCREENS.REPORT_DETAILS.SHARE_CODE]: () => require('../../../pages/home/report/ReportDetailsShareCodePage').default as React.ComponentType, +}); + +const ReportSettingsModalStackNavigator = createModalStackNavigator({ + [SCREENS.REPORT_SETTINGS.ROOT]: () => require('../../../pages/settings/Report/ReportSettingsPage').default as React.ComponentType, + [SCREENS.REPORT_SETTINGS.ROOM_NAME]: () => require('../../../pages/settings/Report/RoomNamePage').default as React.ComponentType, + [SCREENS.REPORT_SETTINGS.NOTIFICATION_PREFERENCES]: () => require('../../../pages/settings/Report/NotificationPreferencePage').default as React.ComponentType, + [SCREENS.REPORT_SETTINGS.WRITE_CAPABILITY]: () => require('../../../pages/settings/Report/WriteCapabilityPage').default as React.ComponentType, +}); + +const TaskModalStackNavigator = createModalStackNavigator({ + [SCREENS.TASK.TITLE]: () => require('../../../pages/tasks/TaskTitlePage').default as React.ComponentType, + [SCREENS.TASK.DESCRIPTION]: () => require('../../../pages/tasks/TaskDescriptionPage').default as React.ComponentType, + [SCREENS.TASK.ASSIGNEE]: () => require('../../../pages/tasks/TaskAssigneeSelectorModal').default as React.ComponentType, +}); + +const ReportWelcomeMessageModalStackNavigator = createModalStackNavigator({ + [SCREENS.REPORT_WELCOME_MESSAGE_ROOT]: () => require('../../../pages/ReportWelcomeMessagePage').default as React.ComponentType, +}); + +const ReportParticipantsModalStackNavigator = createModalStackNavigator({ + [SCREENS.REPORT_PARTICIPANTS_ROOT]: () => require('../../../pages/ReportParticipantsPage').default as React.ComponentType, +}); + +const RoomMembersModalStackNavigator = createModalStackNavigator({ + [SCREENS.ROOM_MEMBERS_ROOT]: () => require('../../../pages/RoomMembersPage').default as React.ComponentType, +}); + +const RoomInviteModalStackNavigator = createModalStackNavigator({ + [SCREENS.ROOM_INVITE_ROOT]: () => require('../../../pages/RoomInvitePage').default as React.ComponentType, +}); + +const SearchModalStackNavigator = createModalStackNavigator({ + [SCREENS.SEARCH_ROOT]: () => require('../../../pages/SearchPage').default as React.ComponentType, +}); + +const NewChatModalStackNavigator = createModalStackNavigator({ + [SCREENS.NEW_CHAT_ROOT]: () => require('../../../pages/NewChatSelectorPage').default as React.ComponentType, +}); + +const NewTaskModalStackNavigator = createModalStackNavigator({ + [SCREENS.NEW_TASK.ROOT]: () => require('../../../pages/tasks/NewTaskPage').default as React.ComponentType, + [SCREENS.NEW_TASK.TASK_ASSIGNEE_SELECTOR]: () => require('../../../pages/tasks/TaskAssigneeSelectorModal').default as React.ComponentType, + [SCREENS.NEW_TASK.TASK_SHARE_DESTINATION_SELECTOR]: () => require('../../../pages/tasks/TaskShareDestinationSelectorModal').default as React.ComponentType, + [SCREENS.NEW_TASK.DETAILS]: () => require('../../../pages/tasks/NewTaskDetailsPage').default as React.ComponentType, + [SCREENS.NEW_TASK.TITLE]: () => require('../../../pages/tasks/NewTaskTitlePage').default as React.ComponentType, + [SCREENS.NEW_TASK.DESCRIPTION]: () => require('../../../pages/tasks/NewTaskDescriptionPage').default as React.ComponentType, +}); + +const NewTeachersUniteNavigator = createModalStackNavigator({ + [SCREENS.SAVE_THE_WORLD.ROOT]: () => require('../../../pages/TeachersUnite/SaveTheWorldPage').default as React.ComponentType, + [SCREENS.I_KNOW_A_TEACHER]: () => require('../../../pages/TeachersUnite/KnowATeacherPage').default as React.ComponentType, + [SCREENS.INTRO_SCHOOL_PRINCIPAL]: () => require('../../../pages/TeachersUnite/ImTeacherPage').default as React.ComponentType, + [SCREENS.I_AM_A_TEACHER]: () => require('../../../pages/TeachersUnite/ImTeacherPage').default as React.ComponentType, +}); + +const SettingsModalStackNavigator = createModalStackNavigator({ + [SCREENS.SETTINGS.ROOT]: () => require('../../../pages/settings/InitialSettingsPage').default as React.ComponentType, + [SCREENS.SETTINGS.SHARE_CODE]: () => require('../../../pages/ShareCodePage').default as React.ComponentType, + [SCREENS.SETTINGS.WORKSPACES]: () => require('../../../pages/workspace/WorkspacesListPage').default as React.ComponentType, + [SCREENS.SETTINGS.PROFILE]: () => require('../../../pages/settings/Profile/ProfilePage').default as React.ComponentType, + [SCREENS.SETTINGS.PRONOUNS]: () => require('../../../pages/settings/Profile/PronounsPage').default as React.ComponentType, + [SCREENS.SETTINGS.DISPLAY_NAME]: () => require('../../../pages/settings/Profile/DisplayNamePage').default as React.ComponentType, + [SCREENS.SETTINGS.TIMEZONE]: () => require('../../../pages/settings/Profile/TimezoneInitialPage').default as React.ComponentType, + [SCREENS.SETTINGS.TIMEZONE_SELECT]: () => require('../../../pages/settings/Profile/TimezoneSelectPage').default as React.ComponentType, + [SCREENS.SETTINGS.PERSONAL_DETAILS_INITIAL]: () => require('../../../pages/settings/Profile/PersonalDetails/PersonalDetailsInitialPage').default as React.ComponentType, + [SCREENS.SETTINGS.PERSONAL_DETAILS_LEGAL_NAME]: () => require('../../../pages/settings/Profile/PersonalDetails/LegalNamePage').default as React.ComponentType, + [SCREENS.SETTINGS.PERSONAL_DETAILS_DATE_OF_BIRTH]: () => require('../../../pages/settings/Profile/PersonalDetails/DateOfBirthPage').default as React.ComponentType, + [SCREENS.SETTINGS.PERSONAL_DETAILS_ADDRESS]: () => require('../../../pages/settings/Profile/PersonalDetails/AddressPage').default as React.ComponentType, + [SCREENS.SETTINGS.PERSONAL_DETAILS_ADDRESS_COUNTRY]: () => require('../../../pages/settings/Profile/PersonalDetails/CountrySelectionPage').default as React.ComponentType, + [SCREENS.SETTINGS.CONTACT_METHODS]: () => require('../../../pages/settings/Profile/Contacts/ContactMethodsPage').default as React.ComponentType, + [SCREENS.SETTINGS.CONTACT_METHOD_DETAILS]: () => require('../../../pages/settings/Profile/Contacts/ContactMethodDetailsPage').default as React.ComponentType, + [SCREENS.SETTINGS.NEW_CONTACT_METHOD]: () => require('../../../pages/settings/Profile/Contacts/NewContactMethodPage').default as React.ComponentType, + [SCREENS.SETTINGS.PREFERENCES]: () => require('../../../pages/settings/Preferences/PreferencesPage').default as React.ComponentType, + [SCREENS.SETTINGS.PREFERENCES_PRIORITY_MODE]: () => require('../../../pages/settings/Preferences/PriorityModePage').default as React.ComponentType, + [SCREENS.SETTINGS.PREFERENCES_LANGUAGE]: () => require('../../../pages/settings/Preferences/LanguagePage').default as React.ComponentType, + // Will be uncommented as part of https://github.com/Expensify/App/issues/21670 + // [SCREENS.SETTINGS.PREFERENCES_THEME]: () => require('../../../pages/settings/Preferences/ThemePage').default as React.ComponentType, + [SCREENS.SETTINGS.CLOSE]: () => require('../../../pages/settings/Security/CloseAccountPage').default as React.ComponentType, + [SCREENS.SETTINGS.SECURITY]: () => require('../../../pages/settings/Security/SecuritySettingsPage').default as React.ComponentType, + [SCREENS.SETTINGS.ABOUT]: () => require('../../../pages/settings/AboutPage/AboutPage').default as React.ComponentType, + [SCREENS.SETTINGS.APP_DOWNLOAD_LINKS]: () => require('../../../pages/settings/AppDownloadLinks').default as React.ComponentType, + [SCREENS.SETTINGS.LOUNGE_ACCESS]: () => require('../../../pages/settings/Profile/LoungeAccessPage').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET]: () => require('../../../pages/settings/Wallet/WalletPage').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET_CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS]: () => require('../../../pages/settings/Profile/PersonalDetails/AddressPage').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET_DOMAIN_CARD]: () => require('../../../pages/settings/Wallet/ExpensifyCardPage').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET_REPORT_VIRTUAL_CARD_FRAUD]: () => require('../../../pages/settings/Wallet/ReportVirtualCardFraudPage').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET_CARD_ACTIVATE]: () => require('../../../pages/settings/Wallet/ActivatePhysicalCardPage').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET_CARD_GET_PHYSICAL.NAME]: () => require('../../../pages/settings/Wallet/Card/GetPhysicalCardName').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET_CARD_GET_PHYSICAL.PHONE]: () => require('../../../pages/settings/Wallet/Card/GetPhysicalCardPhone').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET_CARD_GET_PHYSICAL.ADDRESS]: () => require('../../../pages/settings/Wallet/Card/GetPhysicalCardAddress').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET_CARD_GET_PHYSICAL.CONFIRM]: () => require('../../../pages/settings/Wallet/Card/GetPhysicalCardConfirm').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET_TRANSFER_BALANCE]: () => require('../../../pages/settings/Wallet/TransferBalancePage').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET_CHOOSE_TRANSFER_ACCOUNT]: () => require('../../../pages/settings/Wallet/ChooseTransferAccountPage').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET_ENABLE_PAYMENTS]: () => require('../../../pages/EnablePayments/EnablePaymentsPage').default as React.ComponentType, + [SCREENS.SETTINGS.ADD_DEBIT_CARD]: () => require('../../../pages/settings/Wallet/AddDebitCardPage').default as React.ComponentType, + [SCREENS.SETTINGS.ADD_BANK_ACCOUNT]: () => require('../../../pages/AddPersonalBankAccountPage').default as React.ComponentType, + [SCREENS.SETTINGS.STATUS]: () => require('../../../pages/settings/Profile/CustomStatus/StatusPage').default as React.ComponentType, + [SCREENS.SETTINGS.STATUS_SET]: () => require('../../../pages/settings/Profile/CustomStatus/StatusSetPage').default as React.ComponentType, + [SCREENS.WORKSPACE.INITIAL]: () => require('../../../pages/workspace/WorkspaceInitialPage').default as React.ComponentType, + [SCREENS.WORKSPACE.SETTINGS]: () => require('../../../pages/workspace/WorkspaceSettingsPage').default as React.ComponentType, + [SCREENS.WORKSPACE.CURRENCY]: () => require('../../../pages/workspace/WorkspaceSettingsCurrencyPage').default as React.ComponentType, + [SCREENS.WORKSPACE.CARD]: () => require('../../../pages/workspace/card/WorkspaceCardPage').default as React.ComponentType, + [SCREENS.WORKSPACE.REIMBURSE]: () => require('../../../pages/workspace/reimburse/WorkspaceReimbursePage').default as React.ComponentType, + [SCREENS.WORKSPACE.RATE_AND_UNIT]: () => require('../../../pages/workspace/reimburse/WorkspaceRateAndUnitPage').default as React.ComponentType, + [SCREENS.WORKSPACE.BILLS]: () => require('../../../pages/workspace/bills/WorkspaceBillsPage').default as React.ComponentType, + [SCREENS.WORKSPACE.INVOICES]: () => require('../../../pages/workspace/invoices/WorkspaceInvoicesPage').default as React.ComponentType, + [SCREENS.WORKSPACE.TRAVEL]: () => require('../../../pages/workspace/travel/WorkspaceTravelPage').default as React.ComponentType, + [SCREENS.WORKSPACE.MEMBERS]: () => require('../../../pages/workspace/WorkspaceMembersPage').default as React.ComponentType, + [SCREENS.WORKSPACE.INVITE]: () => require('../../../pages/workspace/WorkspaceInvitePage').default as React.ComponentType, + [SCREENS.WORKSPACE.INVITE_MESSAGE]: () => require('../../../pages/workspace/WorkspaceInviteMessagePage').default as React.ComponentType, + [SCREENS.REIMBURSEMENT_ACCOUNT]: () => require('../../../pages/ReimbursementAccount/ReimbursementAccountPage').default as React.ComponentType, + [SCREENS.GET_ASSISTANCE]: () => require('../../../pages/GetAssistancePage').default as React.ComponentType, + [SCREENS.SETTINGS.TWO_FACTOR_AUTH]: () => require('../../../pages/settings/Security/TwoFactorAuth/TwoFactorAuthPage').default as React.ComponentType, + [SCREENS.SETTINGS.REPORT_CARD_LOST_OR_DAMAGED]: () => require('../../../pages/settings/Wallet/ReportCardLostPage').default as React.ComponentType, + [SCREENS.KEYBOARD_SHORTCUTS]: () => require('../../../pages/KeyboardShortcutsPage').default as React.ComponentType, +}); + +const EnablePaymentsStackNavigator = createModalStackNavigator({ + [SCREENS.ENABLE_PAYMENTS_ROOT]: () => require('../../../pages/EnablePayments/EnablePaymentsPage').default as React.ComponentType, +}); + +const AddPersonalBankAccountModalStackNavigator = createModalStackNavigator({ + [SCREENS.ADD_PERSONAL_BANK_ACCOUNT_ROOT]: () => require('../../../pages/AddPersonalBankAccountPage').default as React.ComponentType, +}); + +const ReimbursementAccountModalStackNavigator = createModalStackNavigator({ + [SCREENS.REIMBURSEMENT_ACCOUNT_ROOT]: () => require('../../../pages/ReimbursementAccount/ReimbursementAccountPage').default as React.ComponentType, +}); + +const WalletStatementStackNavigator = createModalStackNavigator({ + [SCREENS.WALLET_STATEMENT_ROOT]: () => require('../../../pages/wallet/WalletStatementPage').default as React.ComponentType, +}); + +const FlagCommentStackNavigator = createModalStackNavigator({ + [SCREENS.FLAG_COMMENT_ROOT]: () => require('../../../pages/FlagCommentPage').default as React.ComponentType, +}); + +const EditRequestStackNavigator = createModalStackNavigator({ + [SCREENS.EDIT_REQUEST.ROOT]: () => require('../../../pages/EditRequestPage').default as React.ComponentType, + [SCREENS.EDIT_REQUEST.CURRENCY]: () => require('../../../pages/iou/IOUCurrencySelection').default as React.ComponentType, +}); + +const PrivateNotesModalStackNavigator = createModalStackNavigator({ + [SCREENS.PRIVATE_NOTES.VIEW]: () => require('../../../pages/PrivateNotes/PrivateNotesViewPage').default as React.ComponentType, + [SCREENS.PRIVATE_NOTES.LIST]: () => require('../../../pages/PrivateNotes/PrivateNotesListPage').default as React.ComponentType, + [SCREENS.PRIVATE_NOTES.EDIT]: () => require('../../../pages/PrivateNotes/PrivateNotesEditPage').default as React.ComponentType, +}); + +const SignInModalStackNavigator = createModalStackNavigator({ + [SCREENS.SIGN_IN_ROOT]: () => require('../../../pages/signin/SignInModal').default as React.ComponentType, +}); + +const ReferralModalStackNavigator = createModalStackNavigator({ + [SCREENS.REFERRAL_DETAILS]: () => require('../../../pages/ReferralDetailsPage').default as React.ComponentType, +}); + +export { + MoneyRequestModalStackNavigator, + SplitDetailsModalStackNavigator, + DetailsModalStackNavigator, + ProfileModalStackNavigator, + ReportDetailsModalStackNavigator, + TaskModalStackNavigator, + ReportSettingsModalStackNavigator, + ReportWelcomeMessageModalStackNavigator, + ReportParticipantsModalStackNavigator, + SearchModalStackNavigator, + NewChatModalStackNavigator, + NewTaskModalStackNavigator, + SettingsModalStackNavigator, + EnablePaymentsStackNavigator, + AddPersonalBankAccountModalStackNavigator, + ReimbursementAccountModalStackNavigator, + WalletStatementStackNavigator, + FlagCommentStackNavigator, + EditRequestStackNavigator, + PrivateNotesModalStackNavigator, + NewTeachersUniteNavigator, + SignInModalStackNavigator, + RoomMembersModalStackNavigator, + RoomInviteModalStackNavigator, + ReferralModalStackNavigator, +}; diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.js b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.tsx similarity index 89% rename from src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.js rename to src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.tsx index d23b03c8c73e..228ea6bd3dce 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.js +++ b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.tsx @@ -2,10 +2,11 @@ import {createStackNavigator} from '@react-navigation/stack'; import React from 'react'; import ReportScreenWrapper from '@libs/Navigation/AppNavigator/ReportScreenWrapper'; import getCurrentUrl from '@libs/Navigation/currentUrl'; +import type {CentralPaneNavigatorParamList} from '@navigation/types'; import useThemeStyles from '@styles/useThemeStyles'; import SCREENS from '@src/SCREENS'; -const Stack = createStackNavigator(); +const Stack = createStackNavigator(); const url = getCurrentUrl(); const openOnAdminRoom = url ? new URL(url).searchParams.get('openOnAdminRoom') : undefined; diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.native.js b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.native.tsx similarity index 100% rename from src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.native.js rename to src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.native.tsx diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.js b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.tsx similarity index 100% rename from src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.js rename to src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.tsx diff --git a/src/libs/Navigation/AppNavigator/Navigators/Overlay.js b/src/libs/Navigation/AppNavigator/Navigators/Overlay.tsx similarity index 79% rename from src/libs/Navigation/AppNavigator/Navigators/Overlay.js rename to src/libs/Navigation/AppNavigator/Navigators/Overlay.tsx index 44d996282617..31eb818b60dc 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/Overlay.js +++ b/src/libs/Navigation/AppNavigator/Navigators/Overlay.tsx @@ -1,5 +1,4 @@ import {useCardAnimation} from '@react-navigation/stack'; -import PropTypes from 'prop-types'; import React from 'react'; import {Animated, View} from 'react-native'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; @@ -7,12 +6,12 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; -const propTypes = { +type OverlayProps = { /* Callback to close the modal */ - onPress: PropTypes.func.isRequired, + onPress: () => void; }; -function Overlay(props) { +function Overlay({onPress}: OverlayProps) { const styles = useThemeStyles(); const {current} = useCardAnimation(); const {translate} = useLocalize(); @@ -20,20 +19,20 @@ function Overlay(props) { return ( - {/* In the latest Electron version buttons can't be both clickable and draggable. - That's why we added this workaround. Because of two Pressable components on the desktop app + {/* In the latest Electron version buttons can't be both clickable and draggable. + That's why we added this workaround. Because of two Pressable components on the desktop app we have 30px draggable ba at the top and the rest of the dimmed area is clickable. On other devices, everything behaves normally like one big pressable */} ; -const propTypes = { - /* Navigation functions provided by React Navigation */ - navigation: PropTypes.shape({ - goBack: PropTypes.func.isRequired, - }).isRequired, -}; +const Stack = createStackNavigator(); -function RightModalNavigator(props) { +function RightModalNavigator({navigation}: RightModalNavigatorProps) { const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); const screenOptions = useMemo(() => RHPScreenOptions(styles), [styles]); return ( - {!isSmallScreenWidth && } + {!isSmallScreenWidth && } (); function PublicScreens() { return ( @@ -55,4 +56,5 @@ function PublicScreens() { } PublicScreens.displayName = 'PublicScreens'; + export default PublicScreens; diff --git a/src/libs/Navigation/AppNavigator/RHPScreenOptions.js b/src/libs/Navigation/AppNavigator/RHPScreenOptions.js deleted file mode 100644 index 02354b90591f..000000000000 --- a/src/libs/Navigation/AppNavigator/RHPScreenOptions.js +++ /dev/null @@ -1,17 +0,0 @@ -import {CardStyleInterpolators} from '@react-navigation/stack'; - -/** - * RHP stack navigator screen options generator function - * @function - * @param {Object} styles - The styles object - * @returns {Object} - The screen options object - */ -const RHPScreenOptions = (styles) => ({ - headerShown: false, - animationEnabled: true, - gestureDirection: 'horizontal', - cardStyle: styles.navigationScreenCardStyle, - cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS, -}); - -export default RHPScreenOptions; diff --git a/src/libs/Navigation/AppNavigator/RHPScreenOptions.ts b/src/libs/Navigation/AppNavigator/RHPScreenOptions.ts new file mode 100644 index 000000000000..6b56bb00cf56 --- /dev/null +++ b/src/libs/Navigation/AppNavigator/RHPScreenOptions.ts @@ -0,0 +1,17 @@ +import {CardStyleInterpolators, StackNavigationOptions} from '@react-navigation/stack'; +import styles from '@styles/styles'; + +/** + * RHP stack navigator screen options generator function + * @param themeStyles - The styles object + * @returns The screen options object + */ +const RHPScreenOptions = (themeStyles: typeof styles): StackNavigationOptions => ({ + headerShown: false, + animationEnabled: true, + gestureDirection: 'horizontal', + cardStyle: themeStyles.navigationScreenCardStyle, + cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS, +}); + +export default RHPScreenOptions; diff --git a/src/libs/Navigation/AppNavigator/ReportScreenIDSetter.js b/src/libs/Navigation/AppNavigator/ReportScreenIDSetter.js deleted file mode 100644 index bb7acddb188c..000000000000 --- a/src/libs/Navigation/AppNavigator/ReportScreenIDSetter.js +++ /dev/null @@ -1,112 +0,0 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; -import {useEffect} from 'react'; -import {withOnyx} from 'react-native-onyx'; -import usePermissions from '@hooks/usePermissions'; -import * as ReportUtils from '@libs/ReportUtils'; -import reportPropTypes from '@pages/reportPropTypes'; -import * as App from '@userActions/App'; -import ONYXKEYS from '@src/ONYXKEYS'; - -const propTypes = { - /** Available reports that would be displayed in this navigator */ - reports: PropTypes.objectOf(reportPropTypes), - - /** The policies which the user has access to */ - policies: PropTypes.objectOf( - PropTypes.shape({ - /** The policy name */ - name: PropTypes.string, - - /** The type of the policy */ - type: PropTypes.string, - }), - ), - - isFirstTimeNewExpensifyUser: PropTypes.bool, - - /** Navigation route context info provided by react navigation */ - route: PropTypes.shape({ - /** Route specific parameters used on this screen */ - params: PropTypes.shape({ - /** If the admin room should be opened */ - openOnAdminRoom: PropTypes.bool, - - /** The ID of the report this screen should display */ - reportID: PropTypes.string, - }), - }).isRequired, - - /* Navigation functions provided by React Navigation */ - navigation: PropTypes.shape({ - setParams: PropTypes.func.isRequired, - }).isRequired, -}; - -const defaultProps = { - reports: {}, - policies: {}, - isFirstTimeNewExpensifyUser: false, -}; - -/** - * Get the most recently accessed report for the user - * - * @param {Object} reports - * @param {Boolean} ignoreDefaultRooms - * @param {Object} policies - * @param {Boolean} isFirstTimeNewExpensifyUser - * @param {Boolean} openOnAdminRoom - * @returns {Number} - */ -const getLastAccessedReportID = (reports, ignoreDefaultRooms, policies, isFirstTimeNewExpensifyUser, openOnAdminRoom) => { - const lastReport = ReportUtils.findLastAccessedReport(reports, ignoreDefaultRooms, policies, isFirstTimeNewExpensifyUser, openOnAdminRoom); - return lodashGet(lastReport, 'reportID'); -}; - -// This wrapper is reponsible for opening the last accessed report if there is no reportID specified in the route params -function ReportScreenIDSetter({route, reports, policies, isFirstTimeNewExpensifyUser, navigation}) { - const {canUseDefaultRooms} = usePermissions(); - - useEffect(() => { - // Don't update if there is a reportID in the params already - if (lodashGet(route, 'params.reportID', null)) { - App.confirmReadyToOpenApp(); - return; - } - - // If there is no reportID in route, try to find last accessed and use it for setParams - const reportID = getLastAccessedReportID(reports, !canUseDefaultRooms, policies, isFirstTimeNewExpensifyUser, lodashGet(route, 'params.openOnAdminRoom', false)); - - // It's possible that reports aren't fully loaded yet - // in that case the reportID is undefined - if (reportID) { - navigation.setParams({reportID: String(reportID)}); - } else { - App.confirmReadyToOpenApp(); - } - }, [route, navigation, reports, canUseDefaultRooms, policies, isFirstTimeNewExpensifyUser]); - - // The ReportScreen without the reportID set will display a skeleton - // until the reportID is loaded and set in the route param - return null; -} - -ReportScreenIDSetter.propTypes = propTypes; -ReportScreenIDSetter.defaultProps = defaultProps; -ReportScreenIDSetter.displayName = 'ReportScreenIDSetter'; - -export default withOnyx({ - reports: { - key: ONYXKEYS.COLLECTION.REPORT, - allowStaleData: true, - }, - policies: { - key: ONYXKEYS.COLLECTION.POLICY, - allowStaleData: true, - }, - isFirstTimeNewExpensifyUser: { - key: ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER, - initialValue: false, - }, -})(ReportScreenIDSetter); diff --git a/src/libs/Navigation/AppNavigator/ReportScreenIDSetter.ts b/src/libs/Navigation/AppNavigator/ReportScreenIDSetter.ts new file mode 100644 index 000000000000..8be512962981 --- /dev/null +++ b/src/libs/Navigation/AppNavigator/ReportScreenIDSetter.ts @@ -0,0 +1,80 @@ +import {useEffect} from 'react'; +import {OnyxCollection, OnyxEntry, withOnyx} from 'react-native-onyx'; +import usePermissions from '@hooks/usePermissions'; +import * as ReportUtils from '@libs/ReportUtils'; +import * as App from '@userActions/App'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type {Policy, Report} from '@src/types/onyx'; +import type {ReportScreenWrapperProps} from './ReportScreenWrapper'; + +type ReportScreenIDSetterComponentProps = { + /** Available reports that would be displayed in this navigator */ + reports: OnyxCollection; + + /** The policies which the user has access to */ + policies: OnyxCollection; + + /** Whether user is a new user */ + isFirstTimeNewExpensifyUser: OnyxEntry; +}; + +type ReportScreenIDSetterProps = ReportScreenIDSetterComponentProps & ReportScreenWrapperProps; + +/** + * Get the most recently accessed report for the user + */ +const getLastAccessedReportID = ( + reports: OnyxCollection, + ignoreDefaultRooms: boolean, + policies: OnyxCollection, + isFirstTimeNewExpensifyUser: OnyxEntry, + openOnAdminRoom: boolean, +): string | undefined => { + const lastReport = ReportUtils.findLastAccessedReport(reports, ignoreDefaultRooms, policies, !!isFirstTimeNewExpensifyUser, openOnAdminRoom); + return lastReport?.reportID; +}; + +// This wrapper is reponsible for opening the last accessed report if there is no reportID specified in the route params +function ReportScreenIDSetter({route, reports, policies, navigation, isFirstTimeNewExpensifyUser = false}: ReportScreenIDSetterProps) { + const {canUseDefaultRooms} = usePermissions(); + + useEffect(() => { + // Don't update if there is a reportID in the params already + if (route?.params?.reportID) { + App.confirmReadyToOpenApp(); + return; + } + + // If there is no reportID in route, try to find last accessed and use it for setParams + const reportID = getLastAccessedReportID(reports, !canUseDefaultRooms, policies, isFirstTimeNewExpensifyUser, !!reports?.params?.openOnAdminRoom); + + // It's possible that reports aren't fully loaded yet + // in that case the reportID is undefined + if (reportID) { + navigation.setParams({reportID: String(reportID)}); + } else { + App.confirmReadyToOpenApp(); + } + }, [route, navigation, reports, canUseDefaultRooms, policies, isFirstTimeNewExpensifyUser]); + + // The ReportScreen without the reportID set will display a skeleton + // until the reportID is loaded and set in the route param + return null; +} + +ReportScreenIDSetter.displayName = 'ReportScreenIDSetter'; + +export default withOnyx({ + reports: { + key: ONYXKEYS.COLLECTION.REPORT, + allowStaleData: true, + }, + policies: { + key: ONYXKEYS.COLLECTION.POLICY, + allowStaleData: true, + }, + isFirstTimeNewExpensifyUser: { + key: ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER, + initialValue: false, + }, +})(ReportScreenIDSetter); diff --git a/src/libs/Navigation/AppNavigator/ReportScreenWrapper.js b/src/libs/Navigation/AppNavigator/ReportScreenWrapper.js deleted file mode 100644 index 87a8a4abc687..000000000000 --- a/src/libs/Navigation/AppNavigator/ReportScreenWrapper.js +++ /dev/null @@ -1,45 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import ReportScreen from '@pages/home/ReportScreen'; -import ReportScreenIDSetter from './ReportScreenIDSetter'; - -const propTypes = { - /** Navigation route context info provided by react navigation */ - route: PropTypes.shape({ - /** Route specific parameters used on this screen */ - params: PropTypes.shape({ - /** If the admin room should be opened */ - openOnAdminRoom: PropTypes.bool, - - /** The ID of the report this screen should display */ - reportID: PropTypes.string, - }), - }).isRequired, - - /* Navigation functions provided by React Navigation */ - navigation: PropTypes.shape({ - setParams: PropTypes.func.isRequired, - }).isRequired, -}; - -const defaultProps = {}; - -function ReportScreenWrapper(props) { - // The ReportScreen without the reportID set will display a skeleton - // until the reportID is loaded and set in the route param - return ( - <> - - - - ); -} - -ReportScreenWrapper.propTypes = propTypes; -ReportScreenWrapper.defaultProps = defaultProps; -ReportScreenWrapper.displayName = 'ReportScreenWrapper'; - -export default ReportScreenWrapper; diff --git a/src/libs/Navigation/AppNavigator/ReportScreenWrapper.tsx b/src/libs/Navigation/AppNavigator/ReportScreenWrapper.tsx new file mode 100644 index 000000000000..20922fd785ce --- /dev/null +++ b/src/libs/Navigation/AppNavigator/ReportScreenWrapper.tsx @@ -0,0 +1,28 @@ +import {StackScreenProps} from '@react-navigation/stack'; +import React from 'react'; +import type {CentralPaneNavigatorParamList} from '@navigation/types'; +import ReportScreen from '@pages/home/ReportScreen'; +import SCREENS from '@src/SCREENS'; +import ReportScreenIDSetter from './ReportScreenIDSetter'; + +type ReportScreenWrapperProps = StackScreenProps; + +function ReportScreenWrapper({route, navigation}: ReportScreenWrapperProps) { + // The ReportScreen without the reportID set will display a skeleton + // until the reportID is loaded and set in the route param + return ( + <> + {/* @ts-expect-error Error will be resolved after ReportScreen migration to TypeScript */} + + + + ); +} + +ReportScreenWrapper.displayName = 'ReportScreenWrapper'; + +export default ReportScreenWrapper; +export type {ReportScreenWrapperProps}; diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.js b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts similarity index 54% rename from src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.js rename to src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts index 05cc2e1f7976..435ebc00362b 100644 --- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.js +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts @@ -1,37 +1,32 @@ -import {StackRouter} from '@react-navigation/native'; -import lodashFindLast from 'lodash/findLast'; -import _ from 'underscore'; +import {NavigationState, PartialState, RouterConfigOptions, StackNavigationState, StackRouter} from '@react-navigation/native'; +import {ParamListBase} from '@react-navigation/routers'; import getIsSmallScreenWidth from '@libs/getIsSmallScreenWidth'; import NAVIGATORS from '@src/NAVIGATORS'; import SCREENS from '@src/SCREENS'; +import type {ResponsiveStackNavigatorRouterOptions} from './types'; -/** - * @param {Object} state - react-navigation state - * @returns {Boolean} - */ -const isAtLeastOneCentralPaneNavigatorInState = (state) => _.find(state.routes, (r) => r.name === NAVIGATORS.CENTRAL_PANE_NAVIGATOR); +type State = NavigationState | PartialState; -/** - * @param {Object} state - react-navigation state - * @returns {String} - */ -const getTopMostReportIDFromRHP = (state) => { +const isAtLeastOneCentralPaneNavigatorInState = (state: State): boolean => !!state.routes.find((route) => route.name === NAVIGATORS.CENTRAL_PANE_NAVIGATOR); + +const getTopMostReportIDFromRHP = (state: State): string => { if (!state) { return ''; } - const topmostRightPane = lodashFindLast(state.routes, (route) => route.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR); - if (topmostRightPane) { + const topmostRightPane = state.routes.filter((route) => route.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR).at(-1); + + if (topmostRightPane?.state) { return getTopMostReportIDFromRHP(topmostRightPane.state); } - const topmostRoute = lodashFindLast(state.routes); + const topmostRoute = state.routes.at(-1); - if (topmostRoute.state) { + if (topmostRoute?.state) { return getTopMostReportIDFromRHP(topmostRoute.state); } - if (topmostRoute.params && topmostRoute.params.reportID) { + if (topmostRoute?.params && 'reportID' in topmostRoute.params && typeof topmostRoute.params.reportID === 'string' && topmostRoute.params.reportID) { return topmostRoute.params.reportID; } @@ -41,9 +36,9 @@ const getTopMostReportIDFromRHP = (state) => { * Adds report route without any specific reportID to the state. * The report screen will self set proper reportID param based on the helper function findLastAccessedReport (look at ReportScreenWrapper for more info) * - * @param {Object} state - react-navigation state + * @param state - react-navigation state */ -const addCentralPaneNavigatorRoute = (state) => { +const addCentralPaneNavigatorRoute = (state: State) => { const reportID = getTopMostReportIDFromRHP(state); const centralPaneNavigatorRoute = { name: NAVIGATORS.CENTRAL_PANE_NAVIGATOR, @@ -59,25 +54,26 @@ const addCentralPaneNavigatorRoute = (state) => { }, }; state.routes.splice(1, 0, centralPaneNavigatorRoute); - // eslint-disable-next-line no-param-reassign - state.index = state.routes.length - 1; + // eslint-disable-next-line no-param-reassign, @typescript-eslint/non-nullable-type-assertion-style + (state.index as number) = state.routes.length - 1; }; -function CustomRouter(options) { +function CustomRouter(options: ResponsiveStackNavigatorRouterOptions) { const stackRouter = StackRouter(options); return { ...stackRouter, - getRehydratedState(partialState, {routeNames, routeParamList}) { + getRehydratedState(partialState: StackNavigationState, {routeNames, routeParamList, routeGetIdList}: RouterConfigOptions): StackNavigationState { const isSmallScreenWidth = getIsSmallScreenWidth(); // Make sure that there is at least one CentralPaneNavigator (ReportScreen by default) in the state if this is a wide layout if (!isAtLeastOneCentralPaneNavigatorInState(partialState) && !isSmallScreenWidth) { // If we added a route we need to make sure that the state.stale is true to generate new key for this route + // eslint-disable-next-line no-param-reassign - partialState.stale = true; + (partialState.stale as boolean) = true; addCentralPaneNavigatorRoute(partialState); } - const state = stackRouter.getRehydratedState(partialState, {routeNames, routeParamList}); + const state = stackRouter.getRehydratedState(partialState, {routeNames, routeParamList, routeGetIdList}); return state; }, }; diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.js b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.js deleted file mode 100644 index a97e3f2e4ce5..000000000000 --- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.js +++ /dev/null @@ -1,58 +0,0 @@ -import {createNavigatorFactory, useNavigationBuilder} from '@react-navigation/native'; -import {StackView} from '@react-navigation/stack'; -import PropTypes from 'prop-types'; -import React, {useRef} from 'react'; -import useWindowDimensions from '@hooks/useWindowDimensions'; -import CustomRouter from './CustomRouter'; - -const propTypes = { - /* Determines if the navigator should render the StackView (narrow) or ThreePaneView (wide) */ - isSmallScreenWidth: PropTypes.bool.isRequired, - - /* Children for the useNavigationBuilder hook */ - children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired, - - /* initialRouteName for this navigator */ - initialRouteName: PropTypes.oneOf([PropTypes.string, PropTypes.undefined]), - - /* Screen options defined for this navigator */ - // eslint-disable-next-line react/forbid-prop-types - screenOptions: PropTypes.object, -}; - -const defaultProps = { - initialRouteName: undefined, - screenOptions: undefined, -}; - -function ResponsiveStackNavigator(props) { - const {isSmallScreenWidth} = useWindowDimensions(); - - const isSmallScreenWidthRef = useRef(isSmallScreenWidth); - - isSmallScreenWidthRef.current = isSmallScreenWidth; - - const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder(CustomRouter, { - children: props.children, - screenOptions: props.screenOptions, - initialRouteName: props.initialRouteName, - }); - - return ( - - - - ); -} - -ResponsiveStackNavigator.defaultProps = defaultProps; -ResponsiveStackNavigator.propTypes = propTypes; -ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator'; - -export default createNavigatorFactory(ResponsiveStackNavigator); diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.tsx b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.tsx new file mode 100644 index 000000000000..a55c74f3a479 --- /dev/null +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.tsx @@ -0,0 +1,42 @@ +import {createNavigatorFactory, ParamListBase, StackActionHelpers, StackNavigationState, useNavigationBuilder} from '@react-navigation/native'; +import {StackNavigationEventMap, StackNavigationOptions, StackView} from '@react-navigation/stack'; +import React, {useRef} from 'react'; +import useWindowDimensions from '@hooks/useWindowDimensions'; +import CustomRouter from './CustomRouter'; +import type {ResponsiveStackNavigatorProps, ResponsiveStackNavigatorRouterOptions} from './types'; + +function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { + const {isSmallScreenWidth} = useWindowDimensions(); + + const isSmallScreenWidthRef = useRef(isSmallScreenWidth); + + isSmallScreenWidthRef.current = isSmallScreenWidth; + + const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder< + StackNavigationState, + ResponsiveStackNavigatorRouterOptions, + StackActionHelpers, + StackNavigationOptions, + StackNavigationEventMap + >(CustomRouter, { + children: props.children, + screenOptions: props.screenOptions, + initialRouteName: props.initialRouteName, + }); + + return ( + + + + ); +} + +ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator'; + +export default createNavigatorFactory, StackNavigationOptions, StackNavigationEventMap, typeof ResponsiveStackNavigator>(ResponsiveStackNavigator); diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.tsx similarity index 57% rename from src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js rename to src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.tsx index 2e929c685648..dd2e548064c4 100644 --- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.tsx @@ -1,33 +1,14 @@ -import {createNavigatorFactory, useNavigationBuilder} from '@react-navigation/native'; -import {StackView} from '@react-navigation/stack'; -import PropTypes from 'prop-types'; +import {createNavigatorFactory, ParamListBase, StackActionHelpers, StackNavigationState, useNavigationBuilder} from '@react-navigation/native'; +import {StackNavigationEventMap, StackNavigationOptions, StackView} from '@react-navigation/stack'; import React, {useMemo, useRef} from 'react'; import useWindowDimensions from '@hooks/useWindowDimensions'; import NAVIGATORS from '@src/NAVIGATORS'; import CustomRouter from './CustomRouter'; +import type {ResponsiveStackNavigatorProps, ResponsiveStackNavigatorRouterOptions} from './types'; -const propTypes = { - /* Determines if the navigator should render the StackView (narrow) or ThreePaneView (wide) */ - isSmallScreenWidth: PropTypes.bool.isRequired, - - /* Children for the useNavigationBuilder hook */ - children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired, - - /* initialRouteName for this navigator */ - initialRouteName: PropTypes.oneOf([PropTypes.string, PropTypes.undefined]), - - /* Screen options defined for this navigator */ - // eslint-disable-next-line react/forbid-prop-types - screenOptions: PropTypes.object, -}; - -const defaultProps = { - initialRouteName: undefined, - screenOptions: undefined, -}; - -function reduceReportRoutes(routes) { - const result = []; +type Routes = StackNavigationState['routes']; +function reduceReportRoutes(routes: Routes): Routes { + const result: Routes = []; let count = 0; const reverseRoutes = [...routes].reverse(); @@ -46,14 +27,20 @@ function reduceReportRoutes(routes) { return result.reverse(); } -function ResponsiveStackNavigator(props) { +function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { const {isSmallScreenWidth} = useWindowDimensions(); - const isSmallScreenWidthRef = useRef(isSmallScreenWidth); + const isSmallScreenWidthRef = useRef(isSmallScreenWidth); isSmallScreenWidthRef.current = isSmallScreenWidth; - const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder(CustomRouter, { + const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder< + StackNavigationState, + ResponsiveStackNavigatorRouterOptions, + StackActionHelpers, + StackNavigationOptions, + StackNavigationEventMap + >(CustomRouter, { children: props.children, screenOptions: props.screenOptions, initialRouteName: props.initialRouteName, @@ -82,8 +69,6 @@ function ResponsiveStackNavigator(props) { ); } -ResponsiveStackNavigator.defaultProps = defaultProps; -ResponsiveStackNavigator.propTypes = propTypes; ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator'; -export default createNavigatorFactory(ResponsiveStackNavigator); +export default createNavigatorFactory, StackNavigationOptions, StackNavigationEventMap, typeof ResponsiveStackNavigator>(ResponsiveStackNavigator); diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/types.ts b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/types.ts new file mode 100644 index 000000000000..707a0ff4498d --- /dev/null +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/types.ts @@ -0,0 +1,13 @@ +import {DefaultNavigatorOptions, ParamListBase, StackNavigationState, StackRouterOptions} from '@react-navigation/native'; +import {StackNavigationEventMap, StackNavigationOptions} from '@react-navigation/stack'; + +type ResponsiveStackNavigatorConfig = { + isSmallScreenWidth: boolean; +}; + +type ResponsiveStackNavigatorRouterOptions = StackRouterOptions; + +type ResponsiveStackNavigatorProps = DefaultNavigatorOptions, StackNavigationOptions, StackNavigationEventMap> & + ResponsiveStackNavigatorConfig; + +export type {ResponsiveStackNavigatorRouterOptions, ResponsiveStackNavigatorProps, ResponsiveStackNavigatorConfig}; diff --git a/src/libs/Navigation/AppNavigator/defaultScreenOptions.js b/src/libs/Navigation/AppNavigator/defaultScreenOptions.ts similarity index 58% rename from src/libs/Navigation/AppNavigator/defaultScreenOptions.js rename to src/libs/Navigation/AppNavigator/defaultScreenOptions.ts index 3ccffb5f09ab..65a6bd052742 100644 --- a/src/libs/Navigation/AppNavigator/defaultScreenOptions.js +++ b/src/libs/Navigation/AppNavigator/defaultScreenOptions.ts @@ -1,4 +1,6 @@ -const defaultScreenOptions = { +import {StackNavigationOptions} from '@react-navigation/stack'; + +const defaultScreenOptions: StackNavigationOptions = { cardStyle: { overflow: 'visible', flex: 1, diff --git a/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js b/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.ts similarity index 67% rename from src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js rename to src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.ts index 44fa7b6c0b09..08f18ce3ab9d 100644 --- a/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js +++ b/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.ts @@ -1,9 +1,13 @@ +import {StackCardInterpolationProps, StackNavigationOptions} from '@react-navigation/stack'; import getNavigationModalCardStyle from '@styles/getNavigationModalCardStyles'; +import styles from '@styles/styles'; import variables from '@styles/variables'; import CONFIG from '@src/CONFIG'; import modalCardStyleInterpolator from './modalCardStyleInterpolator'; -const commonScreenOptions = { +type ScreenOptions = Record; + +const commonScreenOptions: StackNavigationOptions = { headerShown: false, gestureDirection: 'horizontal', animationEnabled: true, @@ -11,10 +15,10 @@ const commonScreenOptions = { animationTypeForReplace: 'push', }; -export default (isSmallScreenWidth, styles) => ({ +export default (isSmallScreenWidth: boolean, themeStyles: typeof styles): ScreenOptions => ({ rightModalNavigator: { ...commonScreenOptions, - cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, false, props), + cardStyleInterpolator: (props: StackCardInterpolationProps) => modalCardStyleInterpolator(isSmallScreenWidth, false, props), presentation: 'transparentModal', // We want pop in RHP since there are some flows that would work weird otherwise @@ -32,7 +36,7 @@ export default (isSmallScreenWidth, styles) => ({ homeScreen: { title: CONFIG.SITE_TITLE, ...commonScreenOptions, - cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, false, props), + cardStyleInterpolator: (props: StackCardInterpolationProps) => modalCardStyleInterpolator(isSmallScreenWidth, false, props), cardStyle: { ...getNavigationModalCardStyle(), @@ -40,13 +44,13 @@ export default (isSmallScreenWidth, styles) => ({ // We need to translate the sidebar to not be covered by the StackNavigator so it can be clickable. transform: [{translateX: isSmallScreenWidth ? 0 : -variables.sideBarWidth}], - ...(isSmallScreenWidth ? {} : styles.borderRight), + ...(isSmallScreenWidth ? {} : themeStyles.borderRight), }, }, - // eslint-disable-next-line rulesdir/no-negated-variables + fullScreen: { ...commonScreenOptions, - cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, true, props), + cardStyleInterpolator: (props: StackCardInterpolationProps) => modalCardStyleInterpolator(isSmallScreenWidth, true, props), cardStyle: { ...getNavigationModalCardStyle(), @@ -59,7 +63,7 @@ export default (isSmallScreenWidth, styles) => ({ title: CONFIG.SITE_TITLE, ...commonScreenOptions, animationEnabled: isSmallScreenWidth, - cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, true, props), + cardStyleInterpolator: (props: StackCardInterpolationProps) => modalCardStyleInterpolator(isSmallScreenWidth, true, props), cardStyle: { ...getNavigationModalCardStyle(), diff --git a/src/libs/Navigation/AppNavigator/index.js b/src/libs/Navigation/AppNavigator/index.tsx similarity index 68% rename from src/libs/Navigation/AppNavigator/index.js rename to src/libs/Navigation/AppNavigator/index.tsx index 0d03badf37bc..8d65f5166060 100644 --- a/src/libs/Navigation/AppNavigator/index.js +++ b/src/libs/Navigation/AppNavigator/index.tsx @@ -1,13 +1,12 @@ -import PropTypes from 'prop-types'; import React from 'react'; -const propTypes = { +type AppNavigatorProps = { /** If we have an authToken this is true */ - authenticated: PropTypes.bool.isRequired, + authenticated: boolean; }; -function AppNavigator(props) { - if (props.authenticated) { +function AppNavigator({authenticated}: AppNavigatorProps) { + if (authenticated) { const AuthScreens = require('./AuthScreens').default; // These are the protected screens and only accessible when an authToken is present @@ -17,6 +16,5 @@ function AppNavigator(props) { return ; } -AppNavigator.propTypes = propTypes; AppNavigator.displayName = 'AppNavigator'; export default AppNavigator; diff --git a/src/libs/Navigation/AppNavigator/modalCardStyleInterpolator.js b/src/libs/Navigation/AppNavigator/modalCardStyleInterpolator.ts similarity index 69% rename from src/libs/Navigation/AppNavigator/modalCardStyleInterpolator.js rename to src/libs/Navigation/AppNavigator/modalCardStyleInterpolator.ts index 446d195fc466..f7e772148e79 100644 --- a/src/libs/Navigation/AppNavigator/modalCardStyleInterpolator.js +++ b/src/libs/Navigation/AppNavigator/modalCardStyleInterpolator.ts @@ -1,8 +1,9 @@ +import type {StackCardInterpolatedStyle, StackCardInterpolationProps} from '@react-navigation/stack'; import {Animated} from 'react-native'; import getCardStyles from '@styles/cardStyles'; import variables from '@styles/variables'; -export default (isSmallScreenWidth, isFullScreenModal, {current: {progress}, inverted, layouts: {screen}}) => { +export default (isSmallScreenWidth: boolean, isFullScreenModal: boolean, {current: {progress}, inverted, layouts: {screen}}: StackCardInterpolationProps): StackCardInterpolatedStyle => { const translateX = Animated.multiply( progress.interpolate({ inputRange: [0, 1], diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 41df21d8e237..7aa5bb32a4e4 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -37,318 +37,326 @@ type CentralPaneNavigatorParamList = { [SCREENS.REPORT]: { reportActionID: string; reportID: string; + openOnAdminRoom?: boolean; }; }; type SettingsNavigatorParamList = { [SCREENS.SETTINGS.ROOT]: undefined; - Settings_Share_Code: undefined; + [SCREENS.SETTINGS.SHARE_CODE]: undefined; [SCREENS.SETTINGS.WORKSPACES]: undefined; - Settings_Profile: undefined; - Settings_Pronouns: undefined; - Settings_Display_Name: undefined; - Settings_Timezone: undefined; - Settings_Timezone_Select: undefined; - Settings_PersonalDetails_Initial: undefined; - Settings_PersonalDetails_LegalName: undefined; - Settings_PersonalDetails_DateOfBirth: undefined; - Settings_PersonalDetails_Address: undefined; - Settings_PersonalDetails_Address_Country: undefined; - Settings_ContactMethods: undefined; - Settings_ContactMethodDetails: undefined; - Settings_NewContactMethod: undefined; + [SCREENS.SETTINGS.PROFILE]: undefined; + [SCREENS.SETTINGS.PRONOUNS]: undefined; + [SCREENS.SETTINGS.DISPLAY_NAME]: undefined; + [SCREENS.SETTINGS.TIMEZONE]: undefined; + [SCREENS.SETTINGS.TIMEZONE_SELECT]: undefined; + [SCREENS.SETTINGS.PERSONAL_DETAILS_INITIAL]: undefined; + [SCREENS.SETTINGS.PERSONAL_DETAILS_LEGAL_NAME]: undefined; + [SCREENS.SETTINGS.PERSONAL_DETAILS_DATE_OF_BIRTH]: undefined; + [SCREENS.SETTINGS.PERSONAL_DETAILS_ADDRESS]: undefined; + [SCREENS.SETTINGS.PERSONAL_DETAILS_ADDRESS_COUNTRY]: undefined; + [SCREENS.SETTINGS.CONTACT_METHODS]: undefined; + [SCREENS.SETTINGS.CONTACT_METHOD_DETAILS]: undefined; + [SCREENS.SETTINGS.NEW_CONTACT_METHOD]: undefined; [SCREENS.SETTINGS.PREFERENCES]: undefined; - Settings_Preferences_PriorityMode: undefined; - Settings_Preferences_Language: undefined; - Settings_Preferences_Theme: undefined; - Settings_Close: undefined; + [SCREENS.SETTINGS.PREFERENCES_PRIORITY_MODE]: undefined; + [SCREENS.SETTINGS.PREFERENCES_LANGUAGE]: undefined; + [SCREENS.SETTINGS.PREFERENCES_THEME]: undefined; + [SCREENS.SETTINGS.CLOSE]: undefined; [SCREENS.SETTINGS.SECURITY]: undefined; - Settings_About: undefined; - Settings_App_Download_Links: undefined; - Settings_Lounge_Access: undefined; - Settings_Wallet: undefined; - Settings_Wallet_Cards_Digital_Details_Update_Address: undefined; - Settings_Wallet_DomainCard: undefined; - Settings_Wallet_ReportVirtualCardFraud: undefined; - Settings_Wallet_Card_Activate: undefined; + [SCREENS.SETTINGS.ABOUT]: undefined; + [SCREENS.SETTINGS.APP_DOWNLOAD_LINKS]: undefined; + [SCREENS.SETTINGS.LOUNGE_ACCESS]: undefined; + [SCREENS.SETTINGS.WALLET]: undefined; + [SCREENS.SETTINGS.WALLET_CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS]: undefined; + [SCREENS.SETTINGS.WALLET_DOMAIN_CARD]: undefined; + [SCREENS.SETTINGS.WALLET_REPORT_VIRTUAL_CARD_FRAUD]: undefined; + [SCREENS.SETTINGS.WALLET_CARD_ACTIVATE]: undefined; [SCREENS.SETTINGS.WALLET_CARD_GET_PHYSICAL.NAME]: undefined; [SCREENS.SETTINGS.WALLET_CARD_GET_PHYSICAL.PHONE]: undefined; [SCREENS.SETTINGS.WALLET_CARD_GET_PHYSICAL.ADDRESS]: undefined; [SCREENS.SETTINGS.WALLET_CARD_GET_PHYSICAL.CONFIRM]: undefined; - Settings_Wallet_Transfer_Balance: undefined; - Settings_Wallet_Choose_Transfer_Account: undefined; - Settings_Wallet_EnablePayments: undefined; - Settings_Add_Debit_Card: undefined; - Settings_Add_Bank_Account: undefined; + [SCREENS.SETTINGS.WALLET_TRANSFER_BALANCE]: undefined; + [SCREENS.SETTINGS.WALLET_CHOOSE_TRANSFER_ACCOUNT]: undefined; + [SCREENS.SETTINGS.WALLET_ENABLE_PAYMENTS]: undefined; + [SCREENS.SETTINGS.ADD_DEBIT_CARD]: undefined; + [SCREENS.SETTINGS.ADD_BANK_ACCOUNT]: undefined; [SCREENS.SETTINGS.STATUS]: undefined; - Settings_Status_Set: undefined; - Workspace_Initial: undefined; - Workspace_Settings: undefined; - Workspace_Settings_Currency: undefined; - Workspace_Card: { + [SCREENS.SETTINGS.STATUS_SET]: undefined; + [SCREENS.WORKSPACE.INITIAL]: undefined; + [SCREENS.WORKSPACE.SETTINGS]: undefined; + [SCREENS.WORKSPACE.CURRENCY]: undefined; + [SCREENS.WORKSPACE.CARD]: { policyID: string; }; - Workspace_Reimburse: { + [SCREENS.WORKSPACE.REIMBURSE]: { policyID: string; }; - Workspace_RateAndUnit: undefined; - Workspace_Bills: { + [SCREENS.WORKSPACE.RATE_AND_UNIT]: undefined; + [SCREENS.WORKSPACE.BILLS]: { policyID: string; }; - Workspace_Invoices: { + [SCREENS.WORKSPACE.INVOICES]: { policyID: string; }; - Workspace_Travel: { + [SCREENS.WORKSPACE.TRAVEL]: { policyID: string; }; - Workspace_Members: { + [SCREENS.WORKSPACE.MEMBERS]: { policyID: string; }; - Workspace_Invite: { + [SCREENS.WORKSPACE.INVITE]: { policyID: string; }; - Workspace_Invite_Message: { + [SCREENS.WORKSPACE.INVITE_MESSAGE]: { policyID: string; }; - ReimbursementAccount: { + [SCREENS.REIMBURSEMENT_ACCOUNT]: { stepToOpen: string; policyID: string; }; - GetAssistance: { + [SCREENS.GET_ASSISTANCE]: { taskID: string; }; - Settings_TwoFactorAuth: undefined; - Settings_ReportCardLostOrDamaged: undefined; - KeyboardShortcuts: undefined; + [SCREENS.SETTINGS.TWO_FACTOR_AUTH]: undefined; + [SCREENS.SETTINGS.REPORT_CARD_LOST_OR_DAMAGED]: undefined; + [SCREENS.KEYBOARD_SHORTCUTS]: undefined; }; type NewChatNavigatorParamList = { - NewChat_Root: undefined; + [SCREENS.NEW_CHAT_ROOT]: undefined; }; type SearchNavigatorParamList = { - Search_Root: undefined; + [SCREENS.SEARCH_ROOT]: undefined; }; type DetailsNavigatorParamList = { - Details_Root: { + [SCREENS.DETAILS_ROOT]: { login: string; reportID: string; }; }; type ProfileNavigatorParamList = { - Profile_Root: { + [SCREENS.PROFILE_ROOT]: { accountID: string; reportID: string; }; }; type ReportDetailsNavigatorParamList = { - Report_Details_Root: undefined; - Report_Details_Share_Code: { + [SCREENS.REPORT_DETAILS.ROOT]: undefined; + [SCREENS.REPORT_DETAILS.SHARE_CODE]: { reportID: string; }; }; type ReportSettingsNavigatorParamList = { - Report_Settings_Root: undefined; - Report_Settings_Room_Name: undefined; - Report_Settings_Notification_Preferences: undefined; - Report_Settings_Write_Capability: undefined; + [SCREENS.REPORT_SETTINGS.ROOT]: undefined; + [SCREENS.REPORT_SETTINGS.ROOM_NAME]: undefined; + [SCREENS.REPORT_SETTINGS.NOTIFICATION_PREFERENCES]: undefined; + [SCREENS.REPORT_SETTINGS.WRITE_CAPABILITY]: undefined; }; type ReportWelcomeMessageNavigatorParamList = { - Report_WelcomeMessage_Root: {reportID: string}; + [SCREENS.REPORT_WELCOME_MESSAGE_ROOT]: {reportID: string}; }; type ParticipantsNavigatorParamList = { - ReportParticipants_Root: {reportID: string}; + [SCREENS.REPORT_PARTICIPANTS_ROOT]: {reportID: string}; }; type RoomMembersNavigatorParamList = { - RoomMembers_Root: undefined; + [SCREENS.ROOM_MEMBERS_ROOT]: undefined; }; type RoomInviteNavigatorParamList = { - RoomInvite_Root: undefined; + [SCREENS.ROOM_INVITE_ROOT]: undefined; }; type MoneyRequestNavigatorParamList = { - Money_Request: undefined; - Money_Request_Amount: undefined; - Money_Request_Participants: { + [SCREENS.MONEY_REQUEST.ROOT]: undefined; + [SCREENS.MONEY_REQUEST.AMOUNT]: undefined; + [SCREENS.MONEY_REQUEST.PARTICIPANTS]: { iouType: string; reportID: string; }; - Money_Request_Confirmation: { + [SCREENS.MONEY_REQUEST.CONFIRMATION]: { iouType: string; reportID: string; }; - Money_Request_Currency: { + [SCREENS.MONEY_REQUEST.CURRENCY]: { iouType: string; reportID: string; currency: string; backTo: string; }; - Money_Request_Date: { + [SCREENS.MONEY_REQUEST.DATE]: { iouType: string; reportID: string; field: string; threadReportID: string; }; - Money_Request_Description: { + [SCREENS.MONEY_REQUEST.DESCRIPTION]: { iouType: string; reportID: string; field: string; threadReportID: string; }; - Money_Request_Category: { + [SCREENS.MONEY_REQUEST.CATEGORY]: { iouType: string; reportID: string; }; - Money_Request_Tag: { + [SCREENS.MONEY_REQUEST.TAG]: { iouType: string; reportID: string; }; - Money_Request_Merchant: { + [SCREENS.MONEY_REQUEST.MERCHANT]: { iouType: string; reportID: string; field: string; threadReportID: string; }; - IOU_Send_Enable_Payments: undefined; - IOU_Send_Add_Bank_Account: undefined; - IOU_Send_Add_Debit_Card: undefined; - Money_Request_Waypoint: { + [SCREENS.IOU_SEND.ENABLE_PAYMENTS]: undefined; + [SCREENS.IOU_SEND.ADD_BANK_ACCOUNT]: undefined; + [SCREENS.IOU_SEND.ADD_DEBIT_CARD]: undefined; + [SCREENS.MONEY_REQUEST.WAYPOINT]: { iouType: string; transactionID: string; waypointIndex: string; threadReportID: number; }; - Money_Request_Edit_Waypoint: { + [SCREENS.MONEY_REQUEST.EDIT_WAYPOINT]: { iouType: string; transactionID: string; waypointIndex: string; threadReportID: number; }; - Money_Request_Distance: { + [SCREENS.MONEY_REQUEST.DISTANCE]: { iouType: ValueOf; reportID: string; }; - Money_Request_Receipt: { + [SCREENS.MONEY_REQUEST.RECEIPT]: { iouType: string; reportID: string; }; }; type NewTaskNavigatorParamList = { - NewTask_Root: undefined; - NewTask_TaskAssigneeSelector: undefined; - NewTask_TaskShareDestinationSelector: undefined; - NewTask_Details: undefined; - NewTask_Title: undefined; - NewTask_Description: undefined; + [SCREENS.NEW_TASK.ROOT]: undefined; + [SCREENS.NEW_TASK.TASK_ASSIGNEE_SELECTOR]: undefined; + [SCREENS.NEW_TASK.TASK_SHARE_DESTINATION_SELECTOR]: undefined; + [SCREENS.NEW_TASK.DETAILS]: undefined; + [SCREENS.NEW_TASK.TITLE]: undefined; + [SCREENS.NEW_TASK.DESCRIPTION]: undefined; }; type TeachersUniteNavigatorParamList = { [SCREENS.SAVE_THE_WORLD.ROOT]: undefined; - I_Know_A_Teacher: undefined; - Intro_School_Principal: undefined; - I_Am_A_Teacher: undefined; + [SCREENS.I_KNOW_A_TEACHER]: undefined; + [SCREENS.INTRO_SCHOOL_PRINCIPAL]: undefined; + [SCREENS.I_AM_A_TEACHER]: undefined; }; type TaskDetailsNavigatorParamList = { - Task_Title: undefined; - Task_Description: undefined; - Task_Assignee: { + [SCREENS.TASK.TITLE]: undefined; + [SCREENS.TASK.DESCRIPTION]: undefined; + [SCREENS.TASK.ASSIGNEE]: { reportID: string; }; }; type EnablePaymentsNavigatorParamList = { - EnablePayments_Root: undefined; + [SCREENS.ENABLE_PAYMENTS_ROOT]: undefined; }; type SplitDetailsNavigatorParamList = { - SplitDetails_Root: { + [SCREENS.SPLIT_DETAILS.ROOT]: { reportActionID: string; }; - SplitDetails_Edit_Request: undefined; - SplitDetails_Edit_Currency: undefined; + [SCREENS.SPLIT_DETAILS.EDIT_REQUEST]: undefined; + [SCREENS.SPLIT_DETAILS.EDIT_CURRENCY]: undefined; }; type AddPersonalBankAccountNavigatorParamList = { - AddPersonalBankAccount_Root: undefined; + [SCREENS.ADD_PERSONAL_BANK_ACCOUNT_ROOT]: undefined; +}; + +type ReimbursementAccountNavigatorParamList = { + [SCREENS.REIMBURSEMENT_ACCOUNT_ROOT]: { + stepToOpen: string; + policyID: string; + }; }; type WalletStatementNavigatorParamList = { - WalletStatement_Root: undefined; + [SCREENS.WALLET_STATEMENT_ROOT]: undefined; }; type FlagCommentNavigatorParamList = { - FlagComment_Root: { + [SCREENS.FLAG_COMMENT_ROOT]: { reportID: string; reportActionID: string; }; }; type EditRequestNavigatorParamList = { - EditRequest_Root: { + [SCREENS.EDIT_REQUEST.ROOT]: { field: string; threadReportID: string; }; - EditRequest_Currency: undefined; + [SCREENS.EDIT_REQUEST.CURRENCY]: undefined; }; type SignInNavigatorParamList = { - SignIn_Root: undefined; + [SCREENS.SIGN_IN_ROOT]: undefined; }; type ReferralDetailsNavigatorParamList = { - Referral_Details: undefined; + [SCREENS.REFERRAL_DETAILS]: undefined; }; type PrivateNotesNavigatorParamList = { - PrivateNotes_View: { + [SCREENS.PRIVATE_NOTES.VIEW]: { reportID: string; accountID: string; }; - PrivateNotes_List: { + [SCREENS.PRIVATE_NOTES.LIST]: { reportID: string; accountID: string; }; - PrivateNotes_Edit: { + [SCREENS.PRIVATE_NOTES.EDIT]: { reportID: string; accountID: string; }; }; type RightModalNavigatorParamList = { - Settings: NavigatorScreenParams; - NewChat: NavigatorScreenParams; - Search: NavigatorScreenParams; - Details: NavigatorScreenParams; - Profile: NavigatorScreenParams; - Report_Details: NavigatorScreenParams; - Report_Settings: NavigatorScreenParams; - Report_WelcomeMessage: NavigatorScreenParams; - Participants: NavigatorScreenParams; - RoomMembers: NavigatorScreenParams; - RoomInvite: NavigatorScreenParams; - MoneyRequest: NavigatorScreenParams; - NewTask: NavigatorScreenParams; - TeachersUnite: NavigatorScreenParams; - Task_Details: NavigatorScreenParams; - EnablePayments: NavigatorScreenParams; - SplitDetails: NavigatorScreenParams; - AddPersonalBankAccount: NavigatorScreenParams; - Wallet_Statement: NavigatorScreenParams; - Flag_Comment: NavigatorScreenParams; - EditRequest: NavigatorScreenParams; - SignIn: NavigatorScreenParams; - Referral: NavigatorScreenParams; - Private_Notes: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.SETTINGS]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.NEW_CHAT]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.SEARCH]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.DETAILS]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.PROFILE]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.REPORT_DETAILS]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.REPORT_SETTINGS]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.REPORT_WELCOME_MESSAGE]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.PARTICIPANTS]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.ROOM_MEMBERS]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.ROOM_INVITE]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.MONEY_REQUEST]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.NEW_TASK]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.TEACHERS_UNITE]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.TASK_DETAILS]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.ENABLE_PAYMENTS]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.SPLIT_DETAILS]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.ADD_PERSONAL_BANK_ACCOUNT]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.WALLET_STATEMENT]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.FLAG_COMMENT]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.EDIT_REQUEST]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.SIGN_IN]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.REFERRAL]: NavigatorScreenParams; + [SCREENS.RIGHT_MODAL.PRIVATE_NOTES]: NavigatorScreenParams; }; type PublicScreensParamList = { @@ -390,6 +398,12 @@ type AuthScreensParamList = { reportID: string; source: string; }; + [CONST.DEMO_PAGES.SAASTR]: { + name: string; + }; + [CONST.DEMO_PAGES.SBE]: { + name: string; + }; [SCREENS.NOT_FOUND]: undefined; [NAVIGATORS.RIGHT_MODAL_NAVIGATOR]: NavigatorScreenParams; [SCREENS.DESKTOP_SIGN_IN_REDIRECT]: undefined; @@ -398,4 +412,40 @@ type AuthScreensParamList = { type RootStackParamList = PublicScreensParamList & AuthScreensParamList; -export type {NavigationRef, StackNavigationAction, CentralPaneNavigatorParamList, RootStackParamList, StateOrRoute, NavigationStateRoute, NavigationRoot}; +export type { + NavigationRef, + StackNavigationAction, + CentralPaneNavigatorParamList, + RootStackParamList, + StateOrRoute, + NavigationStateRoute, + NavigationRoot, + AuthScreensParamList, + RightModalNavigatorParamList, + PublicScreensParamList, + MoneyRequestNavigatorParamList, + SplitDetailsNavigatorParamList, + DetailsNavigatorParamList, + ProfileNavigatorParamList, + ReportDetailsNavigatorParamList, + ReportSettingsNavigatorParamList, + TaskDetailsNavigatorParamList, + ReportWelcomeMessageNavigatorParamList, + ParticipantsNavigatorParamList, + RoomMembersNavigatorParamList, + RoomInviteNavigatorParamList, + SearchNavigatorParamList, + NewChatNavigatorParamList, + NewTaskNavigatorParamList, + TeachersUniteNavigatorParamList, + SettingsNavigatorParamList, + EnablePaymentsNavigatorParamList, + AddPersonalBankAccountNavigatorParamList, + WalletStatementNavigatorParamList, + FlagCommentNavigatorParamList, + EditRequestNavigatorParamList, + PrivateNotesNavigatorParamList, + SignInNavigatorParamList, + ReferralDetailsNavigatorParamList, + ReimbursementAccountNavigatorParamList, +}; diff --git a/src/libs/NetworkConnection.ts b/src/libs/NetworkConnection.ts index e150b8b650c1..f5c391aad09c 100644 --- a/src/libs/NetworkConnection.ts +++ b/src/libs/NetworkConnection.ts @@ -13,7 +13,7 @@ let hasPendingNetworkCheck = false; // Holds all of the callbacks that need to be triggered when the network reconnects let callbackID = 0; -const reconnectionCallbacks: Record Promise> = {}; +const reconnectionCallbacks: Record void> = {}; /** * Loop over all reconnection callbacks and fire each one @@ -122,7 +122,7 @@ function listenForReconnect() { * Register callback to fire when we reconnect * @returns unsubscribe method */ -function onReconnect(callback: () => Promise): () => void { +function onReconnect(callback: () => void): () => void { const currentID = callbackID; callbackID++; reconnectionCallbacks[currentID] = callback; diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts index 4de8f1c1f171..ec43d4358134 100644 --- a/src/libs/actions/App.ts +++ b/src/libs/actions/App.ts @@ -1,7 +1,7 @@ // Issue - https://github.com/Expensify/App/issues/26719 import Str from 'expensify-common/lib/str'; import {AppState, AppStateStatus} from 'react-native'; -import Onyx, {OnyxCollection, OnyxUpdate} from 'react-native-onyx'; +import Onyx, {OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import {ValueOf} from 'type-fest'; import * as API from '@libs/API'; import * as Browser from '@libs/Browser'; @@ -228,7 +228,7 @@ function openApp() { * Fetches data when the app reconnects to the network * @param [updateIDFrom] the ID of the Onyx update that we want to start fetching from */ -function reconnectApp(updateIDFrom = 0) { +function reconnectApp(updateIDFrom: OnyxEntry = 0) { console.debug(`[OnyxUpdates] App reconnecting with updateIDFrom: ${updateIDFrom}`); getPolicyParamsForOpenOrReconnect().then((policyParams) => { type ReconnectParams = { @@ -384,7 +384,7 @@ function savePolicyDraftByNewWorkspace(policyID?: string, policyName?: string, p * pass it in as a parameter. withOnyx guarantees that the value has been read * from Onyx because it will not render the AuthScreens until that point. */ -function setUpPoliciesAndNavigate(session: OnyxTypes.Session) { +function setUpPoliciesAndNavigate(session: OnyxEntry) { const currentUrl = getCurrentUrl(); if (!session || !currentUrl || !currentUrl.includes('exitTo')) { return; diff --git a/src/pages/ErrorPage/NotFoundPage.js b/src/pages/ErrorPage/NotFoundPage.js index aac2e6d613f9..e10ec32732ea 100644 --- a/src/pages/ErrorPage/NotFoundPage.js +++ b/src/pages/ErrorPage/NotFoundPage.js @@ -13,12 +13,12 @@ const defaultProps = { }; // eslint-disable-next-line rulesdir/no-negated-variables -function NotFoundPage({onBackButtonPress}) { +function NotFoundPage(props) { return ( ); diff --git a/src/styles/getNavigationModalCardStyles/types.ts b/src/styles/getNavigationModalCardStyles/types.ts index 877981dd4dd2..e0dba07dc908 100644 --- a/src/styles/getNavigationModalCardStyles/types.ts +++ b/src/styles/getNavigationModalCardStyles/types.ts @@ -1,7 +1,5 @@ import {ViewStyle} from 'react-native'; -type GetNavigationModalCardStylesParams = {isSmallScreenWidth: number}; - -type GetNavigationModalCardStyles = (params: GetNavigationModalCardStylesParams) => ViewStyle; +type GetNavigationModalCardStyles = () => ViewStyle; export default GetNavigationModalCardStyles; diff --git a/src/types/onyx/DemoInfo.ts b/src/types/onyx/DemoInfo.ts new file mode 100644 index 000000000000..dcd7efc44d8d --- /dev/null +++ b/src/types/onyx/DemoInfo.ts @@ -0,0 +1,8 @@ +type DemoInfo = { + money2020: { + /** If the beginning demo should be shown */ + isBeginningDemo?: boolean; + }; +}; + +export default DemoInfo; diff --git a/src/types/onyx/Report.ts b/src/types/onyx/Report.ts index b49599913543..a077bf1a3281 100644 --- a/src/types/onyx/Report.ts +++ b/src/types/onyx/Report.ts @@ -94,6 +94,9 @@ type Report = { /** The report type */ type?: string; + /** If the admin room should be opened */ + openOnAdminRoom?: boolean; + /** The report visibility */ visibility?: ValueOf; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 8329b56dc4b8..dcaa4ee3d623 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -7,6 +7,7 @@ import Card from './Card'; import Credentials from './Credentials'; import Currency from './Currency'; import CustomStatusDraft from './CustomStatusDraft'; +import DemoInfo from './DemoInfo'; import Download from './Download'; import Form, {AddDebitCardForm, DateOfBirthForm} from './Form'; import FrequentlyUsedEmoji from './FrequentlyUsedEmoji'; @@ -66,6 +67,7 @@ export type { Currency, CustomStatusDraft, DateOfBirthForm, + DemoInfo, Download, Form, FrequentlyUsedEmoji,