11import { PortalHost } from '@gorhom/portal' ;
22import { useIsFocused } from '@react-navigation/native' ;
3- import React , { useEffect , useMemo , useRef , useState } from 'react' ;
3+ import React , { useCallback , useEffect , useMemo , useRef , useState } from 'react' ;
44import type { FlatList } from 'react-native' ;
5- import type { OnyxCollection } from 'react-native-onyx' ;
5+ import type { OnyxCollection , OnyxEntry } from 'react-native-onyx' ;
66import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView' ;
77import DragAndDropProvider from '@components/DragAndDrop/Provider' ;
88import MoneyRequestReportView from '@components/MoneyRequestReportView/MoneyRequestReportView' ;
@@ -14,11 +14,13 @@ import useIsReportReadyToDisplay from '@hooks/useIsReportReadyToDisplay';
1414import useNetwork from '@hooks/useNetwork' ;
1515import useOnyx from '@hooks/useOnyx' ;
1616import usePaginatedReportActions from '@hooks/usePaginatedReportActions' ;
17+ import usePrevious from '@hooks/usePrevious' ;
1718import useReportIsArchived from '@hooks/useReportIsArchived' ;
1819import useResponsiveLayout from '@hooks/useResponsiveLayout' ;
1920import useThemeStyles from '@hooks/useThemeStyles' ;
2021import useTransactionsAndViolationsForReport from '@hooks/useTransactionsAndViolationsForReport' ;
2122import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID' ;
23+ import Log from '@libs/Log' ;
2224import { getAllNonDeletedTransactions } from '@libs/MoneyRequestReportUtils' ;
2325import type { PlatformStackScreenProps } from '@libs/Navigation/PlatformStackNavigation/types' ;
2426import type { RightModalNavigatorParamList } from '@libs/Navigation/types' ;
@@ -31,6 +33,7 @@ import {
3133 isMoneyRequestAction ,
3234} from '@libs/ReportActionsUtils' ;
3335import { isValidReportIDFromPath } from '@libs/ReportUtils' ;
36+ import { isDefaultAvatar , isLetterAvatar , isPresetAvatar } from '@libs/UserAvatarUtils' ;
3437import Navigation from '@navigation/Navigation' ;
3538import ReactionListWrapper from '@pages/home/ReactionListWrapper' ;
3639import { createTransactionThreadReport , openReport , updateLastVisitTime } from '@userActions/Report' ;
@@ -39,7 +42,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
3942import type { ActionListContextType , ScrollPosition } from '@src/pages/home/ReportScreenContext' ;
4043import { ActionListContext } from '@src/pages/home/ReportScreenContext' ;
4144import SCREENS from '@src/SCREENS' ;
42- import type { Policy , Transaction , TransactionViolations } from '@src/types/onyx' ;
45+ import type { PersonalDetailsList , Policy , Transaction , TransactionViolations } from '@src/types/onyx' ;
4346import { getEmptyObject } from '@src/types/utils/EmptyObject' ;
4447
4548type SearchMoneyRequestPageProps =
@@ -114,6 +117,23 @@ function SearchMoneyRequestReportPage({route}: SearchMoneyRequestPageProps) {
114117 const oneTransactionID = reportTransactions . at ( 0 ) ?. transactionID ;
115118
116119 const reportID = report ?. reportID ;
120+ const doesReportIDLookValid = isValidReportIDFromPath ( reportID ) ;
121+ const ownerAccountID = report ?. ownerAccountID ;
122+ const ownerPersonalDetailsSelector = useCallback (
123+ ( personalDetailsList : OnyxEntry < PersonalDetailsList > ) => {
124+ if ( ! ownerAccountID ) {
125+ return undefined ;
126+ }
127+
128+ return personalDetailsList ?. [ ownerAccountID ] ;
129+ } ,
130+ [ ownerAccountID ] ,
131+ ) ;
132+ const [ ownerPersonalDetails ] = useOnyx ( ONYXKEYS . PERSONAL_DETAILS_LIST , { selector : ownerPersonalDetailsSelector , canBeMissing : true } , [ ownerAccountID ] ) ;
133+ const doesOwnerHavePersonalDetails = ! ! ownerPersonalDetails ;
134+ const doesOwnerHaveAvatar = ! ! ownerPersonalDetails ?. avatar ;
135+ const doesOwnerHaveDefaultAvatar =
136+ isDefaultAvatar ( ownerPersonalDetails ?. avatar ) || isPresetAvatar ( ownerPersonalDetails ?. avatar ) || isLetterAvatar ( ownerPersonalDetails ?. originalFileName ) ;
117137
118138 // Prevents creating duplicate transaction threads for legacy transactions
119139 const hasCreatedLegacyThreadRef = useRef ( false ) ;
@@ -211,8 +231,7 @@ function SearchMoneyRequestReportPage({route}: SearchMoneyRequestPageProps) {
211231 visibleTransactions ,
212232 ] ) ;
213233
214- // eslint-disable-next-line rulesdir/no-negated-variables
215- const shouldShowNotFoundPage = useMemo (
234+ const shouldShowAccessErrorPage = useMemo (
216235 ( ) : boolean => {
217236 if ( isLoadingApp !== false ) {
218237 return false ;
@@ -222,11 +241,47 @@ function SearchMoneyRequestReportPage({route}: SearchMoneyRequestPageProps) {
222241 return true ;
223242 }
224243
225- return ! ! reportID && ! isValidReportIDFromPath ( reportID ) ;
244+ return ! ! reportID && ! doesReportIDLookValid ;
226245 } ,
246+
247+ // isLoadingApp intentionally omitted to avoid re-computing after initial load completes.
227248 // eslint-disable-next-line react-hooks/exhaustive-deps
228- [ reportID , reportMetadata ?. isLoadingInitialReportActions ] ,
249+ [ reportID , reportMetadata ?. isLoadingInitialReportActions , doesReportIDLookValid ] ,
229250 ) ;
251+ const prevShouldShowAccessErrorPage = usePrevious ( shouldShowAccessErrorPage ) ;
252+ const participantCount = Object . keys ( report ?. participants ?? { } ) . length ;
253+
254+ useEffect ( ( ) => {
255+ if ( ! shouldShowAccessErrorPage || prevShouldShowAccessErrorPage ) {
256+ return ;
257+ }
258+
259+ Log . info ( '[SearchMoneyRequestReportPage] shouldShowAccessErrorPage changed to true' , false , {
260+ reportIDFromRoute,
261+ reportID,
262+ doesReportIDLookValid,
263+ isLoadingApp,
264+ isLoadingInitialReportActions : reportMetadata ?. isLoadingInitialReportActions ,
265+ ownerAccountID,
266+ doesOwnerHavePersonalDetails,
267+ doesOwnerHaveAvatar,
268+ doesOwnerHaveDefaultAvatar,
269+ participantCount,
270+ } ) ;
271+ } , [
272+ doesOwnerHaveAvatar ,
273+ doesOwnerHaveDefaultAvatar ,
274+ doesOwnerHavePersonalDetails ,
275+ doesReportIDLookValid ,
276+ isLoadingApp ,
277+ ownerAccountID ,
278+ participantCount ,
279+ prevShouldShowAccessErrorPage ,
280+ reportID ,
281+ reportIDFromRoute ,
282+ reportMetadata ?. isLoadingInitialReportActions ,
283+ shouldShowAccessErrorPage ,
284+ ] ) ;
230285
231286 return (
232287 < WideRHPOverlayWrapper >
@@ -238,7 +293,7 @@ function SearchMoneyRequestReportPage({route}: SearchMoneyRequestPageProps) {
238293 offlineIndicatorStyle = { styles . mtAuto }
239294 >
240295 < FullPageNotFoundView
241- shouldShow = { shouldShowNotFoundPage }
296+ shouldShow = { shouldShowAccessErrorPage }
242297 subtitleKey = "notFound.noAccess"
243298 subtitleStyle = { [ styles . textSupporting ] }
244299 shouldDisplaySearchRouter
0 commit comments