mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-18 03:18:19 -07:00
Merge pull request #3563 from thornbill/history-router
Use history for app router
This commit is contained in:
commit
6412156210
35
package-lock.json
generated
35
package-lock.json
generated
@ -2083,7 +2083,6 @@
|
|||||||
"version": "7.13.10",
|
"version": "7.13.10",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz",
|
||||||
"integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==",
|
"integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.4"
|
||||||
}
|
}
|
||||||
@ -7020,6 +7019,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/headroom.js/-/headroom.js-0.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/headroom.js/-/headroom.js-0.12.0.tgz",
|
||||||
"integrity": "sha512-iXnAafUm3FdzfJ91uixLws2hkKI1jC8bAKK/pt7XYr8Ie1jO7xbK48Ycpl9tUPyBgkzuj1p/PhJS0fy4E/5anA=="
|
"integrity": "sha512-iXnAafUm3FdzfJ91uixLws2hkKI1jC8bAKK/pt7XYr8Ie1jO7xbK48Ycpl9tUPyBgkzuj1p/PhJS0fy4E/5anA=="
|
||||||
},
|
},
|
||||||
|
"history": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",
|
||||||
|
"integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.7.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"hls.js": {
|
"hls.js": {
|
||||||
"version": "0.14.17",
|
"version": "0.14.17",
|
||||||
"resolved": "https://registry.npmjs.org/hls.js/-/hls.js-0.14.17.tgz",
|
"resolved": "https://registry.npmjs.org/hls.js/-/hls.js-0.14.17.tgz",
|
||||||
@ -8902,14 +8909,6 @@
|
|||||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"page": {
|
|
||||||
"version": "1.11.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/page/-/page-1.11.6.tgz",
|
|
||||||
"integrity": "sha512-P6e2JfzkBrPeFCIPplLP7vDDiU84RUUZMrWdsH4ZBGJ8OosnwFkcUkBHp1DTIjuipLliw9yQn/ZJsXZvarsO+g==",
|
|
||||||
"requires": {
|
|
||||||
"path-to-regexp": "~1.2.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pako": {
|
"pako": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
||||||
@ -9016,21 +9015,6 @@
|
|||||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"path-to-regexp": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.2.1.tgz",
|
|
||||||
"integrity": "sha1-szcFwUAjTYc8hyHHuf2LVB7Tr/k=",
|
|
||||||
"requires": {
|
|
||||||
"isarray": "0.0.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"isarray": {
|
|
||||||
"version": "0.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
|
||||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"path-type": {
|
"path-type": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||||
@ -10841,8 +10825,7 @@
|
|||||||
"regenerator-runtime": {
|
"regenerator-runtime": {
|
||||||
"version": "0.13.7",
|
"version": "0.13.7",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"regenerator-transform": {
|
"regenerator-transform": {
|
||||||
"version": "0.14.5",
|
"version": "0.14.5",
|
||||||
|
@ -80,6 +80,7 @@
|
|||||||
"fast-text-encoding": "1.0.3",
|
"fast-text-encoding": "1.0.3",
|
||||||
"flv.js": "1.6.2",
|
"flv.js": "1.6.2",
|
||||||
"headroom.js": "0.12.0",
|
"headroom.js": "0.12.0",
|
||||||
|
"history": "5.3.0",
|
||||||
"hls.js": "0.14.17",
|
"hls.js": "0.14.17",
|
||||||
"intersection-observer": "0.12.0",
|
"intersection-observer": "0.12.0",
|
||||||
"jellyfin-apiclient": "1.10.0",
|
"jellyfin-apiclient": "1.10.0",
|
||||||
@ -91,7 +92,6 @@
|
|||||||
"marked": "4.0.10",
|
"marked": "4.0.10",
|
||||||
"material-design-icons-iconfont": "6.1.1",
|
"material-design-icons-iconfont": "6.1.1",
|
||||||
"native-promise-only": "0.8.1",
|
"native-promise-only": "0.8.1",
|
||||||
"page": "1.11.6",
|
|
||||||
"pdfjs-dist": "2.12.313",
|
"pdfjs-dist": "2.12.313",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
|
@ -1,20 +1,22 @@
|
|||||||
|
import { Events } from 'jellyfin-apiclient';
|
||||||
|
import { Action, createHashHistory } from 'history';
|
||||||
|
|
||||||
import { appHost } from './apphost';
|
import { appHost } from './apphost';
|
||||||
import appSettings from '../scripts/settings/appSettings';
|
import appSettings from '../scripts/settings/appSettings';
|
||||||
import { clearBackdrop, setBackdropTransparency } from './backdrop/backdrop';
|
import { clearBackdrop, setBackdropTransparency } from './backdrop/backdrop';
|
||||||
import browser from '../scripts/browser';
|
|
||||||
import { Events } from 'jellyfin-apiclient';
|
|
||||||
import globalize from '../scripts/globalize';
|
import globalize from '../scripts/globalize';
|
||||||
import itemHelper from './itemHelper';
|
import itemHelper from './itemHelper';
|
||||||
import loading from './loading/loading';
|
import loading from './loading/loading';
|
||||||
import page from 'page';
|
|
||||||
import viewManager from './viewManager/viewManager';
|
import viewManager from './viewManager/viewManager';
|
||||||
import Dashboard from '../utils/dashboard';
|
import Dashboard from '../utils/dashboard';
|
||||||
import ServerConnections from './ServerConnections';
|
import ServerConnections from './ServerConnections';
|
||||||
import alert from './alert';
|
import alert from './alert';
|
||||||
import reactControllerFactory from './reactControllerFactory';
|
import reactControllerFactory from './reactControllerFactory';
|
||||||
|
|
||||||
|
const history = createHashHistory();
|
||||||
|
|
||||||
class AppRouter {
|
class AppRouter {
|
||||||
allRoutes = [];
|
allRoutes = new Map();
|
||||||
backdropContainer;
|
backdropContainer;
|
||||||
backgroundContainer;
|
backgroundContainer;
|
||||||
currentRouteInfo;
|
currentRouteInfo;
|
||||||
@ -23,7 +25,6 @@ class AppRouter {
|
|||||||
forcedLogoutMsg;
|
forcedLogoutMsg;
|
||||||
isDummyBackToHome;
|
isDummyBackToHome;
|
||||||
msgTimeout;
|
msgTimeout;
|
||||||
popstateOccurred = false;
|
|
||||||
promiseShow;
|
promiseShow;
|
||||||
resolveOnNextShow;
|
resolveOnNextShow;
|
||||||
previousRoute = {};
|
previousRoute = {};
|
||||||
@ -33,58 +34,24 @@ class AppRouter {
|
|||||||
startPages = ['home', 'login', 'selectserver'];
|
startPages = ['home', 'login', 'selectserver'];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// WebKit fires a popstate event on document load
|
|
||||||
// Skip it using boolean
|
|
||||||
// For Tizen 2.x
|
|
||||||
// See `page` node module
|
|
||||||
let loaded = document.readyState === 'complete';
|
|
||||||
if (!loaded) {
|
|
||||||
window.addEventListener('load', () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
loaded = true;
|
|
||||||
}, 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
window.addEventListener('popstate', () => {
|
|
||||||
if (!loaded) return;
|
|
||||||
this.popstateOccurred = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener('viewshow', () => this.onViewShow());
|
document.addEventListener('viewshow', () => this.onViewShow());
|
||||||
|
|
||||||
|
// TODO: Can this baseRoute logic be simplified?
|
||||||
this.baseRoute = window.location.href.split('?')[0].replace(this.getRequestFile(), '');
|
this.baseRoute = window.location.href.split('?')[0].replace(this.getRequestFile(), '');
|
||||||
// support hashbang
|
// support hashbang
|
||||||
this.baseRoute = this.baseRoute.split('#')[0];
|
this.baseRoute = this.baseRoute.split('#')[0];
|
||||||
if (this.baseRoute.endsWith('/') && !this.baseRoute.endsWith('://')) {
|
if (this.baseRoute.endsWith('/') && !this.baseRoute.endsWith('://')) {
|
||||||
this.baseRoute = this.baseRoute.substring(0, this.baseRoute.length - 1);
|
this.baseRoute = this.baseRoute.substring(0, this.baseRoute.length - 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.setBaseRoute();
|
addRoute(path, route) {
|
||||||
|
this.allRoutes.set(path, {
|
||||||
// paths that start with a hashbang (i.e. /#!/page.html) get transformed to starting with //
|
route,
|
||||||
// we need to strip one "/" for our routes to work
|
handler: this.#getHandler(route)
|
||||||
page('//*', (ctx) => {
|
|
||||||
page.redirect(ctx.path.substring(1));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
setBaseRoute() {
|
|
||||||
let baseRoute = window.location.pathname.replace(this.getRequestFile(), '');
|
|
||||||
if (baseRoute.lastIndexOf('/') === baseRoute.length - 1) {
|
|
||||||
baseRoute = baseRoute.substring(0, baseRoute.length - 1);
|
|
||||||
}
|
|
||||||
console.debug('setting page base to ' + baseRoute);
|
|
||||||
page.base(baseRoute);
|
|
||||||
}
|
|
||||||
|
|
||||||
addRoute(path, newRoute) {
|
|
||||||
page(path, this.getHandler(newRoute));
|
|
||||||
this.allRoutes.push(newRoute);
|
|
||||||
}
|
|
||||||
|
|
||||||
showLocalLogin(serverId) {
|
showLocalLogin(serverId) {
|
||||||
Dashboard.navigate('login.html?serverid=' + serverId);
|
Dashboard.navigate('login.html?serverid=' + serverId);
|
||||||
}
|
}
|
||||||
@ -124,7 +91,7 @@ class AppRouter {
|
|||||||
|
|
||||||
this.promiseShow = new Promise((resolve) => {
|
this.promiseShow = new Promise((resolve) => {
|
||||||
this.resolveOnNextShow = resolve;
|
this.resolveOnNextShow = resolve;
|
||||||
page.back();
|
history.back();
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.promiseShow;
|
return this.promiseShow;
|
||||||
@ -155,7 +122,7 @@ class AppRouter {
|
|||||||
this.promiseShow = new Promise((resolve) => {
|
this.promiseShow = new Promise((resolve) => {
|
||||||
this.resolveOnNextShow = resolve;
|
this.resolveOnNextShow = resolve;
|
||||||
// Schedule a call to return the promise
|
// Schedule a call to return the promise
|
||||||
setTimeout(() => page.show(path, options), 0);
|
setTimeout(() => history.push(path, options), 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.promiseShow;
|
return this.promiseShow;
|
||||||
@ -167,27 +134,50 @@ class AppRouter {
|
|||||||
this.promiseShow = new Promise((resolve) => {
|
this.promiseShow = new Promise((resolve) => {
|
||||||
this.resolveOnNextShow = resolve;
|
this.resolveOnNextShow = resolve;
|
||||||
// Schedule a call to return the promise
|
// Schedule a call to return the promise
|
||||||
setTimeout(() => page.show(this.baseUrl() + path), 0);
|
setTimeout(() => history.push(this.baseUrl() + path), 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.promiseShow;
|
return this.promiseShow;
|
||||||
}
|
}
|
||||||
|
|
||||||
start(options) {
|
#goToRoute({ location, action }) {
|
||||||
|
// Strip the leading "!" if present
|
||||||
|
const normalizedPath = location.pathname.replace(/^!/, '');
|
||||||
|
|
||||||
|
const route = this.allRoutes.get(normalizedPath);
|
||||||
|
if (route) {
|
||||||
|
console.debug('[appRouter] "%s" route found', normalizedPath, location, route);
|
||||||
|
route.handler({
|
||||||
|
// Recreate the default context used by page.js: https://github.com/visionmedia/page.js#context
|
||||||
|
path: normalizedPath + location.search,
|
||||||
|
pathname: normalizedPath,
|
||||||
|
querystring: location.search.replace(/^\?/, ''),
|
||||||
|
state: location.state,
|
||||||
|
// Custom context variables
|
||||||
|
isBack: action === Action.Pop
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.warn('[appRouter] "%s" route not found', normalizedPath, location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
loading.show();
|
loading.show();
|
||||||
this.initApiClients();
|
this.initApiClients();
|
||||||
|
|
||||||
Events.on(appHost, 'beforeexit', this.onBeforeExit);
|
|
||||||
Events.on(appHost, 'resume', this.onAppResume);
|
Events.on(appHost, 'resume', this.onAppResume);
|
||||||
|
|
||||||
ServerConnections.connect({
|
ServerConnections.connect({
|
||||||
enableAutoLogin: appSettings.enableAutoLogin()
|
enableAutoLogin: appSettings.enableAutoLogin()
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
this.firstConnectionResult = result;
|
this.firstConnectionResult = result;
|
||||||
options = options || {};
|
|
||||||
page({
|
// Handle the initial route
|
||||||
click: options.click !== false,
|
this.#goToRoute({ location: history.location });
|
||||||
hashbang: options.hashbang !== false
|
|
||||||
|
// Handle route changes
|
||||||
|
history.listen(params => {
|
||||||
|
this.#goToRoute(params);
|
||||||
});
|
});
|
||||||
}).catch().then(() => {
|
}).catch().then(() => {
|
||||||
loading.hide();
|
loading.hide();
|
||||||
@ -262,19 +252,6 @@ class AppRouter {
|
|||||||
setBackdropTransparency(level);
|
setBackdropTransparency(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRoutes() {
|
|
||||||
return this.allRoutes;
|
|
||||||
}
|
|
||||||
|
|
||||||
pushState(state, title, url) {
|
|
||||||
state.navigate = false;
|
|
||||||
window.history.pushState(state, title, url);
|
|
||||||
}
|
|
||||||
|
|
||||||
enableNativeHistory() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleConnectionResult(result) {
|
handleConnectionResult(result) {
|
||||||
switch (result.State) {
|
switch (result.State) {
|
||||||
case 'SignedIn':
|
case 'SignedIn':
|
||||||
@ -452,12 +429,6 @@ class AppRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeExit() {
|
|
||||||
if (browser.web0s) {
|
|
||||||
page.restorePreviousState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
normalizeImageOptions(options) {
|
normalizeImageOptions(options) {
|
||||||
let setQuality;
|
let setQuality;
|
||||||
if (options.maxWidth || options.width || options.maxHeight || options.height || options.fillWidth || options.fillHeight) {
|
if (options.maxWidth || options.width || options.maxHeight || options.height || options.fillWidth || options.fillHeight) {
|
||||||
@ -544,12 +515,12 @@ class AppRouter {
|
|||||||
const apiClient = ServerConnections.currentApiClient();
|
const apiClient = ServerConnections.currentApiClient();
|
||||||
const pathname = ctx.pathname.toLowerCase();
|
const pathname = ctx.pathname.toLowerCase();
|
||||||
|
|
||||||
console.debug('processing path request: ' + pathname);
|
console.debug('[appRouter] processing path request: ' + pathname);
|
||||||
const isCurrentRouteStartup = this.currentRouteInfo ? this.currentRouteInfo.route.startup : true;
|
const isCurrentRouteStartup = this.currentRouteInfo ? this.currentRouteInfo.route.startup : true;
|
||||||
const shouldExitApp = ctx.isBack && route.isDefaultRoute && isCurrentRouteStartup;
|
const shouldExitApp = ctx.isBack && route.isDefaultRoute && isCurrentRouteStartup;
|
||||||
|
|
||||||
if (!shouldExitApp && (!apiClient || !apiClient.isLoggedIn()) && !route.anonymous) {
|
if (!shouldExitApp && (!apiClient || !apiClient.isLoggedIn()) && !route.anonymous) {
|
||||||
console.debug('route does not allow anonymous access: redirecting to login');
|
console.debug('[appRouter] route does not allow anonymous access: redirecting to login');
|
||||||
this.beginConnectionWizard();
|
this.beginConnectionWizard();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -563,10 +534,10 @@ class AppRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (apiClient && apiClient.isLoggedIn()) {
|
if (apiClient && apiClient.isLoggedIn()) {
|
||||||
console.debug('user is authenticated');
|
console.debug('[appRouter] user is authenticated');
|
||||||
|
|
||||||
if (route.isDefaultRoute) {
|
if (route.isDefaultRoute) {
|
||||||
console.debug('loading home page');
|
console.debug('[appRouter] loading home page');
|
||||||
this.goHome();
|
this.goHome();
|
||||||
return;
|
return;
|
||||||
} else if (route.roles) {
|
} else if (route.roles) {
|
||||||
@ -577,7 +548,7 @@ class AppRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.debug('proceeding to page: ' + pathname);
|
console.debug('[appRouter] proceeding to page: ' + pathname);
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,11 +603,8 @@ class AppRouter {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
getHandler(route) {
|
#getHandler(route) {
|
||||||
return (ctx, next) => {
|
return (ctx, next) => {
|
||||||
ctx.isBack = this.popstateOccurred;
|
|
||||||
this.popstateOccurred = false;
|
|
||||||
|
|
||||||
const ignore = route.dummyRoute === true || this.previousRoute.dummyRoute === true;
|
const ignore = route.dummyRoute === true || this.previousRoute.dummyRoute === true;
|
||||||
this.previousRoute = route;
|
this.previousRoute = route;
|
||||||
if (ignore) {
|
if (ignore) {
|
||||||
|
@ -566,13 +566,7 @@ import { appRouter } from '../components/appRouter';
|
|||||||
});
|
});
|
||||||
|
|
||||||
defineRoute({
|
defineRoute({
|
||||||
path: '',
|
path: '/',
|
||||||
isDefaultRoute: true,
|
|
||||||
autoFocus: false
|
|
||||||
});
|
|
||||||
|
|
||||||
defineRoute({
|
|
||||||
path: 'index.html',
|
|
||||||
autoFocus: false,
|
autoFocus: false,
|
||||||
isDefaultRoute: true
|
isDefaultRoute: true
|
||||||
});
|
});
|
||||||
|
@ -163,10 +163,7 @@ async function onAppReady() {
|
|||||||
import('../assets/css/ios.scss');
|
import('../assets/css/ios.scss');
|
||||||
}
|
}
|
||||||
|
|
||||||
appRouter.start({
|
appRouter.start();
|
||||||
click: false,
|
|
||||||
hashbang: true
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!browser.tv && !browser.xboxOne && !browser.ps4) {
|
if (!browser.tv && !browser.xboxOne && !browser.ps4) {
|
||||||
import('../components/nowPlayingBar/nowPlayingBar');
|
import('../components/nowPlayingBar/nowPlayingBar');
|
||||||
|
Loading…
Reference in New Issue
Block a user