mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-17 19:08:18 -07:00
Merge pull request #3585 from thornbill/moar-router-cleanup
This commit is contained in:
commit
2c02c1c8ea
@ -1,20 +1,49 @@
|
|||||||
import { ConnectionManager, Credentials, ApiClient, Events } from 'jellyfin-apiclient';
|
import { ConnectionManager, Credentials, ApiClient, Events } from 'jellyfin-apiclient';
|
||||||
|
|
||||||
import { appHost } from './apphost';
|
import { appHost } from './apphost';
|
||||||
import Dashboard from '../utils/dashboard';
|
import Dashboard from '../utils/dashboard';
|
||||||
import { setUserInfo } from '../scripts/settings/userSettings';
|
import { setUserInfo } from '../scripts/settings/userSettings';
|
||||||
|
import appSettings from '../scripts/settings/appSettings';
|
||||||
|
|
||||||
|
const normalizeImageOptions = options => {
|
||||||
|
if (!options.quality && (options.maxWidth || options.width || options.maxHeight || options.height || options.fillWidth || options.fillHeight)) {
|
||||||
|
options.quality = 90;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getMaxBandwidth = () => {
|
||||||
|
/* eslint-disable compat/compat */
|
||||||
|
if (navigator.connection) {
|
||||||
|
let max = navigator.connection.downlinkMax;
|
||||||
|
if (max && max > 0 && max < Number.POSITIVE_INFINITY) {
|
||||||
|
max /= 8;
|
||||||
|
max *= 1000000;
|
||||||
|
max *= 0.7;
|
||||||
|
return parseInt(max, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* eslint-enable compat/compat */
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
class ServerConnections extends ConnectionManager {
|
class ServerConnections extends ConnectionManager {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
this.localApiClient = null;
|
this.localApiClient = null;
|
||||||
|
|
||||||
Events.on(this, 'localusersignedout', function (eventName, logoutInfo) {
|
Events.on(this, 'localusersignedout', (_e, logoutInfo) => {
|
||||||
setUserInfo(null, null);
|
setUserInfo(null, null);
|
||||||
|
|
||||||
if (window.NativeShell && typeof window.NativeShell.onLocalUserSignedOut === 'function') {
|
if (window.NativeShell && typeof window.NativeShell.onLocalUserSignedOut === 'function') {
|
||||||
window.NativeShell.onLocalUserSignedOut(logoutInfo);
|
window.NativeShell.onLocalUserSignedOut(logoutInfo);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Events.on(this, 'apiclientcreated', (_e, apiClient) => {
|
||||||
|
apiClient.getMaxBandwidth = getMaxBandwidth;
|
||||||
|
apiClient.normalizeImageOptions = normalizeImageOptions;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initApiClient(server) {
|
initApiClient(server) {
|
||||||
@ -38,6 +67,13 @@ class ServerConnections extends ConnectionManager {
|
|||||||
console.debug('loaded ApiClient singleton');
|
console.debug('loaded ApiClient singleton');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connect(options) {
|
||||||
|
return super.connect({
|
||||||
|
enableAutoLogin: appSettings.enableAutoLogin(),
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setLocalApiClient(apiClient) {
|
setLocalApiClient(apiClient) {
|
||||||
if (apiClient) {
|
if (apiClient) {
|
||||||
this.localApiClient = apiClient;
|
this.localApiClient = apiClient;
|
||||||
|
@ -2,42 +2,38 @@ import { Events } from 'jellyfin-apiclient';
|
|||||||
import { Action, createHashHistory } from 'history';
|
import { Action, createHashHistory } from 'history';
|
||||||
|
|
||||||
import { appHost } from './apphost';
|
import { appHost } from './apphost';
|
||||||
import appSettings from '../scripts/settings/appSettings';
|
|
||||||
import { clearBackdrop, setBackdropTransparency } from './backdrop/backdrop';
|
import { clearBackdrop, setBackdropTransparency } from './backdrop/backdrop';
|
||||||
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 viewManager from './viewManager/viewManager';
|
import viewManager from './viewManager/viewManager';
|
||||||
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();
|
const history = createHashHistory();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page types of "no return" (when "Go back" should behave differently, probably quitting the application).
|
||||||
|
*/
|
||||||
|
const START_PAGE_TYPES = ['home', 'login', 'selectserver'];
|
||||||
|
|
||||||
class AppRouter {
|
class AppRouter {
|
||||||
allRoutes = new Map();
|
allRoutes = new Map();
|
||||||
backdropContainer;
|
|
||||||
backgroundContainer;
|
|
||||||
currentRouteInfo;
|
currentRouteInfo;
|
||||||
currentViewLoadRequest;
|
currentViewLoadRequest;
|
||||||
firstConnectionResult;
|
firstConnectionResult;
|
||||||
forcedLogoutMsg;
|
forcedLogoutMsg;
|
||||||
isDummyBackToHome;
|
|
||||||
msgTimeout;
|
msgTimeout;
|
||||||
promiseShow;
|
promiseShow;
|
||||||
resolveOnNextShow;
|
resolveOnNextShow;
|
||||||
previousRoute = {};
|
previousRoute = {};
|
||||||
/**
|
|
||||||
* Pages of "no return" (when "Go back" should behave differently, probably quitting the application).
|
|
||||||
*/
|
|
||||||
startPages = ['home', 'login', 'selectserver'];
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
document.addEventListener('viewshow', () => this.onViewShow());
|
document.addEventListener('viewshow', () => this.onViewShow());
|
||||||
|
|
||||||
// TODO: Can this baseRoute logic be simplified?
|
// 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('://')) {
|
||||||
@ -52,33 +48,11 @@ class AppRouter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showLocalLogin(serverId) {
|
#beginConnectionWizard() {
|
||||||
Dashboard.navigate('login.html?serverid=' + serverId);
|
|
||||||
}
|
|
||||||
|
|
||||||
showVideoOsd() {
|
|
||||||
return Dashboard.navigate('video');
|
|
||||||
}
|
|
||||||
|
|
||||||
showSelectServer() {
|
|
||||||
Dashboard.navigate('selectserver.html');
|
|
||||||
}
|
|
||||||
|
|
||||||
showSettings() {
|
|
||||||
Dashboard.navigate('mypreferencesmenu.html');
|
|
||||||
}
|
|
||||||
|
|
||||||
showNowPlaying() {
|
|
||||||
this.show('queue');
|
|
||||||
}
|
|
||||||
|
|
||||||
beginConnectionWizard() {
|
|
||||||
clearBackdrop();
|
clearBackdrop();
|
||||||
loading.show();
|
loading.show();
|
||||||
ServerConnections.connect({
|
ServerConnections.connect().then(result => {
|
||||||
enableAutoLogin: appSettings.enableAutoLogin()
|
this.#handleConnectionResult(result);
|
||||||
}).then((result) => {
|
|
||||||
this.handleConnectionResult(result);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,18 +102,6 @@ class AppRouter {
|
|||||||
return this.promiseShow;
|
return this.promiseShow;
|
||||||
}
|
}
|
||||||
|
|
||||||
async showDirect(path) {
|
|
||||||
if (this.promiseShow) await this.promiseShow;
|
|
||||||
|
|
||||||
this.promiseShow = new Promise((resolve) => {
|
|
||||||
this.resolveOnNextShow = resolve;
|
|
||||||
// Schedule a call to return the promise
|
|
||||||
setTimeout(() => history.push(this.baseUrl() + path), 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.promiseShow;
|
|
||||||
}
|
|
||||||
|
|
||||||
#goToRoute({ location, action }) {
|
#goToRoute({ location, action }) {
|
||||||
// Strip the leading "!" if present
|
// Strip the leading "!" if present
|
||||||
const normalizedPath = location.pathname.replace(/^!/, '');
|
const normalizedPath = location.pathname.replace(/^!/, '');
|
||||||
@ -163,13 +125,18 @@ class AppRouter {
|
|||||||
|
|
||||||
start() {
|
start() {
|
||||||
loading.show();
|
loading.show();
|
||||||
this.initApiClients();
|
|
||||||
|
|
||||||
Events.on(appHost, 'resume', this.onAppResume);
|
ServerConnections.getApiClients().forEach(apiClient => {
|
||||||
|
Events.off(apiClient, 'requestfail', this.onRequestFail);
|
||||||
|
Events.on(apiClient, 'requestfail', this.onRequestFail);
|
||||||
|
});
|
||||||
|
|
||||||
ServerConnections.connect({
|
Events.on(ServerConnections, 'apiclientcreated', (_e, apiClient) => {
|
||||||
enableAutoLogin: appSettings.enableAutoLogin()
|
Events.off(apiClient, 'requestfail', this.onRequestFail);
|
||||||
}).then((result) => {
|
Events.on(apiClient, 'requestfail', this.onRequestFail);
|
||||||
|
});
|
||||||
|
|
||||||
|
ServerConnections.connect().then(result => {
|
||||||
this.firstConnectionResult = result;
|
this.firstConnectionResult = result;
|
||||||
|
|
||||||
// Handle the initial route
|
// Handle the initial route
|
||||||
@ -189,40 +156,18 @@ class AppRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
canGoBack() {
|
canGoBack() {
|
||||||
const curr = this.current();
|
const curr = this.currentRouteInfo?.route;
|
||||||
if (!curr) {
|
if (!curr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!document.querySelector('.dialogContainer') && this.startPages.indexOf(curr.type) !== -1) {
|
if (!document.querySelector('.dialogContainer') && START_PAGE_TYPES.includes(curr.type)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return window.history.length > 1;
|
return window.history.length > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
current() {
|
|
||||||
return this.currentRouteInfo ? this.currentRouteInfo.route : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
invokeShortcut(id) {
|
|
||||||
if (id.indexOf('library-') === 0) {
|
|
||||||
id = id.replace('library-', '');
|
|
||||||
id = id.split('_');
|
|
||||||
|
|
||||||
this.showItem(id[0], id[1]);
|
|
||||||
} else if (id.indexOf('item-') === 0) {
|
|
||||||
id = id.replace('item-', '');
|
|
||||||
id = id.split('_');
|
|
||||||
this.showItem(id[0], id[1]);
|
|
||||||
} else {
|
|
||||||
id = id.split('_');
|
|
||||||
this.show(this.getRouteUrl(id[0], {
|
|
||||||
serverId: id[1]
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showItem(item, serverId, options) {
|
showItem(item, serverId, options) {
|
||||||
// TODO: Refactor this so it only gets items, not strings.
|
// TODO: Refactor this so it only gets items, not strings.
|
||||||
if (typeof (item) === 'string') {
|
if (typeof (item) === 'string') {
|
||||||
@ -236,9 +181,7 @@ class AppRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const url = this.getRouteUrl(item, options);
|
const url = this.getRouteUrl(item, options);
|
||||||
this.show(url, {
|
this.show(url, { item });
|
||||||
item: item
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,20 +195,14 @@ class AppRouter {
|
|||||||
setBackdropTransparency(level);
|
setBackdropTransparency(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleConnectionResult(result) {
|
#handleConnectionResult(result) {
|
||||||
switch (result.State) {
|
switch (result.State) {
|
||||||
case 'SignedIn':
|
case 'SignedIn':
|
||||||
loading.hide();
|
loading.hide();
|
||||||
this.goHome();
|
this.goHome();
|
||||||
break;
|
break;
|
||||||
case 'ServerSignIn':
|
case 'ServerSignIn':
|
||||||
result.ApiClient.getPublicUsers().then((users) => {
|
this.showLocalLogin(result.ApiClient.serverId());
|
||||||
if (users.length) {
|
|
||||||
this.showLocalLogin(result.Servers[0].Id);
|
|
||||||
} else {
|
|
||||||
this.showLocalLogin(result.Servers[0].Id, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case 'ServerSelection':
|
case 'ServerSelection':
|
||||||
this.showSelectServer();
|
this.showSelectServer();
|
||||||
@ -283,7 +220,7 @@ class AppRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadContentUrl(ctx, next, route, request) {
|
#loadContentUrl(ctx, _next, route, request) {
|
||||||
let url;
|
let url;
|
||||||
if (route.contentPath && typeof (route.contentPath) === 'function') {
|
if (route.contentPath && typeof (route.contentPath) === 'function') {
|
||||||
url = route.contentPath(ctx.querystring);
|
url = route.contentPath(ctx.querystring);
|
||||||
@ -305,19 +242,19 @@ class AppRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
promise.then((html) => {
|
promise.then((html) => {
|
||||||
this.loadContent(ctx, route, html, request);
|
this.#loadContent(ctx, route, html, request);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleRoute(ctx, next, route) {
|
#handleRoute(ctx, next, route) {
|
||||||
this.authenticate(ctx, route, () => {
|
this.#authenticate(ctx, route, () => {
|
||||||
this.initRoute(ctx, next, route);
|
this.#initRoute(ctx, next, route);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initRoute(ctx, next, route) {
|
#initRoute(ctx, next, route) {
|
||||||
const onInitComplete = (controllerFactory) => {
|
const onInitComplete = (controllerFactory) => {
|
||||||
this.sendRouteToViewManager(ctx, next, route, controllerFactory);
|
this.#sendRouteToViewManager(ctx, next, route, controllerFactory);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (route.pageComponent) {
|
if (route.pageComponent) {
|
||||||
@ -329,20 +266,15 @@ class AppRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelCurrentLoadRequest() {
|
#cancelCurrentLoadRequest() {
|
||||||
const currentRequest = this.currentViewLoadRequest;
|
const currentRequest = this.currentViewLoadRequest;
|
||||||
if (currentRequest) {
|
if (currentRequest) {
|
||||||
currentRequest.cancel = true;
|
currentRequest.cancel = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendRouteToViewManager(ctx, next, route, controllerFactory) {
|
#sendRouteToViewManager(ctx, next, route, controllerFactory) {
|
||||||
if (this.isDummyBackToHome && route.type === 'home') {
|
this.#cancelCurrentLoadRequest();
|
||||||
this.isDummyBackToHome = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.cancelCurrentLoadRequest();
|
|
||||||
const isBackNav = ctx.isBack;
|
const isBackNav = ctx.isBack;
|
||||||
|
|
||||||
const currentRequest = {
|
const currentRequest = {
|
||||||
@ -364,7 +296,7 @@ class AppRouter {
|
|||||||
|
|
||||||
const onNewViewNeeded = () => {
|
const onNewViewNeeded = () => {
|
||||||
if (typeof route.path === 'string') {
|
if (typeof route.path === 'string') {
|
||||||
this.loadContentUrl(ctx, next, route, currentRequest);
|
this.#loadContentUrl(ctx, next, route, currentRequest);
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
@ -413,7 +345,7 @@ class AppRouter {
|
|||||||
this.msgTimeout = setTimeout(this.onForcedLogoutMessageTimeout, 100);
|
this.msgTimeout = setTimeout(this.onForcedLogoutMessageTimeout, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
onRequestFail(e, data) {
|
onRequestFail(_e, data) {
|
||||||
const apiClient = this;
|
const apiClient = this;
|
||||||
|
|
||||||
if (data.status === 403) {
|
if (data.status === 403) {
|
||||||
@ -429,62 +361,7 @@ class AppRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
normalizeImageOptions(options) {
|
#authenticate(ctx, route, callback) {
|
||||||
let setQuality;
|
|
||||||
if (options.maxWidth || options.width || options.maxHeight || options.height || options.fillWidth || options.fillHeight) {
|
|
||||||
setQuality = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setQuality && !options.quality) {
|
|
||||||
options.quality = 90;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getMaxBandwidth() {
|
|
||||||
/* eslint-disable compat/compat */
|
|
||||||
if (navigator.connection) {
|
|
||||||
let max = navigator.connection.downlinkMax;
|
|
||||||
if (max && max > 0 && max < Number.POSITIVE_INFINITY) {
|
|
||||||
max /= 8;
|
|
||||||
max *= 1000000;
|
|
||||||
max *= 0.7;
|
|
||||||
return parseInt(max, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* eslint-enable compat/compat */
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
onApiClientCreated(e, newApiClient) {
|
|
||||||
newApiClient.normalizeImageOptions = this.normalizeImageOptions;
|
|
||||||
newApiClient.getMaxBandwidth = this.getMaxBandwidth;
|
|
||||||
|
|
||||||
Events.off(newApiClient, 'requestfail', this.onRequestFail);
|
|
||||||
Events.on(newApiClient, 'requestfail', this.onRequestFail);
|
|
||||||
}
|
|
||||||
|
|
||||||
initApiClient(apiClient, instance) {
|
|
||||||
instance.onApiClientCreated({}, apiClient);
|
|
||||||
}
|
|
||||||
|
|
||||||
initApiClients() {
|
|
||||||
ServerConnections.getApiClients().forEach((apiClient) => {
|
|
||||||
this.initApiClient(apiClient, this);
|
|
||||||
});
|
|
||||||
|
|
||||||
Events.on(ServerConnections, 'apiclientcreated', this.onApiClientCreated);
|
|
||||||
}
|
|
||||||
|
|
||||||
onAppResume() {
|
|
||||||
const apiClient = ServerConnections.currentApiClient();
|
|
||||||
|
|
||||||
if (apiClient) {
|
|
||||||
apiClient.ensureWebSocket();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
authenticate(ctx, route, callback) {
|
|
||||||
const firstResult = this.firstConnectionResult;
|
const firstResult = this.firstConnectionResult;
|
||||||
|
|
||||||
this.firstConnectionResult = null;
|
this.firstConnectionResult = null;
|
||||||
@ -497,9 +374,9 @@ class AppRouter {
|
|||||||
}).then(data => {
|
}).then(data => {
|
||||||
if (data !== null && data.StartupWizardCompleted === false) {
|
if (data !== null && data.StartupWizardCompleted === false) {
|
||||||
ServerConnections.setLocalApiClient(firstResult.ApiClient);
|
ServerConnections.setLocalApiClient(firstResult.ApiClient);
|
||||||
Dashboard.navigate('wizardstart.html');
|
this.show('wizardstart.html');
|
||||||
} else {
|
} else {
|
||||||
this.handleConnectionResult(firstResult);
|
this.#handleConnectionResult(firstResult);
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@ -507,7 +384,7 @@ class AppRouter {
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
} else if (firstResult.State !== 'SignedIn') {
|
} else if (firstResult.State !== 'SignedIn') {
|
||||||
this.handleConnectionResult(firstResult);
|
this.#handleConnectionResult(firstResult);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -521,7 +398,7 @@ class AppRouter {
|
|||||||
|
|
||||||
if (!shouldExitApp && (!apiClient || !apiClient.isLoggedIn()) && !route.anonymous) {
|
if (!shouldExitApp && (!apiClient || !apiClient.isLoggedIn()) && !route.anonymous) {
|
||||||
console.debug('[appRouter] 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,9 +418,9 @@ class AppRouter {
|
|||||||
this.goHome();
|
this.goHome();
|
||||||
return;
|
return;
|
||||||
} else if (route.roles) {
|
} else if (route.roles) {
|
||||||
this.validateRoles(apiClient, route.roles).then(() => {
|
this.#validateRoles(apiClient, route.roles).then(() => {
|
||||||
callback();
|
callback();
|
||||||
}, this.beginConnectionWizard);
|
}, this.#beginConnectionWizard.bind(this));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -552,13 +429,13 @@ class AppRouter {
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
validateRoles(apiClient, roles) {
|
#validateRoles(apiClient, roles) {
|
||||||
return Promise.all(roles.split(',').map((role) => {
|
return Promise.all(roles.split(',').map((role) => {
|
||||||
return this.validateRole(apiClient, role);
|
return this.#validateRole(apiClient, role);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
validateRole(apiClient, role) {
|
#validateRole(apiClient, role) {
|
||||||
if (role === 'admin') {
|
if (role === 'admin') {
|
||||||
return apiClient.getCurrentUser().then((user) => {
|
return apiClient.getCurrentUser().then((user) => {
|
||||||
if (user.Policy.IsAdministrator) {
|
if (user.Policy.IsAdministrator) {
|
||||||
@ -572,7 +449,7 @@ class AppRouter {
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
loadContent(ctx, route, html, request) {
|
#loadContent(ctx, route, html, request) {
|
||||||
html = globalize.translateHtml(html, route.dictionary);
|
html = globalize.translateHtml(html, route.dictionary);
|
||||||
request.view = html;
|
request.view = html;
|
||||||
|
|
||||||
@ -586,7 +463,7 @@ class AppRouter {
|
|||||||
ctx.handled = true;
|
ctx.handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRequestFile() {
|
#getRequestFile() {
|
||||||
let path = window.location.pathname || '';
|
let path = window.location.pathname || '';
|
||||||
|
|
||||||
const index = path.lastIndexOf('/');
|
const index = path.lastIndexOf('/');
|
||||||
@ -613,34 +490,10 @@ class AppRouter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handleRoute(ctx, next, route);
|
this.#handleRoute(ctx, next, route);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
showGuide() {
|
|
||||||
Dashboard.navigate('livetv.html?tab=1');
|
|
||||||
}
|
|
||||||
|
|
||||||
goHome() {
|
|
||||||
Dashboard.navigate('home.html');
|
|
||||||
}
|
|
||||||
|
|
||||||
showSearch() {
|
|
||||||
Dashboard.navigate('search.html');
|
|
||||||
}
|
|
||||||
|
|
||||||
showLiveTV() {
|
|
||||||
Dashboard.navigate('livetv.html');
|
|
||||||
}
|
|
||||||
|
|
||||||
showRecordedTV() {
|
|
||||||
Dashboard.navigate('livetv.html?tab=3');
|
|
||||||
}
|
|
||||||
|
|
||||||
showFavorites() {
|
|
||||||
Dashboard.navigate('home.html?tab=1');
|
|
||||||
}
|
|
||||||
|
|
||||||
getRouteUrl(item, options) {
|
getRouteUrl(item, options) {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
throw new Error('item cannot be null');
|
throw new Error('item cannot be null');
|
||||||
@ -835,10 +688,53 @@ class AppRouter {
|
|||||||
|
|
||||||
return '#!/details?id=' + id + '&serverId=' + serverId;
|
return '#!/details?id=' + id + '&serverId=' + serverId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showLocalLogin(serverId) {
|
||||||
|
return this.show('login.html?serverid=' + serverId);
|
||||||
|
}
|
||||||
|
|
||||||
|
showVideoOsd() {
|
||||||
|
return this.show('video');
|
||||||
|
}
|
||||||
|
|
||||||
|
showSelectServer() {
|
||||||
|
return this.show('selectserver.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
showSettings() {
|
||||||
|
return this.show('mypreferencesmenu.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
showNowPlaying() {
|
||||||
|
return this.show('queue');
|
||||||
|
}
|
||||||
|
|
||||||
|
showGuide() {
|
||||||
|
return this.show('livetv.html?tab=1');
|
||||||
|
}
|
||||||
|
|
||||||
|
goHome() {
|
||||||
|
return this.show('home.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
showSearch() {
|
||||||
|
return this.show('search.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
showLiveTV() {
|
||||||
|
return this.show('livetv.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
showRecordedTV() {
|
||||||
|
return this.show('livetv.html?tab=3');
|
||||||
|
}
|
||||||
|
|
||||||
|
showFavorites() {
|
||||||
|
return this.show('home.html?tab=1');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const appRouter = new AppRouter();
|
export const appRouter = new AppRouter();
|
||||||
|
|
||||||
window.Emby = window.Emby || {};
|
window.Emby = window.Emby || {};
|
||||||
|
|
||||||
window.Emby.Page = appRouter;
|
window.Emby.Page = appRouter;
|
||||||
|
@ -163,6 +163,10 @@ async function onAppReady() {
|
|||||||
import('../assets/css/ios.scss');
|
import('../assets/css/ios.scss');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Events.on(appHost, 'resume', () => {
|
||||||
|
ServerConnections.currentApiClient()?.ensureWebSocket();
|
||||||
|
});
|
||||||
|
|
||||||
appRouter.start();
|
appRouter.start();
|
||||||
|
|
||||||
if (!browser.tv && !browser.xboxOne && !browser.ps4) {
|
if (!browser.tv && !browser.xboxOne && !browser.ps4) {
|
||||||
|
Loading…
Reference in New Issue
Block a user