Add async loading of react pages

This commit is contained in:
Bill Thornton 2022-10-31 10:17:20 -04:00
parent 41c07d807b
commit 20c33381f9
3 changed files with 112 additions and 27 deletions

72
package-lock.json generated
View file

@ -17,6 +17,7 @@
"@fontsource/noto-sans-tc": "4.5.12",
"@jellyfin/libass-wasm": "4.1.1",
"@jellyfin/sdk": "0.7.0",
"@loadable/component": "5.15.2",
"blurhash": "2.0.3",
"classlist.js": "https://github.com/eligrey/classList.js/archive/1.2.20180112.tar.gz",
"classnames": "2.3.2",
@ -63,6 +64,7 @@
"@babel/preset-react": "7.18.6",
"@babel/preset-typescript": "7.18.6",
"@types/escape-html": "1.0.2",
"@types/loadable__component": "5.13.4",
"@types/lodash-es": "4.17.6",
"@types/react": "17.0.51",
"@types/react-dom": "17.0.17",
@ -2479,6 +2481,26 @@
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
"dev": true
},
"node_modules/@loadable/component": {
"version": "5.15.2",
"resolved": "https://registry.npmjs.org/@loadable/component/-/component-5.15.2.tgz",
"integrity": "sha512-ryFAZOX5P2vFkUdzaAtTG88IGnr9qxSdvLRvJySXcUA4B4xVWurUNADu3AnKPksxOZajljqTrDEDcYjeL4lvLw==",
"dependencies": {
"@babel/runtime": "^7.7.7",
"hoist-non-react-statics": "^3.3.1",
"react-is": "^16.12.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"react": ">=16.3.0"
}
},
"node_modules/@mdn/browser-compat-data": {
"version": "4.1.8",
"resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.1.8.tgz",
@ -2780,6 +2802,15 @@
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true
},
"node_modules/@types/loadable__component": {
"version": "5.13.4",
"resolved": "https://registry.npmjs.org/@types/loadable__component/-/loadable__component-5.13.4.tgz",
"integrity": "sha512-YhoCCxyuvP2XeZNbHbi8Wb9EMaUJuA2VGHxJffcQYrJKIKSkymJrhbzsf9y4zpTmr5pExAAEh5hbF628PAZ8Dg==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/lodash": {
"version": "4.14.178",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz",
@ -8154,6 +8185,14 @@
"url-toolkit": "^2.1.6"
}
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"dependencies": {
"react-is": "^16.7.0"
}
},
"node_modules/hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
@ -12674,8 +12713,7 @@
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-router": {
"version": "6.4.2",
@ -20392,6 +20430,16 @@
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
"dev": true
},
"@loadable/component": {
"version": "5.15.2",
"resolved": "https://registry.npmjs.org/@loadable/component/-/component-5.15.2.tgz",
"integrity": "sha512-ryFAZOX5P2vFkUdzaAtTG88IGnr9qxSdvLRvJySXcUA4B4xVWurUNADu3AnKPksxOZajljqTrDEDcYjeL4lvLw==",
"requires": {
"@babel/runtime": "^7.7.7",
"hoist-non-react-statics": "^3.3.1",
"react-is": "^16.12.0"
}
},
"@mdn/browser-compat-data": {
"version": "4.1.8",
"resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.1.8.tgz",
@ -20649,6 +20697,15 @@
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true
},
"@types/loadable__component": {
"version": "5.13.4",
"resolved": "https://registry.npmjs.org/@types/loadable__component/-/loadable__component-5.13.4.tgz",
"integrity": "sha512-YhoCCxyuvP2XeZNbHbi8Wb9EMaUJuA2VGHxJffcQYrJKIKSkymJrhbzsf9y4zpTmr5pExAAEh5hbF628PAZ8Dg==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/lodash": {
"version": "4.14.178",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz",
@ -24725,6 +24782,14 @@
"url-toolkit": "^2.1.6"
}
},
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"requires": {
"react-is": "^16.7.0"
}
},
"hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
@ -27943,8 +28008,7 @@
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"react-router": {
"version": "6.4.2",

View file

@ -15,6 +15,7 @@
"@babel/preset-react": "7.18.6",
"@babel/preset-typescript": "7.18.6",
"@types/escape-html": "1.0.2",
"@types/loadable__component": "5.13.4",
"@types/lodash-es": "4.17.6",
"@types/react": "17.0.51",
"@types/react-dom": "17.0.17",
@ -75,6 +76,7 @@
"@fontsource/noto-sans-tc": "4.5.12",
"@jellyfin/libass-wasm": "4.1.1",
"@jellyfin/sdk": "0.7.0",
"@loadable/component": "5.15.2",
"blurhash": "2.0.3",
"classlist.js": "https://github.com/eligrey/classList.js/archive/1.2.20180112.tar.gz",
"classnames": "2.3.2",

View file

@ -1,47 +1,66 @@
import loadable from '@loadable/component';
import React from 'react';
import { Navigate, Route, Routes } from 'react-router-dom';
import ConnectionRequired from '../components/ConnectionRequired';
import ServerContentPage from '../components/ServerContentPage';
import { LEGACY_ADMIN_ROUTES, LEGACY_USER_ROUTES, toViewManagerPageRoute } from './legacyRoutes';
import UserNew from './user/usernew';
import Search from './search';
import UserEdit from './user/useredit';
import UserLibraryAccess from './user/userlibraryaccess';
import UserParentalControl from './user/userparentalcontrol';
import UserPassword from './user/userpassword';
import UserProfile from './user/userprofile';
import UserProfiles from './user/userprofiles';
import Home from './home';
import Movies from './movies';
interface AsyncPageProps {
page: string
}
const AsyncPage = loadable(
(props: AsyncPageProps) => import(/* webpackChunkName: "[request]" */ `./${props.page}`),
{ cacheKey: (props: AsyncPageProps) => props.page }
);
interface AsyncRoute {
path: string
page: string
}
const toAsyncPageRoute = (route: AsyncRoute) => (
<Route
key={route.path}
path={route.path}
element={<AsyncPage page={route.page} />}
/>
);
const USER_ROUTES: AsyncRoute[] = [
{ path: 'search.html', page: 'search' },
{ path: 'userprofile.html', page: 'user/userprofile' },
{ path: 'home.html', page: 'home' },
{ path: 'movies.html', page: 'movies' }
];
const ADMIN_ROUTES: AsyncRoute[] = [
{ path: 'usernew.html', page: 'user/usernew' },
{ path: 'userprofiles.html', page: 'user/userprofiles' },
{ path: 'useredit.html', page: 'user/useredit' },
{ path: 'userlibraryaccess.html', page: 'user/userlibraryaccess' },
{ path: 'userparentalcontrol.html', page: 'user/userparentalcontrol' },
{ path: 'userpassword.html', page: 'user/userpassword' }
];
const AppRoutes = () => (
<Routes>
<Route path='/'>
{/* User routes */}
<Route path='/' element={<ConnectionRequired />}>
<Route path='search.html' element={<Search />} />
<Route path='userprofile.html' element={<UserProfile />} />
<Route path='home.html' element={<Home />} />
<Route path='movies.html' element={<Movies />} />
{USER_ROUTES.map(toAsyncPageRoute)}
{LEGACY_USER_ROUTES.map(toViewManagerPageRoute)}
</Route>
{/* Admin routes */}
<Route path='/' element={<ConnectionRequired isAdminRequired />}>
<Route path='usernew.html' element={<UserNew />} />
<Route path='userprofiles.html' element={<UserProfiles />} />
<Route path='useredit.html' element={<UserEdit />} />
<Route path='userlibraryaccess.html' element={<UserLibraryAccess />} />
<Route path='userparentalcontrol.html' element={<UserParentalControl />} />
<Route path='userpassword.html' element={<UserPassword />} />
{ADMIN_ROUTES.map(toAsyncPageRoute)}
{LEGACY_ADMIN_ROUTES.map(toViewManagerPageRoute)}
<Route path='configurationpage' element={
<ServerContentPage view='/web/configurationpage' />
} />
{LEGACY_ADMIN_ROUTES.map(toViewManagerPageRoute)}
</Route>
{/* Public routes */}