diff --git a/src/languages/en.ts b/src/languages/en.ts index b80428166fff..6ef7e74adb1a 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3003,6 +3003,10 @@ export default { offline: "You appear to be offline. Unfortunately, Expensify Classic doesn't work offline, but New Expensify does. If you prefer to use Expensify Classic, try again when you have an internet connection.", }, + listBoundary: { + errorMessage: 'There was an error loading more messages.', + tryAgain: 'Try again', + }, systemMessage: { mergedWithCashTransaction: 'matched a receipt to this transaction.', }, diff --git a/src/languages/es.ts b/src/languages/es.ts index 8ddba987d6f4..351989f5de30 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3507,6 +3507,10 @@ export default { offline: 'Parece que estás desconectado. Desafortunadamente, Expensify Classic no funciona sin conexión, pero New Expensify sí. Si prefieres utilizar Expensify Classic, inténtalo de nuevo cuando tengas conexión a internet.', }, + listBoundary: { + errorMessage: 'Se produjo un error al cargar más mensajes.', + tryAgain: 'Inténtalo de nuevo', + }, systemMessage: { mergedWithCashTransaction: 'encontró un recibo para esta transacción.', }, diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index d71664a959ed..feefd51698f6 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -746,7 +746,9 @@ function openReport( value: { isLoadingInitialReportActions: true, isLoadingOlderReportActions: false, + hasLoadingOlderReportActionsError: false, isLoadingNewerReportActions: false, + hasLoadingNewerReportActionsError: false, lastVisitTime: DateUtils.getDBTime(), }, }, @@ -1038,6 +1040,7 @@ function getOlderActions(reportID: string, reportActionID: string) { key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${reportID}`, value: { isLoadingOlderReportActions: true, + hasLoadingOlderReportActionsError: false, }, }, ]; @@ -1058,6 +1061,7 @@ function getOlderActions(reportID: string, reportActionID: string) { key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${reportID}`, value: { isLoadingOlderReportActions: false, + hasLoadingOlderReportActionsError: true, }, }, ]; @@ -1081,6 +1085,7 @@ function getNewerActions(reportID: string, reportActionID: string) { key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${reportID}`, value: { isLoadingNewerReportActions: true, + hasLoadingNewerReportActionsError: false, }, }, ]; @@ -1101,6 +1106,7 @@ function getNewerActions(reportID: string, reportActionID: string) { key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${reportID}`, value: { isLoadingNewerReportActions: false, + hasLoadingNewerReportActionsError: true, }, }, ]; diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 54e7ab923aa9..645f508a322d 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -137,7 +137,9 @@ function ReportScreen({ reportMetadata = { isLoadingInitialReportActions: true, isLoadingOlderReportActions: false, + hasLoadingOlderReportActionsError: false, isLoadingNewerReportActions: false, + hasLoadingNewerReportActionsError: false, }, parentReportActions, accountManagerReportID, @@ -709,7 +711,9 @@ function ReportScreen({ parentReportAction={parentReportAction} isLoadingInitialReportActions={reportMetadata?.isLoadingInitialReportActions} isLoadingNewerReportActions={reportMetadata?.isLoadingNewerReportActions} + hasLoadingNewerReportActionsError={reportMetadata?.hasLoadingNewerReportActionsError} isLoadingOlderReportActions={reportMetadata?.isLoadingOlderReportActions} + hasLoadingOlderReportActionsError={reportMetadata?.hasLoadingOlderReportActionsError} isReadyForCommentLinking={!shouldShowSkeleton} transactionThreadReportID={transactionThreadReportID} /> @@ -766,7 +770,9 @@ export default withCurrentReportID( initialValue: { isLoadingInitialReportActions: true, isLoadingOlderReportActions: false, + hasLoadingOlderReportActionsError: false, isLoadingNewerReportActions: false, + hasLoadingNewerReportActionsError: false, }, }, isComposerFullSize: { diff --git a/src/pages/home/report/ListBoundaryLoader.tsx b/src/pages/home/report/ListBoundaryLoader.tsx index a359606b9ed5..8081e18bb668 100644 --- a/src/pages/home/report/ListBoundaryLoader.tsx +++ b/src/pages/home/report/ListBoundaryLoader.tsx @@ -1,7 +1,10 @@ -import React from 'react'; +import React, {useEffect} from 'react'; import {ActivityIndicator, View} from 'react-native'; import type {ValueOf} from 'type-fest'; +import Button from '@components/Button'; import ReportActionsSkeletonView from '@components/ReportActionsSkeletonView'; +import Text from '@components/Text'; +import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -22,6 +25,12 @@ type ListBoundaryLoaderProps = { /** Name of the last report action */ lastReportActionName?: string; + + /** Shows if there was an error when loading report actions */ + hasError?: boolean; + + /** Function to retry if there was an error */ + onRetry?: () => void; }; function ListBoundaryLoader({ @@ -30,11 +39,47 @@ function ListBoundaryLoader({ isLoadingInitialReportActions = false, lastReportActionName = '', isLoadingNewerReportActions = false, + hasError = false, + onRetry, }: ListBoundaryLoaderProps) { const theme = useTheme(); const styles = useThemeStyles(); const {isOffline} = useNetwork(); + const {translate} = useLocalize(); + + // When retrying we want to show the loading state in the retry button so we + // have this separate state to handle that. + const [isRetrying, setIsRetrying] = React.useState(false); + + const retry = () => { + setIsRetrying(true); + onRetry?.(); + }; + + // Reset the retrying state once loading is done. + useEffect(() => { + if (isLoadingNewerReportActions || isLoadingOlderReportActions) { + return; + } + setIsRetrying(false); + }, [isLoadingNewerReportActions, isLoadingOlderReportActions]); + + if (hasError || isRetrying) { + return ( + + {translate('listBoundary.errorMessage')} + {!isOffline && ( +