diff --git a/src/App.tsx b/src/App.tsx
index b92a1c6b5a..13ae93dec0 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -3,13 +3,14 @@ import React from 'react';
import { HistoryRouter } from './components/HistoryRouter';
import { ApiProvider } from './hooks/useApi';
-import { AppRoutes } from './routes';
+import { AppRoutes, ExperimentalAppRoutes } from './routes';
const App = ({ history }: { history: History }) => {
+ const layoutMode = localStorage.getItem('layout');
return (
-
+ {layoutMode === 'experimental' ? : }
);
diff --git a/src/routes/experimentalAppRoutes/asyncRoutes/admin.ts b/src/routes/experimentalAppRoutes/asyncRoutes/admin.ts
new file mode 100644
index 0000000000..3c75058288
--- /dev/null
+++ b/src/routes/experimentalAppRoutes/asyncRoutes/admin.ts
@@ -0,0 +1,10 @@
+import { AsyncRoute } from '../../AsyncRoute';
+
+export const ASYNC_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' }
+];
diff --git a/src/routes/experimentalAppRoutes/asyncRoutes/user.ts b/src/routes/experimentalAppRoutes/asyncRoutes/user.ts
new file mode 100644
index 0000000000..7126b0f2ad
--- /dev/null
+++ b/src/routes/experimentalAppRoutes/asyncRoutes/user.ts
@@ -0,0 +1,8 @@
+import { AsyncRoute } from '../../AsyncRoute';
+
+export const ASYNC_USER_ROUTES: AsyncRoute[] = [
+ { path: 'search.html', page: 'search' },
+ { path: 'userprofile.html', page: 'user/userprofile' },
+ { path: 'home.html', page: 'home' },
+ { path: 'movies.html', page: 'movies' }
+];
diff --git a/src/routes/experimentalAppRoutes/index.tsx b/src/routes/experimentalAppRoutes/index.tsx
new file mode 100644
index 0000000000..47b9ec7e54
--- /dev/null
+++ b/src/routes/experimentalAppRoutes/index.tsx
@@ -0,0 +1,44 @@
+import React from 'react';
+import { Navigate, Route, Routes } from 'react-router-dom';
+
+import ConnectionRequired from '../../components/ConnectionRequired';
+import ServerContentPage from '../../components/ServerContentPage';
+import { toAsyncPageRoute } from '../AsyncRoute';
+import { toViewManagerPageRoute } from '../LegacyRoute';
+import { ASYNC_ADMIN_ROUTES } from './asyncRoutes/admin';
+import { ASYNC_USER_ROUTES } from './asyncRoutes/user';
+import { LEGACY_ADMIN_ROUTES } from './legacyRoutes/admin';
+import { LEGACY_PUBLIC_ROUTES } from './legacyRoutes/public';
+import { LEGACY_USER_ROUTES } from './legacyRoutes/user';
+
+export const ExperimentalAppRoutes = () => (
+
+
+ {/* User routes */}
+ }>
+ {ASYNC_USER_ROUTES.map(toAsyncPageRoute)}
+ {LEGACY_USER_ROUTES.map(toViewManagerPageRoute)}
+
+
+ {/* Admin routes */}
+ }>
+ {ASYNC_ADMIN_ROUTES.map(toAsyncPageRoute)}
+ {LEGACY_ADMIN_ROUTES.map(toViewManagerPageRoute)}
+
+
+ } />
+
+
+ {/* Public routes */}
+ }>
+ } />
+
+ {LEGACY_PUBLIC_ROUTES.map(toViewManagerPageRoute)}
+
+
+ {/* Suppress warnings for unhandled routes */}
+
+
+
+);
diff --git a/src/routes/experimentalAppRoutes/legacyRoutes/admin.ts b/src/routes/experimentalAppRoutes/legacyRoutes/admin.ts
new file mode 100644
index 0000000000..16365e4fc8
--- /dev/null
+++ b/src/routes/experimentalAppRoutes/legacyRoutes/admin.ts
@@ -0,0 +1,197 @@
+import { LegacyRoute } from '../../LegacyRoute';
+
+export const LEGACY_ADMIN_ROUTES: LegacyRoute[] = [
+ {
+ path: 'dashboard.html',
+ pageProps: {
+ controller: 'dashboard/dashboard',
+ view: 'dashboard/dashboard.html'
+ }
+ }, {
+ path: 'dashboardgeneral.html',
+ pageProps: {
+ controller: 'dashboard/general',
+ view: 'dashboard/general.html'
+ }
+ }, {
+ path: 'networking.html',
+ pageProps: {
+ controller: 'dashboard/networking',
+ view: 'dashboard/networking.html'
+ }
+ }, {
+ path: 'devices.html',
+ pageProps: {
+ controller: 'dashboard/devices/devices',
+ view: 'dashboard/devices/devices.html'
+ }
+ }, {
+ path: 'device.html',
+ pageProps: {
+ controller: 'dashboard/devices/device',
+ view: 'dashboard/devices/device.html'
+ }
+ }, {
+ path: 'quickConnect.html',
+ pageProps: {
+ controller: 'dashboard/quickConnect',
+ view: 'dashboard/quickConnect.html'
+ }
+ }, {
+ path: 'dlnaprofile.html',
+ pageProps: {
+ controller: 'dashboard/dlna/profile',
+ view: 'dashboard/dlna/profile.html'
+ }
+ }, {
+ path: 'dlnaprofiles.html',
+ pageProps: {
+ controller: 'dashboard/dlna/profiles',
+ view: 'dashboard/dlna/profiles.html'
+ }
+ }, {
+ path: 'dlnasettings.html',
+ pageProps: {
+ controller: 'dashboard/dlna/settings',
+ view: 'dashboard/dlna/settings.html'
+ }
+ }, {
+ path: 'addplugin.html',
+ pageProps: {
+ controller: 'dashboard/plugins/add/index',
+ view: 'dashboard/plugins/add/index.html'
+ }
+ }, {
+ path: 'library.html',
+ pageProps: {
+ controller: 'dashboard/library',
+ view: 'dashboard/library.html'
+ }
+ }, {
+ path: 'librarydisplay.html',
+ pageProps: {
+ controller: 'dashboard/librarydisplay',
+ view: 'dashboard/librarydisplay.html'
+ }
+ }, {
+ path: 'edititemmetadata.html',
+ pageProps: {
+ controller: 'edititemmetadata',
+ view: 'edititemmetadata.html'
+ }
+ }, {
+ path: 'encodingsettings.html',
+ pageProps: {
+ controller: 'dashboard/encodingsettings',
+ view: 'dashboard/encodingsettings.html'
+ }
+ }, {
+ path: 'log.html',
+ pageProps: {
+ controller: 'dashboard/logs',
+ view: 'dashboard/logs.html'
+ }
+ }, {
+ path: 'metadataimages.html',
+ pageProps: {
+ controller: 'dashboard/metadataImages',
+ view: 'dashboard/metadataimages.html'
+ }
+ }, {
+ path: 'metadatanfo.html',
+ pageProps: {
+ controller: 'dashboard/metadatanfo',
+ view: 'dashboard/metadatanfo.html'
+ }
+ }, {
+ path: 'notificationsetting.html',
+ pageProps: {
+ controller: 'dashboard/notifications/notification/index',
+ view: 'dashboard/notifications/notification/index.html'
+ }
+ }, {
+ path: 'notificationsettings.html',
+ pageProps: {
+ controller: 'dashboard/notifications/notifications/index',
+ view: 'dashboard/notifications/notifications/index.html'
+ }
+ }, {
+ path: 'playbackconfiguration.html',
+ pageProps: {
+ controller: 'dashboard/playback',
+ view: 'dashboard/playback.html'
+ }
+ }, {
+ path: 'availableplugins.html',
+ pageProps: {
+ controller: 'dashboard/plugins/available/index',
+ view: 'dashboard/plugins/available/index.html'
+ }
+ }, {
+ path: 'repositories.html',
+ pageProps: {
+ controller: 'dashboard/plugins/repositories/index',
+ view: 'dashboard/plugins/repositories/index.html'
+ }
+ }, {
+ path: 'livetvguideprovider.html',
+ pageProps: {
+ controller: 'livetvguideprovider',
+ view: 'livetvguideprovider.html'
+ }
+ }, {
+ path: 'livetvsettings.html',
+ pageProps: {
+ controller: 'livetvsettings',
+ view: 'livetvsettings.html'
+ }
+ }, {
+ path: 'livetvstatus.html',
+ pageProps: {
+ controller: 'livetvstatus',
+ view: 'livetvstatus.html'
+ }
+ }, {
+ path: 'livetvtuner.html',
+ pageProps: {
+ controller: 'livetvtuner',
+ view: 'livetvtuner.html'
+ }
+ }, {
+ path: 'installedplugins.html',
+ pageProps: {
+ controller: 'dashboard/plugins/installed/index',
+ view: 'dashboard/plugins/installed/index.html'
+ }
+ }, {
+ path: 'scheduledtask.html',
+ pageProps: {
+ controller: 'dashboard/scheduledtasks/scheduledtask',
+ view: 'dashboard/scheduledtasks/scheduledtask.html'
+ }
+ }, {
+ path: 'scheduledtasks.html',
+ pageProps: {
+ controller: 'dashboard/scheduledtasks/scheduledtasks',
+ view: 'dashboard/scheduledtasks/scheduledtasks.html'
+ }
+ }, {
+ path: 'serveractivity.html',
+ pageProps: {
+ controller: 'dashboard/serveractivity',
+ view: 'dashboard/serveractivity.html'
+ }
+ }, {
+ path: 'apikeys.html',
+ pageProps: {
+ controller: 'dashboard/apikeys',
+ view: 'dashboard/apikeys.html'
+ }
+ }, {
+ path: 'streamingsettings.html',
+ pageProps: {
+ view: 'dashboard/streaming.html',
+ controller: 'dashboard/streaming'
+ }
+ }
+];
diff --git a/src/routes/experimentalAppRoutes/legacyRoutes/public.ts b/src/routes/experimentalAppRoutes/legacyRoutes/public.ts
new file mode 100644
index 0000000000..15f8f0e8a9
--- /dev/null
+++ b/src/routes/experimentalAppRoutes/legacyRoutes/public.ts
@@ -0,0 +1,81 @@
+import { LegacyRoute } from '../../LegacyRoute';
+
+export const LEGACY_PUBLIC_ROUTES: LegacyRoute[] = [
+ {
+ path: 'addserver.html',
+ pageProps: {
+ controller: 'session/addServer/index',
+ view: 'session/addServer/index.html'
+ }
+ },
+ {
+ path: 'selectserver.html',
+ pageProps: {
+ controller: 'session/selectServer/index',
+ view: 'session/selectServer/index.html'
+ }
+ },
+ {
+ path: 'login.html',
+ pageProps: {
+ controller: 'session/login/index',
+ view: 'session/login/index.html'
+ }
+ },
+ {
+ path: 'forgotpassword.html',
+ pageProps: {
+ controller: 'session/forgotPassword/index',
+ view: 'session/forgotPassword/index.html'
+ }
+ },
+ {
+ path: 'forgotpasswordpin.html',
+ pageProps: {
+ controller: 'session/resetPassword/index',
+ view: 'session/resetPassword/index.html'
+ }
+ },
+ {
+ path: 'wizardremoteaccess.html',
+ pageProps: {
+ controller: 'wizard/remote/index',
+ view: 'wizard/remote/index.html'
+ }
+ },
+ {
+ path: 'wizardfinish.html',
+ pageProps: {
+ controller: 'wizard/finish/index',
+ view: 'wizard/finish/index.html'
+ }
+ },
+ {
+ path: 'wizardlibrary.html',
+ pageProps: {
+ controller: 'dashboard/library',
+ view: 'wizard/library.html'
+ }
+ },
+ {
+ path: 'wizardsettings.html',
+ pageProps: {
+ controller: 'wizard/settings/index',
+ view: 'wizard/settings/index.html'
+ }
+ },
+ {
+ path: 'wizardstart.html',
+ pageProps: {
+ controller: 'wizard/start/index',
+ view: 'wizard/start/index.html'
+ }
+ },
+ {
+ path: 'wizarduser.html',
+ pageProps: {
+ controller: 'wizard/user/index',
+ view: 'wizard/user/index.html'
+ }
+ }
+];
diff --git a/src/routes/experimentalAppRoutes/legacyRoutes/user.ts b/src/routes/experimentalAppRoutes/legacyRoutes/user.ts
new file mode 100644
index 0000000000..cc41c99957
--- /dev/null
+++ b/src/routes/experimentalAppRoutes/legacyRoutes/user.ts
@@ -0,0 +1,96 @@
+import { LegacyRoute } from '../../LegacyRoute';
+
+export const LEGACY_USER_ROUTES: LegacyRoute[] = [
+ {
+ path: 'details',
+ pageProps: {
+ controller: 'itemDetails/index',
+ view: 'itemDetails/index.html'
+ }
+ }, {
+ path: 'list.html',
+ pageProps: {
+ controller: 'list',
+ view: 'list.html'
+ }
+ }, {
+ path: 'livetv.html',
+ pageProps: {
+ controller: 'livetv/livetvsuggested',
+ view: 'livetv.html'
+ }
+ }, {
+ path: 'music.html',
+ pageProps: {
+ controller: 'music/musicrecommended',
+ view: 'music/music.html'
+ }
+ }, {
+ path: 'mypreferencesmenu.html',
+ pageProps: {
+ controller: 'user/menu/index',
+ view: 'user/menu/index.html'
+ }
+ }, {
+ path: 'mypreferencescontrols.html',
+ pageProps: {
+ controller: 'user/controls/index',
+ view: 'user/controls/index.html'
+ }
+ }, {
+ path: 'mypreferencesdisplay.html',
+ pageProps: {
+ controller: 'user/display/index',
+ view: 'user/display/index.html'
+ }
+ }, {
+ path: 'mypreferenceshome.html',
+ pageProps: {
+ controller: 'user/home/index',
+ view: 'user/home/index.html'
+ }
+ }, {
+ path: 'mypreferencesquickconnect.html',
+ pageProps: {
+ controller: 'user/quickConnect/index',
+ view: 'user/quickConnect/index.html'
+ }
+ }, {
+ path: 'mypreferencesplayback.html',
+ pageProps: {
+ controller: 'user/playback/index',
+ view: 'user/playback/index.html'
+ }
+ }, {
+ path: 'mypreferencessubtitles.html',
+ pageProps: {
+ controller: 'user/subtitles/index',
+ view: 'user/subtitles/index.html'
+ }
+ }, {
+ path: 'tv.html',
+ pageProps: {
+ controller: 'shows/tvrecommended',
+ view: 'shows/tvrecommended.html'
+ }
+ }, {
+ path: 'video',
+ pageProps: {
+ controller: 'playback/video/index',
+ view: 'playback/video/index.html',
+ type: 'video-osd',
+ isFullscreen: true,
+ isNowPlayingBarEnabled: false,
+ isThemeMediaSupported: true
+ }
+ }, {
+ path: 'queue',
+ pageProps: {
+ controller: 'playback/queue/index',
+ view: 'playback/queue/index.html',
+ isFullscreen: true,
+ isNowPlayingBarEnabled: false,
+ isThemeMediaSupported: true
+ }
+ }
+];
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
index 56f72e121e..d06d48a747 100644
--- a/src/routes/index.tsx
+++ b/src/routes/index.tsx
@@ -1 +1,2 @@
export * from './appRoutes';
+export * from './experimentalAppRoutes';