diff --git a/src/CONST.ts b/src/CONST.ts index 9a6bf21db303..4f177d2294de 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -5452,6 +5452,7 @@ const CONST = { INITIAL_URL: 'INITIAL_URL', ACTIVE_WORKSPACE_ID: 'ACTIVE_WORKSPACE_ID', RETRY_LAZY_REFRESHED: 'RETRY_LAZY_REFRESHED', + LAST_REFRESH_TIMESTAMP: 'LAST_REFRESH_TIMESTAMP', }, RESERVATION_TYPE: { @@ -5785,6 +5786,9 @@ const CONST = { TAGS_ARTICLE_LINK: 'https://help.expensify.com/articles/expensify-classic/workspaces/Create-tags#import-a-spreadsheet-1', }, + // The timeout duration (1 minute) (in milliseconds) before the window reloads due to an error. + ERROR_WINDOW_RELOAD_TIMEOUT: 60000, + DEBUG: { DETAILS: 'details', JSON: 'json', diff --git a/src/hooks/usePageRefresh/index.native.ts b/src/hooks/usePageRefresh/index.native.ts new file mode 100644 index 000000000000..eb6a229ad65c --- /dev/null +++ b/src/hooks/usePageRefresh/index.native.ts @@ -0,0 +1,10 @@ +import {useErrorBoundary} from 'react-error-boundary'; +import type UsePageRefresh from './type'; + +const usePageRefresh: UsePageRefresh = () => { + const {resetBoundary} = useErrorBoundary(); + + return resetBoundary; +}; + +export default usePageRefresh; diff --git a/src/hooks/usePageRefresh/index.ts b/src/hooks/usePageRefresh/index.ts new file mode 100644 index 000000000000..3708fe29e966 --- /dev/null +++ b/src/hooks/usePageRefresh/index.ts @@ -0,0 +1,24 @@ +import differenceInMilliseconds from 'date-fns/differenceInMilliseconds'; +import {useErrorBoundary} from 'react-error-boundary'; +import CONST from '@src/CONST'; +import type UsePageRefresh from './type'; + +const usePageRefresh: UsePageRefresh = () => { + const {resetBoundary} = useErrorBoundary(); + + return () => { + const lastRefreshTimestamp = JSON.parse(sessionStorage.getItem(CONST.SESSION_STORAGE_KEYS.LAST_REFRESH_TIMESTAMP) ?? 'null') as string; + + if (lastRefreshTimestamp === null || differenceInMilliseconds(Date.now(), Number(lastRefreshTimestamp)) > CONST.ERROR_WINDOW_RELOAD_TIMEOUT) { + resetBoundary(); + sessionStorage.setItem(CONST.SESSION_STORAGE_KEYS.LAST_REFRESH_TIMESTAMP, Date.now().toString()); + + return; + } + + window.location.reload(); + sessionStorage.removeItem(CONST.SESSION_STORAGE_KEYS.LAST_REFRESH_TIMESTAMP); + }; +}; + +export default usePageRefresh; diff --git a/src/hooks/usePageRefresh/type.ts b/src/hooks/usePageRefresh/type.ts new file mode 100644 index 000000000000..f800cc0224a9 --- /dev/null +++ b/src/hooks/usePageRefresh/type.ts @@ -0,0 +1,3 @@ +type UsePageRefresh = () => () => void; + +export default UsePageRefresh; diff --git a/src/pages/ErrorPage/GenericErrorPage.tsx b/src/pages/ErrorPage/GenericErrorPage.tsx index 9f4186bc354f..0357cdc0204b 100644 --- a/src/pages/ErrorPage/GenericErrorPage.tsx +++ b/src/pages/ErrorPage/GenericErrorPage.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import {useErrorBoundary} from 'react-error-boundary'; import {View} from 'react-native'; import LogoWordmark from '@assets/images/expensify-wordmark.svg'; import Button from '@components/Button'; @@ -10,6 +9,7 @@ import SafeAreaConsumer from '@components/SafeAreaConsumer'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; +import usePageRefresh from '@hooks/usePageRefresh'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -23,8 +23,7 @@ function GenericErrorPage() { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); - - const {resetBoundary} = useErrorBoundary(); + const refreshPage = usePageRefresh(); return ( @@ -59,16 +58,16 @@ function GenericErrorPage() {