Move SoapboxMount into a separate file
This commit is contained in:
parent
e37b24ffe3
commit
111428f46d
|
@ -0,0 +1,105 @@
|
||||||
|
import React, { Suspense } from 'react';
|
||||||
|
import { Toaster } from 'react-hot-toast';
|
||||||
|
import { BrowserRouter, Switch, Redirect, Route } from 'react-router-dom';
|
||||||
|
import { CompatRouter } from 'react-router-dom-v5-compat';
|
||||||
|
// @ts-ignore: it doesn't have types
|
||||||
|
import { ScrollContext } from 'react-router-scroll-4';
|
||||||
|
|
||||||
|
import * as BuildConfig from 'soapbox/build-config';
|
||||||
|
import LoadingScreen from 'soapbox/components/loading-screen';
|
||||||
|
import {
|
||||||
|
ModalContainer,
|
||||||
|
OnboardingWizard,
|
||||||
|
} from 'soapbox/features/ui/util/async-components';
|
||||||
|
import {
|
||||||
|
useAppSelector,
|
||||||
|
useOwnAccount,
|
||||||
|
useSoapboxConfig,
|
||||||
|
} from 'soapbox/hooks';
|
||||||
|
import { useCachedLocationHandler } from 'soapbox/utils/redirect';
|
||||||
|
|
||||||
|
import ErrorBoundary from '../components/error-boundary';
|
||||||
|
|
||||||
|
const GdprBanner = React.lazy(() => import('soapbox/components/gdpr-banner'));
|
||||||
|
const EmbeddedStatus = React.lazy(() => import('soapbox/features/embedded-status'));
|
||||||
|
const UI = React.lazy(() => import('soapbox/features/ui'));
|
||||||
|
|
||||||
|
/** Highest level node with the Redux store. */
|
||||||
|
const SoapboxMount = () => {
|
||||||
|
useCachedLocationHandler();
|
||||||
|
|
||||||
|
const me = useAppSelector(state => state.me);
|
||||||
|
const { account } = useOwnAccount();
|
||||||
|
const soapboxConfig = useSoapboxConfig();
|
||||||
|
|
||||||
|
const needsOnboarding = useAppSelector(state => state.onboarding.needsOnboarding);
|
||||||
|
const showOnboarding = account && needsOnboarding;
|
||||||
|
const { redirectRootNoLogin } = soapboxConfig;
|
||||||
|
|
||||||
|
// @ts-ignore: I don't actually know what these should be, lol
|
||||||
|
const shouldUpdateScroll = (prevRouterProps, { location }) => {
|
||||||
|
return !(location.state?.soapboxModalKey && location.state?.soapboxModalKey !== prevRouterProps?.location?.state?.soapboxModalKey);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Render the onboarding flow. */
|
||||||
|
const renderOnboarding = () => (
|
||||||
|
<Suspense fallback={<LoadingScreen />}>
|
||||||
|
<OnboardingWizard />
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Render the auth layout or UI. */
|
||||||
|
const renderSwitch = () => (
|
||||||
|
<Switch>
|
||||||
|
{(!me && redirectRootNoLogin) && (
|
||||||
|
<Redirect exact from='/' to={redirectRootNoLogin} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Route path='/' component={UI} />
|
||||||
|
</Switch>
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Render the onboarding flow or UI. */
|
||||||
|
const renderBody = () => {
|
||||||
|
if (showOnboarding) {
|
||||||
|
return renderOnboarding();
|
||||||
|
} else {
|
||||||
|
return renderSwitch();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ErrorBoundary>
|
||||||
|
<BrowserRouter basename={BuildConfig.FE_SUBDIRECTORY}>
|
||||||
|
<CompatRouter>
|
||||||
|
<ScrollContext shouldUpdateScroll={shouldUpdateScroll}>
|
||||||
|
<Switch>
|
||||||
|
<Route
|
||||||
|
path='/embed/:statusId'
|
||||||
|
render={(props) => <EmbeddedStatus params={props.match.params} />}
|
||||||
|
/>
|
||||||
|
<Redirect from='/@:username/:statusId/embed' to='/embed/:statusId' />
|
||||||
|
|
||||||
|
<Route>
|
||||||
|
{renderBody()}
|
||||||
|
|
||||||
|
<ModalContainer />
|
||||||
|
<GdprBanner />
|
||||||
|
|
||||||
|
<div id='toaster'>
|
||||||
|
<Toaster
|
||||||
|
position='top-right'
|
||||||
|
containerClassName='top-10'
|
||||||
|
containerStyle={{ top: 75 }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Route>
|
||||||
|
</Switch>
|
||||||
|
</ScrollContext>
|
||||||
|
</CompatRouter>
|
||||||
|
</BrowserRouter>
|
||||||
|
</ErrorBoundary>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SoapboxMount;
|
|
@ -1,23 +1,10 @@
|
||||||
import { QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClientProvider } from '@tanstack/react-query';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { Suspense } from 'react';
|
import React from 'react';
|
||||||
import { Toaster } from 'react-hot-toast';
|
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { BrowserRouter, Switch, Redirect, Route } from 'react-router-dom';
|
|
||||||
import { CompatRouter } from 'react-router-dom-v5-compat';
|
|
||||||
// @ts-ignore: it doesn't have types
|
|
||||||
import { ScrollContext } from 'react-router-scroll-4';
|
|
||||||
|
|
||||||
import * as BuildConfig from 'soapbox/build-config';
|
|
||||||
import LoadingScreen from 'soapbox/components/loading-screen';
|
|
||||||
import { StatProvider } from 'soapbox/contexts/stat-context';
|
import { StatProvider } from 'soapbox/contexts/stat-context';
|
||||||
import {
|
import {
|
||||||
ModalContainer,
|
|
||||||
OnboardingWizard,
|
|
||||||
} from 'soapbox/features/ui/util/async-components';
|
|
||||||
import {
|
|
||||||
useAppSelector,
|
|
||||||
useOwnAccount,
|
|
||||||
useSentry,
|
useSentry,
|
||||||
useSettings,
|
useSettings,
|
||||||
useSoapboxConfig,
|
useSoapboxConfig,
|
||||||
|
@ -26,97 +13,14 @@ import {
|
||||||
} from 'soapbox/hooks';
|
} from 'soapbox/hooks';
|
||||||
import { normalizeSoapboxConfig } from 'soapbox/normalizers';
|
import { normalizeSoapboxConfig } from 'soapbox/normalizers';
|
||||||
import { queryClient } from 'soapbox/queries/client';
|
import { queryClient } from 'soapbox/queries/client';
|
||||||
import { useCachedLocationHandler } from 'soapbox/utils/redirect';
|
|
||||||
import { generateThemeCss } from 'soapbox/utils/theme';
|
import { generateThemeCss } from 'soapbox/utils/theme';
|
||||||
|
|
||||||
import ErrorBoundary from '../components/error-boundary';
|
|
||||||
import { store } from '../store';
|
import { store } from '../store';
|
||||||
|
|
||||||
import SoapboxLoad from './soapbox-load';
|
import SoapboxLoad from './soapbox-load';
|
||||||
|
import SoapboxMount from './soapbox-mount';
|
||||||
|
|
||||||
const GdprBanner = React.lazy(() => import('soapbox/components/gdpr-banner'));
|
|
||||||
const Helmet = React.lazy(() => import('soapbox/components/helmet'));
|
const Helmet = React.lazy(() => import('soapbox/components/helmet'));
|
||||||
const EmbeddedStatus = React.lazy(() => import('soapbox/features/embedded-status'));
|
|
||||||
const UI = React.lazy(() => import('soapbox/features/ui'));
|
|
||||||
|
|
||||||
/** Highest level node with the Redux store. */
|
|
||||||
const SoapboxMount = () => {
|
|
||||||
useCachedLocationHandler();
|
|
||||||
|
|
||||||
const me = useAppSelector(state => state.me);
|
|
||||||
const { account } = useOwnAccount();
|
|
||||||
const soapboxConfig = useSoapboxConfig();
|
|
||||||
|
|
||||||
const needsOnboarding = useAppSelector(state => state.onboarding.needsOnboarding);
|
|
||||||
const showOnboarding = account && needsOnboarding;
|
|
||||||
const { redirectRootNoLogin } = soapboxConfig;
|
|
||||||
|
|
||||||
// @ts-ignore: I don't actually know what these should be, lol
|
|
||||||
const shouldUpdateScroll = (prevRouterProps, { location }) => {
|
|
||||||
return !(location.state?.soapboxModalKey && location.state?.soapboxModalKey !== prevRouterProps?.location?.state?.soapboxModalKey);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Render the onboarding flow. */
|
|
||||||
const renderOnboarding = () => (
|
|
||||||
<Suspense fallback={<LoadingScreen />}>
|
|
||||||
<OnboardingWizard />
|
|
||||||
</Suspense>
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Render the auth layout or UI. */
|
|
||||||
const renderSwitch = () => (
|
|
||||||
<Switch>
|
|
||||||
{(!me && redirectRootNoLogin) && (
|
|
||||||
<Redirect exact from='/' to={redirectRootNoLogin} />
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Route path='/' component={UI} />
|
|
||||||
</Switch>
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Render the onboarding flow or UI. */
|
|
||||||
const renderBody = () => {
|
|
||||||
if (showOnboarding) {
|
|
||||||
return renderOnboarding();
|
|
||||||
} else {
|
|
||||||
return renderSwitch();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ErrorBoundary>
|
|
||||||
<BrowserRouter basename={BuildConfig.FE_SUBDIRECTORY}>
|
|
||||||
<CompatRouter>
|
|
||||||
<ScrollContext shouldUpdateScroll={shouldUpdateScroll}>
|
|
||||||
<Switch>
|
|
||||||
<Route
|
|
||||||
path='/embed/:statusId'
|
|
||||||
render={(props) => <EmbeddedStatus params={props.match.params} />}
|
|
||||||
/>
|
|
||||||
<Redirect from='/@:username/:statusId/embed' to='/embed/:statusId' />
|
|
||||||
|
|
||||||
<Route>
|
|
||||||
{renderBody()}
|
|
||||||
|
|
||||||
<ModalContainer />
|
|
||||||
<GdprBanner />
|
|
||||||
|
|
||||||
<div id='toaster'>
|
|
||||||
<Toaster
|
|
||||||
position='top-right'
|
|
||||||
containerClassName='top-10'
|
|
||||||
containerStyle={{ top: 75 }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Route>
|
|
||||||
</Switch>
|
|
||||||
</ScrollContext>
|
|
||||||
</CompatRouter>
|
|
||||||
</BrowserRouter>
|
|
||||||
</ErrorBoundary>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
interface ISoapboxHead {
|
interface ISoapboxHead {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue