mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge pull request #6472 from thornbill/refactor-app-type
Refactor app type
This commit is contained in:
commit
094c0eee8f
7 changed files with 73 additions and 37 deletions
|
@ -1,16 +1,17 @@
|
||||||
import { AsyncRouteType, type AsyncRoute } from 'components/router/AsyncRoute';
|
import type { AsyncRoute } from 'components/router/AsyncRoute';
|
||||||
|
import { AppType } from 'constants/appType';
|
||||||
|
|
||||||
export const ASYNC_ADMIN_ROUTES: AsyncRoute[] = [
|
export const ASYNC_ADMIN_ROUTES: AsyncRoute[] = [
|
||||||
{ path: 'activity', type: AsyncRouteType.Dashboard },
|
{ path: 'activity', type: AppType.Dashboard },
|
||||||
{ path: 'branding', type: AsyncRouteType.Dashboard },
|
{ path: 'branding', type: AppType.Dashboard },
|
||||||
{ path: 'keys', type: AsyncRouteType.Dashboard },
|
{ path: 'keys', type: AppType.Dashboard },
|
||||||
{ path: 'logs', type: AsyncRouteType.Dashboard },
|
{ path: 'logs', type: AppType.Dashboard },
|
||||||
{ path: 'playback/trickplay', type: AsyncRouteType.Dashboard },
|
{ path: 'playback/trickplay', type: AppType.Dashboard },
|
||||||
{ path: 'plugins/:pluginId', page: 'plugins/plugin', type: AsyncRouteType.Dashboard },
|
{ path: 'plugins/:pluginId', page: 'plugins/plugin', type: AppType.Dashboard },
|
||||||
{ path: 'users', type: AsyncRouteType.Dashboard },
|
{ path: 'users', type: AppType.Dashboard },
|
||||||
{ path: 'users/access', type: AsyncRouteType.Dashboard },
|
{ path: 'users/access', type: AppType.Dashboard },
|
||||||
{ path: 'users/add', type: AsyncRouteType.Dashboard },
|
{ path: 'users/add', type: AppType.Dashboard },
|
||||||
{ path: 'users/parentalcontrol', type: AsyncRouteType.Dashboard },
|
{ path: 'users/parentalcontrol', type: AppType.Dashboard },
|
||||||
{ path: 'users/password', type: AsyncRouteType.Dashboard },
|
{ path: 'users/password', type: AppType.Dashboard },
|
||||||
{ path: 'users/profile', type: AsyncRouteType.Dashboard }
|
{ path: 'users/profile', type: AppType.Dashboard }
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,129 +1,151 @@
|
||||||
import type { LegacyRoute } from 'components/router/LegacyRoute';
|
import type { LegacyRoute } from 'components/router/LegacyRoute';
|
||||||
|
import { AppType } from 'constants/appType';
|
||||||
|
|
||||||
export const LEGACY_ADMIN_ROUTES: LegacyRoute[] = [
|
export const LEGACY_ADMIN_ROUTES: LegacyRoute[] = [
|
||||||
{
|
{
|
||||||
path: '/dashboard',
|
path: '/dashboard',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/dashboard',
|
controller: 'dashboard/dashboard',
|
||||||
view: 'dashboard/dashboard.html'
|
view: 'dashboard/dashboard.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'settings',
|
path: 'settings',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/general',
|
controller: 'dashboard/general',
|
||||||
view: 'dashboard/general.html'
|
view: 'dashboard/general.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'networking',
|
path: 'networking',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/networking',
|
controller: 'dashboard/networking',
|
||||||
view: 'dashboard/networking.html'
|
view: 'dashboard/networking.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'devices',
|
path: 'devices',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/devices/devices',
|
controller: 'dashboard/devices/devices',
|
||||||
view: 'dashboard/devices/devices.html'
|
view: 'dashboard/devices/devices.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'devices/edit',
|
path: 'devices/edit',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/devices/device',
|
controller: 'dashboard/devices/device',
|
||||||
view: 'dashboard/devices/device.html'
|
view: 'dashboard/devices/device.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'libraries',
|
path: 'libraries',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/library',
|
controller: 'dashboard/library',
|
||||||
view: 'dashboard/library.html'
|
view: 'dashboard/library.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'libraries/display',
|
path: 'libraries/display',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/librarydisplay',
|
controller: 'dashboard/librarydisplay',
|
||||||
view: 'dashboard/librarydisplay.html'
|
view: 'dashboard/librarydisplay.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'playback/transcoding',
|
path: 'playback/transcoding',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/encodingsettings',
|
controller: 'dashboard/encodingsettings',
|
||||||
view: 'dashboard/encodingsettings.html'
|
view: 'dashboard/encodingsettings.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'libraries/metadata',
|
path: 'libraries/metadata',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/metadataImages',
|
controller: 'dashboard/metadataImages',
|
||||||
view: 'dashboard/metadataimages.html'
|
view: 'dashboard/metadataimages.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'libraries/nfo',
|
path: 'libraries/nfo',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/metadatanfo',
|
controller: 'dashboard/metadatanfo',
|
||||||
view: 'dashboard/metadatanfo.html'
|
view: 'dashboard/metadatanfo.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'playback/resume',
|
path: 'playback/resume',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/playback',
|
controller: 'dashboard/playback',
|
||||||
view: 'dashboard/playback.html'
|
view: 'dashboard/playback.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'plugins/catalog',
|
path: 'plugins/catalog',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/plugins/available/index',
|
controller: 'dashboard/plugins/available/index',
|
||||||
view: 'dashboard/plugins/available/index.html'
|
view: 'dashboard/plugins/available/index.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'plugins/repositories',
|
path: 'plugins/repositories',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/plugins/repositories/index',
|
controller: 'dashboard/plugins/repositories/index',
|
||||||
view: 'dashboard/plugins/repositories/index.html'
|
view: 'dashboard/plugins/repositories/index.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'livetv/guide',
|
path: 'livetv/guide',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'livetvguideprovider',
|
controller: 'livetvguideprovider',
|
||||||
view: 'livetvguideprovider.html'
|
view: 'livetvguideprovider.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'recordings',
|
path: 'recordings',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'livetvsettings',
|
controller: 'livetvsettings',
|
||||||
view: 'livetvsettings.html'
|
view: 'livetvsettings.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'livetv',
|
path: 'livetv',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'livetvstatus',
|
controller: 'livetvstatus',
|
||||||
view: 'livetvstatus.html'
|
view: 'livetvstatus.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'livetv/tuner',
|
path: 'livetv/tuner',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'livetvtuner',
|
controller: 'livetvtuner',
|
||||||
view: 'livetvtuner.html'
|
view: 'livetvtuner.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'plugins',
|
path: 'plugins',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/plugins/installed/index',
|
controller: 'dashboard/plugins/installed/index',
|
||||||
view: 'dashboard/plugins/installed/index.html'
|
view: 'dashboard/plugins/installed/index.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'tasks/edit',
|
path: 'tasks/edit',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/scheduledtasks/scheduledtask',
|
controller: 'dashboard/scheduledtasks/scheduledtask',
|
||||||
view: 'dashboard/scheduledtasks/scheduledtask.html'
|
view: 'dashboard/scheduledtasks/scheduledtask.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'tasks',
|
path: 'tasks',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
controller: 'dashboard/scheduledtasks/scheduledtasks',
|
controller: 'dashboard/scheduledtasks/scheduledtasks',
|
||||||
view: 'dashboard/scheduledtasks/scheduledtasks.html'
|
view: 'dashboard/scheduledtasks/scheduledtasks.html'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
path: 'playback/streaming',
|
path: 'playback/streaming',
|
||||||
pageProps: {
|
pageProps: {
|
||||||
|
appType: AppType.Dashboard,
|
||||||
view: 'dashboard/streaming.html',
|
view: 'dashboard/streaming.html',
|
||||||
controller: 'dashboard/streaming'
|
controller: 'dashboard/streaming'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { RouteObject } from 'react-router-dom';
|
import { RouteObject } from 'react-router-dom';
|
||||||
|
|
||||||
import ConnectionRequired from 'components/ConnectionRequired';
|
import ConnectionRequired from 'components/ConnectionRequired';
|
||||||
import { ASYNC_ADMIN_ROUTES } from './_asyncRoutes';
|
import { ASYNC_ADMIN_ROUTES } from './_asyncRoutes';
|
||||||
import { toAsyncPageRoute } from 'components/router/AsyncRoute';
|
import { toAsyncPageRoute } from 'components/router/AsyncRoute';
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import { AsyncRoute, AsyncRouteType } from '../../../../components/router/AsyncRoute';
|
import { AsyncRoute } from 'components/router/AsyncRoute';
|
||||||
|
import { AppType } from 'constants/appType';
|
||||||
|
|
||||||
export const ASYNC_USER_ROUTES: AsyncRoute[] = [
|
export const ASYNC_USER_ROUTES: AsyncRoute[] = [
|
||||||
{ path: 'home.html', page: 'home', type: AsyncRouteType.Experimental },
|
{ path: 'home.html', page: 'home', type: AppType.Experimental },
|
||||||
{ path: 'quickconnect', page: 'quickConnect' },
|
{ path: 'quickconnect', page: 'quickConnect' },
|
||||||
{ path: 'search.html', page: 'search' },
|
{ path: 'search.html', page: 'search' },
|
||||||
{ path: 'userprofile.html', page: 'user/userprofile' },
|
{ path: 'userprofile.html', page: 'user/userprofile' },
|
||||||
{ path: 'movies.html', page: 'movies', type: AsyncRouteType.Experimental },
|
{ path: 'movies.html', page: 'movies', type: AppType.Experimental },
|
||||||
{ path: 'tv.html', page: 'shows', type: AsyncRouteType.Experimental },
|
{ path: 'tv.html', page: 'shows', type: AppType.Experimental },
|
||||||
{ path: 'music.html', page: 'music', type: AsyncRouteType.Experimental },
|
{ path: 'music.html', page: 'music', type: AppType.Experimental },
|
||||||
{ path: 'livetv.html', page: 'livetv', type: AsyncRouteType.Experimental },
|
{ path: 'livetv.html', page: 'livetv', type: AppType.Experimental },
|
||||||
{ path: 'mypreferencesdisplay.html', page: 'user/display', type: AsyncRouteType.Experimental },
|
{ path: 'mypreferencesdisplay.html', page: 'user/display', type: AppType.Experimental },
|
||||||
|
{ path: 'homevideos.html', page: 'homevideos', type: AppType.Experimental }
|
||||||
{ path: 'homevideos.html', page: 'homevideos', type: AsyncRouteType.Experimental }
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
import type { RouteObject } from 'react-router-dom';
|
import type { RouteObject } from 'react-router-dom';
|
||||||
|
|
||||||
export enum AsyncRouteType {
|
import { AppType } from 'constants/appType';
|
||||||
Stable,
|
|
||||||
Experimental,
|
|
||||||
Dashboard
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AsyncRoute {
|
export interface AsyncRoute {
|
||||||
/** The URL path for this route. */
|
/** The URL path for this route. */
|
||||||
|
@ -14,17 +10,17 @@ export interface AsyncRoute {
|
||||||
* Will fallback to using the `path` value if not specified.
|
* Will fallback to using the `path` value if not specified.
|
||||||
*/
|
*/
|
||||||
page?: string
|
page?: string
|
||||||
/** The page type used to load the correct page element. */
|
/** The app that this page is part of. */
|
||||||
type?: AsyncRouteType
|
type?: AppType
|
||||||
}
|
}
|
||||||
|
|
||||||
const importRoute = (page: string, type: AsyncRouteType) => {
|
const importRoute = (page: string, type: AppType) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AsyncRouteType.Dashboard:
|
case AppType.Dashboard:
|
||||||
return import(/* webpackChunkName: "[request]" */ `../../apps/dashboard/routes/${page}`);
|
return import(/* webpackChunkName: "[request]" */ `../../apps/dashboard/routes/${page}`);
|
||||||
case AsyncRouteType.Experimental:
|
case AppType.Experimental:
|
||||||
return import(/* webpackChunkName: "[request]" */ `../../apps/experimental/routes/${page}`);
|
return import(/* webpackChunkName: "[request]" */ `../../apps/experimental/routes/${page}`);
|
||||||
case AsyncRouteType.Stable:
|
case AppType.Stable:
|
||||||
return import(/* webpackChunkName: "[request]" */ `../../apps/stable/routes/${page}`);
|
return import(/* webpackChunkName: "[request]" */ `../../apps/stable/routes/${page}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -32,7 +28,7 @@ const importRoute = (page: string, type: AsyncRouteType) => {
|
||||||
export const toAsyncPageRoute = ({
|
export const toAsyncPageRoute = ({
|
||||||
path,
|
path,
|
||||||
page,
|
page,
|
||||||
type = AsyncRouteType.Stable
|
type = AppType.Stable
|
||||||
}: AsyncRoute): RouteObject => {
|
}: AsyncRoute): RouteObject => {
|
||||||
return {
|
return {
|
||||||
path,
|
path,
|
||||||
|
|
|
@ -6,8 +6,10 @@ import globalize from 'lib/globalize';
|
||||||
import type { RestoreViewFailResponse } from 'types/viewManager';
|
import type { RestoreViewFailResponse } from 'types/viewManager';
|
||||||
|
|
||||||
import viewManager from './viewManager';
|
import viewManager from './viewManager';
|
||||||
|
import { AppType } from 'constants/appType';
|
||||||
|
|
||||||
export interface ViewManagerPageProps {
|
export interface ViewManagerPageProps {
|
||||||
|
appType?: AppType
|
||||||
controller: string
|
controller: string
|
||||||
view: string
|
view: string
|
||||||
type?: string
|
type?: string
|
||||||
|
@ -31,7 +33,12 @@ interface ViewOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadView = async (controller: string, view: string, viewOptions: ViewOptions) => {
|
const loadView = async (
|
||||||
|
appType: AppType,
|
||||||
|
controller: string,
|
||||||
|
view: string,
|
||||||
|
viewOptions: ViewOptions
|
||||||
|
) => {
|
||||||
const [ controllerFactory, viewHtml ] = await Promise.all([
|
const [ controllerFactory, viewHtml ] = await Promise.all([
|
||||||
import(/* webpackChunkName: "[request]" */ `../../controllers/${controller}`),
|
import(/* webpackChunkName: "[request]" */ `../../controllers/${controller}`),
|
||||||
import(/* webpackChunkName: "[request]" */ `../../controllers/${view}`)
|
import(/* webpackChunkName: "[request]" */ `../../controllers/${view}`)
|
||||||
|
@ -50,6 +57,7 @@ const loadView = async (controller: string, view: string, viewOptions: ViewOptio
|
||||||
* NOTE: Any new pages should use the generic Page component instead.
|
* NOTE: Any new pages should use the generic Page component instead.
|
||||||
*/
|
*/
|
||||||
const ViewManagerPage: FunctionComponent<ViewManagerPageProps> = ({
|
const ViewManagerPage: FunctionComponent<ViewManagerPageProps> = ({
|
||||||
|
appType = AppType.Stable,
|
||||||
controller,
|
controller,
|
||||||
view,
|
view,
|
||||||
type,
|
type,
|
||||||
|
@ -78,7 +86,7 @@ const ViewManagerPage: FunctionComponent<ViewManagerPageProps> = ({
|
||||||
|
|
||||||
if (navigationType !== Action.Pop) {
|
if (navigationType !== Action.Pop) {
|
||||||
console.debug('[ViewManagerPage] loading view [%s]', view);
|
console.debug('[ViewManagerPage] loading view [%s]', view);
|
||||||
return loadView(controller, view, viewOptions);
|
return loadView(appType, controller, view, viewOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.debug('[ViewManagerPage] restoring view [%s]', view);
|
console.debug('[ViewManagerPage] restoring view [%s]', view);
|
||||||
|
@ -86,7 +94,7 @@ const ViewManagerPage: FunctionComponent<ViewManagerPageProps> = ({
|
||||||
.catch(async (result?: RestoreViewFailResponse) => {
|
.catch(async (result?: RestoreViewFailResponse) => {
|
||||||
if (!result?.cancelled) {
|
if (!result?.cancelled) {
|
||||||
console.debug('[ViewManagerPage] restore failed; loading view [%s]', view);
|
console.debug('[ViewManagerPage] restore failed; loading view [%s]', view);
|
||||||
return loadView(controller, view, viewOptions);
|
return loadView(appType, controller, view, viewOptions);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
8
src/constants/appType.ts
Normal file
8
src/constants/appType.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* App types represented in src/apps.
|
||||||
|
*/
|
||||||
|
export enum AppType {
|
||||||
|
Dashboard = 'dashboard',
|
||||||
|
Experimental = 'experimental',
|
||||||
|
Stable = 'stable'
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue