mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge branch 'master' into audio-normalization
This commit is contained in:
commit
8d5475a21b
143 changed files with 1557 additions and 1079 deletions
|
@ -224,7 +224,7 @@ const uaMatch = function (ua) {
|
|||
|
||||
version = version || match[2] || '0';
|
||||
|
||||
let versionMajor = parseInt(version.split('.')[0]);
|
||||
let versionMajor = parseInt(version.split('.')[0], 10);
|
||||
|
||||
if (isNaN(versionMajor)) {
|
||||
versionMajor = 0;
|
||||
|
@ -295,7 +295,7 @@ if (browser.web0s) {
|
|||
delete browser.safari;
|
||||
|
||||
const v = (navigator.appVersion).match(/Tizen (\d+).(\d+)/);
|
||||
browser.tizenVersion = parseInt(v[1]);
|
||||
browser.tizenVersion = parseInt(v[1], 10);
|
||||
} else {
|
||||
browser.orsay = userAgent.toLowerCase().indexOf('smarthub') !== -1;
|
||||
}
|
||||
|
|
|
@ -303,7 +303,7 @@ import { getParameterByName } from '../utils/url.ts';
|
|||
updateEditorNode(this, item);
|
||||
}).on('pagebeforeshow', '.metadataEditorPage', function () {
|
||||
/* eslint-disable-next-line @babel/no-unused-expressions */
|
||||
import('../assets/css/metadataeditor.scss');
|
||||
import('../styles/metadataeditor.scss');
|
||||
}).on('pagebeforeshow', '.metadataEditorPage', function () {
|
||||
const page = this;
|
||||
Dashboard.getCurrentUser().then(function (user) {
|
||||
|
|
|
@ -50,6 +50,11 @@ const NavigationKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
|||
*/
|
||||
const InteractiveElements = ['INPUT', 'TEXTAREA'];
|
||||
|
||||
/**
|
||||
* Types of INPUT element for which navigation shouldn't be constrained.
|
||||
*/
|
||||
const NonInteractiveInputElements = ['button', 'checkbox', 'color', 'file', 'hidden', 'image', 'radio', 'reset', 'submit'];
|
||||
|
||||
let hasFieldKey = false;
|
||||
try {
|
||||
hasFieldKey = 'key' in new KeyboardEvent('keydown');
|
||||
|
@ -84,6 +89,24 @@ export function isNavigationKey(key) {
|
|||
return NavigationKeys.indexOf(key) != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns _true_ if the element is interactive.
|
||||
*
|
||||
* @param {Element} element - Element.
|
||||
* @return {boolean} _true_ if the element is interactive.
|
||||
*/
|
||||
export function isInteractiveElement(element) {
|
||||
if (element && InteractiveElements.includes(element.tagName)) {
|
||||
if (element.tagName === 'INPUT') {
|
||||
return !NonInteractiveInputElements.includes(element.type);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function enable() {
|
||||
window.addEventListener('keydown', function (e) {
|
||||
const key = getKeyName(e);
|
||||
|
@ -97,7 +120,7 @@ export function enable() {
|
|||
|
||||
switch (key) {
|
||||
case 'ArrowLeft':
|
||||
if (!InteractiveElements.includes(document.activeElement?.tagName)) {
|
||||
if (!isInteractiveElement(document.activeElement)) {
|
||||
inputManager.handleCommand('left');
|
||||
} else {
|
||||
capture = false;
|
||||
|
@ -107,7 +130,7 @@ export function enable() {
|
|||
inputManager.handleCommand('up');
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
if (!InteractiveElements.includes(document.activeElement?.tagName)) {
|
||||
if (!isInteractiveElement(document.activeElement)) {
|
||||
inputManager.handleCommand('right');
|
||||
} else {
|
||||
capture = false;
|
||||
|
|
|
@ -16,14 +16,15 @@ import imageHelper from './imagehelper';
|
|||
import { getMenuLinks } from '../scripts/settings/webSettings';
|
||||
import Dashboard, { pageClassOn } from '../utils/dashboard';
|
||||
import ServerConnections from '../components/ServerConnections';
|
||||
import { PluginType } from '../types/plugin.ts';
|
||||
import Events from '../utils/events.ts';
|
||||
import { getParameterByName } from '../utils/url.ts';
|
||||
|
||||
import '../elements/emby-button/paper-icon-button-light';
|
||||
|
||||
import 'material-design-icons-iconfont';
|
||||
import '../assets/css/scrollstyles.scss';
|
||||
import '../assets/css/flexstyles.scss';
|
||||
import '../styles/scrollstyles.scss';
|
||||
import '../styles/flexstyles.scss';
|
||||
|
||||
/* eslint-disable indent */
|
||||
|
||||
|
@ -159,7 +160,7 @@ import '../assets/css/flexstyles.scss';
|
|||
// Button is present
|
||||
headerSyncButton
|
||||
// SyncPlay plugin is loaded
|
||||
&& pluginManager.plugins.filter(plugin => plugin.id === 'syncplay').length > 0
|
||||
&& pluginManager.ofType(PluginType.SyncPlay).length > 0
|
||||
// SyncPlay enabled for user
|
||||
&& policy?.SyncPlayAccess !== 'None'
|
||||
) {
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
import '../elements/emby-button/emby-button';
|
||||
import '../elements/emby-input/emby-input';
|
||||
import '../scripts/livetvcomponents';
|
||||
import '../elements/emby-button/paper-icon-button-light';
|
||||
import '../elements/emby-itemscontainer/emby-itemscontainer';
|
||||
import '../elements/emby-collapse/emby-collapse';
|
||||
import '../elements/emby-select/emby-select';
|
||||
import '../elements/emby-checkbox/emby-checkbox';
|
||||
import '../elements/emby-slider/emby-slider';
|
||||
import '../assets/css/livetv.scss';
|
||||
import '../components/listview/listview.scss';
|
||||
import '../assets/css/dashboard.scss';
|
||||
import '../assets/css/detailtable.scss';
|
||||
import { appRouter } from '../components/appRouter';
|
||||
|
||||
/* eslint-disable indent */
|
||||
|
||||
console.groupCollapsed('defining core routes');
|
||||
|
||||
function defineRoute(newRoute) {
|
||||
const path = newRoute.alias ? newRoute.alias : newRoute.path;
|
||||
console.debug('defining route: ' + path);
|
||||
newRoute.dictionary = 'core';
|
||||
appRouter.addRoute(path, newRoute);
|
||||
}
|
||||
|
||||
defineRoute({
|
||||
alias: '/addserver.html',
|
||||
path: 'session/addServer/index.html',
|
||||
autoFocus: false,
|
||||
anonymous: true,
|
||||
startup: true,
|
||||
controller: 'session/addServer/index'
|
||||
});
|
||||
|
||||
defineRoute({
|
||||
alias: '/selectserver.html',
|
||||
path: 'session/selectServer/index.html',
|
||||
autoFocus: false,
|
||||
anonymous: true,
|
||||
startup: true,
|
||||
controller: 'session/selectServer/index',
|
||||
type: 'selectserver'
|
||||
});
|
||||
|
||||
defineRoute({
|
||||
alias: '/login.html',
|
||||
path: 'session/login/index.html',
|
||||
autoFocus: false,
|
||||
anonymous: true,
|
||||
startup: true,
|
||||
controller: 'session/login/index',
|
||||
type: 'login'
|
||||
});
|
||||
|
||||
defineRoute({
|
||||
alias: '/forgotpassword.html',
|
||||
path: 'session/forgotPassword/index.html',
|
||||
anonymous: true,
|
||||
startup: true,
|
||||
controller: 'session/forgotPassword/index'
|
||||
});
|
||||
|
||||
defineRoute({
|
||||
alias: '/forgotpasswordpin.html',
|
||||
path: 'session/resetPassword/index.html',
|
||||
autoFocus: false,
|
||||
anonymous: true,
|
||||
startup: true,
|
||||
controller: 'session/resetPassword/index'
|
||||
});
|
||||
|
||||
defineRoute({
|
||||
alias: '/wizardremoteaccess.html',
|
||||
path: 'wizard/remote/index.html',
|
||||
autoFocus: false,
|
||||
anonymous: true,
|
||||
controller: 'wizard/remote/index'
|
||||
});
|
||||
|
||||
defineRoute({
|
||||
alias: '/wizardfinish.html',
|
||||
path: 'wizard/finish/index.html',
|
||||
autoFocus: false,
|
||||
anonymous: true,
|
||||
controller: 'wizard/finish/index'
|
||||
});
|
||||
|
||||
defineRoute({
|
||||
alias: '/wizardlibrary.html',
|
||||
path: 'wizard/library.html',
|
||||
autoFocus: false,
|
||||
anonymous: true,
|
||||
controller: 'dashboard/library'
|
||||
});
|
||||
|
||||
defineRoute({
|
||||
alias: '/wizardsettings.html',
|
||||
path: 'wizard/settings/index.html',
|
||||
autoFocus: false,
|
||||
anonymous: true,
|
||||
controller: 'wizard/settings/index'
|
||||
});
|
||||
|
||||
defineRoute({
|
||||
alias: '/wizardstart.html',
|
||||
path: 'wizard/start/index.html',
|
||||
autoFocus: false,
|
||||
anonymous: true,
|
||||
controller: 'wizard/start/index'
|
||||
});
|
||||
|
||||
defineRoute({
|
||||
alias: '/wizarduser.html',
|
||||
path: 'wizard/user/index.html',
|
||||
controller: 'wizard/user/index',
|
||||
autoFocus: false,
|
||||
anonymous: true
|
||||
});
|
||||
|
||||
console.groupEnd('defining core routes');
|
||||
|
||||
/* eslint-enable indent */
|
|
@ -3,6 +3,7 @@ import { pluginManager } from '../components/pluginManager';
|
|||
import inputManager from './inputManager';
|
||||
import * as userSettings from './settings/userSettings';
|
||||
import ServerConnections from '../components/ServerConnections';
|
||||
import { PluginType } from '../types/plugin.ts';
|
||||
import Events from '../utils/events.ts';
|
||||
|
||||
import './screensavermanager.scss';
|
||||
|
@ -34,7 +35,7 @@ function getScreensaverPlugin(isLoggedIn) {
|
|||
option = isLoggedIn ? 'backdropscreensaver' : 'logoscreensaver';
|
||||
}
|
||||
|
||||
const plugins = pluginManager.ofType('screensaver');
|
||||
const plugins = pluginManager.ofType(PluginType.Screensaver);
|
||||
|
||||
for (const plugin of plugins) {
|
||||
if (plugin.id === option) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import focusManager from '../components/focusManager';
|
||||
import dom from './dom';
|
||||
import '../assets/css/scrollstyles.scss';
|
||||
import '../styles/scrollstyles.scss';
|
||||
|
||||
function getBoundingClientRect(elem) {
|
||||
// Support: BlackBerry 5, iOS 3 (original iPhone)
|
||||
|
|
|
@ -98,11 +98,11 @@ function processGeneralCommand(cmd, apiClient) {
|
|||
break;
|
||||
case 'SetAudioStreamIndex':
|
||||
notifyApp();
|
||||
playbackManager.setAudioStreamIndex(parseInt(cmd.Arguments.Index));
|
||||
playbackManager.setAudioStreamIndex(parseInt(cmd.Arguments.Index, 10));
|
||||
break;
|
||||
case 'SetSubtitleStreamIndex':
|
||||
notifyApp();
|
||||
playbackManager.setSubtitleStreamIndex(parseInt(cmd.Arguments.Index));
|
||||
playbackManager.setSubtitleStreamIndex(parseInt(cmd.Arguments.Index, 10));
|
||||
break;
|
||||
case 'ToggleFullscreen':
|
||||
inputManager.handleCommand('togglefullscreen');
|
||||
|
|
|
@ -70,7 +70,7 @@ class AppSettings {
|
|||
// return a huge number so that it always direct plays
|
||||
return 150000000;
|
||||
} else {
|
||||
return parseInt(this.get(key) || '0') || 1500000;
|
||||
return parseInt(this.get(key) || '0', 10) || 1500000;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ class AppSettings {
|
|||
}
|
||||
|
||||
const defaultValue = 320000;
|
||||
return parseInt(this.get('maxStaticMusicBitrate') || defaultValue.toString()) || defaultValue;
|
||||
return parseInt(this.get('maxStaticMusicBitrate') || defaultValue.toString(), 10) || defaultValue;
|
||||
}
|
||||
|
||||
maxChromecastBitrate(val) {
|
||||
|
@ -89,7 +89,7 @@ class AppSettings {
|
|||
}
|
||||
|
||||
val = this.get('chromecastBitrate1');
|
||||
return val ? parseInt(val) : null;
|
||||
return val ? parseInt(val, 10) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -361,7 +361,7 @@ export class UserSettings {
|
|||
return this.set('skipBackLength', val.toString());
|
||||
}
|
||||
|
||||
return parseInt(this.get('skipBackLength') || '10000');
|
||||
return parseInt(this.get('skipBackLength') || '10000', 10);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -374,7 +374,7 @@ export class UserSettings {
|
|||
return this.set('skipForwardLength', val.toString());
|
||||
}
|
||||
|
||||
return parseInt(this.get('skipForwardLength') || '30000');
|
||||
return parseInt(this.get('skipForwardLength') || '30000', 10);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue