Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3: React.lazy load top-level routes and Settings areas of AuthLayoutRouter #1323

Draft
wants to merge 3 commits into
base: improve-mobile-editor-performance
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 62 additions & 59 deletions src/routes/AuthLayoutRouter/AuthLayoutRouter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useRef, useState } from 'react'
import React, { Suspense, useEffect, useMemo, useRef, useState } from 'react'
import { matchPath, Redirect, Route, Switch } from 'react-router-dom'
import { useDispatch, useSelector } from 'react-redux'
import { IntercomProvider } from 'react-use-intercom'
Expand Down Expand Up @@ -30,7 +30,6 @@ import RedirectRoute from 'router/RedirectRoute'
import AllTopics from 'routes/AllTopics'
import CreateModal from 'components/CreateModal'
import GroupDetail from 'routes/GroupDetail'
import GroupSettings from 'routes/GroupSettings'
import GroupSidebar from 'routes/GroupSidebar'
import GroupWelcomeModal from 'routes/GroupWelcomeModal'
import Groups from 'routes/Groups'
Expand All @@ -55,10 +54,12 @@ import SocketListener from 'components/SocketListener'
import SocketSubscriber from 'components/SocketSubscriber'
import TopNav from './components/TopNav'

import UserSettings from 'routes/UserSettings'
import { GROUP_TYPES } from 'store/models/Group'
import './AuthLayoutRouter.scss'

const UserSettings = React.lazy(() => import('routes/UserSettings'))
const GroupSettings = React.lazy(() => import('routes/GroupSettings'))

export default function AuthLayoutRouter (props) {
const resizeRef = useRef()
const { width } = useResizeDetector({ handleHeight: false, targetRef: resizeRef })
Expand Down Expand Up @@ -275,66 +276,68 @@ export default function AuthLayoutRouter (props) {
}}
/>
<Div100vh styleName={cx('center', { 'map-view': isMapView, collapsedState, withoutNav })} id={CENTER_COLUMN_ID}>
{/* NOTE: It could be more clear to group the following switched routes by component */}
<Switch>
{/* **** Member Routes **** */}
<Route
path={`/:view(members)/:personId/${OPTIONAL_POST_MATCH}`}
render={routeProps => (
<MemberProfile {...routeProps} isSingleColumn={isSingleColumn} />
)}
/>
<Route path={`/:context(all)/:view(members)/:personId/${OPTIONAL_POST_MATCH}`} component={MemberProfile} />
{/* **** All and Public Routes **** */}
<Route path={`/:context(all|public)/:view(stream)/${OPTIONAL_POST_MATCH}`} component={Stream} />
<Route path={`/:context(all|public)/:view(projects)/${OPTIONAL_POST_MATCH}`} component={Stream} />
<Route path={`/:context(all|public)/:view(events)/${OPTIONAL_POST_MATCH}`} component={Events} />
<Route path={`/:context(all|public)/:view(map)/${OPTIONAL_POST_MATCH}`} component={MapExplorer} />
<Route path={`/:context(all|public)/:view(map)/${OPTIONAL_GROUP_MATCH}`} component={MapExplorer} />
<Route path={`/:context(public)/:view(groups)/${OPTIONAL_GROUP_MATCH}`} component={GroupExplorer} />
<Route path='/:context(all|public)/:view(topics)/:topicName' component={Stream} />
<Route path='/:context(all)/:view(topics)' component={AllTopics} />
<Route path={`/:context(all|public)/${OPTIONAL_POST_MATCH}`} component={returnDefaultRouteForGroup(currentGroup)} />
{/* **** Group Routes **** */}
<Route path={['/groups/:joinGroupSlug/join/:accessCode', '/h/use-invitation']} component={JoinGroup} />
{currentGroupLoading && (
<Route path='/:context(groups)/:groupSlug' component={Loading} />
)}
{/* When viewing a group you are not a member of show group detail page */}
{currentGroupSlug && !currentGroupMembership && (
<Suspense fallback={<Loading />}>
{/* NOTE: It could be more clear to group the following switched routes by component */}
<Switch>
{/* **** Member Routes **** */}
<Route
path='/:context(groups)/:groupSlug'
path={`/:view(members)/:personId/${OPTIONAL_POST_MATCH}`}
render={routeProps => (
<GroupDetail {...routeProps} group={currentGroup} />
<MemberProfile {...routeProps} isSingleColumn={isSingleColumn} />
)}
/>
)}
<Route path={`/:context(groups)/:groupSlug/:view(map)/${OPTIONAL_POST_MATCH}`} component={MapExplorer} />
<Route path={`/:context(groups)/:groupSlug/:view(map)/${OPTIONAL_GROUP_MATCH}`} component={MapExplorer} />
<Route path={`/:context(groups)/:groupSlug/:view(stream)/${OPTIONAL_POST_MATCH}`} component={Stream} />
<Route path={`/:context(groups)/:groupSlug/:view(explore)/${GROUP_DETAIL_MATCH}`} exact component={LandingPage} />
<Route path={`/:context(groups)/:groupSlug/:view(explore)/${OPTIONAL_POST_MATCH}`} component={LandingPage} />
<Route path={`/:context(groups)/:groupSlug/:view(projects)/${OPTIONAL_POST_MATCH}`} component={Stream} />
<Route path={`/:context(groups)/:groupSlug/:view(custom)/:customViewId/${OPTIONAL_POST_MATCH}`} component={Stream} />
<Route path={`/:context(groups)/:groupSlug/:view(events)/${OPTIONAL_POST_MATCH}`} component={Events} />
<Route path='/:context(groups)/:groupSlug/:view(groups)' component={Groups} />
<Route path='/:context(groups)/:groupSlug/:view(members)/create' component={Members} />
<Route path={`/:context(groups)/:groupSlug/:view(members)/:personId/${OPTIONAL_POST_MATCH}`} component={MemberProfile} />
<Route path='/:context(groups)/:groupSlug/:view(members)' component={Members} />
<Route path={`/:context(groups)/:groupSlug/:view(topics)/:topicName/${OPTIONAL_POST_MATCH}`} component={Stream} />
<Route path='/:context(groups)/:groupSlug/:view(topics)' component={AllTopics} />
<Route path='/:context(groups)/:groupSlug/:view(settings)' component={GroupSettings} />
<Route path={`/:context(groups)/:groupSlug/${POST_DETAIL_MATCH}`} exact component={returnDefaultRouteForGroup(currentGroup)} />
<Route path='/:context(groups)/:groupSlug' component={returnDefaultRouteForGroup(currentGroup)} />
<Route path={`/${POST_DETAIL_MATCH}`} component={PostDetail} />
{/* **** Other Routes **** */}
<Route path='/welcome' component={WelcomeWizardRouter} />
<Route path='/messages/:messageThreadId?' render={routeProps => <Messages {...routeProps} />} />
<Route path='/settings' component={UserSettings} />
<Route path='/search' component={Search} />
{/* **** Default Route (404) **** */}
<Redirect to={lastViewedGroup ? `/groups/${lastViewedGroup.slug}` : '/all'} />
</Switch>
<Route path={`/:context(all)/:view(members)/:personId/${OPTIONAL_POST_MATCH}`} component={MemberProfile} />
{/* **** All and Public Routes **** */}
<Route path={`/:context(all|public)/:view(stream)/${OPTIONAL_POST_MATCH}`} component={Stream} />
<Route path={`/:context(all|public)/:view(projects)/${OPTIONAL_POST_MATCH}`} component={Stream} />
<Route path={`/:context(all|public)/:view(events)/${OPTIONAL_POST_MATCH}`} component={Events} />
<Route path={`/:context(all|public)/:view(map)/${OPTIONAL_POST_MATCH}`} component={MapExplorer} />
<Route path={`/:context(all|public)/:view(map)/${OPTIONAL_GROUP_MATCH}`} component={MapExplorer} />
<Route path={`/:context(public)/:view(groups)/${OPTIONAL_GROUP_MATCH}`} component={GroupExplorer} />
<Route path='/:context(all|public)/:view(topics)/:topicName' component={Stream} />
<Route path='/:context(all)/:view(topics)' component={AllTopics} />
<Route path={`/:context(all|public)/${OPTIONAL_POST_MATCH}`} component={returnDefaultRouteForGroup(currentGroup)} />
{/* **** Group Routes **** */}
<Route path={['/groups/:joinGroupSlug/join/:accessCode', '/h/use-invitation']} component={JoinGroup} />
{currentGroupLoading && (
<Route path='/:context(groups)/:groupSlug' component={Loading} />
)}
{/* When viewing a group you are not a member of show group detail page */}
{currentGroupSlug && !currentGroupMembership && (
<Route
path='/:context(groups)/:groupSlug'
render={routeProps => (
<GroupDetail {...routeProps} group={currentGroup} />
)}
/>
)}
<Route path={`/:context(groups)/:groupSlug/:view(map)/${OPTIONAL_POST_MATCH}`} component={MapExplorer} />
<Route path={`/:context(groups)/:groupSlug/:view(map)/${OPTIONAL_GROUP_MATCH}`} component={MapExplorer} />
<Route path={`/:context(groups)/:groupSlug/:view(stream)/${OPTIONAL_POST_MATCH}`} component={Stream} />
<Route path={`/:context(groups)/:groupSlug/:view(explore)/${GROUP_DETAIL_MATCH}`} exact component={LandingPage} />
<Route path={`/:context(groups)/:groupSlug/:view(explore)/${OPTIONAL_POST_MATCH}`} component={LandingPage} />
<Route path={`/:context(groups)/:groupSlug/:view(projects)/${OPTIONAL_POST_MATCH}`} component={Stream} />
<Route path={`/:context(groups)/:groupSlug/:view(custom)/:customViewId/${OPTIONAL_POST_MATCH}`} component={Stream} />
<Route path={`/:context(groups)/:groupSlug/:view(events)/${OPTIONAL_POST_MATCH}`} component={Events} />
<Route path='/:context(groups)/:groupSlug/:view(groups)' component={Groups} />
<Route path='/:context(groups)/:groupSlug/:view(members)/create' component={Members} />
<Route path={`/:context(groups)/:groupSlug/:view(members)/:personId/${OPTIONAL_POST_MATCH}`} component={MemberProfile} />
<Route path='/:context(groups)/:groupSlug/:view(members)' component={Members} />
<Route path={`/:context(groups)/:groupSlug/:view(topics)/:topicName/${OPTIONAL_POST_MATCH}`} component={Stream} />
<Route path='/:context(groups)/:groupSlug/:view(topics)' component={AllTopics} />
<Route path='/:context(groups)/:groupSlug/:view(settings)' component={GroupSettings} />
<Route path={`/:context(groups)/:groupSlug/${POST_DETAIL_MATCH}`} exact component={returnDefaultRouteForGroup(currentGroup)} />
<Route path='/:context(groups)/:groupSlug' component={returnDefaultRouteForGroup(currentGroup)} />
<Route path={`/${POST_DETAIL_MATCH}`} component={PostDetail} />
{/* **** Other Routes **** */}
<Route path='/welcome' component={WelcomeWizardRouter} />
<Route path='/messages/:messageThreadId?' render={routeProps => <Messages {...routeProps} />} />
<Route path='/settings' component={UserSettings} />
<Route path='/search' component={Search} />
{/* **** Default Route (404) **** */}
<Redirect to={lastViewedGroup ? `/groups/${lastViewedGroup.slug}` : '/all'} />
</Switch>
</Suspense>
</Div100vh>
{(currentGroup && currentGroupMembership) && (
<div styleName={cx('sidebar', { hidden: (hasDetail || isMapView) })}>
Expand Down
26 changes: 15 additions & 11 deletions src/routes/RootRouter/RootRouter.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import mixpanel from 'mixpanel-browser'
import React, { useState, useEffect } from 'react'
import React, { useState, useEffect, Suspense } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { useHistory, Route, Switch } from 'react-router'
import config, { isProduction, isTest } from 'config'
import { WebViewMessageTypes } from 'hylo-shared'
import Loading from 'components/Loading'
import AuthLayoutRouter from 'routes/AuthLayoutRouter'
import PublicLayoutRouter from 'routes/PublicLayoutRouter'
import NonAuthLayoutRouter from 'routes/NonAuthLayoutRouter'
import checkLogin from 'store/actions/checkLogin'
import { getAuthorized } from 'store/selectors/getAuthState'
import { POST_DETAIL_MATCH } from 'util/navigation'
import isWebView, { sendMessageToWebView } from 'util/webView'

const AuthLayoutRouter = React.lazy(() => import('routes/AuthLayoutRouter'))
const PublicLayoutRouter = React.lazy(() => import('routes/PublicLayoutRouter'))
const NonAuthLayoutRouter = React.lazy(() => import('routes/NonAuthLayoutRouter'))

if (!isTest) {
mixpanel.init(config.mixpanel.token, { debug: !isProduction })
}
Expand Down Expand Up @@ -58,19 +59,22 @@ export default function RootRouter () {

if (isAuthorized) {
return (
<Route component={AuthLayoutRouter} />
<Suspense fallback={<Loading type='fullscreen' />}>
<Route component={AuthLayoutRouter} />
</Suspense>
)
}

if (!isAuthorized) {
// TODO: Can NonAuthLayoutRouter and PublicLayourRouter merge?
return (
<Switch>
<Route path='/post/:id' component={PublicLayoutRouter} />
<Route path='/public/groups' exact component={NonAuthLayoutRouter} />
<Route path='/public' component={PublicLayoutRouter} />
<Route path={'(.*)' + POST_DETAIL_MATCH} component={CheckPublicPost} />
<Route component={NonAuthLayoutRouter} />
<Suspense fallback={<Loading type='fullscreen' />}>
<Route path='/post/:id' component={PublicLayoutRouter} />
<Route path='/public/groups' exact component={NonAuthLayoutRouter} />
<Route path='/public' component={PublicLayoutRouter} />
<Route path={'(.*)' + POST_DETAIL_MATCH} component={CheckPublicPost} />
<Route component={NonAuthLayoutRouter} />
</Suspense>
</Switch>
)
}
Expand Down