Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contributingGuides/NAVIGATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ Considerations when removing `backTo` from a URL:
```ts
type ReportScreenNavigationProps =
| PlatformStackScreenProps<ReportsSplitNavigatorParamList, typeof SCREENS.REPORT>
| PlatformStackScreenProps<SearchReportParamList, typeof SCREENS.SEARCH.REPORT_RHP>;
| PlatformStackScreenProps<RightModalNavigatorParamList, typeof SCREENS.RIGHT_MODAL.SEARCH_REPORT>;
```

An example of a screen that is reused in several flows is `VerifyAccountPage`.
Expand Down
1 change: 0 additions & 1 deletion src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ const SCREENS = {
MONEY_REQUEST_REPORT_VERIFY_ACCOUNT: 'Search_Money_Request_Report_Verify_Account',
MONEY_REQUEST_REPORT_HOLD_TRANSACTIONS: 'Search_Money_Request_Report_Hold_Transactions',
MONEY_REQUEST_REPORT_REJECT_TRANSACTIONS: 'Search_Money_Request_Report_Reject_Transactions',
REPORT_RHP: 'Search_Report_RHP',
COLUMNS_RHP: 'Search_Columns_RHP',
REPORT_VERIFY_ACCOUNT: 'Search_Report_Verify_Account',
ADVANCED_FILTERS_RHP: 'Search_Advanced_Filters_RHP',
Expand Down
6 changes: 3 additions & 3 deletions src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import Log from '@libs/Log';
import {getThreadReportIDsForTransactions, getTotalAmountForIOUReportPreviewButton} from '@libs/MoneyRequestReportUtils';
import Navigation from '@libs/Navigation/Navigation';
import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types';
import type {ReportsSplitNavigatorParamList, SearchFullscreenNavigatorParamList, SearchReportParamList} from '@libs/Navigation/types';
import type {ReportsSplitNavigatorParamList, RightModalNavigatorParamList, SearchFullscreenNavigatorParamList} from '@libs/Navigation/types';
import {buildOptimisticNextStepForPreventSelfApprovalsEnabled, buildOptimisticNextStepForStrictPolicyRuleViolations} from '@libs/NextStepUtils';
import type {KYCFlowEvent, TriggerKYCFlow} from '@libs/PaymentUtils';
import {selectPaymentType} from '@libs/PaymentUtils';
Expand Down Expand Up @@ -193,7 +193,7 @@ function MoneyReportHeader({
const route = useRoute<
| PlatformStackRouteProp<ReportsSplitNavigatorParamList, typeof SCREENS.REPORT>
| PlatformStackRouteProp<SearchFullscreenNavigatorParamList, typeof SCREENS.SEARCH.MONEY_REQUEST_REPORT>
| PlatformStackRouteProp<SearchReportParamList, typeof SCREENS.SEARCH.REPORT_RHP>
| PlatformStackRouteProp<RightModalNavigatorParamList, typeof SCREENS.RIGHT_MODAL.SEARCH_REPORT>
>();
const {login: currentUserLogin, accountID, email} = useCurrentUserPersonalDetails();
const defaultExpensePolicy = useDefaultExpensePolicy();
Expand Down Expand Up @@ -476,7 +476,7 @@ function MoneyReportHeader({
const shouldShowLoadingBar = useLoadingBarVisibility();
const kycWallRef = useContext(KYCWallContext);

const isReportInRHP = route.name === SCREENS.SEARCH.REPORT_RHP;
const isReportInRHP = route.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT;
const shouldDisplaySearchRouter = !isReportInRHP || isSmallScreenWidth;
const isReportInSearch = route.name === SCREENS.SEARCH.MONEY_REQUEST_REPORT;
const isReportSubmitter = isCurrentUserSubmitter(chatIOUReport);
Expand Down
8 changes: 5 additions & 3 deletions src/components/MoneyRequestHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
import Navigation from '@libs/Navigation/Navigation';
import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types';
import type {ReportsSplitNavigatorParamList, SearchReportParamList} from '@libs/Navigation/types';
import type {ReportsSplitNavigatorParamList, RightModalNavigatorParamList} from '@libs/Navigation/types';
import {getOriginalMessage, isMoneyRequestAction, isTrackExpenseAction} from '@libs/ReportActionsUtils';
import {getTransactionThreadPrimaryAction, isMarkAsResolvedAction} from '@libs/ReportPrimaryActionUtils';
import {getSecondaryTransactionThreadActions} from '@libs/ReportSecondaryActionUtils';
Expand Down Expand Up @@ -72,7 +72,7 @@
import HoldOrRejectEducationalModal from './HoldOrRejectEducationalModal';
import HoldSubmitterEducationalModal from './HoldSubmitterEducationalModal';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';

Check warning on line 75 in src/components/MoneyRequestHeader.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'./Icon/Expensicons' import is restricted from being used by a pattern. Direct imports from Icon/Expensicons are deprecated. Please use lazy loading hooks instead. Use `useMemoizedLazyExpensifyIcons` from @hooks/useLazyAsset. See docs/LAZY_ICONS_AND_ILLUSTRATIONS.md for details
import LoadingBar from './LoadingBar';
import type {MoneyRequestHeaderStatusBarProps} from './MoneyRequestHeaderStatusBar';
import MoneyRequestHeaderStatusBar from './MoneyRequestHeaderStatusBar';
Expand All @@ -98,7 +98,9 @@
// We need to use isSmallScreenWidth instead of shouldUseNarrowLayout to use a correct layout for the hold expense modal https://github.com/Expensify/App/pull/47990#issuecomment-2362382026
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
const {shouldUseNarrowLayout, isSmallScreenWidth} = useResponsiveLayout();
const route = useRoute<PlatformStackRouteProp<ReportsSplitNavigatorParamList, typeof SCREENS.REPORT> | PlatformStackRouteProp<SearchReportParamList, typeof SCREENS.SEARCH.REPORT_RHP>>();
const route = useRoute<
PlatformStackRouteProp<ReportsSplitNavigatorParamList, typeof SCREENS.REPORT> | PlatformStackRouteProp<RightModalNavigatorParamList, typeof SCREENS.RIGHT_MODAL.SEARCH_REPORT>
>();
const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`, {
canBeMissing: false,
});
Expand Down Expand Up @@ -143,7 +145,7 @@
const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT);

const {isDelegateAccessRestricted, showDelegateNoAccessModal} = useContext(DelegateNoAccessContext);
const isReportInRHP = route.name === SCREENS.SEARCH.REPORT_RHP;
const isReportInRHP = route.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT;
const isFromReviewDuplicates = !!route.params.backTo?.replaceAll(/\?.*/g, '').endsWith('/duplicates/review');
const shouldDisplayTransactionNavigation = !!(reportID && isReportInRHP);
const isParentReportArchived = useReportIsArchived(report?.parentReportID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {WideRHPContext} from '@components/WideRHPContextProvider';
import useOnyx from '@hooks/useOnyx';
import {createTransactionThreadReport, setOptimisticTransactionThread} from '@libs/actions/Report';
import {clearActiveTransactionIDs} from '@libs/actions/TransactionThreadNavigation';
import type {SearchReportParamList} from '@libs/Navigation/types';
import type {RightModalNavigatorParamList} from '@libs/Navigation/types';
import {getOriginalMessage, isMoneyRequestAction} from '@libs/ReportActionsUtils';
import Navigation from '@navigation/Navigation';
import navigationRef from '@navigation/navigationRef';
Expand Down Expand Up @@ -106,7 +106,7 @@ function MoneyRequestReportTransactionsNavigation({currentTransactionID, isFromR
useEffect(() => {
return () => {
const focusedRoute = findFocusedRoute(navigationRef.getRootState());
if (focusedRoute?.name === SCREENS.SEARCH.REPORT_RHP || focusedRoute?.name === SCREENS.TRANSACTION_DUPLICATE.REVIEW) {
if (focusedRoute?.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT || focusedRoute?.name === SCREENS.TRANSACTION_DUPLICATE.REVIEW) {
return;
}
clearActiveTransactionIDs();
Expand All @@ -123,7 +123,7 @@ function MoneyRequestReportTransactionsNavigation({currentTransactionID, isFromR
let backTo = Navigation.getActiveRoute();
if (isFromReviewDuplicates) {
const currentRoute = navigationRef.getCurrentRoute();
const params = currentRoute?.params as SearchReportParamList[typeof SCREENS.SEARCH.REPORT_RHP] | undefined;
const params = currentRoute?.params as RightModalNavigatorParamList[typeof SCREENS.RIGHT_MODAL.SEARCH_REPORT] | undefined;
backTo = params?.backTo ?? backTo;
}
const nextThreadReportID = nextParentReportAction?.childReportID;
Expand Down Expand Up @@ -151,7 +151,7 @@ function MoneyRequestReportTransactionsNavigation({currentTransactionID, isFromR
let backTo = Navigation.getActiveRoute();
if (isFromReviewDuplicates) {
const currentRoute = navigationRef.getCurrentRoute();
const params = currentRoute?.params as SearchReportParamList[typeof SCREENS.SEARCH.REPORT_RHP] | undefined;
const params = currentRoute?.params as RightModalNavigatorParamList[typeof SCREENS.RIGHT_MODAL.SEARCH_REPORT] | undefined;
backTo = params?.backTo ?? backTo;
}
const prevThreadReportID = prevParentReportAction?.childReportID;
Expand Down
2 changes: 1 addition & 1 deletion src/components/ParentNavigationSubtitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function ParentNavigationSubtitle({
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`, {canBeMissing: false});
const isReportArchived = useReportIsArchived(report?.reportID);
const canUserPerformWriteAction = canUserPerformWriteActionReportUtils(report, isReportArchived);
const isReportInRHP = currentRoute.name === SCREENS.SEARCH.REPORT_RHP;
const isReportInRHP = currentRoute.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT;
const currentFullScreenRoute = useRootNavigationState((state) => state?.routes?.findLast((route) => isFullScreenName(route.name)));
const hasAccessToParentReport = currentReport?.hasParentAccess !== false;

Expand Down
7 changes: 5 additions & 2 deletions src/components/ScreenWrapper/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type {ForwardedFSClassProps} from '@libs/Fullstory/types';
import NarrowPaneContext from '@libs/Navigation/AppNavigator/Navigators/NarrowPaneContext';
import Navigation from '@libs/Navigation/Navigation';
import type {PlatformStackNavigationProp} from '@libs/Navigation/PlatformStackNavigation/types';
import type {ReportsSplitNavigatorParamList, RootNavigatorParamList, SearchReportParamList} from '@libs/Navigation/types';
import type {ReportsSplitNavigatorParamList, RightModalNavigatorParamList, RootNavigatorParamList} from '@libs/Navigation/types';
import {closeReactNativeApp} from '@userActions/HybridApp';
import CONFIG from '@src/CONFIG';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -50,7 +50,10 @@ type ScreenWrapperProps = Omit<ScreenWrapperContainerProps, 'children'> &
*
* This is required because transitionEnd event doesn't trigger in the testing environment.
*/
navigation?: PlatformStackNavigationProp<RootNavigatorParamList> | PlatformStackNavigationProp<ReportsSplitNavigatorParamList> | PlatformStackNavigationProp<SearchReportParamList>;
navigation?:
| PlatformStackNavigationProp<RootNavigatorParamList>
| PlatformStackNavigationProp<ReportsSplitNavigatorParamList>
| PlatformStackNavigationProp<RightModalNavigatorParamList>;

/** A unique ID to find the screen wrapper in tests */
testID: string;
Expand Down
2 changes: 1 addition & 1 deletion src/components/ScrollOffsetContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function ScrollOffsetContextProvider({children}: ScrollOffsetContextProviderProp
const routeName = focusedRoute?.name;

const isSearchScreen = routeName === SCREENS.SEARCH.ROOT;
const isSearchMoneyRequestReport = routeName === SCREENS.SEARCH.MONEY_REQUEST_REPORT || routeName === SCREENS.SEARCH.REPORT_RHP;
const isSearchMoneyRequestReport = routeName === SCREENS.SEARCH.MONEY_REQUEST_REPORT || routeName === SCREENS.RIGHT_MODAL.SEARCH_REPORT;

const scrollOffsetKeys = Object.keys(scrollOffsetsRef.current);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const getCurrentRouteReportID: (url: string) => string | ProtectedCurrentRouteRe
return isFocusedRouteAChatThread ? firstReportThatHasURLInAttachments : focusedRouteReportID;
};

const screensWithReportID = [SCREENS.SEARCH.REPORT_RHP, SCREENS.REPORT, SCREENS.SEARCH.MONEY_REQUEST_REPORT, SCREENS.REPORT_ATTACHMENTS];
const screensWithReportID = [SCREENS.RIGHT_MODAL.SEARCH_REPORT, SCREENS.REPORT, SCREENS.SEARCH.MONEY_REQUEST_REPORT, SCREENS.REPORT_ATTACHMENTS];

function hasReportIdInRouteParams(route: SearchRoute): route is RouteWithReportIDInParams<SearchRoute> {
return !!route && !!route.params && !!screensWithReportID.find((screen) => screen === route.name) && 'reportID' in route.params;
Expand Down
12 changes: 12 additions & 0 deletions src/components/WideRHPContextProvider/WIDE_RIGHT_MODALS.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// These sets contain the names of wide and super wide right modals.
import SCREENS from '@src/SCREENS';

// Wide right modals: modals that can be either wide or regular RHP size
// Super wide right modals: modals that can be super wide size
// All wide right modals: all modals that can be wide size (combination of wide and super wide)

const WIDE_RIGHT_MODALS = new Set<string>([SCREENS.RIGHT_MODAL.SEARCH_REPORT]);
const SUPER_WIDE_RIGHT_MODALS = new Set<string>([SCREENS.RIGHT_MODAL.SEARCH_MONEY_REQUEST_REPORT, SCREENS.RIGHT_MODAL.EXPENSE_REPORT]);
const ALL_WIDE_RIGHT_MODALS = new Set<string>([...WIDE_RIGHT_MODALS, ...SUPER_WIDE_RIGHT_MODALS]);

export {WIDE_RIGHT_MODALS, SUPER_WIDE_RIGHT_MODALS, ALL_WIDE_RIGHT_MODALS};
9 changes: 4 additions & 5 deletions src/components/WideRHPContextProvider/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@ import type {WideRHPContextType} from './types';

const defaultWideRHPContextValue: WideRHPContextType = {
wideRHPRouteKeys: [],
shouldRenderSecondaryOverlay: false,
shouldRenderSecondaryOverlayForWideRHP: false,
shouldRenderSecondaryOverlayForRHPOnWideRHP: false,
shouldRenderSecondaryOverlayForRHPOnSuperWideRHP: false,
showWideRHPVersion: () => {},
removeWideRHPRouteKey: () => {},
markReportIDAsExpense: () => {},
markReportIDAsMultiTransactionExpense: () => {},
unmarkReportIDAsMultiTransactionExpense: () => {},
isReportIDMarkedAsExpense: () => false,
isReportIDMarkedAsMultiTransactionExpense: () => false,
isWideRHPClosing: false,
setIsWideRHPClosing: () => {},
isWideRHPFocused: false,
shouldRenderTertiaryOverlay: false,
superWideRHPRouteKeys: [],
showSuperWideRHPVersion: () => {},
removeSuperWideRHPRouteKey: () => {},
syncWideRHPKeys: () => {},
syncSuperWideRHPKeys: () => {},
syncRHPKeys: () => {},
clearWideRHPKeys: () => {},
};

Expand Down
18 changes: 18 additions & 0 deletions src/components/WideRHPContextProvider/getIsRHPDisplayedBelow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import getVisibleRHPKeys from './getVisibleRHPRouteKeys';

// Helper function to determine if wide or super wide RHP is displayed below the currently focused route
export default function getIsRHPDisplayedBelow(focusedRouteKey: string | undefined, allSuperWideRHPRouteKeys: string[], allWideRHPRouteKeys: string[]) {
const {visibleSuperWideRHPRouteKeys, visibleWideRHPRouteKeys} = getVisibleRHPKeys(allSuperWideRHPRouteKeys, allWideRHPRouteKeys);

if (!focusedRouteKey) {
return {
isWideRHPBelow: false,
isSuperWideRHPBelow: false,
};
}

return {
isWideRHPBelow: visibleWideRHPRouteKeys.length > 0 && !visibleWideRHPRouteKeys.includes(focusedRouteKey),
isSuperWideRHPBelow: visibleSuperWideRHPRouteKeys.length > 0 && !visibleSuperWideRHPRouteKeys.includes(focusedRouteKey),
};
}

This file was deleted.

38 changes: 30 additions & 8 deletions src/components/WideRHPContextProvider/getVisibleRHPRouteKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,55 @@ import extractNavigationKeys from '@libs/Navigation/helpers/extractNavigationKey
import getLastVisibleRHPRouteKey from '@libs/Navigation/helpers/getLastVisibleRHPRouteKey';
import {navigationRef} from '@libs/Navigation/Navigation';

type VisibleRHPKeys = {
visibleWideRHPRouteKeys: string[];
visibleSuperWideRHPRouteKeys: string[];
};

const emptyRHPKeysState: VisibleRHPKeys = {
visibleWideRHPRouteKeys: [],
visibleSuperWideRHPRouteKeys: [],
};

/**
* Extracts the keys of the screens that are currently displayed from the array of all Wide/Super Wide RHP keys
*
* @param allWideRHPKeys - an array of all Wide/Super Wide RHP keys
*/
function getVisibleWideRHPKeys(allWideRHPKeys: string[]) {
function getVisibleRHPKeys(allSuperWideRHPKeys: string[], allWideRHPKeys: string[]): VisibleRHPKeys {
if (!navigationRef.isReady()) {
return [];
return emptyRHPKeysState;
}

const rootState = navigationRef.getRootState();

if (!rootState) {
return [];
return emptyRHPKeysState;
}

const lastVisibleRHPRouteKey = getLastVisibleRHPRouteKey(rootState);
const lastRHPRoute = rootState.routes.find((route) => route.key === lastVisibleRHPRouteKey);

if (!lastRHPRoute) {
return [];
return emptyRHPKeysState;
}

const lastRHPKeys = extractNavigationKeys(lastRHPRoute.state);
const currentKeys = allWideRHPKeys.filter((key) => lastRHPKeys.has(key));
const superWideRHPIndex = lastRHPRoute.state?.routes.findLastIndex((route) => route?.key && allSuperWideRHPKeys.includes(route.key)) ?? -1;
const wideRHPIndex = lastRHPRoute.state?.routes.findLastIndex((route) => route?.key && allWideRHPKeys.includes(route.key)) ?? -1;

let visibleRHPKeys;
if (superWideRHPIndex > -1) {
visibleRHPKeys = extractNavigationKeys(lastRHPRoute.state?.routes.slice(superWideRHPIndex));
} else if (wideRHPIndex > -1) {
visibleRHPKeys = extractNavigationKeys(lastRHPRoute.state?.routes.slice(wideRHPIndex));
} else {
visibleRHPKeys = extractNavigationKeys(lastRHPRoute.state?.routes);
}

return currentKeys;
return {
visibleWideRHPRouteKeys: allWideRHPKeys.filter((key) => visibleRHPKeys.has(key)),
visibleSuperWideRHPRouteKeys: allSuperWideRHPKeys.filter((key) => visibleRHPKeys.has(key)),
};
}

export default getVisibleWideRHPKeys;
export default getVisibleRHPKeys;
19 changes: 7 additions & 12 deletions src/components/WideRHPContextProvider/index.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import React, {createContext} from 'react';
// to interact with react-navigation components (e.g., CardContainer, interpolator), which also use Animated.
// eslint-disable-next-line no-restricted-imports
import {Animated} from 'react-native';
import SCREENS from '@src/SCREENS';
import defaultWideRHPContextValue from './default';
import type {WideRHPContextType} from './types';

const secondOverlayProgress = new Animated.Value(0);
const secondOverlayWideRHPProgress = new Animated.Value(0);
const secondOverlayRHPOnWideRHPProgress = new Animated.Value(0);
const secondOverlayRHPOnSuperWideRHPProgress = new Animated.Value(0);
const thirdOverlayProgress = new Animated.Value(0);

const animatedReceiptPaneRHPWidth = new Animated.Value(0);
Expand All @@ -18,31 +19,25 @@ const modalStackOverlaySuperWideRHPPositionLeft = new Animated.Value(0);
const modalStackOverlayWideRHPPositionLeft = new Animated.Value(0);

const expandedRHPProgress = new Animated.Value(0);
const innerRHPProgress = new Animated.Value(0);

const WideRHPContext = createContext<WideRHPContextType>(defaultWideRHPContextValue);

const WIDE_RIGHT_MODALS = new Set<string>([SCREENS.RIGHT_MODAL.SEARCH_MONEY_REQUEST_REPORT, SCREENS.RIGHT_MODAL.EXPENSE_REPORT, SCREENS.RIGHT_MODAL.SEARCH_REPORT]);

const SUPER_WIDE_RIGHT_MODALS = new Set<string>([SCREENS.RIGHT_MODAL.SEARCH_MONEY_REQUEST_REPORT, SCREENS.RIGHT_MODAL.EXPENSE_REPORT]);

function WideRHPContextProvider({children}: React.PropsWithChildren) {
return <WideRHPContext.Provider value={defaultWideRHPContextValue}>{children}</WideRHPContext.Provider>;
}

export default WideRHPContextProvider;
export type {WideRHPContextType};
export {
animatedReceiptPaneRHPWidth,
animatedSuperWideRHPWidth,
animatedWideRHPWidth,
expandedRHPProgress,
innerRHPProgress,
modalStackOverlaySuperWideRHPPositionLeft,
modalStackOverlayWideRHPPositionLeft,
secondOverlayProgress,
secondOverlayRHPOnSuperWideRHPProgress,
secondOverlayRHPOnWideRHPProgress,
secondOverlayWideRHPProgress,
thirdOverlayProgress,
WideRHPContext,
WIDE_RIGHT_MODALS,
SUPER_WIDE_RIGHT_MODALS,
};
export type {WideRHPContextType};
Loading
Loading