diff --git a/src/features/ui/util/react-router-helpers.tsx b/src/features/ui/util/react-router-helpers.tsx index 92bbf28b4..0487ca825 100644 --- a/src/features/ui/util/react-router-helpers.tsx +++ b/src/features/ui/util/react-router-helpers.tsx @@ -1,6 +1,6 @@ -import React, { ComponentProps, Suspense } from 'react'; -import { ErrorBoundary } from 'react-error-boundary'; -import { Redirect, Route, useHistory, RouteProps, RouteComponentProps, match as MatchType } from 'react-router-dom'; +import React, { Suspense, useEffect, useRef } from 'react'; +import { ErrorBoundary, type FallbackProps } from 'react-error-boundary'; +import { Redirect, Route, useHistory, RouteProps, RouteComponentProps, match as MatchType, useLocation } from 'react-router-dom'; import { Layout } from 'soapbox/components/ui'; import { useOwnAccount, useSettings } from 'soapbox/hooks'; @@ -48,8 +48,8 @@ const WrappedRoute: React.FC = ({ const renderComponent = ({ match }: RouteComponentProps) => { if (Page) { return ( - - + + }> {content} @@ -61,8 +61,8 @@ const WrappedRoute: React.FC = ({ } return ( - - + + }> {content} @@ -73,20 +73,6 @@ const WrappedRoute: React.FC = ({ ); }; - const renderWithLayout = (children: JSX.Element) => ( - <> - - {children} - - - - - ); - - const renderLoading = () => renderWithLayout(); - const renderForbidden = () => renderWithLayout(); - const renderError = (props: ComponentProps) => renderWithLayout(); - const loginRedirect = () => { const actualUrl = encodeURIComponent(`${history.location.pathname}${history.location.search}`); localStorage.setItem('soapbox:redirect_uri', actualUrl); @@ -104,13 +90,58 @@ const WrappedRoute: React.FC = ({ if (!account) { return loginRedirect(); } else { - return renderForbidden(); + return ; } } return ; }; +interface IFallbackLayout { + children: JSX.Element; +} + +const FallbackLayout: React.FC = ({ children }) => ( + <> + + {children} + + + + +); + +const FallbackLoading: React.FC = () => ( + + + +); + +const FallbackForbidden: React.FC = () => ( + + + +); + +const FallbackError: React.FC = ({ error, resetErrorBoundary }) => { + const location = useLocation(); + const firstUpdate = useRef(true); + + useEffect(() => { + if (firstUpdate.current) { + firstUpdate.current = false; + } else { + resetErrorBoundary(); + } + }, [location]); + + return ( + + + + ); +}; + export { WrappedRoute, };