1
0
Fork 0
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:
TelepathicWalrus 2023-04-22 18:59:40 +01:00 committed by GitHub
commit 8bfc387b85
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
320 changed files with 55219 additions and 49479 deletions

View file

@ -6,7 +6,6 @@
"./dist/libraries/pdf.worker.js", "./dist/libraries/pdf.worker.js",
"./dist/libraries/worker-bundle.js", "./dist/libraries/worker-bundle.js",
"./dist/libraries/wasm-gen/libarchive.js", "./dist/libraries/wasm-gen/libarchive.js",
"./dist/node_modules.@jellyfin.libass-wasm.*.chunk.js",
"./dist/serviceworker.js" "./dist/serviceworker.js"
] ]
} }

View file

@ -64,7 +64,9 @@ module.exports = {
'no-var': ['error'], 'no-var': ['error'],
'no-void': ['error', { 'allowAsStatement': true }], 'no-void': ['error', { 'allowAsStatement': true }],
'no-warning-comments': ['warn', { 'terms': ['fixme', 'hack', 'xxx'] }], 'no-warning-comments': ['warn', { 'terms': ['fixme', 'hack', 'xxx'] }],
'object-curly-spacing': ['error', 'always'],
'one-var': ['error', 'never'], 'one-var': ['error', 'never'],
'operator-linebreak': ['error', 'before', { overrides: { '?': 'after', ':': 'after', '=': 'after' } }],
'padded-blocks': ['error', 'never'], 'padded-blocks': ['error', 'never'],
'prefer-const': ['error', { 'destructuring': 'all' }], 'prefer-const': ['error', { 'destructuring': 'all' }],
'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }], 'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }],
@ -267,7 +269,6 @@ module.exports = {
'no-useless-constructor': ['off'], 'no-useless-constructor': ['off'],
'@typescript-eslint/no-useless-constructor': ['error'], '@typescript-eslint/no-useless-constructor': ['error'],
'max-params': ['error', 7],
'sonarjs/cognitive-complexity': ['warn'] 'sonarjs/cognitive-complexity': ['warn']
} }
} }

6
.github/CODEOWNERS vendored
View file

@ -1,6 +1,2 @@
.ci @dkanada @EraYaN * @jellyfin/web
.github @jellyfin/core .github @jellyfin/core
fedora @joshuaboniface
debian @joshuaboniface
.copr @joshuaboniface
deployment @joshuaboniface

View file

@ -19,13 +19,13 @@ jobs:
language: [ 'javascript' ] language: [ 'javascript' ]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7 uses: github/codeql-action/init@b2c19fb9a2a485599ccf4ed5d65527d94bc57226 # v2.3.0
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
queries: +security-extended queries: +security-extended
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7 uses: github/codeql-action/autobuild@b2c19fb9a2a485599ccf4ed5d65527d94bc57226 # v2.3.0
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7 uses: github/codeql-action/analyze@b2c19fb9a2a485599ccf4ed5d65527d94bc57226 # v2.3.0

View file

@ -12,13 +12,13 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Notify as seen - name: Notify as seen
uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # v2.1.1 uses: peter-evans/create-or-update-comment@3383acd359705b10cb1eeef05c0e88c056ea4666 # v3.0.0
with: with:
token: ${{ secrets.JF_BOT_TOKEN }} token: ${{ secrets.JF_BOT_TOKEN }}
comment-id: ${{ github.event.comment.id }} comment-id: ${{ github.event.comment.id }}
reactions: '+1' reactions: '+1'
- name: Checkout the latest code - name: Checkout the latest code
uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
with: with:
token: ${{ secrets.JF_BOT_TOKEN }} token: ${{ secrets.JF_BOT_TOKEN }}
fetch-depth: 0 fetch-depth: 0
@ -26,3 +26,11 @@ jobs:
uses: cirrus-actions/rebase@b87d48154a87a85666003575337e27b8cd65f691 # 1.8 uses: cirrus-actions/rebase@b87d48154a87a85666003575337e27b8cd65f691 # 1.8
env: env:
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}
- name: Comment on failure
if: failure()
uses: peter-evans/create-or-update-comment@3383acd359705b10cb1eeef05c0e88c056ea4666 # v3.0.0
with:
token: ${{ secrets.JF_BOT_TOKEN }}
issue-number: ${{ github.event.issue.number }}
body: |
I'm sorry @${{ github.event.comment.user.login }}, I'm afraid I can't do that.

View file

@ -13,7 +13,7 @@ jobs:
steps: steps:
- name: Check out Git repository - name: Check out Git repository
uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
- name: Setup node environment - name: Setup node environment
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
@ -37,7 +37,7 @@ jobs:
steps: steps:
- name: Check out Git repository - name: Check out Git repository
uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
- name: Setup node environment - name: Setup node environment
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
@ -58,7 +58,7 @@ jobs:
steps: steps:
- name: Check out Git repository - name: Check out Git repository
uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
- name: Setup node environment - name: Setup node environment
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
@ -82,7 +82,7 @@ jobs:
steps: steps:
- name: Check out Git repository - name: Check out Git repository
uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
- name: Setup node environment - name: Setup node environment
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0

View file

@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ contains(github.repository, 'jellyfin/') }} if: ${{ contains(github.repository, 'jellyfin/') }}
steps: steps:
- uses: actions/stale@6f05e4244c9a0b2ed3401882b05d701dd0a7289b # v7.0.0 - uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84 # v8.0.0
with: with:
repo-token: ${{ secrets.JF_BOT_TOKEN }} repo-token: ${{ secrets.JF_BOT_TOKEN }}
operations-per-run: 75 operations-per-run: 75
@ -37,7 +37,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ contains(github.repository, 'jellyfin/') }} if: ${{ contains(github.repository, 'jellyfin/') }}
steps: steps:
- uses: actions/stale@6f05e4244c9a0b2ed3401882b05d701dd0a7289b # v7.0.0 - uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84 # v8.0.0
with: with:
repo-token: ${{ secrets.JF_BOT_TOKEN }} repo-token: ${{ secrets.JF_BOT_TOKEN }}
operations-per-run: 75 operations-per-run: 75

View file

@ -13,7 +13,7 @@ jobs:
steps: steps:
- name: Check out Git repository - name: Check out Git repository
uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
- name: Setup node environment - name: Setup node environment
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0

View file

@ -61,6 +61,8 @@
- [Rob Farraher](https://github.com/farraherbg) - [Rob Farraher](https://github.com/farraherbg)
- [TelepathicWalrus](https://github.com/TelepathicWalrus) - [TelepathicWalrus](https://github.com/TelepathicWalrus)
- [Pier-Luc Ducharme](https://github.com/pl-ducharme) - [Pier-Luc Ducharme](https://github.com/pl-ducharme)
- [Anantharaju S](https://github.com/Anantharajus)
- [Merlin Sievers](https://github.com/dann-merlin)
# Emby Contributors # Emby Contributors

View file

@ -12,14 +12,7 @@ module.exports = {
corejs: 3 corejs: 3
} }
], ],
'@babel/preset-react', '@babel/preset-react'
[
'@babel/preset-typescript',
{
isTSX: true,
allExtensions: true
}
]
], ],
plugins: [ plugins: [
'@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-class-properties',

View file

@ -1,4 +1,4 @@
FROM centos:8 FROM quay.io/centos/centos:stream8
# Docker build arguments # Docker build arguments
ARG SOURCE_DIR=/jellyfin ARG SOURCE_DIR=/jellyfin
@ -12,7 +12,7 @@ ENV IS_DOCKER=YES
# Prepare CentOS environment # Prepare CentOS environment
RUN yum update -y \ RUN yum update -y \
&& yum install -y epel-release \ && yum install -y epel-release \
&& yum install -y @buildsys-build rpmdevtools git yum-plugins-core autoconf automake glibc-devel gcc-c++ make \ && yum install -y rpmdevtools git autoconf automake glibc-devel gcc-c++ make \
&& curl -fsSL https://rpm.nodesource.com/setup_16.x | bash - \ && curl -fsSL https://rpm.nodesource.com/setup_16.x | bash - \
&& yum install -y nodejs && yum install -y nodejs

5745
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -5,24 +5,23 @@
"repository": "https://github.com/jellyfin/jellyfin-web", "repository": "https://github.com/jellyfin/jellyfin-web",
"license": "GPL-2.0-or-later", "license": "GPL-2.0-or-later",
"devDependencies": { "devDependencies": {
"@babel/core": "7.21.0", "@babel/core": "7.21.4",
"@babel/eslint-parser": "7.19.1", "@babel/eslint-parser": "7.21.3",
"@babel/eslint-plugin": "7.19.1", "@babel/eslint-plugin": "7.19.1",
"@babel/plugin-proposal-class-properties": "7.18.6", "@babel/plugin-proposal-class-properties": "7.18.6",
"@babel/plugin-proposal-private-methods": "7.18.6", "@babel/plugin-proposal-private-methods": "7.18.6",
"@babel/plugin-transform-modules-umd": "7.18.6", "@babel/plugin-transform-modules-umd": "7.18.6",
"@babel/preset-env": "7.20.2", "@babel/preset-env": "7.21.4",
"@babel/preset-react": "7.18.6", "@babel/preset-react": "7.18.6",
"@babel/preset-typescript": "7.21.0",
"@types/escape-html": "1.0.2", "@types/escape-html": "1.0.2",
"@types/loadable__component": "5.13.4", "@types/loadable__component": "5.13.4",
"@types/lodash-es": "4.17.6", "@types/lodash-es": "4.17.7",
"@types/react": "17.0.53", "@types/react": "17.0.58",
"@types/react-dom": "17.0.19", "@types/react-dom": "17.0.19",
"@typescript-eslint/eslint-plugin": "5.54.1", "@typescript-eslint/eslint-plugin": "5.58.0",
"@typescript-eslint/parser": "5.54.1", "@typescript-eslint/parser": "5.58.0",
"@uupaa/dynamic-import-polyfill": "1.0.2", "@uupaa/dynamic-import-polyfill": "1.0.2",
"autoprefixer": "10.4.13", "autoprefixer": "10.4.14",
"babel-loader": "9.1.2", "babel-loader": "9.1.2",
"babel-plugin-dynamic-import-polyfill": "1.0.0", "babel-plugin-dynamic-import-polyfill": "1.0.0",
"clean-webpack-plugin": "4.0.0", "clean-webpack-plugin": "4.0.0",
@ -30,39 +29,39 @@
"copy-webpack-plugin": "11.0.0", "copy-webpack-plugin": "11.0.0",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"css-loader": "6.7.3", "css-loader": "6.7.3",
"cssnano": "5.1.15", "cssnano": "6.0.0",
"es-check": "7.1.0", "es-check": "7.1.1",
"eslint": "8.35.0", "eslint": "8.38.0",
"eslint-plugin-compat": "4.1.2", "eslint-plugin-compat": "4.1.4",
"eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-eslint-comments": "3.2.0",
"eslint-plugin-import": "2.27.5", "eslint-plugin-import": "2.27.5",
"eslint-plugin-jsx-a11y": "6.7.1", "eslint-plugin-jsx-a11y": "6.7.1",
"eslint-plugin-promise": "6.1.1", "eslint-plugin-promise": "6.1.1",
"eslint-plugin-react": "7.32.2", "eslint-plugin-react": "7.32.2",
"eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-sonarjs": "0.18.0", "eslint-plugin-sonarjs": "0.19.0",
"expose-loader": "4.0.0", "expose-loader": "4.1.0",
"html-loader": "4.2.0", "html-loader": "4.2.0",
"html-webpack-plugin": "5.5.0", "html-webpack-plugin": "5.5.0",
"mini-css-extract-plugin": "2.7.3", "mini-css-extract-plugin": "2.7.5",
"postcss": "8.4.21", "postcss": "8.4.21",
"postcss-loader": "7.0.2", "postcss-loader": "7.2.4",
"postcss-preset-env": "8.0.1", "postcss-preset-env": "8.3.1",
"postcss-scss": "4.0.6", "postcss-scss": "4.0.6",
"sass": "1.58.3", "sass": "1.62.0",
"sass-loader": "13.2.0", "sass-loader": "13.2.2",
"source-map-loader": "4.0.1", "source-map-loader": "4.0.1",
"style-loader": "3.3.1", "style-loader": "3.3.2",
"stylelint": "15.2.0", "stylelint": "15.4.0",
"stylelint-config-rational-order": "0.1.2", "stylelint-config-rational-order": "0.1.2",
"stylelint-no-browser-hacks": "1.2.1", "stylelint-no-browser-hacks": "1.2.1",
"stylelint-order": "6.0.3", "stylelint-order": "6.0.3",
"stylelint-scss": "4.4.0", "stylelint-scss": "4.6.0",
"ts-loader": "9.4.2", "ts-loader": "9.4.2",
"typescript": "4.9.5", "typescript": "5.0.4",
"webpack": "5.76.0", "webpack": "5.79.0",
"webpack-cli": "5.0.1", "webpack-cli": "5.0.1",
"webpack-dev-server": "4.11.1", "webpack-dev-server": "4.13.2",
"webpack-merge": "5.8.0", "webpack-merge": "5.8.0",
"workbox-webpack-plugin": "6.5.4", "workbox-webpack-plugin": "6.5.4",
"worker-loader": "3.0.8" "worker-loader": "3.0.8"
@ -74,35 +73,36 @@
"@fontsource/noto-sans-kr": "4.5.12", "@fontsource/noto-sans-kr": "4.5.12",
"@fontsource/noto-sans-sc": "4.5.12", "@fontsource/noto-sans-sc": "4.5.12",
"@fontsource/noto-sans-tc": "4.5.12", "@fontsource/noto-sans-tc": "4.5.12",
"@jellyfin/libass-wasm": "4.1.1",
"@jellyfin/sdk": "unstable", "@jellyfin/sdk": "unstable",
"@loadable/component": "5.15.3", "@loadable/component": "5.15.3",
"blurhash": "2.0.5", "blurhash": "2.0.5",
"classlist.js": "https://github.com/eligrey/classList.js/archive/1.2.20180112.tar.gz", "classlist.js": "https://github.com/eligrey/classList.js/archive/1.2.20180112.tar.gz",
"classnames": "2.3.2", "classnames": "2.3.2",
"core-js": "3.29.0", "core-js": "3.30.1",
"date-fns": "2.29.3", "date-fns": "2.29.3",
"dompurify": "3.0.1", "dompurify": "3.0.1",
"epubjs": "0.4.2", "epubjs": "0.3.93",
"escape-html": "1.0.3", "escape-html": "1.0.3",
"event-target-polyfill": "github:ThaUnknown/event-target-polyfill",
"fast-text-encoding": "1.0.6", "fast-text-encoding": "1.0.6",
"flv.js": "1.6.2", "flv.js": "1.6.2",
"headroom.js": "0.12.0", "headroom.js": "0.12.0",
"history": "5.3.0", "history": "5.3.0",
"hls.js": "1.2.4", "hls.js": "1.4.0",
"intersection-observer": "0.12.2", "intersection-observer": "0.12.2",
"jassub": "1.5.12",
"jellyfin-apiclient": "1.10.0", "jellyfin-apiclient": "1.10.0",
"jquery": "3.6.3", "jquery": "3.6.4",
"jstree": "3.3.15", "jstree": "3.3.15",
"libarchive.js": "1.3.0", "libarchive.js": "1.3.0",
"lodash-es": "4.17.21", "lodash-es": "4.17.21",
"marked": "4.2.12", "marked": "4.3.0",
"material-design-icons-iconfont": "6.7.0", "material-design-icons-iconfont": "6.7.0",
"native-promise-only": "0.8.1", "native-promise-only": "0.8.1",
"pdfjs-dist": "2.16.105", "pdfjs-dist": "3.5.141",
"react": "17.0.2", "react": "17.0.2",
"react-dom": "17.0.2", "react-dom": "17.0.2",
"react-router-dom": "6.8.2", "react-router-dom": "6.10.0",
"resize-observer-polyfill": "1.5.1", "resize-observer-polyfill": "1.5.1",
"screenfull": "6.0.2", "screenfull": "6.0.2",
"sortablejs": "1.15.0", "sortablejs": "1.15.0",
@ -131,8 +131,8 @@
"scripts": { "scripts": {
"start": "npm run serve", "start": "npm run serve",
"serve": "webpack serve --config webpack.dev.js", "serve": "webpack serve --config webpack.dev.js",
"build:development": "webpack --config webpack.dev.js", "build:development": "cross-env NODE_OPTIONS=\"--max_old_space_size=6144\" webpack --config webpack.dev.js",
"build:production": "cross-env NODE_ENV=\"production\" webpack --config webpack.prod.js", "build:production": "cross-env NODE_ENV=\"production\" NODE_OPTIONS=\"--max_old_space_size=6144\" webpack --config webpack.prod.js",
"build:check": "tsc --noEmit", "build:check": "tsc --noEmit",
"escheck": "es-check", "escheck": "es-check",
"lint": "eslint \"./\"", "lint": "eslint \"./\"",

View file

@ -7,8 +7,8 @@ const config = () => ({
plugins: [ plugins: [
// Explicitly specify browserslist to override ones from node_modules // Explicitly specify browserslist to override ones from node_modules
// For example, Swiper has it in its package.json // For example, Swiper has it in its package.json
postcssPresetEnv({browsers: packageConfig.browserslist}), postcssPresetEnv({ browsers: packageConfig.browserslist }),
autoprefixer({overrideBrowserslist: packageConfig.browserslist}), autoprefixer({ overrideBrowserslist: packageConfig.browserslist }),
cssnano() cssnano()
] ]
}); });

View file

@ -1,15 +1,38 @@
import { History } from '@remix-run/router'; import { History } from '@remix-run/router';
import React from 'react'; import React, { useEffect } from 'react';
import { HistoryRouter } from './components/HistoryRouter'; import { HistoryRouter } from './components/HistoryRouter';
import { ApiProvider } from './hooks/useApi'; import { ApiProvider } from './hooks/useApi';
import AppRoutes from './routes/index'; import { AppRoutes, ExperimentalAppRoutes } from './routes';
const App = ({ history }: { history: History }) => { const App = ({ history }: { history: History }) => {
const layoutMode = localStorage.getItem('layout');
useEffect(() => {
Promise.all([
// Initialize the UI components after first render
import('./scripts/libraryMenu'),
import('./scripts/autoBackdrops')
]);
}, []);
return ( return (
<ApiProvider> <ApiProvider>
<HistoryRouter history={history}> <HistoryRouter history={history}>
<AppRoutes /> <div className='backdropContainer' />
<div className='backgroundContainer' />
<div className='mainDrawer hide'>
<div className='mainDrawer-scrollContainer scrollContainer focuscontainer-y' />
</div>
<div className='skinHeader focuscontainer-x' />
<div className='mainAnimatedPages skinBody' />
<div className='skinBody'>
{layoutMode === 'experimental' ? <ExperimentalAppRoutes /> : <AppRoutes /> }
</div>
<div className='mainDrawerHandle' />
</HistoryRouter> </HistoryRouter>
</ApiProvider> </ApiProvider>
); );

View file

@ -1,6 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for controlling user parental control from. * Module for controlling user parental control from.
* @module components/accessSchedule/accessSchedule * @module components/accessSchedule/accessSchedule
@ -14,7 +11,7 @@ import '../../elements/emby-button/paper-icon-button-light';
import '../formdialog.scss'; import '../formdialog.scss';
import template from './accessSchedule.template.html'; import template from './accessSchedule.template.html';
function getDisplayTime(hours) { function getDisplayTime(hours) {
let minutes = 0; let minutes = 0;
const pct = hours % 1; const pct = hours % 1;
@ -23,9 +20,9 @@ import template from './accessSchedule.template.html';
} }
return datetime.getDisplayTime(new Date(2000, 1, 1, hours, minutes, 0, 0)); return datetime.getDisplayTime(new Date(2000, 1, 1, hours, minutes, 0, 0));
} }
function populateHours(context) { function populateHours(context) {
let html = ''; let html = '';
for (let i = 0; i < 24; i += 0.5) { for (let i = 0; i < 24; i += 0.5) {
@ -35,15 +32,15 @@ import template from './accessSchedule.template.html';
html += `<option value="24">${getDisplayTime(0)}</option>`; html += `<option value="24">${getDisplayTime(0)}</option>`;
context.querySelector('#selectStart').innerHTML = html; context.querySelector('#selectStart').innerHTML = html;
context.querySelector('#selectEnd').innerHTML = html; context.querySelector('#selectEnd').innerHTML = html;
} }
function loadSchedule(context, {DayOfWeek, StartHour, EndHour}) { function loadSchedule(context, { DayOfWeek, StartHour, EndHour }) {
context.querySelector('#selectDay').value = DayOfWeek || 'Sunday'; context.querySelector('#selectDay').value = DayOfWeek || 'Sunday';
context.querySelector('#selectStart').value = StartHour || 0; context.querySelector('#selectStart').value = StartHour || 0;
context.querySelector('#selectEnd').value = EndHour || 0; context.querySelector('#selectEnd').value = EndHour || 0;
} }
function submitSchedule(context, options) { function submitSchedule(context, options) {
const updatedSchedule = { const updatedSchedule = {
DayOfWeek: context.querySelector('#selectDay').value, DayOfWeek: context.querySelector('#selectDay').value,
StartHour: context.querySelector('#selectStart').value, StartHour: context.querySelector('#selectStart').value,
@ -58,9 +55,9 @@ import template from './accessSchedule.template.html';
context.submitted = true; context.submitted = true;
options.schedule = Object.assign(options.schedule, updatedSchedule); options.schedule = Object.assign(options.schedule, updatedSchedule);
dialogHelper.close(context); dialogHelper.close(context);
} }
export function show(options) { export function show(options) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const dlg = dialogHelper.createDialog({ const dlg = dialogHelper.createDialog({
removeOnClose: true, removeOnClose: true,
@ -89,9 +86,7 @@ import template from './accessSchedule.template.html';
return false; return false;
}); });
}); });
} }
/* eslint-enable indent */
export default { export default {
show: show show: show

View file

@ -11,9 +11,7 @@ import alert from './alert';
import { getLocale } from '../utils/dateFnsLocale.ts'; import { getLocale } from '../utils/dateFnsLocale.ts';
import { toBoolean } from '../utils/string.ts'; import { toBoolean } from '../utils/string.ts';
/* eslint-disable indent */ function getEntryHtml(entry, apiClient) {
function getEntryHtml(entry, apiClient) {
let html = ''; let html = '';
html += '<div class="listItem listItem-border">'; html += '<div class="listItem listItem-border">';
let color = '#00a4dc'; let color = '#00a4dc';
@ -54,15 +52,15 @@ import { toBoolean } from '../utils/string.ts';
html += '</div>'; html += '</div>';
return html; return html;
} }
function renderList(elem, apiClient, result) { function renderList(elem, apiClient, result) {
elem.innerHTML = result.Items.map(function (i) { elem.innerHTML = result.Items.map(function (i) {
return getEntryHtml(i, apiClient); return getEntryHtml(i, apiClient);
}).join(''); }).join('');
} }
function reloadData(instance, elem, apiClient, startIndex, limit) { function reloadData(instance, elem, apiClient, startIndex, limit) {
if (startIndex == null) { if (startIndex == null) {
startIndex = parseInt(elem.getAttribute('data-activitystartindex') || '0', 10); startIndex = parseInt(elem.getAttribute('data-activitystartindex') || '0', 10);
} }
@ -101,17 +99,17 @@ import { toBoolean } from '../utils/string.ts';
instance.items = result.Items; instance.items = result.Items;
renderList(elem, apiClient, result); renderList(elem, apiClient, result);
}); });
} }
function onActivityLogUpdate(e, apiClient) { function onActivityLogUpdate(e, apiClient) {
const options = this.options; const options = this.options;
if (options && options.serverId === apiClient.serverId()) { if (options && options.serverId === apiClient.serverId()) {
reloadData(this, options.element, apiClient); reloadData(this, options.element, apiClient);
} }
} }
function onListClick(e) { function onListClick(e) {
const btnEntryInfo = dom.parentWithClass(e.target, 'btnEntryInfo'); const btnEntryInfo = dom.parentWithClass(e.target, 'btnEntryInfo');
if (btnEntryInfo) { if (btnEntryInfo) {
@ -128,13 +126,13 @@ import { toBoolean } from '../utils/string.ts';
} }
} }
} }
} }
function showItemOverview(item) { function showItemOverview(item) {
alert({ alert({
text: item.Overview text: item.Overview
}); });
} }
class ActivityLog { class ActivityLog {
constructor(options) { constructor(options) {
@ -169,5 +167,3 @@ class ActivityLog {
} }
export default ActivityLog; export default ActivityLog;
/* eslint-enable indent */

View file

@ -3,18 +3,16 @@ import browser from '../scripts/browser';
import dialog from './dialog/dialog'; import dialog from './dialog/dialog';
import globalize from '../scripts/globalize'; import globalize from '../scripts/globalize';
/* eslint-disable indent */ function useNativeAlert() {
function useNativeAlert() {
// webOS seems to block modals // webOS seems to block modals
// Tizen 2.x seems to block modals // Tizen 2.x seems to block modals
return !browser.web0s return !browser.web0s
&& !(browser.tizenVersion && browser.tizenVersion < 3) && !(browser.tizenVersion && browser.tizenVersion < 3)
&& browser.tv && browser.tv
&& window.alert; && window.alert;
} }
export default async function (text, title) { export default async function (text, title) {
let options; let options;
if (typeof text === 'string') { if (typeof text === 'string') {
options = { options = {
@ -42,6 +40,4 @@ import globalize from '../scripts/globalize';
options.buttons = items; options.buttons = items;
return dialog.show(options); return dialog.show(options);
} }
} }
/* eslint-enable indent */

View file

@ -1,5 +1,3 @@
/* eslint-disable indent */
/** /**
* Module alphaPicker. * Module alphaPicker.
* @module components/alphaPicker/alphaPicker * @module components/alphaPicker/alphaPicker
@ -13,9 +11,9 @@ import './style.scss';
import '../../elements/emby-button/paper-icon-button-light'; import '../../elements/emby-button/paper-icon-button-light';
import 'material-design-icons-iconfont'; import 'material-design-icons-iconfont';
const selectedButtonClass = 'alphaPickerButton-selected'; const selectedButtonClass = 'alphaPickerButton-selected';
function focus() { function focus() {
const scope = this; const scope = this;
const selected = scope.querySelector(`.${selectedButtonClass}`); const selected = scope.querySelector(`.${selectedButtonClass}`);
@ -24,9 +22,9 @@ import 'material-design-icons-iconfont';
} else { } else {
focusManager.autoFocus(scope, true); focusManager.autoFocus(scope, true);
} }
} }
function getAlphaPickerButtonClassName(vertical) { function getAlphaPickerButtonClassName(vertical) {
let alphaPickerButtonClassName = 'alphaPickerButton'; let alphaPickerButtonClassName = 'alphaPickerButton';
if (layoutManager.tv) { if (layoutManager.tv) {
@ -38,19 +36,19 @@ import 'material-design-icons-iconfont';
} }
return alphaPickerButtonClassName; return alphaPickerButtonClassName;
} }
function getLetterButton(l, vertical) { function getLetterButton(l, vertical) {
return `<button data-value="${l}" class="${getAlphaPickerButtonClassName(vertical)}">${l}</button>`; return `<button data-value="${l}" class="${getAlphaPickerButtonClassName(vertical)}">${l}</button>`;
} }
function mapLetters(letters, vertical) { function mapLetters(letters, vertical) {
return letters.map(l => { return letters.map(l => {
return getLetterButton(l, vertical); return getLetterButton(l, vertical);
}); });
} }
function render(element, options) { function render(element, options) {
element.classList.add('alphaPicker'); element.classList.add('alphaPicker');
if (layoutManager.tv) { if (layoutManager.tv) {
@ -102,9 +100,9 @@ import 'material-design-icons-iconfont';
element.classList.add('focusable'); element.classList.add('focusable');
element.focus = focus; element.focus = focus;
} }
export class AlphaPicker { export class AlphaPicker {
constructor(options) { constructor(options) {
const self = this; const self = this;
@ -318,7 +316,6 @@ import 'material-design-icons-iconfont';
element.classList.remove('focuscontainer-x'); element.classList.remove('focuscontainer-x');
this.options = null; this.options = null;
} }
} }
/* eslint-enable indent */
export default AlphaPicker; export default AlphaPicker;

View file

@ -309,8 +309,8 @@ function askForExit() {
exitPromise = actionsheet.show({ exitPromise = actionsheet.show({
title: globalize.translate('MessageConfirmAppExit'), title: globalize.translate('MessageConfirmAppExit'),
items: [ items: [
{id: 'yes', name: globalize.translate('Yes')}, { id: 'yes', name: globalize.translate('Yes') },
{id: 'no', name: globalize.translate('No')} { id: 'no', name: globalize.translate('No') }
] ]
}).then(function (value) { }).then(function (value) {
if (value === 'yes') { if (value === 'yes') {
@ -366,20 +366,20 @@ export const appHost = {
}; };
}, },
deviceName: function () { deviceName: function () {
return window.NativeShell?.AppHost?.deviceName return window.NativeShell?.AppHost?.deviceName ?
? window.NativeShell.AppHost.deviceName() : getDeviceName(); window.NativeShell.AppHost.deviceName() : getDeviceName();
}, },
deviceId: function () { deviceId: function () {
return window.NativeShell?.AppHost?.deviceId return window.NativeShell?.AppHost?.deviceId ?
? window.NativeShell.AppHost.deviceId() : getDeviceId(); window.NativeShell.AppHost.deviceId() : getDeviceId();
}, },
appName: function () { appName: function () {
return window.NativeShell?.AppHost?.appName return window.NativeShell?.AppHost?.appName ?
? window.NativeShell.AppHost.appName() : appName; window.NativeShell.AppHost.appName() : appName;
}, },
appVersion: function () { appVersion: function () {
return window.NativeShell?.AppHost?.appVersion return window.NativeShell?.AppHost?.appVersion ?
? window.NativeShell.AppHost.appVersion() : Package.version; window.NativeShell.AppHost.appVersion() : Package.version;
}, },
getPushTokenInfo: function () { getPushTokenInfo: function () {
return {}; return {};

View file

@ -1,5 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for performing auto-focus. * Module for performing auto-focus.
* @module components/autoFocuser * @module components/autoFocuser
@ -8,22 +6,22 @@
import focusManager from './focusManager'; import focusManager from './focusManager';
import layoutManager from './layoutManager'; import layoutManager from './layoutManager';
/** /**
* Previously selected element. * Previously selected element.
*/ */
let activeElement; let activeElement;
/** /**
* Returns _true_ if AutoFocuser is enabled. * Returns _true_ if AutoFocuser is enabled.
*/ */
export function isEnabled() { export function isEnabled() {
return layoutManager.tv; return layoutManager.tv;
} }
/** /**
* Start AutoFocuser. * Start AutoFocuser.
*/ */
export function enable() { export function enable() {
if (!isEnabled()) { if (!isEnabled()) {
return; return;
} }
@ -33,14 +31,14 @@ import layoutManager from './layoutManager';
}); });
console.debug('AutoFocuser enabled'); console.debug('AutoFocuser enabled');
} }
/** /**
* Set focus on a suitable element, taking into account the previously selected. * Set focus on a suitable element, taking into account the previously selected.
* @param {HTMLElement} [container] - Element to limit scope. * @param {HTMLElement} [container] - Element to limit scope.
* @returns {HTMLElement} Focused element. * @returns {HTMLElement} Focused element.
*/ */
export function autoFocus(container) { export function autoFocus(container) {
if (!isEnabled()) { if (!isEnabled()) {
return null; return null;
} }
@ -92,9 +90,7 @@ import layoutManager from './layoutManager';
} }
return focusedElement; return focusedElement;
} }
/* eslint-enable indent */
export default { export default {
isEnabled: isEnabled, isEnabled: isEnabled,

View file

@ -7,19 +7,17 @@ import ServerConnections from '../ServerConnections';
import './backdrop.scss'; import './backdrop.scss';
/* eslint-disable indent */ function enableAnimation() {
function enableAnimation() {
return !browser.slow; return !browser.slow;
} }
function enableRotation() { function enableRotation() {
return !browser.tv return !browser.tv
// Causes high cpu usage // Causes high cpu usage
&& !browser.firefox; && !browser.firefox;
} }
class Backdrop { class Backdrop {
load(url, parent, existingBackdropImage) { load(url, parent, existingBackdropImage) {
const img = new Image(); const img = new Image();
const self = this; const self = this;
@ -80,10 +78,10 @@ import './backdrop.scss';
this.isDestroyed = true; this.isDestroyed = true;
this.cancelAnimation(); this.cancelAnimation();
} }
} }
let backdropContainer; let backdropContainer;
function getBackdropContainer() { function getBackdropContainer() {
if (!backdropContainer) { if (!backdropContainer) {
backdropContainer = document.querySelector('.backdropContainer'); backdropContainer = document.querySelector('.backdropContainer');
} }
@ -95,9 +93,9 @@ import './backdrop.scss';
} }
return backdropContainer; return backdropContainer;
} }
export function clearBackdrop(clearAll) { export function clearBackdrop(clearAll) {
clearRotation(); clearRotation();
if (currentLoadingBackdrop) { if (currentLoadingBackdrop) {
@ -113,38 +111,38 @@ import './backdrop.scss';
} }
internalBackdrop(false); internalBackdrop(false);
} }
let backgroundContainer; let backgroundContainer;
function getBackgroundContainer() { function getBackgroundContainer() {
if (!backgroundContainer) { if (!backgroundContainer) {
backgroundContainer = document.querySelector('.backgroundContainer'); backgroundContainer = document.querySelector('.backgroundContainer');
} }
return backgroundContainer; return backgroundContainer;
} }
function setBackgroundContainerBackgroundEnabled() { function setBackgroundContainerBackgroundEnabled() {
if (hasInternalBackdrop || hasExternalBackdrop) { if (hasInternalBackdrop || hasExternalBackdrop) {
getBackgroundContainer().classList.add('withBackdrop'); getBackgroundContainer().classList.add('withBackdrop');
} else { } else {
getBackgroundContainer().classList.remove('withBackdrop'); getBackgroundContainer().classList.remove('withBackdrop');
} }
} }
let hasInternalBackdrop; let hasInternalBackdrop;
function internalBackdrop(isEnabled) { function internalBackdrop(isEnabled) {
hasInternalBackdrop = isEnabled; hasInternalBackdrop = isEnabled;
setBackgroundContainerBackgroundEnabled(); setBackgroundContainerBackgroundEnabled();
} }
let hasExternalBackdrop; let hasExternalBackdrop;
export function externalBackdrop(isEnabled) { export function externalBackdrop(isEnabled) {
hasExternalBackdrop = isEnabled; hasExternalBackdrop = isEnabled;
setBackgroundContainerBackgroundEnabled(); setBackgroundContainerBackgroundEnabled();
} }
let currentLoadingBackdrop; let currentLoadingBackdrop;
function setBackdropImage(url) { function setBackdropImage(url) {
if (currentLoadingBackdrop) { if (currentLoadingBackdrop) {
currentLoadingBackdrop.destroy(); currentLoadingBackdrop.destroy();
currentLoadingBackdrop = null; currentLoadingBackdrop = null;
@ -163,9 +161,9 @@ import './backdrop.scss';
const instance = new Backdrop(); const instance = new Backdrop();
instance.load(url, elem, existingBackdropImage); instance.load(url, elem, existingBackdropImage);
currentLoadingBackdrop = instance; currentLoadingBackdrop = instance;
} }
function getItemImageUrls(item, imageOptions) { function getItemImageUrls(item, imageOptions) {
imageOptions = imageOptions || {}; imageOptions = imageOptions || {};
const apiClient = ServerConnections.getApiClient(item.ServerId); const apiClient = ServerConnections.getApiClient(item.ServerId);
@ -192,9 +190,9 @@ import './backdrop.scss';
} }
return []; return [];
} }
function getImageUrls(items, imageOptions) { function getImageUrls(items, imageOptions) {
const list = []; const list = [];
const onImg = img => { const onImg = img => {
list.push(img); list.push(img);
@ -206,16 +204,16 @@ import './backdrop.scss';
} }
return list; return list;
} }
function enabled() { function enabled() {
return userSettings.enableBackdrops(); return userSettings.enableBackdrops();
} }
let rotationInterval; let rotationInterval;
let currentRotatingImages = []; let currentRotatingImages = [];
let currentRotationIndex = -1; let currentRotationIndex = -1;
export function setBackdrops(items, imageOptions, enableImageRotation) { export function setBackdrops(items, imageOptions, enableImageRotation) {
if (enabled()) { if (enabled()) {
const images = getImageUrls(items, imageOptions); const images = getImageUrls(items, imageOptions);
@ -225,9 +223,9 @@ import './backdrop.scss';
clearBackdrop(); clearBackdrop();
} }
} }
} }
function startRotation(images, enableImageRotation) { function startRotation(images, enableImageRotation) {
if (isEqual(images, currentRotatingImages)) { if (isEqual(images, currentRotatingImages)) {
return; return;
} }
@ -242,9 +240,9 @@ import './backdrop.scss';
} }
onRotationInterval(); onRotationInterval();
} }
function onRotationInterval() { function onRotationInterval() {
if (playbackManager.isPlayingLocally(['Video'])) { if (playbackManager.isPlayingLocally(['Video'])) {
return; return;
} }
@ -256,9 +254,9 @@ import './backdrop.scss';
currentRotationIndex = newIndex; currentRotationIndex = newIndex;
setBackdropImage(currentRotatingImages[newIndex]); setBackdropImage(currentRotatingImages[newIndex]);
} }
function clearRotation() { function clearRotation() {
const interval = rotationInterval; const interval = rotationInterval;
if (interval) { if (interval) {
clearInterval(interval); clearInterval(interval);
@ -267,9 +265,9 @@ import './backdrop.scss';
rotationInterval = null; rotationInterval = null;
currentRotatingImages = []; currentRotatingImages = [];
currentRotationIndex = -1; currentRotationIndex = -1;
} }
export function setBackdrop(url, imageOptions) { export function setBackdrop(url, imageOptions) {
if (url && typeof url !== 'string') { if (url && typeof url !== 'string') {
url = getImageUrls([url], imageOptions)[0]; url = getImageUrls([url], imageOptions)[0];
} }
@ -280,9 +278,7 @@ import './backdrop.scss';
} else { } else {
clearBackdrop(); clearBackdrop();
} }
} }
/* eslint-enable indent */
/** /**
* @enum TransparencyLevel * @enum TransparencyLevel

View file

@ -1,4 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for building cards from item data. * Module for building cards from item data.
@ -25,31 +24,31 @@ import '../guide/programs.scss';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';
import { appRouter } from '../appRouter'; import { appRouter } from '../appRouter';
const enableFocusTransform = !browser.slow && !browser.edge; const enableFocusTransform = !browser.slow && !browser.edge;
/** /**
* Generate the HTML markup for cards for a set of items. * Generate the HTML markup for cards for a set of items.
* @param items - The items used to generate cards. * @param items - The items used to generate cards.
* @param options - The options of the cards. * @param options - The options of the cards.
* @returns {string} The HTML markup for the cards. * @returns {string} The HTML markup for the cards.
*/ */
export function getCardsHtml(items, options) { export function getCardsHtml(items, options) {
if (arguments.length === 1) { if (arguments.length === 1) {
options = arguments[0]; options = arguments[0];
items = options.items; items = options.items;
} }
return buildCardsHtmlInternal(items, options); return buildCardsHtmlInternal(items, options);
} }
/** /**
* Computes the number of posters per row. * Computes the number of posters per row.
* @param {string} shape - Shape of the cards. * @param {string} shape - Shape of the cards.
* @param {number} screenWidth - Width of the screen. * @param {number} screenWidth - Width of the screen.
* @param {boolean} isOrientationLandscape - Flag for the orientation of the screen. * @param {boolean} isOrientationLandscape - Flag for the orientation of the screen.
* @returns {number} Number of cards per row for an itemsContainer. * @returns {number} Number of cards per row for an itemsContainer.
*/ */
function getPostersPerRow(shape, screenWidth, isOrientationLandscape) { function getPostersPerRow(shape, screenWidth, isOrientationLandscape) {
switch (shape) { switch (shape) {
case 'portrait': case 'portrait':
if (layoutManager.tv) { if (layoutManager.tv) {
@ -251,14 +250,14 @@ import { appRouter } from '../appRouter';
default: default:
return 4; return 4;
} }
} }
/** /**
* Checks if the window is resizable. * Checks if the window is resizable.
* @param {number} windowWidth - Width of the device's screen. * @param {number} windowWidth - Width of the device's screen.
* @returns {boolean} - Result of the check. * @returns {boolean} - Result of the check.
*/ */
function isResizable(windowWidth) { function isResizable(windowWidth) {
const screen = window.screen; const screen = window.screen;
if (screen) { if (screen) {
const screenWidth = screen.availWidth; const screenWidth = screen.availWidth;
@ -269,26 +268,26 @@ import { appRouter } from '../appRouter';
} }
return false; return false;
} }
/** /**
* Gets the width of a card's image according to the shape and amount of cards per row. * Gets the width of a card's image according to the shape and amount of cards per row.
* @param {string} shape - Shape of the card. * @param {string} shape - Shape of the card.
* @param {number} screenWidth - Width of the screen. * @param {number} screenWidth - Width of the screen.
* @param {boolean} isOrientationLandscape - Flag for the orientation of the screen. * @param {boolean} isOrientationLandscape - Flag for the orientation of the screen.
* @returns {number} Width of the image for a card. * @returns {number} Width of the image for a card.
*/ */
function getImageWidth(shape, screenWidth, isOrientationLandscape) { function getImageWidth(shape, screenWidth, isOrientationLandscape) {
const imagesPerRow = getPostersPerRow(shape, screenWidth, isOrientationLandscape); const imagesPerRow = getPostersPerRow(shape, screenWidth, isOrientationLandscape);
return Math.round(screenWidth / imagesPerRow); return Math.round(screenWidth / imagesPerRow);
} }
/** /**
* Normalizes the options for a card. * Normalizes the options for a card.
* @param {Object} items - A set of items. * @param {Object} items - A set of items.
* @param {Object} options - Options for handling the items. * @param {Object} options - Options for handling the items.
*/ */
function setCardData(items, options) { function setCardData(items, options) {
options.shape = options.shape || 'auto'; options.shape = options.shape || 'auto';
const primaryImageAspectRatio = imageLoader.getPrimaryImageAspectRatio(items); const primaryImageAspectRatio = imageLoader.getPrimaryImageAspectRatio(items);
@ -341,15 +340,15 @@ import { appRouter } from '../appRouter';
options.width = getImageWidth(options.shape, screenWidth, screenWidth > (screenHeight * 1.3)); options.width = getImageWidth(options.shape, screenWidth, screenWidth > (screenHeight * 1.3));
} }
} }
/** /**
* Generates the internal HTML markup for cards. * Generates the internal HTML markup for cards.
* @param {Object} items - Items for which to generate the markup. * @param {Object} items - Items for which to generate the markup.
* @param {Object} options - Options for generating the markup. * @param {Object} options - Options for generating the markup.
* @returns {string} The internal HTML markup of the cards. * @returns {string} The internal HTML markup of the cards.
*/ */
function buildCardsHtmlInternal(items, options) { function buildCardsHtmlInternal(items, options) {
let isVertical = false; let isVertical = false;
if (options.shape === 'autoVertical') { if (options.shape === 'autoVertical') {
@ -459,14 +458,14 @@ import { appRouter } from '../appRouter';
} }
return html; return html;
} }
/** /**
* Computes the aspect ratio for a card given its shape. * Computes the aspect ratio for a card given its shape.
* @param {string} shape - Shape for which to get the aspect ratio. * @param {string} shape - Shape for which to get the aspect ratio.
* @returns {null|number} Ratio of the shape. * @returns {null|number} Ratio of the shape.
*/ */
function getDesiredAspect(shape) { function getDesiredAspect(shape) {
if (shape) { if (shape) {
shape = shape.toLowerCase(); shape = shape.toLowerCase();
if (shape.indexOf('portrait') !== -1) { if (shape.indexOf('portrait') !== -1) {
@ -483,9 +482,9 @@ import { appRouter } from '../appRouter';
} }
} }
return null; return null;
} }
/** /**
* @typedef {Object} CardImageUrl * @typedef {Object} CardImageUrl
* @property {string} imgUrl - Image URL. * @property {string} imgUrl - Image URL.
* @property {string} blurhash - Image blurhash. * @property {string} blurhash - Image blurhash.
@ -493,14 +492,14 @@ import { appRouter } from '../appRouter';
* @property {boolean} coverImage - Use cover style. * @property {boolean} coverImage - Use cover style.
*/ */
/** Get the URL of the card's image. /** Get the URL of the card's image.
* @param {Object} item - Item for which to generate a card. * @param {Object} item - Item for which to generate a card.
* @param {Object} apiClient - API client object. * @param {Object} apiClient - API client object.
* @param {Object} options - Options of the card. * @param {Object} options - Options of the card.
* @param {string} shape - Shape of the desired image. * @param {string} shape - Shape of the desired image.
* @returns {CardImageUrl} Object representing the URL of the card's image. * @returns {CardImageUrl} Object representing the URL of the card's image.
*/ */
function getCardImageUrl(item, apiClient, options, shape) { function getCardImageUrl(item, apiClient, options, shape) {
item = item.ProgramInfo || item; item = item.ProgramInfo || item;
const width = options.width; const width = options.width;
@ -639,14 +638,14 @@ import { appRouter } from '../appRouter';
forceName: forceName, forceName: forceName,
coverImage: coverImage coverImage: coverImage
}; };
} }
/** /**
* Generates an index used to select the default color of a card based on a string. * Generates an index used to select the default color of a card based on a string.
* @param {?string} [str] - String to use for generating the index. * @param {?string} [str] - String to use for generating the index.
* @returns {number} Index of the color. * @returns {number} Index of the color.
*/ */
function getDefaultColorIndex(str) { function getDefaultColorIndex(str) {
const numRandomColors = 5; const numRandomColors = 5;
if (str) { if (str) {
@ -662,9 +661,9 @@ import { appRouter } from '../appRouter';
} else { } else {
return randomInt(1, numRandomColors); return randomInt(1, numRandomColors);
} }
} }
/** /**
* Generates the HTML markup for a card's text. * Generates the HTML markup for a card's text.
* @param {Array} lines - Array containing the text lines. * @param {Array} lines - Array containing the text lines.
* @param {string} cssClass - Base CSS class to use for the lines. * @param {string} cssClass - Base CSS class to use for the lines.
@ -675,7 +674,7 @@ import { appRouter } from '../appRouter';
* @param {number} maxLines - Maximum number of lines to render. * @param {number} maxLines - Maximum number of lines to render.
* @returns {string} HTML markup for the card's text. * @returns {string} HTML markup for the card's text.
*/ */
function getCardTextLines(lines, cssClass, forceLines, isOuterFooter, cardLayout, addRightMargin, maxLines) { function getCardTextLines(lines, cssClass, forceLines, isOuterFooter, cardLayout, addRightMargin, maxLines) {
let html = ''; let html = '';
let valid = 0; let valid = 0;
@ -716,25 +715,25 @@ import { appRouter } from '../appRouter';
} }
return html; return html;
} }
/** /**
* Determines if the item is live TV. * Determines if the item is live TV.
* @param {Object} item - Item to use for the check. * @param {Object} item - Item to use for the check.
* @returns {boolean} Flag showing if the item is live TV. * @returns {boolean} Flag showing if the item is live TV.
*/ */
function isUsingLiveTvNaming(item) { function isUsingLiveTvNaming(item) {
return item.Type === 'Program' || item.Type === 'Timer' || item.Type === 'Recording'; return item.Type === 'Program' || item.Type === 'Timer' || item.Type === 'Recording';
} }
/** /**
* Returns the air time text for the item based on the given times. * Returns the air time text for the item based on the given times.
* @param {object} item - Item used to generate the air time text. * @param {object} item - Item used to generate the air time text.
* @param {boolean} showAirDateTime - ISO8601 date for the start of the show. * @param {boolean} showAirDateTime - ISO8601 date for the start of the show.
* @param {boolean} showAirEndTime - ISO8601 date for the end of the show. * @param {boolean} showAirEndTime - ISO8601 date for the end of the show.
* @returns {string} The air time text for the item based on the given dates. * @returns {string} The air time text for the item based on the given dates.
*/ */
function getAirTimeText(item, showAirDateTime, showAirEndTime) { function getAirTimeText(item, showAirDateTime, showAirEndTime) {
let airTimeText = ''; let airTimeText = '';
if (item.StartDate) { if (item.StartDate) {
@ -757,9 +756,9 @@ import { appRouter } from '../appRouter';
} }
return airTimeText; return airTimeText;
} }
/** /**
* Generates the HTML markup for the card's footer text. * Generates the HTML markup for the card's footer text.
* @param {Object} item - Item used to generate the footer text. * @param {Object} item - Item used to generate the footer text.
* @param {Object} apiClient - API client instance. * @param {Object} apiClient - API client instance.
@ -770,7 +769,7 @@ import { appRouter } from '../appRouter';
* @param {Object} urls - Various urls for the footer * @param {Object} urls - Various urls for the footer
* @returns {string} HTML markup of the card's footer text element. * @returns {string} HTML markup of the card's footer text element.
*/ */
function getCardFooterText(item, apiClient, options, footerClass, progressHtml, flags, urls) { function getCardFooterText(item, apiClient, options, footerClass, progressHtml, flags, urls) {
item = item.ProgramInfo || item; item = item.ProgramInfo || item;
let html = ''; let html = '';
@ -896,13 +895,13 @@ import { appRouter } from '../appRouter';
} }
if (options.showYear || options.showSeriesYear) { if (options.showYear || options.showSeriesYear) {
const productionYear = item.ProductionYear && datetime.toLocaleString(item.ProductionYear, {useGrouping: false}); const productionYear = item.ProductionYear && datetime.toLocaleString(item.ProductionYear, { useGrouping: false });
if (item.Type === 'Series') { if (item.Type === 'Series') {
if (item.Status === 'Continuing') { if (item.Status === 'Continuing') {
lines.push(globalize.translate('SeriesYearToPresent', productionYear || '')); lines.push(globalize.translate('SeriesYearToPresent', productionYear || ''));
} else { } else {
if (item.EndDate && item.ProductionYear) { if (item.EndDate && item.ProductionYear) {
const endYear = datetime.toLocaleString(datetime.parseISO8601Date(item.EndDate).getFullYear(), {useGrouping: false}); const endYear = datetime.toLocaleString(datetime.parseISO8601Date(item.EndDate).getFullYear(), { useGrouping: false });
lines.push(productionYear + ((endYear === item.ProductionYear) ? '' : (' - ' + endYear))); lines.push(productionYear + ((endYear === item.ProductionYear) ? '' : (' - ' + endYear)));
} else { } else {
lines.push(productionYear || ''); lines.push(productionYear || '');
@ -1003,16 +1002,16 @@ import { appRouter } from '../appRouter';
} }
return html; return html;
} }
/** /**
* Generates the HTML markup for the action button. * Generates the HTML markup for the action button.
* @param {Object} item - Item used to generate the action button. * @param {Object} item - Item used to generate the action button.
* @param {string} text - Text of the action button. * @param {string} text - Text of the action button.
* @param {string} serverId - ID of the server. * @param {string} serverId - ID of the server.
* @returns {string} HTML markup of the action button. * @returns {string} HTML markup of the action button.
*/ */
function getTextActionButton(item, text, serverId) { function getTextActionButton(item, text, serverId) {
if (!text) { if (!text) {
text = itemHelper.getDisplayName(item); text = itemHelper.getDisplayName(item);
} }
@ -1029,15 +1028,15 @@ import { appRouter } from '../appRouter';
html += '</a>'; html += '</a>';
return html; return html;
} }
/** /**
* Generates HTML markup for the item count indicator. * Generates HTML markup for the item count indicator.
* @param {Object} options - Options used to generate the item count. * @param {Object} options - Options used to generate the item count.
* @param {Object} item - Item used to generate the item count. * @param {Object} item - Item used to generate the item count.
* @returns {string} HTML markup for the item count indicator. * @returns {string} HTML markup for the item count indicator.
*/ */
function getItemCountsHtml(options, item) { function getItemCountsHtml(options, item) {
const counts = []; const counts = [];
let childText; let childText;
@ -1109,31 +1108,31 @@ import { appRouter } from '../appRouter';
} }
return counts.join(', '); return counts.join(', ');
} }
let refreshIndicatorLoaded; let refreshIndicatorLoaded;
/** /**
* Imports the refresh indicator element. * Imports the refresh indicator element.
*/ */
function importRefreshIndicator() { function importRefreshIndicator() {
if (!refreshIndicatorLoaded) { if (!refreshIndicatorLoaded) {
refreshIndicatorLoaded = true; refreshIndicatorLoaded = true;
/* eslint-disable-next-line @babel/no-unused-expressions */ /* eslint-disable-next-line @babel/no-unused-expressions */
import('../../elements/emby-itemrefreshindicator/emby-itemrefreshindicator'); import('../../elements/emby-itemrefreshindicator/emby-itemrefreshindicator');
} }
} }
/** /**
* Returns the default background class for a card based on a string. * Returns the default background class for a card based on a string.
* @param {?string} [str] - Text used to generate the background class. * @param {?string} [str] - Text used to generate the background class.
* @returns {string} CSS classes for default card backgrounds. * @returns {string} CSS classes for default card backgrounds.
*/ */
export function getDefaultBackgroundClass(str) { export function getDefaultBackgroundClass(str) {
return 'defaultCardBackground defaultCardBackground' + getDefaultColorIndex(str); return 'defaultCardBackground defaultCardBackground' + getDefaultColorIndex(str);
} }
/** /**
* Builds the HTML markup for an individual card. * Builds the HTML markup for an individual card.
* @param {number} index - Index of the card * @param {number} index - Index of the card
* @param {object} item - Item used to generate the card. * @param {object} item - Item used to generate the card.
@ -1141,7 +1140,7 @@ import { appRouter } from '../appRouter';
* @param {object} options - Options used to generate the card. * @param {object} options - Options used to generate the card.
* @returns {string} HTML markup for the generated card. * @returns {string} HTML markup for the generated card.
*/ */
function buildCard(index, item, apiClient, options) { function buildCard(index, item, apiClient, options) {
let action = options.action || 'link'; let action = options.action || 'link';
if (action === 'play' && item.IsFolder) { if (action === 'play' && item.IsFolder) {
@ -1444,15 +1443,15 @@ import { appRouter } from '../appRouter';
} }
return '<' + tagName + ' data-index="' + index + '"' + timerAttributes + actionAttribute + ' data-isfolder="' + (item.IsFolder || false) + '" data-serverid="' + (item.ServerId || options.serverId) + '" data-id="' + (item.Id || item.ItemId) + '" data-type="' + item.Type + '"' + mediaTypeData + collectionTypeData + channelIdData + pathData + positionTicksData + collectionIdData + playlistIdData + contextData + parentIdData + startDate + endDate + ' data-prefix="' + escapeHtml(prefix) + '" class="' + className + '"' + ariaLabelAttribute + '>' + cardImageContainerOpen + innerCardFooter + cardImageContainerClose + overlayButtons + additionalCardContent + cardScalableClose + outerCardFooter + cardBoxClose + '</' + tagName + '>'; return '<' + tagName + ' data-index="' + index + '"' + timerAttributes + actionAttribute + ' data-isfolder="' + (item.IsFolder || false) + '" data-serverid="' + (item.ServerId || options.serverId) + '" data-id="' + (item.Id || item.ItemId) + '" data-type="' + item.Type + '"' + mediaTypeData + collectionTypeData + channelIdData + pathData + positionTicksData + collectionIdData + playlistIdData + contextData + parentIdData + startDate + endDate + ' data-prefix="' + escapeHtml(prefix) + '" class="' + className + '"' + ariaLabelAttribute + '>' + cardImageContainerOpen + innerCardFooter + cardImageContainerClose + overlayButtons + additionalCardContent + cardScalableClose + outerCardFooter + cardBoxClose + '</' + tagName + '>';
} }
/** /**
* Generates HTML markup for the card overlay. * Generates HTML markup for the card overlay.
* @param {object} item - Item used to generate the card overlay. * @param {object} item - Item used to generate the card overlay.
* @param {string} action - Action assigned to the overlay. * @param {string} action - Action assigned to the overlay.
* @returns {string} HTML markup of the card overlay. * @returns {string} HTML markup of the card overlay.
*/ */
function getHoverMenuHtml(item, action) { function getHoverMenuHtml(item, action) {
let html = ''; let html = '';
html += '<div class="cardOverlayContainer itemAction" data-action="' + action + '">'; html += '<div class="cardOverlayContainer itemAction" data-action="' + action + '">';
@ -1488,15 +1487,15 @@ import { appRouter } from '../appRouter';
html += '</div>'; html += '</div>';
return html; return html;
} }
/** /**
* Generates the text or icon used for default card backgrounds. * Generates the text or icon used for default card backgrounds.
* @param {object} item - Item used to generate the card overlay. * @param {object} item - Item used to generate the card overlay.
* @param {object} options - Options used to generate the card overlay. * @param {object} options - Options used to generate the card overlay.
* @returns {string} HTML markup of the card overlay. * @returns {string} HTML markup of the card overlay.
*/ */
export function getDefaultText(item, options) { export function getDefaultText(item, options) {
if (item.CollectionType) { if (item.CollectionType) {
return '<span class="cardImageIcon material-icons ' + imageHelper.getLibraryIcon(item.CollectionType) + '" aria-hidden="true"></span>'; return '<span class="cardImageIcon material-icons ' + imageHelper.getLibraryIcon(item.CollectionType) + '" aria-hidden="true"></span>';
} }
@ -1536,14 +1535,14 @@ import { appRouter } from '../appRouter';
const defaultName = isUsingLiveTvNaming(item) ? item.Name : itemHelper.getDisplayName(item); const defaultName = isUsingLiveTvNaming(item) ? item.Name : itemHelper.getDisplayName(item);
return '<div class="cardText cardDefaultText">' + escapeHtml(defaultName) + '</div>'; return '<div class="cardText cardDefaultText">' + escapeHtml(defaultName) + '</div>';
} }
/** /**
* Builds a set of cards and inserts them into the page. * Builds a set of cards and inserts them into the page.
* @param {Array} items - Array of items used to build the cards. * @param {Array} items - Array of items used to build the cards.
* @param {options} options - Options of the cards to build. * @param {options} options - Options of the cards to build.
*/ */
export function buildCards(items, options) { export function buildCards(items, options) {
// Abort if the container has been disposed // Abort if the container has been disposed
if (!document.body.contains(options.itemsContainer)) { if (!document.body.contains(options.itemsContainer)) {
return; return;
@ -1580,15 +1579,15 @@ import { appRouter } from '../appRouter';
if (options.autoFocus) { if (options.autoFocus) {
focusManager.autoFocus(options.itemsContainer, true); focusManager.autoFocus(options.itemsContainer, true);
} }
} }
/** /**
* Ensures the indicators for a card exist and creates them if they don't exist. * Ensures the indicators for a card exist and creates them if they don't exist.
* @param {HTMLDivElement} card - DOM element of the card. * @param {HTMLDivElement} card - DOM element of the card.
* @param {HTMLDivElement} indicatorsElem - DOM element of the indicators. * @param {HTMLDivElement} indicatorsElem - DOM element of the indicators.
* @returns {HTMLDivElement} - DOM element of the indicators. * @returns {HTMLDivElement} - DOM element of the indicators.
*/ */
function ensureIndicators(card, indicatorsElem) { function ensureIndicators(card, indicatorsElem) {
if (indicatorsElem) { if (indicatorsElem) {
return indicatorsElem; return indicatorsElem;
} }
@ -1603,14 +1602,14 @@ import { appRouter } from '../appRouter';
} }
return indicatorsElem; return indicatorsElem;
} }
/** /**
* Adds user data to the card such as progress indicators and played status. * Adds user data to the card such as progress indicators and played status.
* @param {HTMLDivElement} card - DOM element of the card. * @param {HTMLDivElement} card - DOM element of the card.
* @param {Object} userData - User data to apply to the card. * @param {Object} userData - User data to apply to the card.
*/ */
function updateUserData(card, userData) { function updateUserData(card, userData) {
const type = card.getAttribute('data-type'); const type = card.getAttribute('data-type');
const enableCountIndicator = type === 'Series' || type === 'BoxSet' || type === 'Season'; const enableCountIndicator = type === 'Series' || type === 'BoxSet' || type === 'Season';
let indicatorsElem = null; let indicatorsElem = null;
@ -1682,28 +1681,28 @@ import { appRouter } from '../appRouter';
itemProgressBar.parentNode.removeChild(itemProgressBar); itemProgressBar.parentNode.removeChild(itemProgressBar);
} }
} }
} }
/** /**
* Handles when user data has changed. * Handles when user data has changed.
* @param {Object} userData - User data to apply to the card. * @param {Object} userData - User data to apply to the card.
* @param {HTMLElement} scope - DOM element to use as a scope when selecting cards. * @param {HTMLElement} scope - DOM element to use as a scope when selecting cards.
*/ */
export function onUserDataChanged(userData, scope) { export function onUserDataChanged(userData, scope) {
const cards = (scope || document.body).querySelectorAll('.card-withuserdata[data-id="' + userData.ItemId + '"]'); const cards = (scope || document.body).querySelectorAll('.card-withuserdata[data-id="' + userData.ItemId + '"]');
for (let i = 0, length = cards.length; i < length; i++) { for (let i = 0, length = cards.length; i < length; i++) {
updateUserData(cards[i], userData); updateUserData(cards[i], userData);
} }
} }
/** /**
* Handles when a timer has been created. * Handles when a timer has been created.
* @param {string} programId - ID of the program. * @param {string} programId - ID of the program.
* @param {string} newTimerId - ID of the new timer. * @param {string} newTimerId - ID of the new timer.
* @param {HTMLElement} itemsContainer - DOM element of the itemsContainer. * @param {HTMLElement} itemsContainer - DOM element of the itemsContainer.
*/ */
export function onTimerCreated(programId, newTimerId, itemsContainer) { export function onTimerCreated(programId, newTimerId, itemsContainer) {
const cells = itemsContainer.querySelectorAll('.card[data-id="' + programId + '"]'); const cells = itemsContainer.querySelectorAll('.card[data-id="' + programId + '"]');
for (let i = 0, length = cells.length; i < length; i++) { for (let i = 0, length = cells.length; i < length; i++) {
@ -1715,14 +1714,14 @@ import { appRouter } from '../appRouter';
} }
cell.setAttribute('data-timerid', newTimerId); cell.setAttribute('data-timerid', newTimerId);
} }
} }
/** /**
* Handles when a timer has been cancelled. * Handles when a timer has been cancelled.
* @param {string} timerId - ID of the cancelled timer. * @param {string} timerId - ID of the cancelled timer.
* @param {HTMLElement} itemsContainer - DOM element of the itemsContainer. * @param {HTMLElement} itemsContainer - DOM element of the itemsContainer.
*/ */
export function onTimerCancelled(timerId, itemsContainer) { export function onTimerCancelled(timerId, itemsContainer) {
const cells = itemsContainer.querySelectorAll('.card[data-timerid="' + timerId + '"]'); const cells = itemsContainer.querySelectorAll('.card[data-timerid="' + timerId + '"]');
for (let i = 0; i < cells.length; i++) { for (let i = 0; i < cells.length; i++) {
@ -1733,14 +1732,14 @@ import { appRouter } from '../appRouter';
} }
cell.removeAttribute('data-timerid'); cell.removeAttribute('data-timerid');
} }
} }
/** /**
* Handles when a series timer has been cancelled. * Handles when a series timer has been cancelled.
* @param {string} cancelledTimerId - ID of the cancelled timer. * @param {string} cancelledTimerId - ID of the cancelled timer.
* @param {HTMLElement} itemsContainer - DOM element of the itemsContainer. * @param {HTMLElement} itemsContainer - DOM element of the itemsContainer.
*/ */
export function onSeriesTimerCancelled(cancelledTimerId, itemsContainer) { export function onSeriesTimerCancelled(cancelledTimerId, itemsContainer) {
const cells = itemsContainer.querySelectorAll('.card[data-seriestimerid="' + cancelledTimerId + '"]'); const cells = itemsContainer.querySelectorAll('.card[data-seriestimerid="' + cancelledTimerId + '"]');
for (let i = 0; i < cells.length; i++) { for (let i = 0; i < cells.length; i++) {
@ -1751,9 +1750,7 @@ import { appRouter } from '../appRouter';
} }
cell.removeAttribute('data-seriestimerid'); cell.removeAttribute('data-seriestimerid');
} }
} }
/* eslint-enable indent */
export default { export default {
getCardsHtml: getCardsHtml, getCardsHtml: getCardsHtml,

View file

@ -1,4 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for building cards from item data. * Module for building cards from item data.
@ -12,9 +11,9 @@ import layoutManager from '../layoutManager';
import browser from '../../scripts/browser'; import browser from '../../scripts/browser';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';
const enableFocusTransform = !browser.slow && !browser.edge; const enableFocusTransform = !browser.slow && !browser.edge;
function buildChapterCardsHtml(item, chapters, options) { function buildChapterCardsHtml(item, chapters, options) {
// TODO move card creation code to Card component // TODO move card creation code to Card component
let className = 'card itemAction chapterCard'; let className = 'card itemAction chapterCard';
@ -28,7 +27,7 @@ import ServerConnections from '../ServerConnections';
} }
const mediaStreams = ((item.MediaSources || [])[0] || {}).MediaStreams || []; const mediaStreams = ((item.MediaSources || [])[0] || {}).MediaStreams || [];
const videoStream = mediaStreams.filter(({Type}) => { const videoStream = mediaStreams.filter(({ Type }) => {
return Type === 'Video'; return Type === 'Video';
})[0] || {}; })[0] || {};
@ -66,9 +65,9 @@ import ServerConnections from '../ServerConnections';
} }
return html; return html;
} }
function getImgUrl({Id}, {ImageTag}, index, maxWidth, apiClient) { function getImgUrl({ Id }, { ImageTag }, index, maxWidth, apiClient) {
if (ImageTag) { if (ImageTag) {
return apiClient.getScaledImageUrl(Id, { return apiClient.getScaledImageUrl(Id, {
@ -80,9 +79,9 @@ import ServerConnections from '../ServerConnections';
} }
return null; return null;
} }
function buildChapterCard(item, apiClient, chapter, index, {width, coverImage}, className, shape) { function buildChapterCard(item, apiClient, chapter, index, { width, coverImage }, className, shape) {
const imgUrl = getImgUrl(item, chapter, index, width || 400, apiClient); const imgUrl = getImgUrl(item, chapter, index, width || 400, apiClient);
let cardImageContainerClass = 'cardContent cardContent-shadow cardImageContainer chapterCardImageContainer'; let cardImageContainerClass = 'cardContent cardContent-shadow cardImageContainer chapterCardImageContainer';
@ -104,9 +103,9 @@ import ServerConnections from '../ServerConnections';
const cardScalableClass = 'cardScalable'; const cardScalableClass = 'cardScalable';
return `<button type="button" class="${className}"${dataAttributes}><div class="${cardBoxCssClass}"><div class="${cardScalableClass}"><div class="cardPadder-${shape}"></div>${cardImageContainer}</div><div class="innerCardFooter">${nameHtml}</div></div></div></button>`; return `<button type="button" class="${className}"${dataAttributes}><div class="${cardBoxCssClass}"><div class="${cardScalableClass}"><div class="cardPadder-${shape}"></div>${cardImageContainer}</div><div class="innerCardFooter">${nameHtml}</div></div></div></button>`;
} }
export function buildChapterCards(item, chapters, options) { export function buildChapterCards(item, chapters, options) {
if (options.parentContainer) { if (options.parentContainer) {
// Abort if the container has been disposed // Abort if the container has been disposed
if (!document.body.contains(options.parentContainer)) { if (!document.body.contains(options.parentContainer)) {
@ -126,9 +125,7 @@ import ServerConnections from '../ServerConnections';
options.itemsContainer.innerHTML = html; options.itemsContainer.innerHTML = html;
imageLoader.lazyChildren(options.itemsContainer); imageLoader.lazyChildren(options.itemsContainer);
} }
/* eslint-enable indent */
export default { export default {
buildChapterCards: buildChapterCards buildChapterCards: buildChapterCards

View file

@ -1,4 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for building cards from item data. * Module for building cards from item data.
@ -7,7 +6,7 @@
import cardBuilder from './cardBuilder'; import cardBuilder from './cardBuilder';
export function buildPeopleCards(items, options) { export function buildPeopleCards(items, options) {
options = Object.assign(options || {}, { options = Object.assign(options || {}, {
cardLayout: false, cardLayout: false,
centerText: true, centerText: true,
@ -18,9 +17,7 @@ import cardBuilder from './cardBuilder';
defaultCardImageIcon: 'person' defaultCardImageIcon: 'person'
}); });
cardBuilder.buildCards(items, options); cardBuilder.buildCards(items, options);
} }
/* eslint-enable indent */
export default { export default {
buildPeopleCards: buildPeopleCards buildPeopleCards: buildPeopleCards

View file

@ -16,11 +16,9 @@ import '../../styles/flexstyles.scss';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';
import toast from '../toast/toast'; import toast from '../toast/toast';
/* eslint-disable indent */ let currentServerId;
let currentServerId; function onSubmit(e) {
function onSubmit(e) {
loading.show(); loading.show();
const panel = dom.parentWithClass(this, 'dialog'); const panel = dom.parentWithClass(this, 'dialog');
@ -37,9 +35,9 @@ import toast from '../toast/toast';
e.preventDefault(); e.preventDefault();
return false; return false;
} }
function createCollection(apiClient, dlg) { function createCollection(apiClient, dlg) {
const url = apiClient.getUrl('Collections', { const url = apiClient.getUrl('Collections', {
Name: dlg.querySelector('#txtNewCollectionName').value, Name: dlg.querySelector('#txtNewCollectionName').value,
@ -61,13 +59,13 @@ import toast from '../toast/toast';
dialogHelper.close(dlg); dialogHelper.close(dlg);
redirectToCollection(apiClient, id); redirectToCollection(apiClient, id);
}); });
} }
function redirectToCollection(apiClient, id) { function redirectToCollection(apiClient, id) {
appRouter.showItem(id, apiClient.serverId()); appRouter.showItem(id, apiClient.serverId());
} }
function addToCollection(apiClient, dlg, id) { function addToCollection(apiClient, dlg, id) {
const url = apiClient.getUrl(`Collections/${id}/Items`, { const url = apiClient.getUrl(`Collections/${id}/Items`, {
Ids: dlg.querySelector('.fldSelectedItemIds').value || '' Ids: dlg.querySelector('.fldSelectedItemIds').value || ''
@ -85,13 +83,13 @@ import toast from '../toast/toast';
toast(globalize.translate('MessageItemsAdded')); toast(globalize.translate('MessageItemsAdded'));
}); });
} }
function triggerChange(select) { function triggerChange(select) {
select.dispatchEvent(new CustomEvent('change', {})); select.dispatchEvent(new CustomEvent('change', {}));
} }
function populateCollections(panel) { function populateCollections(panel) {
loading.show(); loading.show();
const select = panel.querySelector('#selectCollectionToAddTo'); const select = panel.querySelector('#selectCollectionToAddTo');
@ -122,9 +120,9 @@ import toast from '../toast/toast';
loading.hide(); loading.hide();
}); });
} }
function getEditorHtml() { function getEditorHtml() {
let html = ''; let html = '';
html += '<div class="formDialogContent smoothScrollY" style="padding-top:2em;">'; html += '<div class="formDialogContent smoothScrollY" style="padding-top:2em;">';
@ -169,9 +167,9 @@ import toast from '../toast/toast';
html += '</div>'; html += '</div>';
return html; return html;
} }
function initEditor(content, items) { function initEditor(content, items) {
content.querySelector('#selectCollectionToAddTo').addEventListener('change', function () { content.querySelector('#selectCollectionToAddTo').addEventListener('change', function () {
if (this.value) { if (this.value) {
content.querySelector('.newCollectionInfo').classList.add('hide'); content.querySelector('.newCollectionInfo').classList.add('hide');
@ -197,16 +195,16 @@ import toast from '../toast/toast';
selectCollectionToAddTo.value = ''; selectCollectionToAddTo.value = '';
triggerChange(selectCollectionToAddTo); triggerChange(selectCollectionToAddTo);
} }
} }
function centerFocus(elem, horiz, on) { function centerFocus(elem, horiz, on) {
import('../../scripts/scrollHelper').then((scrollHelper) => { import('../../scripts/scrollHelper').then((scrollHelper) => {
const fn = on ? 'on' : 'off'; const fn = on ? 'on' : 'off';
scrollHelper.centerFocus[fn](elem, horiz); scrollHelper.centerFocus[fn](elem, horiz);
}); });
} }
class CollectionEditor { class CollectionEditor {
show(options) { show(options) {
const items = options.items || {}; const items = options.items || {};
currentServerId = options.serverId; currentServerId = options.serverId;
@ -263,7 +261,6 @@ import toast from '../toast/toast';
return Promise.reject(); return Promise.reject();
}); });
} }
} }
/* eslint-enable indent */
export default CollectionEditor; export default CollectionEditor;

View file

@ -22,7 +22,7 @@ const Filter: FC<FilterProps> = ({
const element = useRef<HTMLDivElement>(null); const element = useRef<HTMLDivElement>(null);
const showFilterMenu = useCallback(() => { const showFilterMenu = useCallback(() => {
import('../filtermenu/filtermenu').then(({default: FilterMenu}) => { import('../filtermenu/filtermenu').then(({ default: FilterMenu }) => {
const filterMenu = new FilterMenu(); const filterMenu = new FilterMenu();
filterMenu.show({ filterMenu.show({
settings: viewQuerySettings, settings: viewQuerySettings,

View file

@ -6,7 +6,7 @@ const NewCollection: FC = () => {
const element = useRef<HTMLDivElement>(null); const element = useRef<HTMLDivElement>(null);
const showCollectionEditor = useCallback(() => { const showCollectionEditor = useCallback(() => {
import('../collectionEditor/collectionEditor').then(({default: CollectionEditor}) => { import('../collectionEditor/collectionEditor').then(({ default: CollectionEditor }) => {
const serverId = window.ApiClient.serverId(); const serverId = window.ApiClient.serverId();
const collectionEditor = new CollectionEditor(); const collectionEditor = new CollectionEditor();
collectionEditor.show({ collectionEditor.show({

View file

@ -16,7 +16,7 @@ const SelectView: FC<SelectViewProps> = ({
const element = useRef<HTMLDivElement>(null); const element = useRef<HTMLDivElement>(null);
const showViewSettingsMenu = useCallback(() => { const showViewSettingsMenu = useCallback(() => {
import('../viewSettings/viewSettings').then(({default: ViewSettings}) => { import('../viewSettings/viewSettings').then(({ default: ViewSettings }) => {
const viewsettings = new ViewSettings(); const viewsettings = new ViewSettings();
viewsettings.show({ viewsettings.show({
settings: viewQuerySettings, settings: viewQuerySettings,

View file

@ -19,7 +19,7 @@ const Sort: FC<SortProps> = ({
const element = useRef<HTMLDivElement>(null); const element = useRef<HTMLDivElement>(null);
const showSortMenu = useCallback(() => { const showSortMenu = useCallback(() => {
import('../sortmenu/sortmenu').then(({default: SortMenu}) => { import('../sortmenu/sortmenu').then(({ default: SortMenu }) => {
const sortMenu = new SortMenu(); const sortMenu = new SortMenu();
sortMenu.show({ sortMenu.show({
settings: viewQuerySettings, settings: viewQuerySettings,

View file

@ -14,7 +14,7 @@ type IProps = {
children?: React.ReactNode children?: React.ReactNode
} }
const AccessContainer: FunctionComponent<IProps> = ({containerClassName, headerTitle, checkBoxClassName, checkBoxTitle, listContainerClassName, accessClassName, listTitle, description, children }: IProps) => { const AccessContainer: FunctionComponent<IProps> = ({ containerClassName, headerTitle, checkBoxClassName, checkBoxTitle, listContainerClassName, accessClassName, listTitle, description, children }: IProps) => {
return ( return (
<div className={containerClassName}> <div className={containerClassName}>
<h2>{globalize.translate(headerTitle)}</h2> <h2>{globalize.translate(headerTitle)}</h2>

View file

@ -22,7 +22,7 @@ function getDisplayTime(hours = 0) {
return datetime.getDisplayTime(new Date(2000, 1, 1, hours, minutes, 0, 0)); return datetime.getDisplayTime(new Date(2000, 1, 1, hours, minutes, 0, 0));
} }
const AccessScheduleList: FunctionComponent<AccessScheduleListProps> = ({index, DayOfWeek, StartHour, EndHour}: AccessScheduleListProps) => { const AccessScheduleList: FunctionComponent<AccessScheduleListProps> = ({ index, DayOfWeek, StartHour, EndHour }: AccessScheduleListProps) => {
return ( return (
<div <div
className='liSchedule listItem' className='liSchedule listItem'

View file

@ -5,7 +5,7 @@ type IProps = {
tag?: string; tag?: string;
} }
const BlockedTagList: FunctionComponent<IProps> = ({tag}: IProps) => { const BlockedTagList: FunctionComponent<IProps> = ({ tag }: IProps) => {
return ( return (
<div className='paperList'> <div className='paperList'>
<div className='listItem'> <div className='listItem'>

View file

@ -36,7 +36,7 @@ const createLinkElement = (activeTab: string) => ({
</a>` </a>`
}); });
const SectionTabs: FunctionComponent<IProps> = ({activeTab}: IProps) => { const SectionTabs: FunctionComponent<IProps> = ({ activeTab }: IProps) => {
return ( return (
<div <div
data-role='controlgroup' data-role='controlgroup'

View file

@ -74,7 +74,7 @@ const UserCardBox: FunctionComponent<IProps> = ({ user = {} }: IProps) => {
</div> </div>
<div className='cardFooter visualCardBox-cardFooter'> <div className='cardFooter visualCardBox-cardFooter'>
<div <div
style={{textAlign: 'right', float: 'right', paddingTop: '5px'}} style={{ textAlign: 'right', float: 'right', paddingTop: '5px' }}
> >
<IconButtonElement <IconButtonElement
is='paper-icon-button-light' is='paper-icon-button-light'

View file

@ -14,7 +14,7 @@ type IProps = {
userId: string; userId: string;
} }
const UserPasswordForm: FunctionComponent<IProps> = ({userId}: IProps) => { const UserPasswordForm: FunctionComponent<IProps> = ({ userId }: IProps) => {
const element = useRef<HTMLDivElement>(null); const element = useRef<HTMLDivElement>(null);
const loadUser = useCallback(() => { const loadUser = useCallback(() => {
@ -76,7 +76,7 @@ const UserPasswordForm: FunctionComponent<IProps> = ({userId}: IProps) => {
chkEnableLocalEasyPassword.checked = user.Configuration.EnableLocalPassword || false; chkEnableLocalEasyPassword.checked = user.Configuration.EnableLocalPassword || false;
import('../../autoFocuser').then(({default: autoFocuser}) => { import('../../autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(page); autoFocuser.autoFocus(page);
}); });
}); });
@ -214,7 +214,7 @@ const UserPasswordForm: FunctionComponent<IProps> = ({userId}: IProps) => {
<div ref={element}> <div ref={element}>
<form <form
className='updatePasswordForm passwordSection hide' className='updatePasswordForm passwordSection hide'
style={{margin: '0 auto 2em'}} style={{ margin: '0 auto 2em' }}
> >
<div className='detailSection'> <div className='detailSection'>
<div id='fldCurrentPassword' className='inputContainer hide'> <div id='fldCurrentPassword' className='inputContainer hide'>
@ -260,7 +260,7 @@ const UserPasswordForm: FunctionComponent<IProps> = ({userId}: IProps) => {
<br /> <br />
<form <form
className='localAccessForm localAccessSection' className='localAccessForm localAccessSection'
style={{margin: '0 auto'}} style={{ margin: '0 auto' }}
> >
<div className='detailSection'> <div className='detailSection'>
<div className='detailSectionHeader'> <div className='detailSectionHeader'>

View file

@ -13,9 +13,7 @@ import '../formdialog.scss';
import '../../styles/flexstyles.scss'; import '../../styles/flexstyles.scss';
import template from './dialog.template.html'; import template from './dialog.template.html';
/* eslint-disable indent */ function showDialog(options = { dialogOptions: {}, buttons: [] }) {
function showDialog(options = { dialogOptions: {}, buttons: [] }) {
const dialogOptions = { const dialogOptions = {
removeOnClose: true, removeOnClose: true,
scrollY: false, scrollY: false,
@ -119,9 +117,9 @@ import template from './dialog.template.html';
return Promise.reject(); return Promise.reject();
} }
}); });
} }
export function show(text, title) { export function show(text, title) {
let options; let options;
if (typeof text === 'string') { if (typeof text === 'string') {
options = { options = {
@ -133,9 +131,8 @@ import template from './dialog.template.html';
} }
return showDialog(options); return showDialog(options);
} }
/* eslint-enable indent */
export default { export default {
show: show show: show
}; };

View file

@ -9,20 +9,18 @@ import dom from '../../scripts/dom';
import './dialoghelper.scss'; import './dialoghelper.scss';
import '../../styles/scrollstyles.scss'; import '../../styles/scrollstyles.scss';
/* eslint-disable indent */ let globalOnOpenCallback;
let globalOnOpenCallback; function enableAnimation() {
function enableAnimation() {
// too slow // too slow
if (browser.tv) { if (browser.tv) {
return false; return false;
} }
return browser.supportsCssAnimation(); return browser.supportsCssAnimation();
} }
function removeCenterFocus(dlg) { function removeCenterFocus(dlg) {
if (layoutManager.tv) { if (layoutManager.tv) {
if (dlg.classList.contains('scrollX')) { if (dlg.classList.contains('scrollX')) {
centerFocus(dlg, true, false); centerFocus(dlg, true, false);
@ -30,9 +28,9 @@ import '../../styles/scrollstyles.scss';
centerFocus(dlg, false, false); centerFocus(dlg, false, false);
} }
} }
} }
function tryRemoveElement(elem) { function tryRemoveElement(elem) {
const parentNode = elem.parentNode; const parentNode = elem.parentNode;
if (parentNode) { if (parentNode) {
// Seeing crashes in edge webview // Seeing crashes in edge webview
@ -42,9 +40,9 @@ import '../../styles/scrollstyles.scss';
console.error('[dialogHelper] error removing dialog element: ' + err); console.error('[dialogHelper] error removing dialog element: ' + err);
} }
} }
} }
function DialogHashHandler(dlg, hash, resolve) { function DialogHashHandler(dlg, hash, resolve) {
const self = this; const self = this;
self.originalUrl = window.location.href; self.originalUrl = window.location.href;
const activeElement = document.activeElement; const activeElement = document.activeElement;
@ -192,9 +190,9 @@ import '../../styles/scrollstyles.scss';
} else { } else {
inputManager.on(dlg, onBackCommand); inputManager.on(dlg, onBackCommand);
} }
} }
function addBackdropOverlay(dlg) { function addBackdropOverlay(dlg) {
const backdrop = document.createElement('div'); const backdrop = document.createElement('div');
backdrop.classList.add('dialogBackdrop'); backdrop.classList.add('dialogBackdrop');
@ -222,13 +220,13 @@ import '../../styles/scrollstyles.scss';
e.preventDefault(); e.preventDefault();
} }
}); });
} }
function isHistoryEnabled(dlg) { function isHistoryEnabled(dlg) {
return dlg.getAttribute('data-history') === 'true'; return dlg.getAttribute('data-history') === 'true';
} }
export function open(dlg) { export function open(dlg) {
if (globalOnOpenCallback) { if (globalOnOpenCallback) {
globalOnOpenCallback(dlg); globalOnOpenCallback(dlg);
} }
@ -247,14 +245,13 @@ import '../../styles/scrollstyles.scss';
return new Promise((resolve) => { return new Promise((resolve) => {
new DialogHashHandler(dlg, `dlg${new Date().getTime()}`, resolve); new DialogHashHandler(dlg, `dlg${new Date().getTime()}`, resolve);
}); });
} }
function isOpened(dlg) { function isOpened(dlg) {
//return dlg.opened;
return !dlg.classList.contains('hide'); return !dlg.classList.contains('hide');
} }
export function close(dlg) { export function close(dlg) {
if (!dlg.classList.contains('hide')) { if (!dlg.classList.contains('hide')) {
dlg.dispatchEvent(new CustomEvent('closing', { dlg.dispatchEvent(new CustomEvent('closing', {
bubbles: false, bubbles: false,
@ -273,14 +270,14 @@ import '../../styles/scrollstyles.scss';
animateDialogClose(dlg, onAnimationFinish); animateDialogClose(dlg, onAnimationFinish);
} }
} }
const getAnimationEndHandler = (dlg, callback) => function handler() { const getAnimationEndHandler = (dlg, callback) => function handler() {
dom.removeEventListener(dlg, dom.whichAnimationEvent(), handler, { once: true }); dom.removeEventListener(dlg, dom.whichAnimationEvent(), handler, { once: true });
callback(); callback();
}; };
function animateDialogOpen(dlg) { function animateDialogOpen(dlg) {
const onAnimationFinish = () => { const onAnimationFinish = () => {
focusManager.pushScope(dlg); focusManager.pushScope(dlg);
@ -305,9 +302,9 @@ import '../../styles/scrollstyles.scss';
} }
onAnimationFinish(); onAnimationFinish();
} }
function animateDialogClose(dlg, onAnimationFinish) { function animateDialogClose(dlg, onAnimationFinish) {
if (enableAnimation()) { if (enableAnimation()) {
let animated = true; let animated = true;
@ -338,11 +335,11 @@ import '../../styles/scrollstyles.scss';
} }
onAnimationFinish(); onAnimationFinish();
} }
const supportsOverscrollBehavior = 'overscroll-behavior-y' in document.body.style; const supportsOverscrollBehavior = 'overscroll-behavior-y' in document.body.style;
function shouldLockDocumentScroll(options) { function shouldLockDocumentScroll(options) {
if (options.lockScroll != null) { if (options.lockScroll != null) {
return options.lockScroll; return options.lockScroll;
} }
@ -360,9 +357,9 @@ import '../../styles/scrollstyles.scss';
} }
return browser.touch; return browser.touch;
} }
function removeBackdrop(dlg) { function removeBackdrop(dlg) {
const backdrop = dlg.backdrop; const backdrop = dlg.backdrop;
if (!backdrop) { if (!backdrop) {
@ -384,16 +381,16 @@ import '../../styles/scrollstyles.scss';
} }
onAnimationFinish(); onAnimationFinish();
} }
function centerFocus(elem, horiz, on) { function centerFocus(elem, horiz, on) {
import('../../scripts/scrollHelper').then((scrollHelper) => { import('../../scripts/scrollHelper').then((scrollHelper) => {
const fn = on ? 'on' : 'off'; const fn = on ? 'on' : 'off';
scrollHelper.centerFocus[fn](elem, horiz); scrollHelper.centerFocus[fn](elem, horiz);
}); });
} }
export function createDialog(options = {}) { export function createDialog(options = {}) {
// If there's no native dialog support, use a plain div // If there's no native dialog support, use a plain div
// Also not working well in samsung tizen browser, content inside not clickable // Also not working well in samsung tizen browser, content inside not clickable
// Just go ahead and always use a plain div because we're seeing issues overlaying absoltutely positioned content over a modal dialog // Just go ahead and always use a plain div because we're seeing issues overlaying absoltutely positioned content over a modal dialog
@ -502,13 +499,11 @@ import '../../styles/scrollstyles.scss';
} }
return dlg; return dlg;
} }
export function setOnOpen(val) { export function setOnOpen(val) {
globalOnOpenCallback = val; globalOnOpenCallback = val;
} }
/* eslint-enable indent */
export default { export default {
open: open, open: open,

View file

@ -18,9 +18,7 @@ import ServerConnections from '../ServerConnections';
import toast from '../toast/toast'; import toast from '../toast/toast';
import template from './displaySettings.template.html'; import template from './displaySettings.template.html';
/* eslint-disable indent */ function fillThemes(select, selectedTheme) {
function fillThemes(select, selectedTheme) {
skinManager.getThemes().then(themes => { skinManager.getThemes().then(themes => {
select.innerHTML = themes.map(t => { select.innerHTML = themes.map(t => {
return `<option value="${t.id}">${escapeHtml(t.name)}</option>`; return `<option value="${t.id}">${escapeHtml(t.name)}</option>`;
@ -32,9 +30,9 @@ import template from './displaySettings.template.html';
// set the current theme // set the current theme
select.value = selectedTheme || defaultTheme.id; select.value = selectedTheme || defaultTheme.id;
}); });
} }
function loadScreensavers(context, userSettings) { function loadScreensavers(context, userSettings) {
const selectScreensaver = context.querySelector('.selectScreensaver'); const selectScreensaver = context.querySelector('.selectScreensaver');
const options = pluginManager.ofType(PluginType.Screensaver).map(plugin => { const options = pluginManager.ofType(PluginType.Screensaver).map(plugin => {
return { return {
@ -58,18 +56,18 @@ import template from './displaySettings.template.html';
// TODO: set the default instead of none // TODO: set the default instead of none
selectScreensaver.value = 'none'; selectScreensaver.value = 'none';
} }
} }
function showOrHideMissingEpisodesField(context) { function showOrHideMissingEpisodesField(context) {
if (browser.tizen || browser.web0s) { if (browser.tizen || browser.web0s) {
context.querySelector('.fldDisplayMissingEpisodes').classList.add('hide'); context.querySelector('.fldDisplayMissingEpisodes').classList.add('hide');
return; return;
} }
context.querySelector('.fldDisplayMissingEpisodes').classList.remove('hide'); context.querySelector('.fldDisplayMissingEpisodes').classList.remove('hide');
} }
function loadForm(context, user, userSettings) { function loadForm(context, user, userSettings) {
if (appHost.supports('displaylanguage')) { if (appHost.supports('displaylanguage')) {
context.querySelector('.languageSection').classList.remove('hide'); context.querySelector('.languageSection').classList.remove('hide');
} else { } else {
@ -133,9 +131,9 @@ import template from './displaySettings.template.html';
showOrHideMissingEpisodesField(context); showOrHideMissingEpisodesField(context);
loading.hide(); loading.hide();
} }
function saveUser(context, user, userSettingsInstance, apiClient) { function saveUser(context, user, userSettingsInstance, apiClient) {
user.Configuration.DisplayMissingEpisodes = context.querySelector('.chkDisplayMissingEpisodes').checked; user.Configuration.DisplayMissingEpisodes = context.querySelector('.chkDisplayMissingEpisodes').checked;
if (appHost.supports('displaylanguage')) { if (appHost.supports('displaylanguage')) {
@ -170,9 +168,9 @@ import template from './displaySettings.template.html';
layoutManager.setLayout(context.querySelector('.selectLayout').value); layoutManager.setLayout(context.querySelector('.selectLayout').value);
return apiClient.updateUserConfiguration(user.Id, user.Configuration); return apiClient.updateUserConfiguration(user.Id, user.Configuration);
} }
function save(instance, context, userId, userSettings, apiClient, enableSaveConfirmation) { function save(instance, context, userId, userSettings, apiClient, enableSaveConfirmation) {
loading.show(); loading.show();
apiClient.getUser(userId).then(user => { apiClient.getUser(userId).then(user => {
@ -186,9 +184,9 @@ import template from './displaySettings.template.html';
loading.hide(); loading.hide();
}); });
}); });
} }
function onSubmit(e) { function onSubmit(e) {
const self = this; const self = this;
const apiClient = ServerConnections.getApiClient(self.options.serverId); const apiClient = ServerConnections.getApiClient(self.options.serverId);
const userId = self.options.userId; const userId = self.options.userId;
@ -204,18 +202,18 @@ import template from './displaySettings.template.html';
e.preventDefault(); e.preventDefault();
} }
return false; return false;
} }
function embed(options, self) { function embed(options, self) {
options.element.innerHTML = globalize.translateHtml(template, 'core'); options.element.innerHTML = globalize.translateHtml(template, 'core');
options.element.querySelector('form').addEventListener('submit', onSubmit.bind(self)); options.element.querySelector('form').addEventListener('submit', onSubmit.bind(self));
if (options.enableSaveButton) { if (options.enableSaveButton) {
options.element.querySelector('.btnSave').classList.remove('hide'); options.element.querySelector('.btnSave').classList.remove('hide');
} }
self.loadData(options.autoFocus); self.loadData(options.autoFocus);
} }
class DisplaySettings { class DisplaySettings {
constructor(options) { constructor(options) {
this.options = options; this.options = options;
embed(options, this); embed(options, this);
@ -249,7 +247,6 @@ import template from './displaySettings.template.html';
destroy() { destroy() {
this.options = null; this.options = null;
} }
} }
/* eslint-enable indent */
export default DisplaySettings; export default DisplaySettings;

View file

@ -9,25 +9,23 @@ import { getParameterByName } from '../utils/url.ts';
import '../styles/scrollstyles.scss'; import '../styles/scrollstyles.scss';
import '../elements/emby-itemscontainer/emby-itemscontainer'; import '../elements/emby-itemscontainer/emby-itemscontainer';
/* eslint-disable indent */ function enableScrollX() {
function enableScrollX() {
return !layoutManager.desktop; return !layoutManager.desktop;
} }
function getThumbShape() { function getThumbShape() {
return enableScrollX() ? 'overflowBackdrop' : 'backdrop'; return enableScrollX() ? 'overflowBackdrop' : 'backdrop';
} }
function getPosterShape() { function getPosterShape() {
return enableScrollX() ? 'overflowPortrait' : 'portrait'; return enableScrollX() ? 'overflowPortrait' : 'portrait';
} }
function getSquareShape() { function getSquareShape() {
return enableScrollX() ? 'overflowSquare' : 'square'; return enableScrollX() ? 'overflowSquare' : 'square';
} }
function getSections() { function getSections() {
return [{ return [{
name: 'Movies', name: 'Movies',
types: 'Movie', types: 'Movie',
@ -101,9 +99,9 @@ import '../elements/emby-itemscontainer/emby-itemscontainer';
action: 'instantmix', action: 'instantmix',
coverImage: true coverImage: true
}]; }];
} }
function loadSection(elem, userId, topParentId, section, isSingleSection) { function loadSection(elem, userId, topParentId, section, isSingleSection) {
const screenWidth = dom.getWindowSize().innerWidth; const screenWidth = dom.getWindowSize().innerWidth;
const options = { const options = {
SortBy: 'SortName', SortBy: 'SortName',
@ -193,9 +191,9 @@ import '../elements/emby-itemscontainer/emby-itemscontainer';
elem.innerHTML = html; elem.innerHTML = html;
imageLoader.lazyChildren(elem); imageLoader.lazyChildren(elem);
}); });
} }
export function loadSections(page, userId, topParentId, types) { export function loadSections(page, userId, topParentId, types) {
loading.show(); loading.show();
let sections = getSections(); let sections = getSections();
const sectionid = getParameterByName('sectionid'); const sectionid = getParameterByName('sectionid');
@ -235,10 +233,8 @@ import '../elements/emby-itemscontainer/emby-itemscontainer';
Promise.all(promises).then(function () { Promise.all(promises).then(function () {
loading.hide(); loading.hide();
}); });
} }
export default { export default {
render: loadSections render: loadSections
}; };
/* eslint-enable indent */

View file

@ -1,5 +1,4 @@
/* eslint-disable indent */ export function getFetchPromise(request) {
export function getFetchPromise(request) {
const headers = request.headers || {}; const headers = request.headers || {};
if (request.dataType === 'json') { if (request.dataType === 'json') {
@ -42,9 +41,9 @@
} }
return fetchWithTimeout(url, fetchRequest, request.timeout); return fetchWithTimeout(url, fetchRequest, request.timeout);
} }
function fetchWithTimeout(url, options, timeoutMs) { function fetchWithTimeout(url, options, timeoutMs) {
console.debug(`fetchWithTimeout: timeoutMs: ${timeoutMs}, url: ${url}`); console.debug(`fetchWithTimeout: timeoutMs: ${timeoutMs}, url: ${url}`);
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
@ -67,20 +66,20 @@
reject(error); reject(error);
}); });
}); });
} }
/** /**
* @param params {Record<string, string | number | boolean>} * @param params {Record<string, string | number | boolean>}
* @returns {string} Query string * @returns {string} Query string
*/ */
function paramsToString(params) { function paramsToString(params) {
return Object.entries(params) return Object.entries(params)
.filter(([, v]) => v !== null && v !== undefined && v !== '') .filter(([, v]) => v !== null && v !== undefined && v !== '')
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`) .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&'); .join('&');
} }
export function ajax(request) { export function ajax(request) {
if (!request) { if (!request) {
throw new Error('Request cannot be null'); throw new Error('Request cannot be null');
} }
@ -106,5 +105,4 @@
console.error(`request failed to url: ${request.url}`); console.error(`request failed to url: ${request.url}`);
throw err; throw err;
}); });
} }
/* eslint-enable indent */

View file

@ -8,8 +8,7 @@ import './style.scss';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';
import template from './filterdialog.template.html'; import template from './filterdialog.template.html';
/* eslint-disable indent */ function renderOptions(context, selector, cssClass, items, isCheckedFn) {
function renderOptions(context, selector, cssClass, items, isCheckedFn) {
const elem = context.querySelector(selector); const elem = context.querySelector(selector);
if (items.length) { if (items.length) {
elem.classList.remove('hide'); elem.classList.remove('hide');
@ -29,9 +28,9 @@ import template from './filterdialog.template.html';
}).join(''); }).join('');
html += '</div>'; html += '</div>';
elem.querySelector('.filterOptions').innerHTML = html; elem.querySelector('.filterOptions').innerHTML = html;
} }
function renderFilters(context, result, query) { function renderFilters(context, result, query) {
renderOptions(context, '.genreFilters', 'chkGenreFilter', result.Genres, function (i) { renderOptions(context, '.genreFilters', 'chkGenreFilter', result.Genres, function (i) {
const delimeter = '|'; const delimeter = '|';
return (delimeter + (query.Genres || '') + delimeter).includes(delimeter + i + delimeter); return (delimeter + (query.Genres || '') + delimeter).includes(delimeter + i + delimeter);
@ -48,9 +47,9 @@ import template from './filterdialog.template.html';
const delimeter = ','; const delimeter = ',';
return (delimeter + (query.Years || '') + delimeter).includes(delimeter + i + delimeter); return (delimeter + (query.Years || '') + delimeter).includes(delimeter + i + delimeter);
}); });
} }
function loadDynamicFilters(context, apiClient, userId, itemQuery) { function loadDynamicFilters(context, apiClient, userId, itemQuery) {
return apiClient.getJSON(apiClient.getUrl('Items/Filters', { return apiClient.getJSON(apiClient.getUrl('Items/Filters', {
UserId: userId, UserId: userId,
ParentId: itemQuery.ParentId, ParentId: itemQuery.ParentId,
@ -58,13 +57,13 @@ import template from './filterdialog.template.html';
})).then(function (result) { })).then(function (result) {
renderFilters(context, result, itemQuery); renderFilters(context, result, itemQuery);
}); });
} }
/** /**
* @param context {HTMLDivElement} Dialog * @param context {HTMLDivElement} Dialog
* @param options {any} Options * @param options {any} Options
*/ */
function updateFilterControls(context, options) { function updateFilterControls(context, options) {
const query = options.query; const query = options.query;
if (options.mode === 'livetvchannels') { if (options.mode === 'livetvchannels') {
@ -99,16 +98,16 @@ import template from './filterdialog.template.html';
const filterName = elem.getAttribute('data-filter'); const filterName = elem.getAttribute('data-filter');
elem.checked = filters.includes(`,${filterName}`); elem.checked = filters.includes(`,${filterName}`);
} }
} }
/** /**
* @param instance {FilterDialog} An instance of FilterDialog * @param instance {FilterDialog} An instance of FilterDialog
*/ */
function triggerChange(instance) { function triggerChange(instance) {
Events.trigger(instance, 'filterchange'); Events.trigger(instance, 'filterchange');
} }
function setVisibility(context, options) { function setVisibility(context, options) {
if (options.mode === 'livetvchannels' || options.mode === 'albums' || options.mode === 'artists' || options.mode === 'albumartists' || options.mode === 'songs') { if (options.mode === 'livetvchannels' || options.mode === 'albums' || options.mode === 'artists' || options.mode === 'albumartists' || options.mode === 'songs') {
hideByClass(context, 'videoStandard'); hideByClass(context, 'videoStandard');
} }
@ -135,25 +134,25 @@ import template from './filterdialog.template.html';
if (options.mode === 'episodes') { if (options.mode === 'episodes') {
showByClass(context, 'episodeFilter'); showByClass(context, 'episodeFilter');
} }
} }
function showByClass(context, className) { function showByClass(context, className) {
for (const elem of context.querySelectorAll(`.${className}`)) { for (const elem of context.querySelectorAll(`.${className}`)) {
elem.classList.remove('hide'); elem.classList.remove('hide');
} }
} }
function hideByClass(context, className) { function hideByClass(context, className) {
for (const elem of context.querySelectorAll(`.${className}`)) { for (const elem of context.querySelectorAll(`.${className}`)) {
elem.classList.add('hide'); elem.classList.add('hide');
} }
} }
function enableDynamicFilters(mode) { function enableDynamicFilters(mode) {
return mode === 'movies' || mode === 'series' || mode === 'albums' || mode === 'albumartists' || mode === 'artists' || mode === 'songs' || mode === 'episodes'; return mode === 'movies' || mode === 'series' || mode === 'albums' || mode === 'albumartists' || mode === 'artists' || mode === 'songs' || mode === 'episodes';
} }
class FilterDialog { class FilterDialog {
constructor(options) { constructor(options) {
/** /**
* @private * @private
@ -417,8 +416,6 @@ import template from './filterdialog.template.html';
} }
}); });
} }
} }
/* eslint-enable indent */
export default FilterDialog; export default FilterDialog;

View file

@ -297,10 +297,8 @@ class FilterMenu {
} }
if (submitted) { if (submitted) {
//if (!options.onChange) {
saveValues(dlg, options.settings, options.settingsKey, options.setfilters); saveValues(dlg, options.settings, options.settingsKey, options.setfilters);
return resolve(); return resolve();
//}
} }
return resolve(); return resolve();
}); });

View file

@ -1,20 +1,18 @@
/* eslint-disable indent */
import dom from '../scripts/dom'; import dom from '../scripts/dom';
import scrollManager from './scrollManager'; import scrollManager from './scrollManager';
const scopes = []; const scopes = [];
function pushScope(elem) { function pushScope(elem) {
scopes.push(elem); scopes.push(elem);
} }
function popScope() { function popScope() {
if (scopes.length) { if (scopes.length) {
scopes.length -= 1; scopes.length -= 1;
} }
} }
function autoFocus(view, defaultToFirst, findAutoFocusElement) { function autoFocus(view, defaultToFirst, findAutoFocusElement) {
let element; let element;
if (findAutoFocusElement !== false) { if (findAutoFocusElement !== false) {
element = view.querySelector('*[autofocus]'); element = view.querySelector('*[autofocus]');
@ -34,9 +32,9 @@ import scrollManager from './scrollManager';
} }
return null; return null;
} }
function focus(element) { function focus(element) {
try { try {
element.focus({ element.focus({
preventScroll: scrollManager.isEnabled() preventScroll: scrollManager.isEnabled()
@ -44,23 +42,23 @@ import scrollManager from './scrollManager';
} catch (err) { } catch (err) {
console.error('Error in focusManager.autoFocus: ' + err); console.error('Error in focusManager.autoFocus: ' + err);
} }
} }
const focusableTagNames = ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON', 'A']; const focusableTagNames = ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON', 'A'];
const focusableContainerTagNames = ['BODY', 'DIALOG']; const focusableContainerTagNames = ['BODY', 'DIALOG'];
const focusableQuery = focusableTagNames.map(function (t) { const focusableQuery = focusableTagNames.map(function (t) {
if (t === 'INPUT') { if (t === 'INPUT') {
t += ':not([type="range"]):not([type="file"])'; t += ':not([type="range"]):not([type="file"])';
} }
return t + ':not([tabindex="-1"]):not(:disabled)'; return t + ':not([tabindex="-1"]):not(:disabled)';
}).join(',') + ',.focusable'; }).join(',') + ',.focusable';
function isFocusable(elem) { function isFocusable(elem) {
return focusableTagNames.indexOf(elem.tagName) !== -1 return focusableTagNames.indexOf(elem.tagName) !== -1
|| (elem.classList?.contains('focusable')); || (elem.classList?.contains('focusable'));
} }
function normalizeFocusable(elem, originalElement) { function normalizeFocusable(elem, originalElement) {
if (elem) { if (elem) {
const tagName = elem.tagName; const tagName = elem.tagName;
if (!tagName || tagName === 'HTML' || tagName === 'BODY') { if (!tagName || tagName === 'HTML' || tagName === 'BODY') {
@ -69,9 +67,9 @@ import scrollManager from './scrollManager';
} }
return elem; return elem;
} }
function focusableParent(elem) { function focusableParent(elem) {
const originalElement = elem; const originalElement = elem;
while (!isFocusable(elem)) { while (!isFocusable(elem)) {
@ -85,16 +83,16 @@ import scrollManager from './scrollManager';
} }
return normalizeFocusable(elem, originalElement); return normalizeFocusable(elem, originalElement);
} }
// Determines if a focusable element can be focused at a given point in time // Determines if a focusable element can be focused at a given point in time
function isCurrentlyFocusableInternal(elem) { function isCurrentlyFocusableInternal(elem) {
// http://stackoverflow.com/questions/19669786/check-if-element-is-visible-in-dom // http://stackoverflow.com/questions/19669786/check-if-element-is-visible-in-dom
return elem.offsetParent !== null; return elem.offsetParent !== null;
} }
// Determines if a focusable element can be focused at a given point in time // Determines if a focusable element can be focused at a given point in time
function isCurrentlyFocusable(elem) { function isCurrentlyFocusable(elem) {
if (elem.disabled) { if (elem.disabled) {
return false; return false;
} }
@ -114,13 +112,13 @@ import scrollManager from './scrollManager';
} }
return isCurrentlyFocusableInternal(elem); return isCurrentlyFocusableInternal(elem);
} }
function getDefaultScope() { function getDefaultScope() {
return scopes[0] || document.body; return scopes[0] || document.body;
} }
function getFocusableElements(parent, limit, excludeClass) { function getFocusableElements(parent, limit, excludeClass) {
const elems = (parent || getDefaultScope()).querySelectorAll(focusableQuery); const elems = (parent || getDefaultScope()).querySelectorAll(focusableQuery);
const focusableElements = []; const focusableElements = [];
@ -141,9 +139,9 @@ import scrollManager from './scrollManager';
} }
return focusableElements; return focusableElements;
} }
function isFocusContainer(elem, direction) { function isFocusContainer(elem, direction) {
if (focusableContainerTagNames.indexOf(elem.tagName) !== -1) { if (focusableContainerTagNames.indexOf(elem.tagName) !== -1) {
return true; return true;
} }
@ -182,9 +180,9 @@ import scrollManager from './scrollManager';
} }
return false; return false;
} }
function getFocusContainer(elem, direction) { function getFocusContainer(elem, direction) {
while (!isFocusContainer(elem, direction)) { while (!isFocusContainer(elem, direction)) {
elem = elem.parentNode; elem = elem.parentNode;
@ -194,9 +192,9 @@ import scrollManager from './scrollManager';
} }
return elem; return elem;
} }
function getOffset(elem) { function getOffset(elem) {
let box; let box;
// Support: BlackBerry 5, iOS 3 (original iPhone) // Support: BlackBerry 5, iOS 3 (original iPhone)
@ -228,9 +226,9 @@ import scrollManager from './scrollManager';
} }
return box; return box;
} }
function nav(activeElement, direction, container, focusableElements) { function nav(activeElement, direction, container, focusableElements) {
activeElement = activeElement || document.activeElement; activeElement = activeElement || document.activeElement;
if (activeElement) { if (activeElement) {
@ -382,23 +380,23 @@ import scrollManager from './scrollManager';
} }
focus(nearestElement); focus(nearestElement);
} }
} }
function intersectsInternal(a1, a2, b1, b2) { function intersectsInternal(a1, a2, b1, b2) {
return (b1 >= a1 && b1 <= a2) || (b2 >= a1 && b2 <= a2); return (b1 >= a1 && b1 <= a2) || (b2 >= a1 && b2 <= a2);
} }
function intersects(a1, a2, b1, b2) { function intersects(a1, a2, b1, b2) {
return intersectsInternal(a1, a2, b1, b2) || intersectsInternal(b1, b2, a1, a2); return intersectsInternal(a1, a2, b1, b2) || intersectsInternal(b1, b2, a1, a2);
} }
function sendText(text) { function sendText(text) {
const elem = document.activeElement; const elem = document.activeElement;
elem.value = text; elem.value = text;
} }
function focusFirst(container, focusableSelector) { function focusFirst(container, focusableSelector) {
const elems = container.querySelectorAll(focusableSelector); const elems = container.querySelectorAll(focusableSelector);
for (let i = 0, length = elems.length; i < length; i++) { for (let i = 0, length = elems.length; i < length; i++) {
@ -409,9 +407,9 @@ import scrollManager from './scrollManager';
break; break;
} }
} }
} }
function focusLast(container, focusableSelector) { function focusLast(container, focusableSelector) {
const elems = [].slice.call(container.querySelectorAll(focusableSelector), 0).reverse(); const elems = [].slice.call(container.querySelectorAll(focusableSelector), 0).reverse();
for (let i = 0, length = elems.length; i < length; i++) { for (let i = 0, length = elems.length; i < length; i++) {
@ -422,9 +420,9 @@ import scrollManager from './scrollManager';
break; break;
} }
} }
} }
function moveFocus(sourceElement, container, focusableSelector, offset) { function moveFocus(sourceElement, container, focusableSelector, offset) {
const elems = container.querySelectorAll(focusableSelector); const elems = container.querySelectorAll(focusableSelector);
const list = []; const list = [];
let i; let i;
@ -462,9 +460,7 @@ import scrollManager from './scrollManager';
if (newElem) { if (newElem) {
focus(newElem); focus(newElem);
} }
} }
/* eslint-enable indent */
export default { export default {
autoFocus: autoFocus, autoFocus: autoFocus,

View file

@ -1,11 +1,9 @@
/* eslint-disable indent */
import dom from '../scripts/dom'; import dom from '../scripts/dom';
import { appRouter } from './appRouter'; import { appRouter } from './appRouter';
import Dashboard from '../utils/dashboard'; import Dashboard from '../utils/dashboard';
import ServerConnections from './ServerConnections'; import ServerConnections from './ServerConnections';
function onGroupedCardClick(e, card) { function onGroupedCardClick(e, card) {
const itemId = card.getAttribute('data-id'); const itemId = card.getAttribute('data-id');
const serverId = card.getAttribute('data-serverid'); const serverId = card.getAttribute('data-serverid');
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
@ -34,14 +32,12 @@ import ServerConnections from './ServerConnections';
e.preventDefault(); e.preventDefault();
return false; return false;
} }
} }
export default function onItemsContainerClick(e) { export default function onItemsContainerClick(e) {
const groupedCard = dom.parentWithClass(e.target, 'groupedCard'); const groupedCard = dom.parentWithClass(e.target, 'groupedCard');
if (groupedCard) { if (groupedCard) {
onGroupedCardClick(e, groupedCard); onGroupedCardClick(e, groupedCard);
} }
} }
/* eslint-enable indent */

View file

@ -29,7 +29,7 @@ import ServerConnections from '../ServerConnections';
import template from './tvguide.template.html'; import template from './tvguide.template.html';
function showViewSettings(instance) { function showViewSettings(instance) {
import('./guide-settings').then(({default: guideSettingsDialog}) => { import('./guide-settings').then(({ default: guideSettingsDialog }) => {
guideSettingsDialog.show(instance.categoryOptions).then(function () { guideSettingsDialog.show(instance.categoryOptions).then(function () {
instance.refresh(); instance.refresh();
}); });

View file

@ -14,11 +14,9 @@ import ServerConnections from '../ServerConnections';
import toast from '../toast/toast'; import toast from '../toast/toast';
import template from './homeScreenSettings.template.html'; import template from './homeScreenSettings.template.html';
/* eslint-disable indent */ const numConfigurableSections = 7;
const numConfigurableSections = 7; function renderViews(page, user, result) {
function renderViews(page, user, result) {
let folderHtml = ''; let folderHtml = '';
folderHtml += '<div class="checkboxList">'; folderHtml += '<div class="checkboxList">';
@ -42,9 +40,9 @@ import template from './homeScreenSettings.template.html';
folderHtml += '</div>'; folderHtml += '</div>';
page.querySelector('.folderGroupList').innerHTML = folderHtml; page.querySelector('.folderGroupList').innerHTML = folderHtml;
} }
function getLandingScreenOptions(type) { function getLandingScreenOptions(type) {
const list = []; const list = [];
if (type === 'movies') { if (type === 'movies') {
@ -158,9 +156,9 @@ import template from './homeScreenSettings.template.html';
} }
return list; return list;
} }
function getLandingScreenOptionsHtml(type, userValue) { function getLandingScreenOptionsHtml(type, userValue) {
return getLandingScreenOptions(type).map(o => { return getLandingScreenOptions(type).map(o => {
const selected = userValue === o.value || (o.isDefault && !userValue); const selected = userValue === o.value || (o.isDefault && !userValue);
const selectedHtml = selected ? ' selected' : ''; const selectedHtml = selected ? ' selected' : '';
@ -168,9 +166,9 @@ import template from './homeScreenSettings.template.html';
return `<option value="${optionValue}"${selectedHtml}>${escapeHtml(o.name)}</option>`; return `<option value="${optionValue}"${selectedHtml}>${escapeHtml(o.name)}</option>`;
}).join(''); }).join('');
} }
function renderViewOrder(context, user, result) { function renderViewOrder(context, user, result) {
let html = ''; let html = '';
html += result.Items.map((view) => { html += result.Items.map((view) => {
@ -197,9 +195,9 @@ import template from './homeScreenSettings.template.html';
}).join(''); }).join('');
context.querySelector('.viewOrderList').innerHTML = html; context.querySelector('.viewOrderList').innerHTML = html;
} }
function updateHomeSectionValues(context, userSettings) { function updateHomeSectionValues(context, userSettings) {
for (let i = 1; i <= 7; i++) { for (let i = 1; i <= 7; i++) {
const select = context.querySelector(`#selectHomeSection${i}`); const select = context.querySelector(`#selectHomeSection${i}`);
const defaultValue = homeSections.getDefaultSection(i - 1); const defaultValue = homeSections.getDefaultSection(i - 1);
@ -218,9 +216,9 @@ import template from './homeScreenSettings.template.html';
} }
context.querySelector('.selectTVHomeScreen').value = userSettings.get('tvhome') || ''; context.querySelector('.selectTVHomeScreen').value = userSettings.get('tvhome') || '';
} }
function getPerLibrarySettingsHtml(item, user, userSettings) { function getPerLibrarySettingsHtml(item, user, userSettings) {
let html = ''; let html = '';
let isChecked; let isChecked;
@ -274,9 +272,9 @@ import template from './homeScreenSettings.template.html';
} }
return html; return html;
} }
function renderPerLibrarySettings(context, user, userViews, userSettings) { function renderPerLibrarySettings(context, user, userViews, userSettings) {
const elem = context.querySelector('.perLibrarySettings'); const elem = context.querySelector('.perLibrarySettings');
let html = ''; let html = '';
@ -285,9 +283,9 @@ import template from './homeScreenSettings.template.html';
} }
elem.innerHTML = html; elem.innerHTML = html;
} }
function loadForm(context, user, userSettings, apiClient) { function loadForm(context, user, userSettings, apiClient) {
context.querySelector('.chkHidePlayedFromLatest').checked = user.Configuration.HidePlayedInLatest || false; context.querySelector('.chkHidePlayedFromLatest').checked = user.Configuration.HidePlayedInLatest || false;
updateHomeSectionValues(context, userSettings); updateHomeSectionValues(context, userSettings);
@ -304,9 +302,9 @@ import template from './homeScreenSettings.template.html';
loading.hide(); loading.hide();
}); });
} }
function onSectionOrderListClick(e) { function onSectionOrderListClick(e) {
const target = dom.parentWithClass(e.target, 'btnViewItemMove'); const target = dom.parentWithClass(e.target, 'btnViewItemMove');
if (target) { if (target) {
@ -332,9 +330,9 @@ import template from './homeScreenSettings.template.html';
} }
} }
} }
} }
function getCheckboxItems(selector, context, isChecked) { function getCheckboxItems(selector, context, isChecked) {
const inputs = context.querySelectorAll(selector); const inputs = context.querySelectorAll(selector);
const list = []; const list = [];
@ -345,9 +343,9 @@ import template from './homeScreenSettings.template.html';
} }
return list; return list;
} }
function saveUser(context, user, userSettingsInstance, apiClient) { function saveUser(context, user, userSettingsInstance, apiClient) {
user.Configuration.HidePlayedInLatest = context.querySelector('.chkHidePlayedFromLatest').checked; user.Configuration.HidePlayedInLatest = context.querySelector('.chkHidePlayedFromLatest').checked;
user.Configuration.LatestItemsExcludes = getCheckboxItems('.chkIncludeInLatest', context, false).map(i => { user.Configuration.LatestItemsExcludes = getCheckboxItems('.chkIncludeInLatest', context, false).map(i => {
@ -389,9 +387,9 @@ import template from './homeScreenSettings.template.html';
} }
return apiClient.updateUserConfiguration(user.Id, user.Configuration); return apiClient.updateUserConfiguration(user.Id, user.Configuration);
} }
function save(instance, context, userId, userSettings, apiClient, enableSaveConfirmation) { function save(instance, context, userId, userSettings, apiClient, enableSaveConfirmation) {
loading.show(); loading.show();
apiClient.getUser(userId).then(user => { apiClient.getUser(userId).then(user => {
@ -406,9 +404,9 @@ import template from './homeScreenSettings.template.html';
loading.hide(); loading.hide();
}); });
}); });
} }
function onSubmit(e) { function onSubmit(e) {
const self = this; const self = this;
const apiClient = ServerConnections.getApiClient(self.options.serverId); const apiClient = ServerConnections.getApiClient(self.options.serverId);
const userId = self.options.userId; const userId = self.options.userId;
@ -424,9 +422,9 @@ import template from './homeScreenSettings.template.html';
e.preventDefault(); e.preventDefault();
} }
return false; return false;
} }
function onChange(e) { function onChange(e) {
const chkIncludeInMyMedia = dom.parentWithClass(e.target, 'chkIncludeInMyMedia'); const chkIncludeInMyMedia = dom.parentWithClass(e.target, 'chkIncludeInMyMedia');
if (!chkIncludeInMyMedia) { if (!chkIncludeInMyMedia) {
return; return;
@ -441,9 +439,9 @@ import template from './homeScreenSettings.template.html';
fldIncludeInLatest.classList.add('hide'); fldIncludeInLatest.classList.add('hide');
} }
} }
} }
function embed(options, self) { function embed(options, self) {
let workingTemplate = template; let workingTemplate = template;
for (let i = 1; i <= numConfigurableSections; i++) { for (let i = 1; i <= numConfigurableSections; i++) {
workingTemplate = workingTemplate.replace(`{section${i}label}`, globalize.translate('LabelHomeScreenSectionValue', i)); workingTemplate = workingTemplate.replace(`{section${i}label}`, globalize.translate('LabelHomeScreenSectionValue', i));
@ -466,9 +464,9 @@ import template from './homeScreenSettings.template.html';
} }
self.loadData(options.autoFocus); self.loadData(options.autoFocus);
} }
class HomeScreenSettings { class HomeScreenSettings {
constructor(options) { constructor(options) {
this.options = options; this.options = options;
embed(options, this); embed(options, this);
@ -504,8 +502,6 @@ import template from './homeScreenSettings.template.html';
destroy() { destroy() {
this.options = null; this.options = null;
} }
} }
/* eslint-enable indent */
export default HomeScreenSettings; export default HomeScreenSettings;

View file

@ -13,9 +13,7 @@ import './homesections.scss';
import Dashboard from '../../utils/dashboard'; import Dashboard from '../../utils/dashboard';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';
/* eslint-disable indent */ export function getDefaultSection(index) {
export function getDefaultSection(index) {
switch (index) { switch (index) {
case 0: case 0:
return 'smalllibrarytiles'; return 'smalllibrarytiles';
@ -36,9 +34,9 @@ import ServerConnections from '../ServerConnections';
default: default:
return ''; return '';
} }
} }
function getAllSectionsToShow(userSettings, sectionCount) { function getAllSectionsToShow(userSettings, sectionCount) {
const sections = []; const sections = [];
for (let i = 0, length = sectionCount; i < length; i++) { for (let i = 0, length = sectionCount; i < length; i++) {
let section = userSettings.get('homesection' + i) || getDefaultSection(i); let section = userSettings.get('homesection' + i) || getDefaultSection(i);
@ -50,9 +48,9 @@ import ServerConnections from '../ServerConnections';
} }
return sections; return sections;
} }
export function loadSections(elem, apiClient, user, userSettings) { export function loadSections(elem, apiClient, user, userSettings) {
return getUserViews(apiClient, user.Id).then(function (userViews) { return getUserViews(apiClient, user.Id).then(function (userViews) {
let html = ''; let html = '';
@ -98,9 +96,9 @@ import ServerConnections from '../ServerConnections';
} }
} }
}); });
} }
export function destroySections(elem) { export function destroySections(elem) {
const elems = elem.querySelectorAll('.itemsContainer'); const elems = elem.querySelectorAll('.itemsContainer');
for (let i = 0; i < elems.length; i++) { for (let i = 0; i < elems.length; i++) {
elems[i].fetchData = null; elems[i].fetchData = null;
@ -109,16 +107,16 @@ import ServerConnections from '../ServerConnections';
} }
elem.innerHTML = ''; elem.innerHTML = '';
} }
export function pause(elem) { export function pause(elem) {
const elems = elem.querySelectorAll('.itemsContainer'); const elems = elem.querySelectorAll('.itemsContainer');
for (let i = 0; i < elems.length; i++) { for (let i = 0; i < elems.length; i++) {
elems[i].pause(); elems[i].pause();
} }
} }
export function resume(elem, options) { export function resume(elem, options) {
const elems = elem.querySelectorAll('.itemsContainer'); const elems = elem.querySelectorAll('.itemsContainer');
const promises = []; const promises = [];
@ -127,9 +125,9 @@ import ServerConnections from '../ServerConnections';
} }
return Promise.all(promises); return Promise.all(promises);
} }
function loadSection(page, apiClient, user, userSettings, userViews, allSections, index) { function loadSection(page, apiClient, user, userSettings, userViews, allSections, index) {
const section = allSections[index]; const section = allSections[index];
const elem = page.querySelector('.section' + index); const elem = page.querySelector('.section' + index);
@ -156,31 +154,31 @@ import ServerConnections from '../ServerConnections';
return Promise.resolve(); return Promise.resolve();
} }
return Promise.resolve(); return Promise.resolve();
} }
function getUserViews(apiClient, userId) { function getUserViews(apiClient, userId) {
return apiClient.getUserViews({}, userId || apiClient.getCurrentUserId()).then(function (result) { return apiClient.getUserViews({}, userId || apiClient.getCurrentUserId()).then(function (result) {
return result.Items; return result.Items;
}); });
} }
function enableScrollX() { function enableScrollX() {
return true; return true;
} }
function getSquareShape() { function getSquareShape() {
return enableScrollX() ? 'overflowSquare' : 'square'; return enableScrollX() ? 'overflowSquare' : 'square';
} }
function getThumbShape() { function getThumbShape() {
return enableScrollX() ? 'overflowBackdrop' : 'backdrop'; return enableScrollX() ? 'overflowBackdrop' : 'backdrop';
} }
function getPortraitShape() { function getPortraitShape() {
return enableScrollX() ? 'overflowPortrait' : 'portrait'; return enableScrollX() ? 'overflowPortrait' : 'portrait';
} }
function getLibraryButtonsHtml(items) { function getLibraryButtonsHtml(items) {
let html = ''; let html = '';
html += '<div class="verticalSection verticalSection-extrabottompadding">'; html += '<div class="verticalSection verticalSection-extrabottompadding">';
@ -199,17 +197,17 @@ import ServerConnections from '../ServerConnections';
html += '</div>'; html += '</div>';
return html; return html;
} }
function loadlibraryButtons(elem, apiClient, user, userSettings, userViews) { function loadlibraryButtons(elem, apiClient, user, userSettings, userViews) {
elem.classList.remove('verticalSection'); elem.classList.remove('verticalSection');
const html = getLibraryButtonsHtml(userViews); const html = getLibraryButtonsHtml(userViews);
elem.innerHTML = html; elem.innerHTML = html;
imageLoader.lazyChildren(elem); imageLoader.lazyChildren(elem);
} }
function getFetchLatestItemsFn(serverId, parentId, collectionType) { function getFetchLatestItemsFn(serverId, parentId, collectionType) {
return function () { return function () {
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
let limit = 16; let limit = 16;
@ -238,9 +236,9 @@ import ServerConnections from '../ServerConnections';
return apiClient.getLatestItems(options); return apiClient.getLatestItems(options);
}; };
} }
function getLatestItemsHtmlFn(itemType, viewType) { function getLatestItemsHtmlFn(itemType, viewType) {
return function (items) { return function (items) {
const cardLayout = false; const cardLayout = false;
let shape; let shape;
@ -270,9 +268,9 @@ import ServerConnections from '../ServerConnections';
lines: 2 lines: 2
}); });
}; };
} }
function renderLatestSection(elem, apiClient, user, parent) { function renderLatestSection(elem, apiClient, user, parent) {
let html = ''; let html = '';
html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">'; html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">';
@ -308,9 +306,9 @@ import ServerConnections from '../ServerConnections';
itemsContainer.fetchData = getFetchLatestItemsFn(apiClient.serverId(), parent.Id, parent.CollectionType); itemsContainer.fetchData = getFetchLatestItemsFn(apiClient.serverId(), parent.Id, parent.CollectionType);
itemsContainer.getItemsHtml = getLatestItemsHtmlFn(parent.Type, parent.CollectionType); itemsContainer.getItemsHtml = getLatestItemsHtmlFn(parent.Type, parent.CollectionType);
itemsContainer.parentContainer = elem; itemsContainer.parentContainer = elem;
} }
function loadRecentlyAdded(elem, apiClient, user, userViews) { function loadRecentlyAdded(elem, apiClient, user, userViews) {
elem.classList.remove('verticalSection'); elem.classList.remove('verticalSection');
const excludeViewTypes = ['playlists', 'livetv', 'boxsets', 'channels']; const excludeViewTypes = ['playlists', 'livetv', 'boxsets', 'channels'];
@ -331,9 +329,9 @@ import ServerConnections from '../ServerConnections';
renderLatestSection(frag, apiClient, user, item); renderLatestSection(frag, apiClient, user, item);
} }
} }
export function loadLibraryTiles(elem, apiClient, user, userSettings, shape, userViews) { export function loadLibraryTiles(elem, apiClient, user, userSettings, shape, userViews) {
let html = ''; let html = '';
if (userViews.length) { if (userViews.length) {
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderMyMedia') + '</h2>'; html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderMyMedia') + '</h2>';
@ -363,14 +361,14 @@ import ServerConnections from '../ServerConnections';
elem.innerHTML = html; elem.innerHTML = html;
imageLoader.lazyChildren(elem); imageLoader.lazyChildren(elem);
} }
const dataMonitorHints = { const dataMonitorHints = {
'Audio': 'audioplayback,markplayed', 'Audio': 'audioplayback,markplayed',
'Video': 'videoplayback,markplayed' 'Video': 'videoplayback,markplayed'
}; };
function loadResume(elem, apiClient, headerText, mediaType, userSettings) { function loadResume(elem, apiClient, headerText, mediaType, userSettings) {
let html = ''; let html = '';
const dataMonitor = dataMonitorHints[mediaType] || 'markplayed'; const dataMonitor = dataMonitorHints[mediaType] || 'markplayed';
@ -395,9 +393,9 @@ import ServerConnections from '../ServerConnections';
itemsContainer.fetchData = getItemsToResumeFn(mediaType, apiClient.serverId()); itemsContainer.fetchData = getItemsToResumeFn(mediaType, apiClient.serverId());
itemsContainer.getItemsHtml = getItemsToResumeHtmlFn(userSettings.useEpisodeImagesInNextUpAndResume(), mediaType); itemsContainer.getItemsHtml = getItemsToResumeHtmlFn(userSettings.useEpisodeImagesInNextUpAndResume(), mediaType);
itemsContainer.parentContainer = elem; itemsContainer.parentContainer = elem;
} }
function getItemsToResumeFn(mediaType, serverId) { function getItemsToResumeFn(mediaType, serverId) {
return function () { return function () {
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
@ -415,9 +413,9 @@ import ServerConnections from '../ServerConnections';
return apiClient.getResumableItems(apiClient.getCurrentUserId(), options); return apiClient.getResumableItems(apiClient.getCurrentUserId(), options);
}; };
} }
function getItemsToResumeHtmlFn(useEpisodeImages, mediaType) { function getItemsToResumeHtmlFn(useEpisodeImages, mediaType) {
return function (items) { return function (items) {
const cardLayout = false; const cardLayout = false;
return cardBuilder.getCardsHtml({ return cardBuilder.getCardsHtml({
@ -439,9 +437,9 @@ import ServerConnections from '../ServerConnections';
lines: 2 lines: 2
}); });
}; };
} }
function getOnNowFetchFn(serverId) { function getOnNowFetchFn(serverId) {
return function () { return function () {
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
return apiClient.getLiveTvRecommendedPrograms({ return apiClient.getLiveTvRecommendedPrograms({
@ -454,9 +452,9 @@ import ServerConnections from '../ServerConnections';
Fields: 'ChannelInfo,PrimaryImageAspectRatio' Fields: 'ChannelInfo,PrimaryImageAspectRatio'
}); });
}; };
} }
function getOnNowItemsHtml(items) { function getOnNowItemsHtml(items) {
return cardBuilder.getCardsHtml({ return cardBuilder.getCardsHtml({
items: items, items: items,
preferThumb: 'auto', preferThumb: 'auto',
@ -476,9 +474,9 @@ import ServerConnections from '../ServerConnections';
lines: 3, lines: 3,
overlayPlayButton: true overlayPlayButton: true
}); });
} }
function loadOnNow(elem, apiClient, user) { function loadOnNow(elem, apiClient, user) {
if (!user.Policy.EnableLiveTvAccess) { if (!user.Policy.EnableLiveTvAccess) {
return Promise.resolve(); return Promise.resolve();
} }
@ -587,9 +585,9 @@ import ServerConnections from '../ServerConnections';
itemsContainer.getItemsHtml = getOnNowItemsHtml; itemsContainer.getItemsHtml = getOnNowItemsHtml;
} }
}); });
} }
function getNextUpFetchFn(serverId, userSettings) { function getNextUpFetchFn(serverId, userSettings) {
return function () { return function () {
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
const oldestDateForNextUp = new Date(); const oldestDateForNextUp = new Date();
@ -606,9 +604,9 @@ import ServerConnections from '../ServerConnections';
EnableRewatching: userSettings.enableRewatchingInNextUp() EnableRewatching: userSettings.enableRewatchingInNextUp()
}); });
}; };
} }
function getNextUpItemsHtmlFn(useEpisodeImages) { function getNextUpItemsHtmlFn(useEpisodeImages) {
return function (items) { return function (items) {
const cardLayout = false; const cardLayout = false;
return cardBuilder.getCardsHtml({ return cardBuilder.getCardsHtml({
@ -627,9 +625,9 @@ import ServerConnections from '../ServerConnections';
cardLayout: cardLayout cardLayout: cardLayout
}); });
}; };
} }
function loadNextUp(elem, apiClient, userSettings) { function loadNextUp(elem, apiClient, userSettings) {
let html = ''; let html = '';
html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">'; html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">';
@ -668,9 +666,9 @@ import ServerConnections from '../ServerConnections';
itemsContainer.fetchData = getNextUpFetchFn(apiClient.serverId(), userSettings); itemsContainer.fetchData = getNextUpFetchFn(apiClient.serverId(), userSettings);
itemsContainer.getItemsHtml = getNextUpItemsHtmlFn(userSettings.useEpisodeImagesInNextUpAndResume()); itemsContainer.getItemsHtml = getNextUpItemsHtmlFn(userSettings.useEpisodeImagesInNextUpAndResume());
itemsContainer.parentContainer = elem; itemsContainer.parentContainer = elem;
} }
function getLatestRecordingsFetchFn(serverId, activeRecordingsOnly) { function getLatestRecordingsFetchFn(serverId, activeRecordingsOnly) {
return function () { return function () {
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
return apiClient.getLiveTvRecordings({ return apiClient.getLiveTvRecordings({
@ -682,9 +680,9 @@ import ServerConnections from '../ServerConnections';
IsInProgress: activeRecordingsOnly ? true : null IsInProgress: activeRecordingsOnly ? true : null
}); });
}; };
} }
function getLatestRecordingItemsHtml(activeRecordingsOnly) { function getLatestRecordingItemsHtml(activeRecordingsOnly) {
return function (items) { return function (items) {
return cardBuilder.getCardsHtml({ return cardBuilder.getCardsHtml({
items: items, items: items,
@ -707,9 +705,9 @@ import ServerConnections from '../ServerConnections';
centerPlayButton: activeRecordingsOnly centerPlayButton: activeRecordingsOnly
}); });
}; };
} }
function loadLatestLiveTvRecordings(elem, activeRecordingsOnly, apiClient) { function loadLatestLiveTvRecordings(elem, activeRecordingsOnly, apiClient) {
const title = activeRecordingsOnly ? const title = activeRecordingsOnly ?
globalize.translate('HeaderActiveRecordings') : globalize.translate('HeaderActiveRecordings') :
globalize.translate('HeaderLatestRecordings'); globalize.translate('HeaderLatestRecordings');
@ -739,7 +737,7 @@ import ServerConnections from '../ServerConnections';
itemsContainer.fetchData = getLatestRecordingsFetchFn(apiClient.serverId(), activeRecordingsOnly); itemsContainer.fetchData = getLatestRecordingsFetchFn(apiClient.serverId(), activeRecordingsOnly);
itemsContainer.getItemsHtml = getLatestRecordingItemsHtml(activeRecordingsOnly); itemsContainer.getItemsHtml = getLatestRecordingItemsHtml(activeRecordingsOnly);
itemsContainer.parentContainer = elem; itemsContainer.parentContainer = elem;
} }
export default { export default {
loadLibraryTiles: loadLibraryTiles, loadLibraryTiles: loadLibraryTiles,
@ -750,4 +748,3 @@ export default {
resume: resume resume: resume
}; };
/* eslint-enable indent */

View file

@ -1,36 +1,33 @@
/* eslint-disable indent */
import appSettings from '../scripts/settings/appSettings' ; import appSettings from '../scripts/settings/appSettings' ;
import browser from '../scripts/browser'; import browser from '../scripts/browser';
import Events from '../utils/events.ts'; import Events from '../utils/events.ts';
export function getSavedVolume() { export function getSavedVolume() {
return appSettings.get('volume') || 1; return appSettings.get('volume') || 1;
} }
export function saveVolume(value) { export function saveVolume(value) {
if (value) { if (value) {
appSettings.set('volume', value); appSettings.set('volume', value);
} }
} }
export function getCrossOriginValue(mediaSource) { export function getCrossOriginValue(mediaSource) {
if (mediaSource.IsRemote) { if (mediaSource.IsRemote) {
return null; return null;
} }
return 'anonymous'; return 'anonymous';
} }
function canPlayNativeHls() { function canPlayNativeHls() {
const media = document.createElement('video'); const media = document.createElement('video');
return !!(media.canPlayType('application/x-mpegURL').replace(/no/, '') || return !!(media.canPlayType('application/x-mpegURL').replace(/no/, '')
media.canPlayType('application/vnd.apple.mpegURL').replace(/no/, '')); || media.canPlayType('application/vnd.apple.mpegURL').replace(/no/, ''));
} }
export function enableHlsJsPlayer(runTimeTicks, mediaType) { export function enableHlsJsPlayer(runTimeTicks, mediaType) {
if (window.MediaSource == null) { if (window.MediaSource == null) {
return false; return false;
} }
@ -51,26 +48,18 @@ import Events from '../utils/events.ts';
return true; return true;
} }
if (browser.edge && mediaType === 'Video') {
//return true;
}
// simple playback should use the native support // simple playback should use the native support
if (runTimeTicks) { if (runTimeTicks) {
//if (!browser.edge) {
return false; return false;
//}
} }
//return false;
} }
return true; return true;
} }
let recoverDecodingErrorDate; let recoverDecodingErrorDate;
let recoverSwapAudioCodecDate; let recoverSwapAudioCodecDate;
export function handleHlsJsMediaError(instance, reject) { export function handleHlsJsMediaError(instance, reject) {
const hlsPlayer = instance._hlsPlayer; const hlsPlayer = instance._hlsPlayer;
if (!hlsPlayer) { if (!hlsPlayer) {
@ -103,9 +92,9 @@ import Events from '../utils/events.ts';
} }
} }
} }
} }
export function onErrorInternal(instance, type) { export function onErrorInternal(instance, type) {
// Needed for video // Needed for video
if (instance.destroyCustomTrack) { if (instance.destroyCustomTrack) {
instance.destroyCustomTrack(instance._mediaElement); instance.destroyCustomTrack(instance._mediaElement);
@ -116,23 +105,23 @@ import Events from '../utils/events.ts';
type: type type: type
} }
]); ]);
} }
export function isValidDuration(duration) { export function isValidDuration(duration) {
return duration return duration
&& !isNaN(duration) && !isNaN(duration)
&& duration !== Number.POSITIVE_INFINITY && duration !== Number.POSITIVE_INFINITY
&& duration !== Number.NEGATIVE_INFINITY; && duration !== Number.NEGATIVE_INFINITY;
} }
function setCurrentTimeIfNeeded(element, seconds) { function setCurrentTimeIfNeeded(element, seconds) {
// If it's worth skipping (1 sec or less of a difference) // If it's worth skipping (1 sec or less of a difference)
if (Math.abs((element.currentTime || 0) - seconds) >= 1) { if (Math.abs((element.currentTime || 0) - seconds) >= 1) {
element.currentTime = seconds; element.currentTime = seconds;
} }
} }
export function seekOnPlaybackStart(instance, element, ticks, onMediaReady) { export function seekOnPlaybackStart(instance, element, ticks, onMediaReady) {
const seconds = (ticks || 0) / 10000000; const seconds = (ticks || 0) / 10000000;
if (seconds) { if (seconds) {
@ -165,9 +154,9 @@ import Events from '../utils/events.ts';
}); });
} }
} }
} }
export function applySrc(elem, src, options) { export function applySrc(elem, src, options) {
if (window.Windows && options.mediaSource && options.mediaSource.IsLocal) { if (window.Windows && options.mediaSource && options.mediaSource.IsLocal) {
return Windows.Storage.StorageFile.getFileFromPathAsync(options.url).then(function (file) { return Windows.Storage.StorageFile.getFileFromPathAsync(options.url).then(function (file) {
const playlist = new Windows.Media.Playback.MediaPlaybackList(); const playlist = new Windows.Media.Playback.MediaPlaybackList();
@ -183,26 +172,26 @@ import Events from '../utils/events.ts';
} }
return Promise.resolve(); return Promise.resolve();
} }
export function resetSrc(elem) { export function resetSrc(elem) {
elem.src = ''; elem.src = '';
elem.innerHTML = ''; elem.innerHTML = '';
elem.removeAttribute('src'); elem.removeAttribute('src');
} }
function onSuccessfulPlay(elem, onErrorFn) { function onSuccessfulPlay(elem, onErrorFn) {
elem.addEventListener('error', onErrorFn); elem.addEventListener('error', onErrorFn);
} }
export function playWithPromise(elem, onErrorFn) { export function playWithPromise(elem, onErrorFn) {
try { try {
return elem.play() return elem.play()
.catch((e) => { .catch((e) => {
const errorName = (e.name || '').toLowerCase(); const errorName = (e.name || '').toLowerCase();
// safari uses aborterror // safari uses aborterror
if (errorName === 'notallowederror' || if (errorName === 'notallowederror'
errorName === 'aborterror') { || errorName === 'aborterror') {
// swallow this error because the user can still click the play button on the video element // swallow this error because the user can still click the play button on the video element
return Promise.resolve(); return Promise.resolve();
} }
@ -216,9 +205,9 @@ import Events from '../utils/events.ts';
console.error('error calling video.play: ' + err); console.error('error calling video.play: ' + err);
return Promise.reject(); return Promise.reject();
} }
} }
export function destroyCastPlayer(instance) { export function destroyCastPlayer(instance) {
const player = instance._castPlayer; const player = instance._castPlayer;
if (player) { if (player) {
try { try {
@ -229,9 +218,9 @@ import Events from '../utils/events.ts';
instance._castPlayer = null; instance._castPlayer = null;
} }
} }
export function destroyHlsPlayer(instance) { export function destroyHlsPlayer(instance) {
const player = instance._hlsPlayer; const player = instance._hlsPlayer;
if (player) { if (player) {
try { try {
@ -242,9 +231,9 @@ import Events from '../utils/events.ts';
instance._hlsPlayer = null; instance._hlsPlayer = null;
} }
} }
export function destroyFlvPlayer(instance) { export function destroyFlvPlayer(instance) {
const player = instance._flvPlayer; const player = instance._flvPlayer;
if (player) { if (player) {
try { try {
@ -257,9 +246,9 @@ import Events from '../utils/events.ts';
instance._flvPlayer = null; instance._flvPlayer = null;
} }
} }
export function bindEventsToHlsPlayer(instance, hls, elem, onErrorFn, resolve, reject) { export function bindEventsToHlsPlayer(instance, hls, elem, onErrorFn, resolve, reject) {
hls.on(Hls.Events.MANIFEST_PARSED, function () { hls.on(Hls.Events.MANIFEST_PARSED, function () {
playWithPromise(elem, onErrorFn).then(resolve, function () { playWithPromise(elem, onErrorFn).then(resolve, function () {
if (reject) { if (reject) {
@ -337,9 +326,9 @@ import Events from '../utils/events.ts';
} }
} }
}); });
} }
export function onEndedInternal(instance, elem, onErrorFn) { export function onEndedInternal(instance, elem, onErrorFn) {
elem.removeEventListener('error', onErrorFn); elem.removeEventListener('error', onErrorFn);
resetSrc(elem); resetSrc(elem);
@ -357,9 +346,9 @@ import Events from '../utils/events.ts';
instance._currentTime = null; instance._currentTime = null;
instance._currentSrc = null; instance._currentSrc = null;
instance._currentPlayOptions = null; instance._currentPlayOptions = null;
} }
export function getBufferedRanges(instance, elem) { export function getBufferedRanges(instance, elem) {
const ranges = []; const ranges = [];
const seekable = elem.buffered || []; const seekable = elem.buffered || [];
@ -390,6 +379,4 @@ import Events from '../utils/events.ts';
} }
return ranges; return ranges;
} }
/* eslint-enable indent */

View file

@ -15,25 +15,23 @@ import '../cardbuilder/card.scss';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';
import template from './imageDownloader.template.html'; import template from './imageDownloader.template.html';
/* eslint-disable indent */ const enableFocusTransform = !browser.slow && !browser.edge;
const enableFocusTransform = !browser.slow && !browser.edge; let currentItemId;
let currentItemType;
let currentResolve;
let currentReject;
let hasChanges = false;
let currentItemId; // These images can be large and we're seeing memory problems in safari
let currentItemType; const browsableImagePageSize = browser.slow ? 6 : 30;
let currentResolve;
let currentReject;
let hasChanges = false;
// These images can be large and we're seeing memory problems in safari let browsableImageStartIndex = 0;
const browsableImagePageSize = browser.slow ? 6 : 30; let browsableImageType = 'Primary';
let selectedProvider;
let browsableParentId;
let browsableImageStartIndex = 0; function getBaseRemoteOptions(page, forceCurrentItemId = false) {
let browsableImageType = 'Primary';
let selectedProvider;
let browsableParentId;
function getBaseRemoteOptions(page, forceCurrentItemId = false) {
const options = {}; const options = {};
if (!forceCurrentItemId && page.querySelector('#chkShowParentImages').checked && browsableParentId) { if (!forceCurrentItemId && page.querySelector('#chkShowParentImages').checked && browsableParentId) {
@ -43,9 +41,9 @@ import template from './imageDownloader.template.html';
} }
return options; return options;
} }
function reloadBrowsableImages(page, apiClient) { function reloadBrowsableImages(page, apiClient) {
loading.show(); loading.show();
const options = getBaseRemoteOptions(page); const options = getBaseRemoteOptions(page);
@ -76,9 +74,9 @@ import template from './imageDownloader.template.html';
loading.hide(); loading.hide();
}); });
} }
function renderRemoteImages(page, apiClient, imagesResult, imageType, startIndex, limit) { function renderRemoteImages(page, apiClient, imagesResult, imageType, startIndex, limit) {
page.querySelector('.availableImagesPaging').innerHTML = getPagingHtml(startIndex, limit, imagesResult.TotalRecordCount); page.querySelector('.availableImagesPaging').innerHTML = getPagingHtml(startIndex, limit, imagesResult.TotalRecordCount);
let html = ''; let html = '';
@ -107,9 +105,9 @@ import template from './imageDownloader.template.html';
reloadBrowsableImages(page, apiClient); reloadBrowsableImages(page, apiClient);
}); });
} }
} }
function getPagingHtml(startIndex, limit, totalRecordCount) { function getPagingHtml(startIndex, limit, totalRecordCount) {
let html = ''; let html = '';
const recordsEnd = Math.min(startIndex + limit, totalRecordCount); const recordsEnd = Math.min(startIndex + limit, totalRecordCount);
@ -137,9 +135,9 @@ import template from './imageDownloader.template.html';
html += '</div>'; html += '</div>';
return html; return html;
} }
function downloadRemoteImage(page, apiClient, url, type, provider) { function downloadRemoteImage(page, apiClient, url, type, provider) {
const options = getBaseRemoteOptions(page, true); const options = getBaseRemoteOptions(page, true);
options.Type = type; options.Type = type;
@ -153,9 +151,9 @@ import template from './imageDownloader.template.html';
const dlg = dom.parentWithClass(page, 'dialog'); const dlg = dom.parentWithClass(page, 'dialog');
dialogHelper.close(dlg); dialogHelper.close(dlg);
}); });
} }
function getRemoteImageHtml(image, imageType) { function getRemoteImageHtml(image, imageType) {
const tagName = layoutManager.tv ? 'button' : 'div'; const tagName = layoutManager.tv ? 'button' : 'div';
const enableFooterButtons = !layoutManager.tv; const enableFooterButtons = !layoutManager.tv;
@ -276,14 +274,14 @@ import template from './imageDownloader.template.html';
html += '</' + tagName + '>'; html += '</' + tagName + '>';
return html; return html;
} }
function reloadBrowsableImagesFirstPage(page, apiClient) { function reloadBrowsableImagesFirstPage(page, apiClient) {
browsableImageStartIndex = 0; browsableImageStartIndex = 0;
reloadBrowsableImages(page, apiClient); reloadBrowsableImages(page, apiClient);
} }
function initEditor(page, apiClient) { function initEditor(page, apiClient) {
page.querySelector('#selectBrowsableImageType').addEventListener('change', function () { page.querySelector('#selectBrowsableImageType').addEventListener('change', function () {
browsableImageType = this.value; browsableImageType = this.value;
selectedProvider = null; selectedProvider = null;
@ -318,9 +316,9 @@ import template from './imageDownloader.template.html';
downloadRemoteImage(page, apiClient, btnImageCard.getAttribute('data-imageurl'), btnImageCard.getAttribute('data-imagetype'), btnImageCard.getAttribute('data-imageprovider')); downloadRemoteImage(page, apiClient, btnImageCard.getAttribute('data-imageurl'), btnImageCard.getAttribute('data-imagetype'), btnImageCard.getAttribute('data-imageprovider'));
} }
}); });
} }
function showEditor(itemId, serverId, itemType) { function showEditor(itemId, serverId, itemType) {
loading.show(); loading.show();
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
@ -363,9 +361,9 @@ import template from './imageDownloader.template.html';
}); });
reloadBrowsableImages(editorContent, apiClient); reloadBrowsableImages(editorContent, apiClient);
} }
function onDialogClosed() { function onDialogClosed() {
const dlg = this; const dlg = this;
if (layoutManager.tv) { if (layoutManager.tv) {
@ -378,7 +376,7 @@ import template from './imageDownloader.template.html';
} else { } else {
currentReject(); currentReject();
} }
} }
export function show(itemId, serverId, itemType, imageType, parentId) { export function show(itemId, serverId, itemType, imageType, parentId) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
@ -397,4 +395,3 @@ export default {
show: show show: show
}; };
/* eslint-enable indent */

View file

@ -1,4 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for image Options Editor. * Module for image Options Editor.
@ -13,25 +12,25 @@ import '../../elements/emby-select/emby-select';
import '../../elements/emby-input/emby-input'; import '../../elements/emby-input/emby-input';
import template from './imageOptionsEditor.template.html'; import template from './imageOptionsEditor.template.html';
function getDefaultImageConfig(itemType, type) { function getDefaultImageConfig(itemType, type) {
return { return {
Type: type, Type: type,
MinWidth: 0, MinWidth: 0,
Limit: type === 'Primary' ? 1 : 0 Limit: type === 'Primary' ? 1 : 0
}; };
} }
function findImageOptions(imageOptions, type) { function findImageOptions(imageOptions, type) {
return imageOptions.filter(i => { return imageOptions.filter(i => {
return i.Type == type; return i.Type == type;
})[0]; })[0];
} }
function getImageConfig(options, availableOptions, imageType, itemType) { function getImageConfig(options, availableOptions, imageType, itemType) {
return findImageOptions(options.ImageOptions || [], imageType) || findImageOptions(availableOptions.DefaultImageOptions || [], imageType) || getDefaultImageConfig(itemType, imageType); return findImageOptions(options.ImageOptions || [], imageType) || findImageOptions(availableOptions.DefaultImageOptions || [], imageType) || getDefaultImageConfig(itemType, imageType);
} }
function setVisibilityOfBackdrops(elem, visible) { function setVisibilityOfBackdrops(elem, visible) {
if (visible) { if (visible) {
elem.classList.remove('hide'); elem.classList.remove('hide');
elem.querySelector('input').setAttribute('required', 'required'); elem.querySelector('input').setAttribute('required', 'required');
@ -40,9 +39,9 @@ import template from './imageOptionsEditor.template.html';
elem.querySelector('input').setAttribute('required', ''); elem.querySelector('input').setAttribute('required', '');
elem.querySelector('input').removeAttribute('required'); elem.querySelector('input').removeAttribute('required');
} }
} }
function loadValues(context, itemType, options, availableOptions) { function loadValues(context, itemType, options, availableOptions) {
const supportedImageTypes = availableOptions.SupportedImageTypes || []; const supportedImageTypes = availableOptions.SupportedImageTypes || [];
setVisibilityOfBackdrops(context.querySelector('.backdropFields'), supportedImageTypes.includes('Backdrop')); setVisibilityOfBackdrops(context.querySelector('.backdropFields'), supportedImageTypes.includes('Backdrop'));
Array.prototype.forEach.call(context.querySelectorAll('.imageType'), i => { Array.prototype.forEach.call(context.querySelectorAll('.imageType'), i => {
@ -64,9 +63,9 @@ import template from './imageOptionsEditor.template.html';
const backdropConfig = getImageConfig(options, availableOptions, 'Backdrop', itemType); const backdropConfig = getImageConfig(options, availableOptions, 'Backdrop', itemType);
context.querySelector('#txtMaxBackdrops').value = backdropConfig.Limit; context.querySelector('#txtMaxBackdrops').value = backdropConfig.Limit;
context.querySelector('#txtMinBackdropDownloadWidth').value = backdropConfig.MinWidth; context.querySelector('#txtMinBackdropDownloadWidth').value = backdropConfig.MinWidth;
} }
function saveValues(context, options) { function saveValues(context, options) {
options.ImageOptions = Array.prototype.map.call(context.querySelectorAll('.imageType:not(.hide)'), c => { options.ImageOptions = Array.prototype.map.call(context.querySelectorAll('.imageType:not(.hide)'), c => {
return { return {
Type: c.getAttribute('data-imagetype'), Type: c.getAttribute('data-imagetype'),
@ -79,9 +78,9 @@ import template from './imageOptionsEditor.template.html';
Limit: context.querySelector('#txtMaxBackdrops').value, Limit: context.querySelector('#txtMaxBackdrops').value,
MinWidth: context.querySelector('#txtMinBackdropDownloadWidth').value MinWidth: context.querySelector('#txtMinBackdropDownloadWidth').value
}); });
} }
function showEditor(itemType, options, availableOptions) { function showEditor(itemType, options, availableOptions) {
const dlg = dialogHelper.createDialog({ const dlg = dialogHelper.createDialog({
size: 'small', size: 'small',
removeOnClose: true, removeOnClose: true,
@ -101,7 +100,7 @@ import template from './imageOptionsEditor.template.html';
dlg.querySelector('.btnCancel').addEventListener('click', function () { dlg.querySelector('.btnCancel').addEventListener('click', function () {
dialogHelper.close(dlg); dialogHelper.close(dlg);
}); });
} }
export class editor { export class editor {
constructor() { constructor() {
@ -109,5 +108,4 @@ export class editor {
} }
} }
/* eslint-enable indent */
export default editor; export default editor;

View file

@ -1,4 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for imageUploader. * Module for imageUploader.
@ -19,12 +18,12 @@ import ServerConnections from '../ServerConnections';
import toast from '../toast/toast'; import toast from '../toast/toast';
import template from './imageUploader.template.html'; import template from './imageUploader.template.html';
let currentItemId; let currentItemId;
let currentServerId; let currentServerId;
let currentFile; let currentFile;
let hasChanges = false; let hasChanges = false;
function onFileReaderError(evt) { function onFileReaderError(evt) {
loading.hide(); loading.hide();
switch (evt.target.error.code) { switch (evt.target.error.code) {
@ -37,9 +36,9 @@ import template from './imageUploader.template.html';
toast(globalize.translate('MessageFileReadError')); toast(globalize.translate('MessageFileReadError'));
break; break;
} }
} }
function setFiles(page, files) { function setFiles(page, files) {
const file = files[0]; const file = files[0];
if (!file || !file.type.match('image.*')) { if (!file || !file.type.match('image.*')) {
@ -76,9 +75,9 @@ import template from './imageUploader.template.html';
// Read in the image file as a data URL. // Read in the image file as a data URL.
reader.readAsDataURL(file); reader.readAsDataURL(file);
} }
function onSubmit(e) { function onSubmit(e) {
const file = currentFile; const file = currentFile;
if (!file) { if (!file) {
@ -112,9 +111,9 @@ import template from './imageUploader.template.html';
e.preventDefault(); e.preventDefault();
return false; return false;
} }
function initEditor(page) { function initEditor(page) {
page.querySelector('form').addEventListener('submit', onSubmit); page.querySelector('form').addEventListener('submit', onSubmit);
page.querySelector('#uploadImage').addEventListener('change', function () { page.querySelector('#uploadImage').addEventListener('change', function () {
@ -124,9 +123,9 @@ import template from './imageUploader.template.html';
page.querySelector('.btnBrowse').addEventListener('click', () => { page.querySelector('.btnBrowse').addEventListener('click', () => {
page.querySelector('#uploadImage').click(); page.querySelector('#uploadImage').click();
}); });
} }
function showEditor(options, resolve) { function showEditor(options, resolve) {
options = options || {}; options = options || {};
currentItemId = options.itemId; currentItemId = options.itemId;
@ -171,17 +170,16 @@ import template from './imageUploader.template.html';
dlg.querySelector('.btnCancel').addEventListener('click', () => { dlg.querySelector('.btnCancel').addEventListener('click', () => {
dialogHelper.close(dlg); dialogHelper.close(dlg);
}); });
} }
export function show(options) { export function show(options) {
return new Promise(resolve => { return new Promise(resolve => {
hasChanges = false; hasChanges = false;
showEditor(options, resolve); showEditor(options, resolve);
}); });
} }
/* eslint-enable indent */
export default { export default {
show: show show: show
}; };

View file

@ -18,18 +18,16 @@ import alert from '../alert';
import confirm from '../confirm/confirm'; import confirm from '../confirm/confirm';
import template from './imageeditor.template.html'; import template from './imageeditor.template.html';
/* eslint-disable indent */ const enableFocusTransform = !browser.slow && !browser.edge;
const enableFocusTransform = !browser.slow && !browser.edge; let currentItem;
let hasChanges = false;
let currentItem; function getBaseRemoteOptions() {
let hasChanges = false;
function getBaseRemoteOptions() {
return { itemId: currentItem.Id }; return { itemId: currentItem.Id };
} }
function reload(page, item, focusContext) { function reload(page, item, focusContext) {
loading.show(); loading.show();
let apiClient; let apiClient;
@ -43,18 +41,18 @@ import template from './imageeditor.template.html';
reloadItem(page, itemToReload, apiClient, focusContext); reloadItem(page, itemToReload, apiClient, focusContext);
}); });
} }
} }
function addListeners(container, className, eventName, fn) { function addListeners(container, className, eventName, fn) {
container.addEventListener(eventName, function (e) { container.addEventListener(eventName, function (e) {
const elem = dom.parentWithClass(e.target, className); const elem = dom.parentWithClass(e.target, className);
if (elem) { if (elem) {
fn.call(elem, e); fn.call(elem, e);
} }
}); });
} }
function reloadItem(page, item, apiClient, focusContext) { function reloadItem(page, item, apiClient, focusContext) {
currentItem = item; currentItem = item;
apiClient.getRemoteImageProviders(getBaseRemoteOptions()).then(function (providers) { apiClient.getRemoteImageProviders(getBaseRemoteOptions()).then(function (providers) {
@ -77,9 +75,9 @@ import template from './imageeditor.template.html';
} }
}); });
}); });
} }
function getImageUrl(item, apiClient, type, index, options) { function getImageUrl(item, apiClient, type, index, options) {
options = options || {}; options = options || {};
options.type = type; options.type = type;
options.index = index; options.index = index;
@ -94,9 +92,9 @@ import template from './imageeditor.template.html';
// For search hints // For search hints
return apiClient.getScaledImageUrl(item.Id || item.ItemId, options); return apiClient.getScaledImageUrl(item.Id || item.ItemId, options);
} }
function getCardHtml(image, apiClient, options) { function getCardHtml(image, apiClient, options) {
// TODO move card creation code to Card component // TODO move card creation code to Card component
let html = ''; let html = '';
@ -181,9 +179,9 @@ import template from './imageeditor.template.html';
html += '</' + options.tagName + '>'; html += '</' + options.tagName + '>';
return html; return html;
} }
function deleteImage(context, itemId, type, index, apiClient, enableConfirmation) { function deleteImage(context, itemId, type, index, apiClient, enableConfirmation) {
const afterConfirm = function () { const afterConfirm = function () {
apiClient.deleteItemImage(itemId, type, index).then(function () { apiClient.deleteItemImage(itemId, type, index).then(function () {
hasChanges = true; hasChanges = true;
@ -201,18 +199,18 @@ import template from './imageeditor.template.html';
confirmText: globalize.translate('Delete'), confirmText: globalize.translate('Delete'),
primary: 'delete' primary: 'delete'
}).then(afterConfirm); }).then(afterConfirm);
} }
function moveImage(context, apiClient, itemId, type, index, newIndex, focusContext) { function moveImage(context, apiClient, itemId, type, index, newIndex, focusContext) {
apiClient.updateItemImageIndex(itemId, type, index, newIndex).then(function () { apiClient.updateItemImageIndex(itemId, type, index, newIndex).then(function () {
hasChanges = true; hasChanges = true;
reload(context, null, focusContext); reload(context, null, focusContext);
}, function () { }, function () {
alert(globalize.translate('ErrorDefault')); alert(globalize.translate('ErrorDefault'));
}); });
} }
function renderImages(page, item, apiClient, images, imageProviders, elem) { function renderImages(page, item, apiClient, images, imageProviders, elem) {
let html = ''; let html = '';
let imageSize = 300; let imageSize = 300;
@ -232,17 +230,17 @@ import template from './imageeditor.template.html';
elem.innerHTML = html; elem.innerHTML = html;
imageLoader.lazyChildren(elem); imageLoader.lazyChildren(elem);
} }
function renderStandardImages(page, apiClient, item, imageInfos, imageProviders) { function renderStandardImages(page, apiClient, item, imageInfos, imageProviders) {
const images = imageInfos.filter(function (i) { const images = imageInfos.filter(function (i) {
return i.ImageType !== 'Backdrop' && i.ImageType !== 'Chapter'; return i.ImageType !== 'Backdrop' && i.ImageType !== 'Chapter';
}); });
renderImages(page, item, apiClient, images, imageProviders, page.querySelector('#images')); renderImages(page, item, apiClient, images, imageProviders, page.querySelector('#images'));
} }
function renderBackdrops(page, apiClient, item, imageInfos, imageProviders) { function renderBackdrops(page, apiClient, item, imageInfos, imageProviders) {
const images = imageInfos.filter(function (i) { const images = imageInfos.filter(function (i) {
return i.ImageType === 'Backdrop'; return i.ImageType === 'Backdrop';
}).sort(function (a, b) { }).sort(function (a, b) {
@ -255,9 +253,9 @@ import template from './imageeditor.template.html';
} else { } else {
page.querySelector('#backdropsContainer', page).classList.add('hide'); page.querySelector('#backdropsContainer', page).classList.add('hide');
} }
} }
function showImageDownloader(page, imageType) { function showImageDownloader(page, imageType) {
import('../imageDownloader/imageDownloader').then((ImageDownloader) => { import('../imageDownloader/imageDownloader').then((ImageDownloader) => {
ImageDownloader.show( ImageDownloader.show(
currentItem.Id, currentItem.Id,
@ -270,9 +268,9 @@ import template from './imageeditor.template.html';
reload(page); reload(page);
}); });
}); });
} }
function showActionSheet(context, imageCard) { function showActionSheet(context, imageCard) {
const itemId = imageCard.getAttribute('data-id'); const itemId = imageCard.getAttribute('data-id');
const serverId = imageCard.getAttribute('data-serverid'); const serverId = imageCard.getAttribute('data-serverid');
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
@ -282,7 +280,7 @@ import template from './imageeditor.template.html';
const providerCount = parseInt(imageCard.getAttribute('data-providers'), 10); const providerCount = parseInt(imageCard.getAttribute('data-providers'), 10);
const numImages = parseInt(imageCard.getAttribute('data-numimages'), 10); const numImages = parseInt(imageCard.getAttribute('data-numimages'), 10);
import('../actionSheet/actionSheet').then(({default: actionSheet}) => { import('../actionSheet/actionSheet').then(({ default: actionSheet }) => {
const commands = []; const commands = [];
commands.push({ commands.push({
@ -337,9 +335,9 @@ import template from './imageeditor.template.html';
} }
}); });
}); });
} }
function initEditor(context, options) { function initEditor(context, options) {
const uploadButtons = context.querySelectorAll('.btnOpenUploadMenu'); const uploadButtons = context.querySelectorAll('.btnOpenUploadMenu');
const isFileInputSupported = appHost.supports('fileinput'); const isFileInputSupported = appHost.supports('fileinput');
for (let i = 0, length = uploadButtons.length; i < length; i++) { for (let i = 0, length = uploadButtons.length; i < length; i++) {
@ -353,7 +351,7 @@ import template from './imageeditor.template.html';
addListeners(context, 'btnOpenUploadMenu', 'click', function () { addListeners(context, 'btnOpenUploadMenu', 'click', function () {
const imageType = this.getAttribute('data-imagetype'); const imageType = this.getAttribute('data-imagetype');
import('../imageUploader/imageUploader').then(({default: imageUploader}) => { import('../imageUploader/imageUploader').then(({ default: imageUploader }) => {
imageUploader.show({ imageUploader.show({
theme: options.theme, theme: options.theme,
@ -397,9 +395,9 @@ import template from './imageeditor.template.html';
const apiClient = ServerConnections.getApiClient(currentItem.ServerId); const apiClient = ServerConnections.getApiClient(currentItem.ServerId);
moveImage(context, apiClient, currentItem.Id, type, index, newIndex, dom.parentWithClass(this, 'itemsContainer')); moveImage(context, apiClient, currentItem.Id, type, index, newIndex, dom.parentWithClass(this, 'itemsContainer'));
}); });
} }
function showEditor(options, resolve, reject) { function showEditor(options, resolve, reject) {
const itemId = options.itemId; const itemId = options.itemId;
const serverId = options.serverId; const serverId = options.serverId;
@ -452,7 +450,7 @@ import template from './imageeditor.template.html';
dialogHelper.close(dlg); dialogHelper.close(dlg);
}); });
}); });
} }
export function show (options) { export function show (options) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
@ -465,4 +463,3 @@ export default {
show show
}; };
/* eslint-enable indent */

View file

@ -17,17 +17,16 @@ worker.addEventListener(
} }
} }
); );
/* eslint-disable indent */
export function lazyImage(elem, source = elem.getAttribute('data-src')) { export function lazyImage(elem, source = elem.getAttribute('data-src')) {
if (!source) { if (!source) {
return; return;
} }
fillImageElement(elem, source); fillImageElement(elem, source);
} }
function drawBlurhash(target, pixels, width, height) { function drawBlurhash(target, pixels, width, height) {
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
canvas.setAttribute('aria-hidden', 'true'); canvas.setAttribute('aria-hidden', 'true');
canvas.width = width; canvas.width = width;
@ -46,9 +45,9 @@ worker.addEventListener(
target.classList.add('blurhashed'); target.classList.add('blurhashed');
target.removeAttribute('data-blurhash'); target.removeAttribute('data-blurhash');
}); });
} }
function itemBlurhashing(target, hash) { function itemBlurhashing(target, hash) {
try { try {
// Although the default values recommended by Blurhash developers is 32x32, a size of 20x20 seems to be the sweet spot for us, // Although the default values recommended by Blurhash developers is 32x32, a size of 20x20 seems to be the sweet spot for us,
// improving the performance and reducing the memory usage, while retaining almost full blur quality. // improving the performance and reducing the memory usage, while retaining almost full blur quality.
@ -68,9 +67,9 @@ worker.addEventListener(
target.classList.add('non-blurhashable'); target.classList.add('non-blurhashable');
return; return;
} }
} }
export function fillImage(entry) { export function fillImage(entry) {
if (!entry) { if (!entry) {
throw new Error('entry cannot be null'); throw new Error('entry cannot be null');
} }
@ -90,9 +89,9 @@ worker.addEventListener(
} else if (!source) { } else if (!source) {
emptyImageElement(target); emptyImageElement(target);
} }
} }
function onAnimationEnd(event) { function onAnimationEnd(event) {
const elem = event.target; const elem = event.target;
requestAnimationFrame(() => { requestAnimationFrame(() => {
const canvas = elem.previousSibling; const canvas = elem.previousSibling;
@ -104,9 +103,9 @@ worker.addEventListener(
elem.parentNode?.querySelector('.cardPadder')?.classList.add('lazy-hidden-children'); elem.parentNode?.querySelector('.cardPadder')?.classList.add('lazy-hidden-children');
}); });
elem.removeEventListener('animationend', onAnimationEnd); elem.removeEventListener('animationend', onAnimationEnd);
} }
function fillImageElement(elem, url) { function fillImageElement(elem, url) {
if (url === undefined) { if (url === undefined) {
throw new TypeError('url cannot be undefined'); throw new TypeError('url cannot be undefined');
} }
@ -134,9 +133,9 @@ worker.addEventListener(
elem.classList.remove('lazy-hidden'); elem.classList.remove('lazy-hidden');
}); });
}); });
} }
function emptyImageElement(elem) { function emptyImageElement(elem) {
elem.removeEventListener('animationend', onAnimationEnd); elem.removeEventListener('animationend', onAnimationEnd);
const canvas = elem.previousSibling; const canvas = elem.previousSibling;
if (canvas?.tagName === 'CANVAS') { if (canvas?.tagName === 'CANVAS') {
@ -159,9 +158,9 @@ worker.addEventListener(
elem.classList.remove('lazy-image-fadein-fast', 'lazy-image-fadein'); elem.classList.remove('lazy-image-fadein-fast', 'lazy-image-fadein');
elem.classList.add('lazy-hidden'); elem.classList.add('lazy-hidden');
} }
export function lazyChildren(elem) { export function lazyChildren(elem) {
if (userSettings.enableBlurhash()) { if (userSettings.enableBlurhash()) {
for (const lazyElem of elem.querySelectorAll('.lazy')) { for (const lazyElem of elem.querySelectorAll('.lazy')) {
const blurhashstr = lazyElem.getAttribute('data-blurhash'); const blurhashstr = lazyElem.getAttribute('data-blurhash');
@ -174,9 +173,9 @@ worker.addEventListener(
} }
lazyLoader.lazyChildren(elem, fillImage); lazyLoader.lazyChildren(elem, fillImage);
} }
export function getPrimaryImageAspectRatio(items) { export function getPrimaryImageAspectRatio(items) {
const values = []; const values = [];
for (let i = 0, length = items.length; i < length; i++) { for (let i = 0, length = items.length; i < length; i++) {
@ -232,22 +231,21 @@ worker.addEventListener(
} }
return result; return result;
} }
export function fillImages(elems) { export function fillImages(elems) {
for (let i = 0, length = elems.length; i < length; i++) { for (let i = 0, length = elems.length; i < length; i++) {
const elem = elems[0]; const elem = elems[0];
fillImage(elem); fillImage(elem);
} }
} }
export function setLazyImage(element, url) { export function setLazyImage(element, url) {
element.classList.add('lazy'); element.classList.add('lazy');
element.setAttribute('data-src', url); element.setAttribute('data-src', url);
lazyImage(element); lazyImage(element);
} }
/* eslint-enable indent */
export default { export default {
setLazyImage: setLazyImage, setLazyImage: setLazyImage,
fillImages: fillImages, fillImages: fillImages,

View file

@ -9,8 +9,7 @@ import { playbackManager } from './playback/playbackmanager';
import ServerConnections from './ServerConnections'; import ServerConnections from './ServerConnections';
import toast from './toast/toast'; import toast from './toast/toast';
/* eslint-disable indent */ export function getCommands(options) {
export function getCommands(options) {
const item = options.item; const item = options.item;
const user = options.user; const user = options.user;
@ -305,9 +304,9 @@ import toast from './toast/toast';
} }
return commands; return commands;
} }
function getResolveFunction(resolve, id, changed, deleted) { function getResolveFunction(resolve, id, changed, deleted) {
return function () { return function () {
resolve({ resolve({
command: id, command: id,
@ -315,9 +314,9 @@ import toast from './toast/toast';
deleted: deleted deleted: deleted
}); });
}; };
} }
function executeCommand(item, id, options) { function executeCommand(item, id, options) {
const itemId = item.Id; const itemId = item.Id;
const serverId = item.ServerId; const serverId = item.ServerId;
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
@ -326,7 +325,7 @@ import toast from './toast/toast';
// eslint-disable-next-line sonarjs/max-switch-cases // eslint-disable-next-line sonarjs/max-switch-cases
switch (id) { switch (id) {
case 'addtocollection': case 'addtocollection':
import('./collectionEditor/collectionEditor').then(({default: CollectionEditor}) => { import('./collectionEditor/collectionEditor').then(({ default: CollectionEditor }) => {
const collectionEditor = new CollectionEditor(); const collectionEditor = new CollectionEditor();
collectionEditor.show({ collectionEditor.show({
items: [itemId], items: [itemId],
@ -335,7 +334,7 @@ import toast from './toast/toast';
}); });
break; break;
case 'addtoplaylist': case 'addtoplaylist':
import('./playlisteditor/playlisteditor').then(({default: playlistEditor}) => { import('./playlisteditor/playlisteditor').then(({ default: playlistEditor }) => {
new playlistEditor({ new playlistEditor({
items: [itemId], items: [itemId],
serverId: serverId serverId: serverId
@ -408,7 +407,7 @@ import toast from './toast/toast';
break; break;
} }
case 'editsubtitles': case 'editsubtitles':
import('./subtitleeditor/subtitleeditor').then(({default: subtitleEditor}) => { import('./subtitleeditor/subtitleeditor').then(({ default: subtitleEditor }) => {
subtitleEditor.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); subtitleEditor.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
}); });
break; break;
@ -464,7 +463,7 @@ import toast from './toast/toast';
playbackManager.clearQueue(); playbackManager.clearQueue();
break; break;
case 'record': case 'record':
import('./recordingcreator/recordingcreator').then(({default: recordingCreator}) => { import('./recordingcreator/recordingcreator').then(({ default: recordingCreator }) => {
recordingCreator.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); recordingCreator.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
}); });
break; break;
@ -532,26 +531,26 @@ import toast from './toast/toast';
break; break;
} }
}); });
} }
function deleteTimer(apiClient, item, resolve, command) { function deleteTimer(apiClient, item, resolve, command) {
import('./recordingcreator/recordinghelper').then(({default: recordingHelper}) => { import('./recordingcreator/recordinghelper').then(({ default: recordingHelper }) => {
const timerId = item.TimerId || item.Id; const timerId = item.TimerId || item.Id;
recordingHelper.cancelTimerWithConfirmation(timerId, item.ServerId).then(function () { recordingHelper.cancelTimerWithConfirmation(timerId, item.ServerId).then(function () {
getResolveFunction(resolve, command, true)(); getResolveFunction(resolve, command, true)();
}); });
}); });
} }
function deleteSeriesTimer(apiClient, item, resolve, command) { function deleteSeriesTimer(apiClient, item, resolve, command) {
import('./recordingcreator/recordinghelper').then(({default: recordingHelper}) => { import('./recordingcreator/recordinghelper').then(({ default: recordingHelper }) => {
recordingHelper.cancelSeriesTimerWithConfirmation(item.Id, item.ServerId).then(function () { recordingHelper.cancelSeriesTimerWithConfirmation(item.Id, item.ServerId).then(function () {
getResolveFunction(resolve, command, true)(); getResolveFunction(resolve, command, true)();
}); });
}); });
} }
function play(item, resume, queue, queueNext) { function play(item, resume, queue, queueNext) {
let method = 'play'; let method = 'play';
if (queue) { if (queue) {
if (queueNext) { if (queueNext) {
@ -578,29 +577,29 @@ import toast from './toast/toast';
startPositionTicks: startPosition startPositionTicks: startPosition
}); });
} }
} }
function editItem(apiClient, item) { function editItem(apiClient, item) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
const serverId = apiClient.serverInfo().Id; const serverId = apiClient.serverInfo().Id;
if (item.Type === 'Timer') { if (item.Type === 'Timer') {
import('./recordingcreator/recordingeditor').then(({default: recordingEditor}) => { import('./recordingcreator/recordingeditor').then(({ default: recordingEditor }) => {
recordingEditor.show(item.Id, serverId).then(resolve, reject); recordingEditor.show(item.Id, serverId).then(resolve, reject);
}); });
} else if (item.Type === 'SeriesTimer') { } else if (item.Type === 'SeriesTimer') {
import('./recordingcreator/seriesrecordingeditor').then(({default: recordingEditor}) => { import('./recordingcreator/seriesrecordingeditor').then(({ default: recordingEditor }) => {
recordingEditor.show(item.Id, serverId).then(resolve, reject); recordingEditor.show(item.Id, serverId).then(resolve, reject);
}); });
} else { } else {
import('./metadataEditor/metadataEditor').then(({default: metadataEditor}) => { import('./metadataEditor/metadataEditor').then(({ default: metadataEditor }) => {
metadataEditor.show(item.Id, serverId).then(resolve, reject); metadataEditor.show(item.Id, serverId).then(resolve, reject);
}); });
} }
}); });
} }
function deleteItem(apiClient, item) { function deleteItem(apiClient, item) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
import('../scripts/deleteHelper').then((deleteHelper) => { import('../scripts/deleteHelper').then((deleteHelper) => {
deleteHelper.deleteItem({ deleteHelper.deleteItem({
@ -611,19 +610,19 @@ import toast from './toast/toast';
}, reject); }, reject);
}); });
}); });
} }
function refresh(apiClient, item) { function refresh(apiClient, item) {
import('./refreshdialog/refreshdialog').then(({default: refreshDialog}) => { import('./refreshdialog/refreshdialog').then(({ default: refreshDialog }) => {
new refreshDialog({ new refreshDialog({
itemIds: [item.Id], itemIds: [item.Id],
serverId: apiClient.serverInfo().Id, serverId: apiClient.serverInfo().Id,
mode: item.Type === 'CollectionFolder' ? 'scan' : null mode: item.Type === 'CollectionFolder' ? 'scan' : null
}).show(); }).show();
}); });
} }
export function show(options) { export function show(options) {
const commands = getCommands(options); const commands = getCommands(options);
if (!commands.length) { if (!commands.length) {
return Promise.reject(); return Promise.reject();
@ -636,9 +635,7 @@ import toast from './toast/toast';
}).then(function (id) { }).then(function (id) {
return executeCommand(options.item, id, options); return executeCommand(options.item, id, options);
}); });
} }
/* eslint-enable indent */
export default { export default {
getCommands: getCommands, getCommands: getCommands,

View file

@ -1,4 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for display media info. * Module for display media info.
@ -30,7 +29,7 @@ const copyButtonHtml = layoutManager.tv ? '' :
><span class="material-icons content_copy" aria-hidden="true"></span></button>`; ><span class="material-icons content_copy" aria-hidden="true"></span></button>`;
const attributeDelimiterHtml = layoutManager.tv ? '' : '<span class="hide">: </span>'; const attributeDelimiterHtml = layoutManager.tv ? '' : '<span class="hide">: </span>';
function setMediaInfo(user, page, item) { function setMediaInfo(user, page, item) {
let html = item.MediaSources.map(version => { let html = item.MediaSources.map(version => {
return getMediaSourceHtml(user, item, version); return getMediaSourceHtml(user, item, version);
}).join('<div style="border-top:1px solid #444;margin: 1em 0;"></div>'); }).join('<div style="border-top:1px solid #444;margin: 1em 0;"></div>');
@ -52,9 +51,9 @@ const attributeDelimiterHtml = layoutManager.tv ? '' : '<span class="hide">: </s
}); });
}); });
} }
} }
function getMediaSourceHtml(user, item, version) { function getMediaSourceHtml(user, item, version) {
let html = '<div class="mediaInfoSource">'; let html = '<div class="mediaInfoSource">';
if (version.Name) { if (version.Name) {
html += `<div><h2 class="mediaInfoStreamType">${escapeHtml(version.Name)}${copyButtonHtml}</h2></div>\n`; html += `<div><h2 class="mediaInfoStreamType">${escapeHtml(version.Name)}${copyButtonHtml}</h2></div>\n`;
@ -210,14 +209,14 @@ const attributeDelimiterHtml = layoutManager.tv ? '' : '<span class="hide">: </s
} }
html += '</div>'; html += '</div>';
return html; return html;
} }
// File Paths should be always ltr. The isLtr parameter allows this. // File Paths should be always ltr. The isLtr parameter allows this.
function createAttribute(label, value, isLtr) { function createAttribute(label, value, isLtr) {
return `<span class="mediaInfoLabel">${label}</span>${attributeDelimiterHtml}<span class="mediaInfoAttribute" ${isLtr && 'dir="ltr"'}>${escapeHtml(value)}</span>\n`; return `<span class="mediaInfoLabel">${label}</span>${attributeDelimiterHtml}<span class="mediaInfoAttribute" ${isLtr && 'dir="ltr"'}>${escapeHtml(value)}</span>\n`;
} }
function loadMediaInfo(itemId, serverId) { function loadMediaInfo(itemId, serverId) {
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
return apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(item => { return apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(item => {
const dialogOptions = { const dialogOptions = {
@ -245,14 +244,13 @@ const attributeDelimiterHtml = layoutManager.tv ? '' : '<span class="hide">: </s
}); });
loading.hide(); loading.hide();
}); });
} }
export function show(itemId, serverId) { export function show(itemId, serverId) {
loading.show(); loading.show();
return loadMediaInfo(itemId, serverId); return loadMediaInfo(itemId, serverId);
} }
/* eslint-enable indent */
export default { export default {
show: show show: show
}; };

View file

@ -1,4 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for itemidentifier media item. * Module for itemidentifier media item.
@ -24,21 +23,21 @@ import toast from '../toast/toast';
import template from './itemidentifier.template.html'; import template from './itemidentifier.template.html';
import datetime from '../../scripts/datetime'; import datetime from '../../scripts/datetime';
const enableFocusTransform = !browser.slow && !browser.edge; const enableFocusTransform = !browser.slow && !browser.edge;
let currentItem; let currentItem;
let currentItemType; let currentItemType;
let currentServerId; let currentServerId;
let currentResolve; let currentResolve;
let currentReject; let currentReject;
let hasChanges = false; let hasChanges = false;
let currentSearchResult; let currentSearchResult;
function getApiClient() { function getApiClient() {
return ServerConnections.getApiClient(currentServerId); return ServerConnections.getApiClient(currentServerId);
} }
function searchForIdentificationResults(page) { function searchForIdentificationResults(page) {
let lookupInfo = { let lookupInfo = {
ProviderIds: {} ProviderIds: {}
}; };
@ -101,9 +100,9 @@ import datetime from '../../scripts/datetime';
loading.hide(); loading.hide();
showIdentificationSearchResults(page, results); showIdentificationSearchResults(page, results);
}); });
} }
function showIdentificationSearchResults(page, results) { function showIdentificationSearchResults(page, results) {
const identificationSearchResults = page.querySelector('.identificationSearchResults'); const identificationSearchResults = page.querySelector('.identificationSearchResults');
page.querySelector('.popupIdentifyForm').classList.add('hide'); page.querySelector('.popupIdentifyForm').classList.add('hide');
@ -142,17 +141,17 @@ import datetime from '../../scripts/datetime';
if (layoutManager.tv) { if (layoutManager.tv) {
focusManager.autoFocus(identificationSearchResults); focusManager.autoFocus(identificationSearchResults);
} }
} }
function finishFindNewDialog(dlg, identifyResult) { function finishFindNewDialog(dlg, identifyResult) {
currentSearchResult = identifyResult; currentSearchResult = identifyResult;
hasChanges = true; hasChanges = true;
loading.hide(); loading.hide();
dialogHelper.close(dlg); dialogHelper.close(dlg);
} }
function showIdentifyOptions(page, identifyResult) { function showIdentifyOptions(page, identifyResult) {
const identifyOptionsForm = page.querySelector('.identifyOptionsForm'); const identifyOptionsForm = page.querySelector('.identifyOptionsForm');
page.querySelector('.popupIdentifyForm').classList.add('hide'); page.querySelector('.popupIdentifyForm').classList.add('hide');
@ -167,7 +166,7 @@ import datetime from '../../scripts/datetime';
lines.push(escapeHtml(identifyResult.Name)); lines.push(escapeHtml(identifyResult.Name));
if (identifyResult.ProductionYear) { if (identifyResult.ProductionYear) {
lines.push(datetime.toLocaleString(identifyResult.ProductionYear, {useGrouping: false})); lines.push(datetime.toLocaleString(identifyResult.ProductionYear, { useGrouping: false }));
} }
let resultHtml = lines.join('<br/>'); let resultHtml = lines.join('<br/>');
@ -179,9 +178,9 @@ import datetime from '../../scripts/datetime';
page.querySelector('.selectedSearchResult').innerHTML = resultHtml; page.querySelector('.selectedSearchResult').innerHTML = resultHtml;
focusManager.focus(identifyOptionsForm.querySelector('.btnSubmit')); focusManager.focus(identifyOptionsForm.querySelector('.btnSubmit'));
} }
function getSearchResultHtml(result, index) { function getSearchResultHtml(result, index) {
// TODO move card creation code to Card component // TODO move card creation code to Card component
let html = ''; let html = '';
@ -254,9 +253,9 @@ import datetime from '../../scripts/datetime';
html += '</div>'; html += '</div>';
html += '</button>'; html += '</button>';
return html; return html;
} }
function submitIdentficationResult(page) { function submitIdentficationResult(page) {
loading.show(); loading.show();
const options = { const options = {
@ -281,9 +280,9 @@ import datetime from '../../scripts/datetime';
dialogHelper.close(page); dialogHelper.close(page);
}); });
} }
function showIdentificationForm(page, item) { function showIdentificationForm(page, item) {
const apiClient = getApiClient(); const apiClient = getApiClient();
apiClient.getJSON(apiClient.getUrl(`Items/${item.Id}/ExternalIdInfos`)).then(idList => { apiClient.getJSON(apiClient.getUrl(`Items/${item.Id}/ExternalIdInfos`)).then(idList => {
@ -322,9 +321,9 @@ import datetime from '../../scripts/datetime';
page.querySelector('.formDialogHeaderTitle').innerHTML = globalize.translate('Identify'); page.querySelector('.formDialogHeaderTitle').innerHTML = globalize.translate('Identify');
}); });
} }
function showEditor(itemId) { function showEditor(itemId) {
loading.show(); loading.show();
const apiClient = getApiClient(); const apiClient = getApiClient();
@ -391,19 +390,19 @@ import datetime from '../../scripts/datetime';
showIdentificationForm(dlg, item); showIdentificationForm(dlg, item);
loading.hide(); loading.hide();
}); });
} }
function onDialogClosed() { function onDialogClosed() {
loading.hide(); loading.hide();
if (hasChanges) { if (hasChanges) {
currentResolve(); currentResolve();
} else { } else {
currentReject(); currentReject();
} }
} }
// TODO investigate where this was used // TODO investigate where this was used
function showEditorFindNew(itemName, itemYear, itemType, resolveFunc) { function showEditorFindNew(itemName, itemYear, itemType, resolveFunc) {
currentItem = null; currentItem = null;
currentItemType = itemType; currentItemType = itemType;
@ -453,9 +452,9 @@ import datetime from '../../scripts/datetime';
dlg.classList.add('identifyDialog'); dlg.classList.add('identifyDialog');
showIdentificationFormFindNew(dlg, itemName, itemYear, itemType); showIdentificationFormFindNew(dlg, itemName, itemYear, itemType);
} }
function showIdentificationFormFindNew(dlg, itemName, itemYear, itemType) { function showIdentificationFormFindNew(dlg, itemName, itemYear, itemType) {
dlg.querySelector('#txtLookupName').value = itemName; dlg.querySelector('#txtLookupName').value = itemName;
if (itemType === 'Person' || itemType === 'BoxSet') { if (itemType === 'Person' || itemType === 'BoxSet') {
@ -467,9 +466,9 @@ import datetime from '../../scripts/datetime';
} }
dlg.querySelector('.formDialogHeaderTitle').innerHTML = globalize.translate('Search'); dlg.querySelector('.formDialogHeaderTitle').innerHTML = globalize.translate('Search');
} }
export function show(itemId, serverId) { export function show(itemId, serverId) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
currentResolve = resolve; currentResolve = resolve;
currentReject = reject; currentReject = reject;
@ -478,18 +477,17 @@ import datetime from '../../scripts/datetime';
showEditor(itemId); showEditor(itemId);
}); });
} }
export function showFindNew(itemName, itemYear, itemType, serverId) { export function showFindNew(itemName, itemYear, itemType, serverId) {
return new Promise((resolve) => { return new Promise((resolve) => {
currentServerId = serverId; currentServerId = serverId;
hasChanges = false; hasChanges = false;
showEditorFindNew(itemName, itemYear, itemType, resolve); showEditorFindNew(itemName, itemYear, itemType, resolve);
}); });
} }
/* eslint-enable indent */
export default { export default {
show: show, show: show,
showFindNew: showFindNew showFindNew: showFindNew

View file

@ -1,5 +1,5 @@
/* eslint-disable indent */
export class LazyLoader { export class LazyLoader {
constructor(options) { constructor(options) {
this.options = options; this.options = options;
} }
@ -47,9 +47,9 @@
this.destroyObserver(); this.destroyObserver();
this.options = null; this.options = null;
} }
} }
function unveilElements(elements, root, callback) { function unveilElements(elements, root, callback) {
if (!elements.length) { if (!elements.length) {
return; return;
} }
@ -57,13 +57,12 @@
callback: callback callback: callback
}); });
lazyLoader.addElements(elements); lazyLoader.addElements(elements);
} }
export function lazyChildren(elem, callback) { export function lazyChildren(elem, callback) {
unveilElements(elem.getElementsByClassName('lazy'), elem, callback); unveilElements(elem.getElementsByClassName('lazy'), elem, callback);
} }
/* eslint-enable indent */
export default { export default {
LazyLoader: LazyLoader, LazyLoader: LazyLoader,
lazyChildren: lazyChildren lazyChildren: lazyChildren

View file

@ -1,4 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for library options editor. * Module for library options editor.
@ -14,14 +13,14 @@ import '../../elements/emby-input/emby-input';
import './style.scss'; import './style.scss';
import template from './libraryoptionseditor.template.html'; import template from './libraryoptionseditor.template.html';
function populateLanguages(parent) { function populateLanguages(parent) {
return ApiClient.getCultures().then(languages => { return ApiClient.getCultures().then(languages => {
populateLanguagesIntoSelect(parent.querySelector('#selectLanguage'), languages); populateLanguagesIntoSelect(parent.querySelector('#selectLanguage'), languages);
populateLanguagesIntoList(parent.querySelector('.subtitleDownloadLanguages'), languages); populateLanguagesIntoList(parent.querySelector('.subtitleDownloadLanguages'), languages);
}); });
} }
function populateLanguagesIntoSelect(select, languages) { function populateLanguagesIntoSelect(select, languages) {
let html = ''; let html = '';
html += "<option value=''></option>"; html += "<option value=''></option>";
for (let i = 0; i < languages.length; i++) { for (let i = 0; i < languages.length; i++) {
@ -29,18 +28,18 @@ import template from './libraryoptionseditor.template.html';
html += `<option value='${culture.TwoLetterISOLanguageName}'>${culture.DisplayName}</option>`; html += `<option value='${culture.TwoLetterISOLanguageName}'>${culture.DisplayName}</option>`;
} }
select.innerHTML = html; select.innerHTML = html;
} }
function populateLanguagesIntoList(element, languages) { function populateLanguagesIntoList(element, languages) {
let html = ''; let html = '';
for (let i = 0; i < languages.length; i++) { for (let i = 0; i < languages.length; i++) {
const culture = languages[i]; const culture = languages[i];
html += `<label><input type="checkbox" is="emby-checkbox" class="chkSubtitleLanguage" data-lang="${culture.ThreeLetterISOLanguageName.toLowerCase()}" /><span>${culture.DisplayName}</span></label>`; html += `<label><input type="checkbox" is="emby-checkbox" class="chkSubtitleLanguage" data-lang="${culture.ThreeLetterISOLanguageName.toLowerCase()}" /><span>${culture.DisplayName}</span></label>`;
} }
element.innerHTML = html; element.innerHTML = html;
} }
function populateCountries(select) { function populateCountries(select) {
return ApiClient.getCountries().then(allCountries => { return ApiClient.getCountries().then(allCountries => {
let html = ''; let html = '';
html += "<option value=''></option>"; html += "<option value=''></option>";
@ -50,18 +49,18 @@ import template from './libraryoptionseditor.template.html';
} }
select.innerHTML = html; select.innerHTML = html;
}); });
} }
function populateRefreshInterval(select) { function populateRefreshInterval(select) {
let html = ''; let html = '';
html += `<option value='0'>${globalize.translate('Never')}</option>`; html += `<option value='0'>${globalize.translate('Never')}</option>`;
html += [30, 60, 90].map(val => { html += [30, 60, 90].map(val => {
return `<option value='${val}'>${globalize.translate('EveryNDays', val)}</option>`; return `<option value='${val}'>${globalize.translate('EveryNDays', val)}</option>`;
}).join(''); }).join('');
select.innerHTML = html; select.innerHTML = html;
} }
function renderMetadataReaders(page, plugins) { function renderMetadataReaders(page, plugins) {
let html = ''; let html = '';
const elem = page.querySelector('.metadataReaders'); const elem = page.querySelector('.metadataReaders');
@ -98,9 +97,9 @@ import template from './libraryoptionseditor.template.html';
} }
elem.innerHTML = html; elem.innerHTML = html;
return true; return true;
} }
function renderMetadataSavers(page, metadataSavers) { function renderMetadataSavers(page, metadataSavers) {
let html = ''; let html = '';
const elem = page.querySelector('.metadataSavers'); const elem = page.querySelector('.metadataSavers');
if (!metadataSavers.length) { if (!metadataSavers.length) {
@ -119,9 +118,9 @@ import template from './libraryoptionseditor.template.html';
elem.innerHTML = html; elem.innerHTML = html;
elem.classList.remove('hide'); elem.classList.remove('hide');
return true; return true;
} }
function getMetadataFetchersForTypeHtml(availableTypeOptions, libraryOptionsForType) { function getMetadataFetchersForTypeHtml(availableTypeOptions, libraryOptionsForType) {
let html = ''; let html = '';
let plugins = availableTypeOptions.MetadataFetchers; let plugins = availableTypeOptions.MetadataFetchers;
@ -154,18 +153,18 @@ import template from './libraryoptionseditor.template.html';
html += '<div class="fieldDescription">' + globalize.translate('LabelMetadataDownloadersHelp') + '</div>'; html += '<div class="fieldDescription">' + globalize.translate('LabelMetadataDownloadersHelp') + '</div>';
html += '</div>'; html += '</div>';
return html; return html;
} }
function getTypeOptions(allOptions, type) { function getTypeOptions(allOptions, type) {
const allTypeOptions = allOptions.TypeOptions || []; const allTypeOptions = allOptions.TypeOptions || [];
for (let i = 0; i < allTypeOptions.length; i++) { for (let i = 0; i < allTypeOptions.length; i++) {
const typeOptions = allTypeOptions[i]; const typeOptions = allTypeOptions[i];
if (typeOptions.Type === type) return typeOptions; if (typeOptions.Type === type) return typeOptions;
} }
return null; return null;
} }
function renderMetadataFetchers(page, availableOptions, libraryOptions) { function renderMetadataFetchers(page, availableOptions, libraryOptions) {
let html = ''; let html = '';
const elem = page.querySelector('.metadataFetchers'); const elem = page.querySelector('.metadataFetchers');
for (let i = 0; i < availableOptions.TypeOptions.length; i++) { for (let i = 0; i < availableOptions.TypeOptions.length; i++) {
@ -185,9 +184,9 @@ import template from './libraryoptionseditor.template.html';
page.querySelector('.fldMetadataCountry').classList.add('hide'); page.querySelector('.fldMetadataCountry').classList.add('hide');
} }
return true; return true;
} }
function renderSubtitleFetchers(page, availableOptions, libraryOptions) { function renderSubtitleFetchers(page, availableOptions, libraryOptions) {
let html = ''; let html = '';
const elem = page.querySelector('.subtitleFetchers'); const elem = page.querySelector('.subtitleFetchers');
@ -218,9 +217,9 @@ import template from './libraryoptionseditor.template.html';
html += '</div>'; html += '</div>';
html += `<div class="fieldDescription">${globalize.translate('SubtitleDownloadersHelp')}</div>`; html += `<div class="fieldDescription">${globalize.translate('SubtitleDownloadersHelp')}</div>`;
elem.innerHTML = html; elem.innerHTML = html;
} }
function getImageFetchersForTypeHtml(availableTypeOptions, libraryOptionsForType) { function getImageFetchersForTypeHtml(availableTypeOptions, libraryOptionsForType) {
let html = ''; let html = '';
let plugins = availableTypeOptions.ImageFetchers; let plugins = availableTypeOptions.ImageFetchers;
@ -258,9 +257,9 @@ import template from './libraryoptionseditor.template.html';
html += '<div class="fieldDescription">' + globalize.translate('LabelImageFetchersHelp') + '</div>'; html += '<div class="fieldDescription">' + globalize.translate('LabelImageFetchersHelp') + '</div>';
html += '</div>'; html += '</div>';
return html; return html;
} }
function renderImageFetchers(page, availableOptions, libraryOptions) { function renderImageFetchers(page, availableOptions, libraryOptions) {
let html = ''; let html = '';
const elem = page.querySelector('.imageFetchers'); const elem = page.querySelector('.imageFetchers');
for (let i = 0; i < availableOptions.TypeOptions.length; i++) { for (let i = 0; i < availableOptions.TypeOptions.length; i++) {
@ -276,9 +275,9 @@ import template from './libraryoptionseditor.template.html';
page.querySelector('.chkSaveLocalContainer').classList.add('hide'); page.querySelector('.chkSaveLocalContainer').classList.add('hide');
} }
return true; return true;
} }
function populateMetadataSettings(parent, contentType) { function populateMetadataSettings(parent, contentType) {
const isNewLibrary = parent.classList.contains('newlibrary'); const isNewLibrary = parent.classList.contains('newlibrary');
return ApiClient.getJSON(ApiClient.getUrl('Libraries/AvailableOptions', { return ApiClient.getJSON(ApiClient.getUrl('Libraries/AvailableOptions', {
LibraryContentType: contentType, LibraryContentType: contentType,
@ -295,9 +294,9 @@ import template from './libraryoptionseditor.template.html';
}).catch(() => { }).catch(() => {
return Promise.resolve(); return Promise.resolve();
}); });
} }
function adjustSortableListElement(elem) { function adjustSortableListElement(elem) {
const btnSortable = elem.querySelector('.btnSortable'); const btnSortable = elem.querySelector('.btnSortable');
const inner = btnSortable.querySelector('.material-icons'); const inner = btnSortable.querySelector('.material-icons');
if (elem.previousSibling) { if (elem.previousSibling) {
@ -313,10 +312,10 @@ import template from './libraryoptionseditor.template.html';
inner.classList.remove('keyboard_arrow_up'); inner.classList.remove('keyboard_arrow_up');
inner.classList.add('keyboard_arrow_down'); inner.classList.add('keyboard_arrow_down');
} }
} }
function showImageOptionsForType(type) { function showImageOptionsForType(type) {
import('../imageOptionsEditor/imageOptionsEditor').then(({default: ImageOptionsEditor}) => { import('../imageOptionsEditor/imageOptionsEditor').then(({ default: ImageOptionsEditor }) => {
let typeOptions = getTypeOptions(currentLibraryOptions, type); let typeOptions = getTypeOptions(currentLibraryOptions, type);
if (!typeOptions) { if (!typeOptions) {
typeOptions = { typeOptions = {
@ -328,18 +327,18 @@ import template from './libraryoptionseditor.template.html';
const imageOptionsEditor = new ImageOptionsEditor(); const imageOptionsEditor = new ImageOptionsEditor();
imageOptionsEditor.show(type, typeOptions, availableOptions); imageOptionsEditor.show(type, typeOptions, availableOptions);
}); });
} }
function onImageFetchersContainerClick(e) { function onImageFetchersContainerClick(e) {
const btnImageOptionsForType = dom.parentWithClass(e.target, 'btnImageOptionsForType'); const btnImageOptionsForType = dom.parentWithClass(e.target, 'btnImageOptionsForType');
if (btnImageOptionsForType) { if (btnImageOptionsForType) {
showImageOptionsForType(dom.parentWithClass(btnImageOptionsForType, 'imageFetcher').getAttribute('data-type')); showImageOptionsForType(dom.parentWithClass(btnImageOptionsForType, 'imageFetcher').getAttribute('data-type'));
return; return;
} }
onSortableContainerClick.call(this, e); onSortableContainerClick.call(this, e);
} }
function onSortableContainerClick(e) { function onSortableContainerClick(e) {
const btnSortable = dom.parentWithClass(e.target, 'btnSortable'); const btnSortable = dom.parentWithClass(e.target, 'btnSortable');
if (btnSortable) { if (btnSortable) {
const li = dom.parentWithClass(btnSortable, 'sortableOption'); const li = dom.parentWithClass(btnSortable, 'sortableOption');
@ -359,9 +358,9 @@ import template from './libraryoptionseditor.template.html';
} }
Array.prototype.forEach.call(list.querySelectorAll('.sortableOption'), adjustSortableListElement); Array.prototype.forEach.call(list.querySelectorAll('.sortableOption'), adjustSortableListElement);
} }
} }
function bindEvents(parent) { function bindEvents(parent) {
parent.querySelector('.metadataReaders').addEventListener('click', onSortableContainerClick); parent.querySelector('.metadataReaders').addEventListener('click', onSortableContainerClick);
parent.querySelector('.subtitleFetchers').addEventListener('click', onSortableContainerClick); parent.querySelector('.subtitleFetchers').addEventListener('click', onSortableContainerClick);
parent.querySelector('.metadataFetchers').addEventListener('click', onSortableContainerClick); parent.querySelector('.metadataFetchers').addEventListener('click', onSortableContainerClick);
@ -370,9 +369,9 @@ import template from './libraryoptionseditor.template.html';
parent.querySelector('#chkEnableEmbeddedTitles').addEventListener('change', (e) => { parent.querySelector('#chkEnableEmbeddedTitles').addEventListener('change', (e) => {
parent.querySelector('.chkEnableEmbeddedExtrasTitlesContainer').classList.toggle('hide', !e.currentTarget.checked); parent.querySelector('.chkEnableEmbeddedExtrasTitlesContainer').classList.toggle('hide', !e.currentTarget.checked);
}); });
} }
export async function embed(parent, contentType, libraryOptions) { export async function embed(parent, contentType, libraryOptions) {
currentLibraryOptions = { currentLibraryOptions = {
TypeOptions: [] TypeOptions: []
}; };
@ -389,9 +388,9 @@ import template from './libraryoptionseditor.template.html';
bindEvents(parent); bindEvents(parent);
}); });
}); });
} }
export function setContentType(parent, contentType) { export function setContentType(parent, contentType) {
if (contentType === 'homevideos' || contentType === 'photos') { if (contentType === 'homevideos' || contentType === 'photos') {
parent.querySelector('.chkEnablePhotosContainer').classList.remove('hide'); parent.querySelector('.chkEnablePhotosContainer').classList.remove('hide');
} else { } else {
@ -439,9 +438,9 @@ import template from './libraryoptionseditor.template.html';
parent.querySelector('.chkAutomaticallyAddToCollectionContainer').classList.toggle('hide', contentType !== 'movies' && contentType !== 'mixed'); parent.querySelector('.chkAutomaticallyAddToCollectionContainer').classList.toggle('hide', contentType !== 'movies' && contentType !== 'mixed');
return populateMetadataSettings(parent, contentType); return populateMetadataSettings(parent, contentType);
} }
function setSubtitleFetchersIntoOptions(parent, options) { function setSubtitleFetchersIntoOptions(parent, options) {
options.DisabledSubtitleFetchers = Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkSubtitleFetcher'), elem => { options.DisabledSubtitleFetchers = Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkSubtitleFetcher'), elem => {
return !elem.checked; return !elem.checked;
}), elem => { }), elem => {
@ -451,9 +450,9 @@ import template from './libraryoptionseditor.template.html';
options.SubtitleFetcherOrder = Array.prototype.map.call(parent.querySelectorAll('.subtitleFetcherItem'), elem => { options.SubtitleFetcherOrder = Array.prototype.map.call(parent.querySelectorAll('.subtitleFetcherItem'), elem => {
return elem.getAttribute('data-pluginname'); return elem.getAttribute('data-pluginname');
}); });
} }
function setMetadataFetchersIntoOptions(parent, options) { function setMetadataFetchersIntoOptions(parent, options) {
const sections = parent.querySelectorAll('.metadataFetcher'); const sections = parent.querySelectorAll('.metadataFetcher');
for (let i = 0; i < sections.length; i++) { for (let i = 0; i < sections.length; i++) {
const section = sections[i]; const section = sections[i];
@ -475,9 +474,9 @@ import template from './libraryoptionseditor.template.html';
return elem.getAttribute('data-pluginname'); return elem.getAttribute('data-pluginname');
}); });
} }
} }
function setImageFetchersIntoOptions(parent, options) { function setImageFetchersIntoOptions(parent, options) {
const sections = parent.querySelectorAll('.imageFetcher'); const sections = parent.querySelectorAll('.imageFetcher');
for (let i = 0; i < sections.length; i++) { for (let i = 0; i < sections.length; i++) {
const section = sections[i]; const section = sections[i];
@ -500,9 +499,9 @@ import template from './libraryoptionseditor.template.html';
return elem.getAttribute('data-pluginname'); return elem.getAttribute('data-pluginname');
}); });
} }
} }
function setImageOptionsIntoOptions(options) { function setImageOptionsIntoOptions(options) {
const originalTypeOptions = (currentLibraryOptions || {}).TypeOptions || []; const originalTypeOptions = (currentLibraryOptions || {}).TypeOptions || [];
for (let i = 0; i < originalTypeOptions.length; i++) { for (let i = 0; i < originalTypeOptions.length; i++) {
const originalTypeOption = originalTypeOptions[i]; const originalTypeOption = originalTypeOptions[i];
@ -516,9 +515,9 @@ import template from './libraryoptionseditor.template.html';
} }
originalTypeOption.ImageOptions && (typeOptions.ImageOptions = originalTypeOption.ImageOptions); originalTypeOption.ImageOptions && (typeOptions.ImageOptions = originalTypeOption.ImageOptions);
} }
} }
export function getLibraryOptions(parent) { export function getLibraryOptions(parent) {
const options = { const options = {
EnableArchiveMediaFiles: false, EnableArchiveMediaFiles: false,
EnablePhotos: parent.querySelector('.chkEnablePhotos').checked, EnablePhotos: parent.querySelector('.chkEnablePhotos').checked,
@ -563,9 +562,9 @@ import template from './libraryoptionseditor.template.html';
setImageOptionsIntoOptions(options); setImageOptionsIntoOptions(options);
return options; return options;
} }
function getOrderedPlugins(plugins, configuredOrder) { function getOrderedPlugins(plugins, configuredOrder) {
plugins = plugins.slice(0); plugins = plugins.slice(0);
plugins.sort((a, b) => { plugins.sort((a, b) => {
a = configuredOrder.indexOf(a.Name); a = configuredOrder.indexOf(a.Name);
@ -573,9 +572,9 @@ import template from './libraryoptionseditor.template.html';
return a - b; return a - b;
}); });
return plugins; return plugins;
} }
export function setLibraryOptions(parent, options) { export function setLibraryOptions(parent, options) {
currentLibraryOptions = options; currentLibraryOptions = options;
currentAvailableOptions = parent.availableOptions; currentAvailableOptions = parent.availableOptions;
parent.querySelector('#selectLanguage').value = options.PreferredMetadataLanguage || ''; parent.querySelector('#selectLanguage').value = options.PreferredMetadataLanguage || '';
@ -608,12 +607,11 @@ import template from './libraryoptionseditor.template.html';
renderMetadataFetchers(parent, parent.availableOptions, options); renderMetadataFetchers(parent, parent.availableOptions, options);
renderImageFetchers(parent, parent.availableOptions, options); renderImageFetchers(parent, parent.availableOptions, options);
renderSubtitleFetchers(parent, parent.availableOptions, options); renderSubtitleFetchers(parent, parent.availableOptions, options);
} }
let currentLibraryOptions; let currentLibraryOptions;
let currentAvailableOptions; let currentAvailableOptions;
/* eslint-enable indent */
export default { export default {
embed: embed, embed: embed,
setContentType: setContentType, setContentType: setContentType,

View file

@ -1,4 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for display list view. * Module for display list view.
@ -18,7 +17,7 @@ import '../../elements/emby-ratingbutton/emby-ratingbutton';
import '../../elements/emby-playstatebutton/emby-playstatebutton'; import '../../elements/emby-playstatebutton/emby-playstatebutton';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';
function getIndex(item, options) { function getIndex(item, options) {
if (options.index === 'disc') { if (options.index === 'disc') {
return item.ParentIndexNumber == null ? '' : globalize.translate('ValueDiscNumber', item.ParentIndexNumber); return item.ParentIndexNumber == null ? '' : globalize.translate('ValueDiscNumber', item.ParentIndexNumber);
} }
@ -75,9 +74,9 @@ import ServerConnections from '../ServerConnections';
return name.toUpperCase(); return name.toUpperCase();
} }
return ''; return '';
} }
function getImageUrl(item, size) { function getImageUrl(item, size) {
const apiClient = ServerConnections.getApiClient(item.ServerId); const apiClient = ServerConnections.getApiClient(item.ServerId);
let itemId; let itemId;
@ -105,9 +104,9 @@ import ServerConnections from '../ServerConnections';
return apiClient.getScaledImageUrl(itemId, options); return apiClient.getScaledImageUrl(itemId, options);
} }
return null; return null;
} }
function getChannelImageUrl(item, size) { function getChannelImageUrl(item, size) {
const apiClient = ServerConnections.getApiClient(item.ServerId); const apiClient = ServerConnections.getApiClient(item.ServerId);
const options = { const options = {
fillWidth: size, fillWidth: size,
@ -122,9 +121,9 @@ import ServerConnections from '../ServerConnections';
if (item.ChannelId) { if (item.ChannelId) {
return apiClient.getScaledImageUrl(item.ChannelId, options); return apiClient.getScaledImageUrl(item.ChannelId, options);
} }
} }
function getTextLinesHtml(textlines, isLargeStyle) { function getTextLinesHtml(textlines, isLargeStyle) {
let html = ''; let html = '';
const largeTitleTagName = layoutManager.tv ? 'h2' : 'div'; const largeTitleTagName = layoutManager.tv ? 'h2' : 'div';
@ -155,9 +154,9 @@ import ServerConnections from '../ServerConnections';
} }
return html; return html;
} }
function getRightButtonsHtml(options) { function getRightButtonsHtml(options) {
let html = ''; let html = '';
for (let i = 0, length = options.rightButtons.length; i < length; i++) { for (let i = 0, length = options.rightButtons.length; i < length; i++) {
@ -167,9 +166,9 @@ import ServerConnections from '../ServerConnections';
} }
return html; return html;
} }
export function getListViewHtml(options) { export function getListViewHtml(options) {
const items = options.items; const items = options.items;
let groupTitle = ''; let groupTitle = '';
@ -493,9 +492,8 @@ import ServerConnections from '../ServerConnections';
} }
return outerHtml; return outerHtml;
} }
/* eslint-enable indent */
export default { export default {
getListViewHtml: getListViewHtml getListViewHtml: getListViewHtml
}; };

View file

@ -4,25 +4,23 @@ import Events from '../utils/events.ts';
import '../elements/emby-tabs/emby-tabs'; import '../elements/emby-tabs/emby-tabs';
import '../elements/emby-button/emby-button'; import '../elements/emby-button/emby-button';
/* eslint-disable indent */ let tabOwnerView;
const queryScope = document.querySelector('.skinHeader');
let headerTabsContainer;
let tabsElem;
let tabOwnerView; function ensureElements() {
const queryScope = document.querySelector('.skinHeader');
let headerTabsContainer;
let tabsElem;
function ensureElements() {
if (!headerTabsContainer) { if (!headerTabsContainer) {
headerTabsContainer = queryScope.querySelector('.headerTabs'); headerTabsContainer = queryScope.querySelector('.headerTabs');
} }
} }
function onViewTabsReady() { function onViewTabsReady() {
this.selectedIndex(this.readySelectedIndex); this.selectedIndex(this.readySelectedIndex);
this.readySelectedIndex = null; this.readySelectedIndex = null;
} }
function allowSwipe(target) { function allowSwipe(target) {
function allowSwipeOn(elem) { function allowSwipeOn(elem) {
if (dom.parentWithTag(elem, 'input')) { if (dom.parentWithTag(elem, 'input')) {
return false; return false;
@ -45,9 +43,9 @@ import '../elements/emby-button/emby-button';
} }
return true; return true;
} }
function configureSwipeTabs(view, currentElement) { function configureSwipeTabs(view, currentElement) {
if (!browser.touch) { if (!browser.touch) {
return; return;
} }
@ -65,7 +63,7 @@ import '../elements/emby-button/emby-button';
} }
}; };
import('../scripts/touchHelper').then(({default: TouchHelper}) => { import('../scripts/touchHelper').then(({ default: TouchHelper }) => {
const touchHelper = new TouchHelper(view.parentNode.parentNode); const touchHelper = new TouchHelper(view.parentNode.parentNode);
Events.on(touchHelper, 'swipeleft', onSwipeLeft); Events.on(touchHelper, 'swipeleft', onSwipeLeft);
@ -75,9 +73,9 @@ import '../elements/emby-button/emby-button';
touchHelper.destroy(); touchHelper.destroy();
}); });
}); });
} }
export function setTabs(view, selectedIndex, getTabsFn, getTabContainersFn, onBeforeTabChange, onTabChange, setSelectedIndex) { export function setTabs(view, selectedIndex, getTabsFn, getTabContainersFn, onBeforeTabChange, onTabChange, setSelectedIndex) {
ensureElements(); ensureElements();
if (!view) { if (!view) {
@ -186,18 +184,16 @@ import '../elements/emby-button/emby-button';
tabs: tabsElem, tabs: tabsElem,
replaced: false replaced: false
}; };
} }
export function selectedTabIndex(index) { export function selectedTabIndex(index) {
if (index != null) { if (index != null) {
tabsElem.selectedIndex(index); tabsElem.selectedIndex(index);
} else { } else {
tabsElem.triggerTabChange(); tabsElem.triggerTabChange();
} }
} }
export function getTabsElement() { export function getTabsElement() {
return document.querySelector('.tabs-viewmenubar'); return document.querySelector('.tabs-viewmenubar');
} }
/* eslint-enable indent */

View file

@ -1,4 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for media library creator. * Module for media library creator.
@ -25,7 +24,7 @@ import toast from '../toast/toast';
import alert from '../alert'; import alert from '../alert';
import template from './mediaLibraryCreator.template.html'; import template from './mediaLibraryCreator.template.html';
function onAddLibrary() { function onAddLibrary(e) {
if (isCreating) { if (isCreating) {
return false; return false;
} }
@ -62,16 +61,16 @@ import template from './mediaLibraryCreator.template.html';
isCreating = false; isCreating = false;
loading.hide(); loading.hide();
}); });
return false; e.preventDefault();
} }
function getCollectionTypeOptionsHtml(collectionTypeOptions) { function getCollectionTypeOptionsHtml(collectionTypeOptions) {
return collectionTypeOptions.map(i => { return collectionTypeOptions.map(i => {
return `<option value="${i.value}">${i.name}</option>`; return `<option value="${i.value}">${i.name}</option>`;
}).join(''); }).join('');
} }
function initEditor(page, collectionTypeOptions) { function initEditor(page, collectionTypeOptions) {
$('#selectCollectionType', page).html(getCollectionTypeOptionsHtml(collectionTypeOptions)).val('').on('change', function () { $('#selectCollectionType', page).html(getCollectionTypeOptionsHtml(collectionTypeOptions)).val('').on('change', function () {
const value = this.value; const value = this.value;
const dlg = $(this).parents('.dialog')[0]; const dlg = $(this).parents('.dialog')[0];
@ -87,7 +86,9 @@ import template from './mediaLibraryCreator.template.html';
const index = this.selectedIndex; const index = this.selectedIndex;
if (index != -1) { if (index != -1) {
const name = this.options[index].innerHTML.replace('*', '').replace('&amp;', '&'); const name = this.options[index].innerHTML
.replaceAll('*', '')
.replaceAll('&amp;', '&');
$('#txtValue', dlg).val(name); $('#txtValue', dlg).val(name);
} }
} }
@ -96,14 +97,14 @@ import template from './mediaLibraryCreator.template.html';
$('.collectionTypeFieldDescription', dlg).html(folderOption?.message || ''); $('.collectionTypeFieldDescription', dlg).html(folderOption?.message || '');
}); });
page.querySelector('.btnAddFolder').addEventListener('click', onAddButtonClick); page.querySelector('.btnAddFolder').addEventListener('click', onAddButtonClick);
page.querySelector('.btnSubmit').addEventListener('click', onAddLibrary); page.querySelector('.addLibraryForm').addEventListener('submit', onAddLibrary);
page.querySelector('.folderList').addEventListener('click', onRemoveClick); page.querySelector('.folderList').addEventListener('click', onRemoveClick);
} }
function onAddButtonClick() { function onAddButtonClick() {
const page = dom.parentWithClass(this, 'dlg-librarycreator'); const page = dom.parentWithClass(this, 'dlg-librarycreator');
import('../directorybrowser/directorybrowser').then(({default: DirectoryBrowser}) => { import('../directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser(); const picker = new DirectoryBrowser();
picker.show({ picker.show({
enableNetworkSharePath: true, enableNetworkSharePath: true,
@ -116,9 +117,9 @@ import template from './mediaLibraryCreator.template.html';
} }
}); });
}); });
} }
function getFolderHtml(pathInfo, index) { function getFolderHtml(pathInfo, index) {
let html = ''; let html = '';
html += '<div class="listItem listItem-border lnkPath">'; html += '<div class="listItem listItem-border lnkPath">';
html += `<div class="${pathInfo.NetworkPath ? 'listItemBody two-line' : 'listItemBody'}">`; html += `<div class="${pathInfo.NetworkPath ? 'listItemBody two-line' : 'listItemBody'}">`;
@ -132,9 +133,9 @@ import template from './mediaLibraryCreator.template.html';
html += `<button type="button" is="paper-icon-button-light"" class="listItemButton btnRemovePath" data-index="${index}"><span class="material-icons remove_circle" aria-hidden="true"></span></button>`; html += `<button type="button" is="paper-icon-button-light"" class="listItemButton btnRemovePath" data-index="${index}"><span class="material-icons remove_circle" aria-hidden="true"></span></button>`;
html += '</div>'; html += '</div>';
return html; return html;
} }
function renderPaths(page) { function renderPaths(page) {
const foldersHtml = pathInfos.map(getFolderHtml).join(''); const foldersHtml = pathInfos.map(getFolderHtml).join('');
const folderList = page.querySelector('.folderList'); const folderList = page.querySelector('.folderList');
folderList.innerHTML = foldersHtml; folderList.innerHTML = foldersHtml;
@ -144,9 +145,9 @@ import template from './mediaLibraryCreator.template.html';
} else { } else {
folderList.classList.add('hide'); folderList.classList.add('hide');
} }
} }
function addMediaLocation(page, path, networkSharePath) { function addMediaLocation(page, path, networkSharePath) {
const pathLower = path.toLowerCase(); const pathLower = path.toLowerCase();
const pathFilter = pathInfos.filter(p => { const pathFilter = pathInfos.filter(p => {
return p.Path.toLowerCase() == pathLower; return p.Path.toLowerCase() == pathLower;
@ -164,9 +165,9 @@ import template from './mediaLibraryCreator.template.html';
pathInfos.push(pathInfo); pathInfos.push(pathInfo);
renderPaths(page); renderPaths(page);
} }
} }
function onRemoveClick(e) { function onRemoveClick(e) {
const button = dom.parentWithClass(e.target, 'btnRemovePath'); const button = dom.parentWithClass(e.target, 'btnRemovePath');
const index = parseInt(button.getAttribute('data-index'), 10); const index = parseInt(button.getAttribute('data-index'), 10);
const location = pathInfos[index].Path; const location = pathInfos[index].Path;
@ -175,17 +176,17 @@ import template from './mediaLibraryCreator.template.html';
return p.Path.toLowerCase() != locationLower; return p.Path.toLowerCase() != locationLower;
}); });
renderPaths(dom.parentWithClass(button, 'dlg-librarycreator')); renderPaths(dom.parentWithClass(button, 'dlg-librarycreator'));
} }
function onDialogClosed() { function onDialogClosed() {
currentResolve(hasChanges); currentResolve(hasChanges);
} }
function initLibraryOptions(dlg) { function initLibraryOptions(dlg) {
libraryoptionseditor.embed(dlg.querySelector('.libraryOptions')).then(() => { libraryoptionseditor.embed(dlg.querySelector('.libraryOptions')).then(() => {
$('#selectCollectionType', dlg).trigger('change'); $('#selectCollectionType', dlg).trigger('change');
}); });
} }
export class showEditor { export class showEditor {
constructor(options) { constructor(options) {
@ -217,11 +218,10 @@ export class showEditor {
} }
} }
let pathInfos = []; let pathInfos = [];
let currentResolve; let currentResolve;
let currentOptions; let currentOptions;
let hasChanges = false; let hasChanges = false;
let isCreating = false; let isCreating = false;
/* eslint-enable indent */
export default showEditor; export default showEditor;

View file

@ -1,9 +1,10 @@
<div class="formDialogHeader"> <form class="addLibraryForm" style="max-width:100%;">
<div class="formDialogHeader">
<button type="button" is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1" title="${ButtonBack}"><span class="material-icons arrow_back" aria-hidden="true"></span></button> <button type="button" is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1" title="${ButtonBack}"><span class="material-icons arrow_back" aria-hidden="true"></span></button>
<h3 class="formDialogHeaderTitle">${ButtonAddMediaLibrary}</h3> <h3 class="formDialogHeaderTitle">${ButtonAddMediaLibrary}</h3>
</div> </div>
<div class="formDialogContent scrollY" style="padding-top:2em;"> <div class="formDialogContent scrollY" style="padding-top:2em;">
<div class="dialogContentInner dialog-content-centered"> <div class="dialogContentInner dialog-content-centered">
<div id="fldCollectionType" class="selectContainer"> <div id="fldCollectionType" class="selectContainer">
@ -28,10 +29,11 @@
<div class="libraryOptions"></div> <div class="libraryOptions"></div>
</div> </div>
</div> </div>
<div class="formDialogFooter"> <div class="formDialogFooter">
<button is="emby-button" type="button" class="raised btnSubmit button-submit block formDialogFooterItem"> <button is="emby-button" type="submit" class="raised btnSubmit button-submit block formDialogFooterItem">
<span>${ButtonOk}</span> <span>${ButtonOk}</span>
</button> </button>
</div> </div>
</form>

View file

@ -1,4 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for media library editor. * Module for media library editor.
@ -23,7 +22,7 @@ import toast from '../toast/toast';
import confirm from '../confirm/confirm'; import confirm from '../confirm/confirm';
import template from './mediaLibraryEditor.template.html'; import template from './mediaLibraryEditor.template.html';
function onEditLibrary() { function onEditLibrary() {
if (isCreating) { if (isCreating) {
return false; return false;
} }
@ -43,9 +42,9 @@ import template from './mediaLibraryEditor.template.html';
loading.hide(); loading.hide();
}); });
return false; return false;
} }
function addMediaLocation(page, path, networkSharePath) { function addMediaLocation(page, path, networkSharePath) {
const virtualFolder = currentOptions.library; const virtualFolder = currentOptions.library;
const refreshAfterChange = currentOptions.refresh; const refreshAfterChange = currentOptions.refresh;
ApiClient.addMediaPath(virtualFolder.Name, path, networkSharePath, refreshAfterChange).then(() => { ApiClient.addMediaPath(virtualFolder.Name, path, networkSharePath, refreshAfterChange).then(() => {
@ -54,9 +53,9 @@ import template from './mediaLibraryEditor.template.html';
}, () => { }, () => {
toast(globalize.translate('ErrorAddingMediaPathToVirtualFolder')); toast(globalize.translate('ErrorAddingMediaPathToVirtualFolder'));
}); });
} }
function updateMediaLocation(page, path, networkSharePath) { function updateMediaLocation(page, path, networkSharePath) {
const virtualFolder = currentOptions.library; const virtualFolder = currentOptions.library;
ApiClient.updateMediaPath(virtualFolder.Name, { ApiClient.updateMediaPath(virtualFolder.Name, {
Path: path, Path: path,
@ -67,9 +66,9 @@ import template from './mediaLibraryEditor.template.html';
}, () => { }, () => {
toast(globalize.translate('ErrorAddingMediaPathToVirtualFolder')); toast(globalize.translate('ErrorAddingMediaPathToVirtualFolder'));
}); });
} }
function onRemoveClick(btnRemovePath, location) { function onRemoveClick(btnRemovePath, location) {
const button = btnRemovePath; const button = btnRemovePath;
const virtualFolder = currentOptions.library; const virtualFolder = currentOptions.library;
@ -87,9 +86,9 @@ import template from './mediaLibraryEditor.template.html';
toast(globalize.translate('ErrorDefault')); toast(globalize.translate('ErrorDefault'));
}); });
}); });
} }
function onListItemClick(e) { function onListItemClick(e) {
const listItem = dom.parentWithClass(e.target, 'listItem'); const listItem = dom.parentWithClass(e.target, 'listItem');
if (listItem) { if (listItem) {
@ -106,9 +105,9 @@ import template from './mediaLibraryEditor.template.html';
showDirectoryBrowser(dom.parentWithClass(listItem, 'dlg-libraryeditor'), originalPath, pathInfo.NetworkPath); showDirectoryBrowser(dom.parentWithClass(listItem, 'dlg-libraryeditor'), originalPath, pathInfo.NetworkPath);
} }
} }
function getFolderHtml(pathInfo, index) { function getFolderHtml(pathInfo, index) {
let html = ''; let html = '';
html += `<div class="listItem listItem-border lnkPath" data-index="${index}">`; html += `<div class="listItem listItem-border lnkPath" data-index="${index}">`;
html += `<div class="${pathInfo.NetworkPath ? 'listItemBody two-line' : 'listItemBody'}">`; html += `<div class="${pathInfo.NetworkPath ? 'listItemBody two-line' : 'listItemBody'}">`;
@ -124,9 +123,9 @@ import template from './mediaLibraryEditor.template.html';
html += `<button type="button" is="paper-icon-button-light" class="listItemButton btnRemovePath" data-index="${index}"><span class="material-icons remove_circle" aria-hidden="true"></span></button>`; html += `<button type="button" is="paper-icon-button-light" class="listItemButton btnRemovePath" data-index="${index}"><span class="material-icons remove_circle" aria-hidden="true"></span></button>`;
html += '</div>'; html += '</div>';
return html; return html;
} }
function refreshLibraryFromServer(page) { function refreshLibraryFromServer(page) {
ApiClient.getVirtualFolders().then(result => { ApiClient.getVirtualFolders().then(result => {
const library = result.filter(f => { const library = result.filter(f => {
return f.Name === currentOptions.library.Name; return f.Name === currentOptions.library.Name;
@ -137,9 +136,9 @@ import template from './mediaLibraryEditor.template.html';
renderLibrary(page, currentOptions); renderLibrary(page, currentOptions);
} }
}); });
} }
function renderLibrary(page, options) { function renderLibrary(page, options) {
let pathInfos = (options.library.LibraryOptions || {}).PathInfos || []; let pathInfos = (options.library.LibraryOptions || {}).PathInfos || [];
if (!pathInfos.length) { if (!pathInfos.length) {
@ -157,14 +156,14 @@ import template from './mediaLibraryEditor.template.html';
} }
page.querySelector('.folderList').innerHTML = pathInfos.map(getFolderHtml).join(''); page.querySelector('.folderList').innerHTML = pathInfos.map(getFolderHtml).join('');
} }
function onAddButtonClick() { function onAddButtonClick() {
showDirectoryBrowser(dom.parentWithClass(this, 'dlg-libraryeditor')); showDirectoryBrowser(dom.parentWithClass(this, 'dlg-libraryeditor'));
} }
function showDirectoryBrowser(context, originalPath, networkPath) { function showDirectoryBrowser(context, originalPath, networkPath) {
import('../directorybrowser/directorybrowser').then(({default: DirectoryBrowser}) => { import('../directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser(); const picker = new DirectoryBrowser();
picker.show({ picker.show({
enableNetworkSharePath: true, enableNetworkSharePath: true,
@ -184,19 +183,19 @@ import template from './mediaLibraryEditor.template.html';
} }
}); });
}); });
} }
function initEditor(dlg, options) { function initEditor(dlg, options) {
renderLibrary(dlg, options); renderLibrary(dlg, options);
dlg.querySelector('.btnAddFolder').addEventListener('click', onAddButtonClick); dlg.querySelector('.btnAddFolder').addEventListener('click', onAddButtonClick);
dlg.querySelector('.folderList').addEventListener('click', onListItemClick); dlg.querySelector('.folderList').addEventListener('click', onListItemClick);
dlg.querySelector('.btnSubmit').addEventListener('click', onEditLibrary); dlg.querySelector('.btnSubmit').addEventListener('click', onEditLibrary);
libraryoptionseditor.embed(dlg.querySelector('.libraryOptions'), options.library.CollectionType, options.library.LibraryOptions); libraryoptionseditor.embed(dlg.querySelector('.libraryOptions'), options.library.CollectionType, options.library.LibraryOptions);
} }
function onDialogClosed() { function onDialogClosed() {
currentDeferred.resolveWith(null, [hasChanges]); currentDeferred.resolveWith(null, [hasChanges]);
} }
export class showEditor { export class showEditor {
constructor(options) { constructor(options) {
@ -227,10 +226,9 @@ export class showEditor {
} }
} }
let currentDeferred; let currentDeferred;
let currentOptions; let currentOptions;
let hasChanges = false; let hasChanges = false;
let isCreating = false; let isCreating = false;
/* eslint-enable indent */
export default showEditor; export default showEditor;

View file

@ -10,8 +10,7 @@ import '../guide/programs.scss';
import '../../elements/emby-button/emby-button'; import '../../elements/emby-button/emby-button';
import * as userSettings from '../../scripts/settings/userSettings'; import * as userSettings from '../../scripts/settings/userSettings';
/* eslint-disable indent */ function getTimerIndicator(item) {
function getTimerIndicator(item) {
let status; let status;
if (item.Type === 'SeriesTimer') { if (item.Type === 'SeriesTimer') {
@ -33,9 +32,9 @@ import * as userSettings from '../../scripts/settings/userSettings';
} }
return '<span class="material-icons mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon fiber_manual_record" aria-hidden="true"></span>'; return '<span class="material-icons mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon fiber_manual_record" aria-hidden="true"></span>';
} }
function getProgramInfoHtml(item, options) { function getProgramInfoHtml(item, options) {
let html = ''; let html = '';
const miscInfo = []; const miscInfo = [];
@ -100,9 +99,9 @@ import * as userSettings from '../../scripts/settings/userSettings';
}).join(''); }).join('');
return html; return html;
} }
export function getMediaInfoHtml(item, options = {}) { export function getMediaInfoHtml(item, options = {}) {
let html = ''; let html = '';
const miscInfo = []; const miscInfo = [];
@ -177,13 +176,13 @@ import * as userSettings from '../../scripts/settings/userSettings';
if (options.year !== false && item.ProductionYear && item.Type === 'Series') { if (options.year !== false && item.ProductionYear && item.Type === 'Series') {
if (item.Status === 'Continuing') { if (item.Status === 'Continuing') {
miscInfo.push(globalize.translate('SeriesYearToPresent', datetime.toLocaleString(item.ProductionYear, {useGrouping: false}))); miscInfo.push(globalize.translate('SeriesYearToPresent', datetime.toLocaleString(item.ProductionYear, { useGrouping: false })));
} else if (item.ProductionYear) { } else if (item.ProductionYear) {
text = datetime.toLocaleString(item.ProductionYear, {useGrouping: false}); text = datetime.toLocaleString(item.ProductionYear, { useGrouping: false });
if (item.EndDate) { if (item.EndDate) {
try { try {
const endYear = datetime.toLocaleString(datetime.parseISO8601Date(item.EndDate).getFullYear(), {useGrouping: false}); const endYear = datetime.toLocaleString(datetime.parseISO8601Date(item.EndDate).getFullYear(), { useGrouping: false });
if (endYear !== item.ProductionYear) { if (endYear !== item.ProductionYear) {
text += `-${endYear}`; text += `-${endYear}`;
@ -253,7 +252,7 @@ import * as userSettings from '../../scripts/settings/userSettings';
miscInfo.push(item.ProductionYear); miscInfo.push(item.ProductionYear);
} else if (item.PremiereDate) { } else if (item.PremiereDate) {
try { try {
text = datetime.toLocaleString(datetime.parseISO8601Date(item.PremiereDate).getFullYear(), {useGrouping: false}); text = datetime.toLocaleString(datetime.parseISO8601Date(item.PremiereDate).getFullYear(), { useGrouping: false });
miscInfo.push(text); miscInfo.push(text);
} catch (e) { } catch (e) {
console.error('error parsing date:', item.PremiereDate); console.error('error parsing date:', item.PremiereDate);
@ -318,9 +317,9 @@ import * as userSettings from '../../scripts/settings/userSettings';
html += indicators.getMissingIndicator(item); html += indicators.getMissingIndicator(item);
return html; return html;
} }
export function getEndsAt(item) { export function getEndsAt(item) {
if (item.MediaType === 'Video' && item.RunTimeTicks && !item.StartDate) { if (item.MediaType === 'Video' && item.RunTimeTicks && !item.StartDate) {
let endDate = new Date().getTime() + (item.RunTimeTicks / 10000); let endDate = new Date().getTime() + (item.RunTimeTicks / 10000);
endDate = new Date(endDate); endDate = new Date(endDate);
@ -330,9 +329,9 @@ import * as userSettings from '../../scripts/settings/userSettings';
} }
return null; return null;
} }
export function getEndsAtFromPosition(runtimeTicks, positionTicks, playbackRate, includeText) { export function getEndsAtFromPosition(runtimeTicks, positionTicks, playbackRate, includeText) {
let endDate = new Date().getTime() + (1 / playbackRate) * ((runtimeTicks - (positionTicks || 0)) / 10000); let endDate = new Date().getTime() + (1 / playbackRate) * ((runtimeTicks - (positionTicks || 0)) / 10000);
endDate = new Date(endDate); endDate = new Date(endDate);
@ -342,9 +341,9 @@ import * as userSettings from '../../scripts/settings/userSettings';
return displayTime; return displayTime;
} }
return globalize.translate('EndsAtValue', displayTime); return globalize.translate('EndsAtValue', displayTime);
} }
function getMediaInfoItem(m, cssClass) { function getMediaInfoItem(m, cssClass) {
cssClass = cssClass ? (`${cssClass} mediaInfoItem`) : 'mediaInfoItem'; cssClass = cssClass ? (`${cssClass} mediaInfoItem`) : 'mediaInfoItem';
let mediaInfoText = m; let mediaInfoText = m;
@ -356,9 +355,9 @@ import * as userSettings from '../../scripts/settings/userSettings';
cssClass += ` ${m.cssClass}`; cssClass += ` ${m.cssClass}`;
} }
return `<div class="${cssClass}">${mediaInfoText}</div>`; return `<div class="${cssClass}">${mediaInfoText}</div>`;
} }
function getStarIconsHtml(item) { function getStarIconsHtml(item) {
let html = ''; let html = '';
if (item.CommunityRating) { if (item.CommunityRating) {
@ -370,9 +369,9 @@ import * as userSettings from '../../scripts/settings/userSettings';
} }
return html; return html;
} }
function dynamicEndTime(elem, item) { function dynamicEndTime(elem, item) {
const interval = setInterval(() => { const interval = setInterval(() => {
if (!document.body.contains(elem)) { if (!document.body.contains(elem)) {
clearInterval(interval); clearInterval(interval);
@ -381,23 +380,23 @@ import * as userSettings from '../../scripts/settings/userSettings';
elem.innerHTML = getEndsAt(item); elem.innerHTML = getEndsAt(item);
}, 60000); }, 60000);
} }
export function fillPrimaryMediaInfo(elem, item, options) { export function fillPrimaryMediaInfo(elem, item, options) {
const html = getPrimaryMediaInfoHtml(item, options); const html = getPrimaryMediaInfoHtml(item, options);
elem.innerHTML = html; elem.innerHTML = html;
afterFill(elem, item, options); afterFill(elem, item, options);
} }
export function fillSecondaryMediaInfo(elem, item, options) { export function fillSecondaryMediaInfo(elem, item, options) {
const html = getSecondaryMediaInfoHtml(item, options); const html = getSecondaryMediaInfoHtml(item, options);
elem.innerHTML = html; elem.innerHTML = html;
afterFill(elem, item, options); afterFill(elem, item, options);
} }
function afterFill(elem, item, options) { function afterFill(elem, item, options) {
if (options.endsAt !== false) { if (options.endsAt !== false) {
const endsAtElem = elem.querySelector('.endsAt'); const endsAtElem = elem.querySelector('.endsAt');
if (endsAtElem) { if (endsAtElem) {
@ -409,9 +408,9 @@ import * as userSettings from '../../scripts/settings/userSettings';
if (lnkChannel) { if (lnkChannel) {
lnkChannel.addEventListener('click', onChannelLinkClick); lnkChannel.addEventListener('click', onChannelLinkClick);
} }
} }
function onChannelLinkClick(e) { function onChannelLinkClick(e) {
const channelId = this.getAttribute('data-id'); const channelId = this.getAttribute('data-id');
const serverId = this.getAttribute('data-serverid'); const serverId = this.getAttribute('data-serverid');
@ -419,17 +418,17 @@ import * as userSettings from '../../scripts/settings/userSettings';
e.preventDefault(); e.preventDefault();
return false; return false;
} }
export function getPrimaryMediaInfoHtml(item, options = {}) { export function getPrimaryMediaInfoHtml(item, options = {}) {
if (options.interactive === undefined) { if (options.interactive === undefined) {
options.interactive = false; options.interactive = false;
} }
return getMediaInfoHtml(item, options); return getMediaInfoHtml(item, options);
} }
export function getSecondaryMediaInfoHtml(item, options) { export function getSecondaryMediaInfoHtml(item, options) {
options = options || {}; options = options || {};
if (options.interactive == null) { if (options.interactive == null) {
options.interactive = false; options.interactive = false;
@ -439,9 +438,9 @@ import * as userSettings from '../../scripts/settings/userSettings';
} }
return ''; return '';
} }
export function getResolutionText(i) { export function getResolutionText(i) {
const width = i.Width; const width = i.Width;
const height = i.Height; const height = i.Height;
@ -475,9 +474,9 @@ import * as userSettings from '../../scripts/settings/userSettings';
} }
} }
return null; return null;
} }
function getAudioStreamForDisplay(item) { function getAudioStreamForDisplay(item) {
if (!item.MediaSources) { if (!item.MediaSources) {
return null; return null;
} }
@ -490,9 +489,9 @@ import * as userSettings from '../../scripts/settings/userSettings';
return (mediaSource.MediaStreams || []).filter(i => { return (mediaSource.MediaStreams || []).filter(i => {
return i.Type === 'Audio' && (i.Index === mediaSource.DefaultAudioStreamIndex || mediaSource.DefaultAudioStreamIndex == null); return i.Type === 'Audio' && (i.Index === mediaSource.DefaultAudioStreamIndex || mediaSource.DefaultAudioStreamIndex == null);
})[0]; })[0];
} }
export function getMediaInfoStats(item) { export function getMediaInfoStats(item) {
const list = []; const list = [];
const mediaSource = (item.MediaSources || [])[0] || {}; const mediaSource = (item.MediaSources || [])[0] || {};
@ -575,9 +574,7 @@ import * as userSettings from '../../scripts/settings/userSettings';
} }
return list; return list;
} }
/* eslint-enable indent */
export default { export default {
getMediaInfoHtml: getPrimaryMediaInfoHtml, getMediaInfoHtml: getPrimaryMediaInfoHtml,

View file

@ -23,23 +23,21 @@ import toast from '../toast/toast';
import { appRouter } from '../appRouter'; import { appRouter } from '../appRouter';
import template from './metadataEditor.template.html'; import template from './metadataEditor.template.html';
/* eslint-disable indent */ let currentContext;
let metadataEditorInfo;
let currentItem;
let currentContext; function isDialog() {
let metadataEditorInfo;
let currentItem;
function isDialog() {
return currentContext.classList.contains('dialog'); return currentContext.classList.contains('dialog');
} }
function closeDialog() { function closeDialog() {
if (isDialog()) { if (isDialog()) {
dialogHelper.close(currentContext); dialogHelper.close(currentContext);
} }
} }
function submitUpdatedItem(form, item) { function submitUpdatedItem(form, item) {
function afterContentTypeUpdated() { function afterContentTypeUpdated() {
toast(globalize.translate('MessageItemSaved')); toast(globalize.translate('MessageItemSaved'));
@ -68,16 +66,16 @@ import template from './metadataEditor.template.html';
afterContentTypeUpdated(); afterContentTypeUpdated();
} }
}); });
} }
function getSelectedAirDays(form) { function getSelectedAirDays(form) {
const checkedItems = form.querySelectorAll('.chkAirDay:checked') || []; const checkedItems = form.querySelectorAll('.chkAirDay:checked') || [];
return Array.prototype.map.call(checkedItems, function (c) { return Array.prototype.map.call(checkedItems, function (c) {
return c.getAttribute('data-day'); return c.getAttribute('data-day');
}); });
} }
function getAlbumArtists(form) { function getAlbumArtists(form) {
return form.querySelector('#txtAlbumArtist').value.trim().split(';').filter(function (s) { return form.querySelector('#txtAlbumArtist').value.trim().split(';').filter(function (s) {
return s.length > 0; return s.length > 0;
}).map(function (a) { }).map(function (a) {
@ -85,9 +83,9 @@ import template from './metadataEditor.template.html';
Name: a Name: a
}; };
}); });
} }
function getArtists(form) { function getArtists(form) {
return form.querySelector('#txtArtist').value.trim().split(';').filter(function (s) { return form.querySelector('#txtArtist').value.trim().split(';').filter(function (s) {
return s.length > 0; return s.length > 0;
}).map(function (a) { }).map(function (a) {
@ -95,9 +93,9 @@ import template from './metadataEditor.template.html';
Name: a Name: a
}; };
}); });
} }
function getDateValue(form, element, property) { function getDateValue(form, element, property) {
let val = form.querySelector(element).value; let val = form.querySelector(element).value;
if (!val) { if (!val) {
@ -118,9 +116,9 @@ import template from './metadataEditor.template.html';
} }
return val; return val;
} }
function onSubmit(e) { function onSubmit(e) {
loading.show(); loading.show();
const form = this; const form = this;
@ -202,16 +200,16 @@ import template from './metadataEditor.template.html';
// Disable default form submission // Disable default form submission
return false; return false;
} }
function getListValues(list) { function getListValues(list) {
return Array.prototype.map.call(list.querySelectorAll('.textValue'), function (el) { return Array.prototype.map.call(list.querySelectorAll('.textValue'), function (el) {
return el.textContent; return el.textContent;
}); });
} }
function addElementToList(source, sortCallback) { function addElementToList(source, sortCallback) {
import('../prompt/prompt').then(({default: prompt}) => { import('../prompt/prompt').then(({ default: prompt }) => {
prompt({ prompt({
label: 'Value:' label: 'Value:'
}).then(function (text) { }).then(function (text) {
@ -221,15 +219,15 @@ import template from './metadataEditor.template.html';
populateListView(list, items, sortCallback); populateListView(list, items, sortCallback);
}); });
}); });
} }
function removeElementFromList(source) { function removeElementFromList(source) {
const el = dom.parentWithClass(source, 'listItem'); const el = dom.parentWithClass(source, 'listItem');
el.parentNode.removeChild(el); el.parentNode.removeChild(el);
} }
function editPerson(context, person, index) { function editPerson(context, person, index) {
import('./personEditor').then(({default: personEditor}) => { import('./personEditor').then(({ default: personEditor }) => {
personEditor.show(person).then(function (updatedPerson) { personEditor.show(person).then(function (updatedPerson) {
const isNew = index === -1; const isNew = index === -1;
@ -240,9 +238,9 @@ import template from './metadataEditor.template.html';
populatePeople(context, currentItem.People); populatePeople(context, currentItem.People);
}); });
}); });
} }
function afterDeleted(context, item) { function afterDeleted(context, item) {
const parentId = item.ParentId || item.SeasonId || item.SeriesId; const parentId = item.ParentId || item.SeasonId || item.SeriesId;
if (parentId) { if (parentId) {
@ -250,10 +248,10 @@ import template from './metadataEditor.template.html';
} else { } else {
appRouter.goHome(); appRouter.goHome();
} }
} }
function showMoreMenu(context, button, user) { function showMoreMenu(context, button, user) {
import('../itemContextMenu').then(({default: itemContextMenu}) => { import('../itemContextMenu').then(({ default: itemContextMenu }) => {
const item = currentItem; const item = currentItem;
itemContextMenu.show({ itemContextMenu.show({
@ -275,9 +273,9 @@ import template from './metadataEditor.template.html';
} }
}); });
}); });
} }
function onEditorClick(e) { function onEditorClick(e) {
const btnRemoveFromEditorList = dom.parentWithClass(e.target, 'btnRemoveFromEditorList'); const btnRemoveFromEditorList = dom.parentWithClass(e.target, 'btnRemoveFromEditorList');
if (btnRemoveFromEditorList) { if (btnRemoveFromEditorList) {
removeElementFromList(btnRemoveFromEditorList); removeElementFromList(btnRemoveFromEditorList);
@ -288,19 +286,19 @@ import template from './metadataEditor.template.html';
if (btnAddTextItem) { if (btnAddTextItem) {
addElementToList(btnAddTextItem); addElementToList(btnAddTextItem);
} }
} }
function getApiClient() { function getApiClient() {
return ServerConnections.getApiClient(currentItem.ServerId); return ServerConnections.getApiClient(currentItem.ServerId);
} }
function bindAll(elems, eventName, fn) { function bindAll(elems, eventName, fn) {
for (let i = 0, length = elems.length; i < length; i++) { for (let i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener(eventName, fn); elems[i].addEventListener(eventName, fn);
} }
} }
function init(context) { function init(context) {
context.querySelector('.externalIds').addEventListener('click', function (e) { context.querySelector('.externalIds').addEventListener('click', function (e) {
const btnOpenExternalId = dom.parentWithClass(e.target, 'btnOpenExternalId'); const btnOpenExternalId = dom.parentWithClass(e.target, 'btnOpenExternalId');
if (btnOpenExternalId) { if (btnOpenExternalId) {
@ -368,9 +366,9 @@ import template from './metadataEditor.template.html';
editPerson(context, currentItem.People[index], index); editPerson(context, currentItem.People[index], index);
} }
}); });
} }
function getItem(itemId, serverId) { function getItem(itemId, serverId) {
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
if (itemId) { if (itemId) {
@ -378,9 +376,9 @@ import template from './metadataEditor.template.html';
} }
return apiClient.getRootFolder(apiClient.getCurrentUserId()); return apiClient.getRootFolder(apiClient.getCurrentUserId());
} }
function getEditorConfig(itemId, serverId) { function getEditorConfig(itemId, serverId) {
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
if (itemId) { if (itemId) {
@ -388,9 +386,9 @@ import template from './metadataEditor.template.html';
} }
return Promise.resolve({}); return Promise.resolve({});
} }
function populateCountries(select, allCountries) { function populateCountries(select, allCountries) {
let html = ''; let html = '';
html += "<option value=''></option>"; html += "<option value=''></option>";
@ -402,9 +400,9 @@ import template from './metadataEditor.template.html';
} }
select.innerHTML = html; select.innerHTML = html;
} }
function populateLanguages(select, languages) { function populateLanguages(select, languages) {
let html = ''; let html = '';
html += "<option value=''></option>"; html += "<option value=''></option>";
@ -416,9 +414,9 @@ import template from './metadataEditor.template.html';
} }
select.innerHTML = html; select.innerHTML = html;
} }
function renderContentTypeOptions(context, metadataInfo) { function renderContentTypeOptions(context, metadataInfo) {
if (!metadataInfo.ContentTypeOptions.length) { if (!metadataInfo.ContentTypeOptions.length) {
hideElement('#fldContentType', context); hideElement('#fldContentType', context);
} else { } else {
@ -432,9 +430,9 @@ import template from './metadataEditor.template.html';
const selectEl = context.querySelector('#selectContentType'); const selectEl = context.querySelector('#selectContentType');
selectEl.innerHTML = html; selectEl.innerHTML = html;
selectEl.value = metadataInfo.ContentType || ''; selectEl.value = metadataInfo.ContentType || '';
} }
function loadExternalIds(context, item, externalIds) { function loadExternalIds(context, item, externalIds) {
let html = ''; let html = '';
const providerIds = item.ProviderIds || {}; const providerIds = item.ProviderIds || {};
@ -477,12 +475,12 @@ import template from './metadataEditor.template.html';
} else { } else {
context.querySelector('.externalIdsSection').classList.add('hide'); context.querySelector('.externalIdsSection').classList.add('hide');
} }
} }
// Function to hide the element by selector or raw element // Function to hide the element by selector or raw element
// Selector can be an element or a selector string // Selector can be an element or a selector string
// Context is optional and restricts the querySelector to the context // Context is optional and restricts the querySelector to the context
function hideElement(selector, context, multiple) { function hideElement(selector, context, multiple) {
context = context || document; context = context || document;
if (typeof selector === 'string') { if (typeof selector === 'string') {
const elements = multiple ? context.querySelectorAll(selector) : [context.querySelector(selector)]; const elements = multiple ? context.querySelectorAll(selector) : [context.querySelector(selector)];
@ -495,12 +493,12 @@ import template from './metadataEditor.template.html';
} else { } else {
selector.classList.add('hide'); selector.classList.add('hide');
} }
} }
// Function to show the element by selector or raw element // Function to show the element by selector or raw element
// Selector can be an element or a selector string // Selector can be an element or a selector string
// Context is optional and restricts the querySelector to the context // Context is optional and restricts the querySelector to the context
function showElement(selector, context, multiple) { function showElement(selector, context, multiple) {
context = context || document; context = context || document;
if (typeof selector === 'string') { if (typeof selector === 'string') {
const elements = multiple ? context.querySelectorAll(selector) : [context.querySelector(selector)]; const elements = multiple ? context.querySelectorAll(selector) : [context.querySelector(selector)];
@ -513,9 +511,9 @@ import template from './metadataEditor.template.html';
} else { } else {
selector.classList.remove('hide'); selector.classList.remove('hide');
} }
} }
function setFieldVisibilities(context, item) { function setFieldVisibilities(context, item) {
if (item.Path && item.EnableMediaSourceDisplay !== false) { if (item.Path && item.EnableMediaSourceDisplay !== false) {
showElement('#fldPath', context); showElement('#fldPath', context);
} else { } else {
@ -588,12 +586,12 @@ import template from './metadataEditor.template.html';
hideElement('#collapsibleSpecialEpisodeInfo', context); hideElement('#collapsibleSpecialEpisodeInfo', context);
} }
if (item.Type === 'Person' || if (item.Type === 'Person'
item.Type === 'Genre' || || item.Type === 'Genre'
item.Type === 'Studio' || || item.Type === 'Studio'
item.Type === 'MusicGenre' || || item.Type === 'MusicGenre'
item.Type === 'TvChannel' || || item.Type === 'TvChannel'
item.Type === 'Book') { || item.Type === 'Book') {
hideElement('#peopleCollapsible', context); hideElement('#peopleCollapsible', context);
} else { } else {
showElement('#peopleCollapsible', context); showElement('#peopleCollapsible', context);
@ -713,9 +711,9 @@ import template from './metadataEditor.template.html';
context.querySelector('#selectDisplayOrder').innerHTML = ''; context.querySelector('#selectDisplayOrder').innerHTML = '';
hideElement('#fldDisplayOrder', context); hideElement('#fldDisplayOrder', context);
} }
} }
function fillItemInfo(context, item, parentalRatingOptions) { function fillItemInfo(context, item, parentalRatingOptions) {
let select = context.querySelector('#selectOfficialRating'); let select = context.querySelector('#selectOfficialRating');
populateRatings(parentalRatingOptions, select, item.OfficialRating); populateRatings(parentalRatingOptions, select, item.OfficialRating);
@ -843,9 +841,9 @@ import template from './metadataEditor.template.html';
} else { } else {
context.querySelector('#txtSeriesRuntime', context).value = ''; context.querySelector('#txtSeriesRuntime', context).value = '';
} }
} }
function populateRatings(allParentalRatings, select, currentValue) { function populateRatings(allParentalRatings, select, currentValue) {
let html = ''; let html = '';
html += "<option value=''></option>"; html += "<option value=''></option>";
@ -876,18 +874,18 @@ import template from './metadataEditor.template.html';
} }
select.innerHTML = html; select.innerHTML = html;
} }
function populateStatus(select) { function populateStatus(select) {
let html = ''; let html = '';
html += "<option value=''></option>"; html += "<option value=''></option>";
html += "<option value='Continuing'>" + globalize.translate('Continuing') + '</option>'; html += "<option value='Continuing'>" + globalize.translate('Continuing') + '</option>';
html += "<option value='Ended'>" + globalize.translate('Ended') + '</option>'; html += "<option value='Ended'>" + globalize.translate('Ended') + '</option>';
select.innerHTML = html; select.innerHTML = html;
} }
function populateListView(list, items, sortCallback) { function populateListView(list, items, sortCallback) {
items = items || []; items = items || [];
if (typeof (sortCallback) === 'undefined') { if (typeof (sortCallback) === 'undefined') {
items.sort(function (a, b) { items.sort(function (a, b) {
@ -916,9 +914,9 @@ import template from './metadataEditor.template.html';
} }
list.innerHTML = html; list.innerHTML = html;
} }
function populatePeople(context, people) { function populatePeople(context, people) {
const lastType = ''; const lastType = '';
let html = ''; let html = '';
@ -953,9 +951,9 @@ import template from './metadataEditor.template.html';
} }
elem.innerHTML = html; elem.innerHTML = html;
} }
function getLockedFieldsHtml(fields, currentFields) { function getLockedFieldsHtml(fields, currentFields) {
let html = ''; let html = '';
for (let i = 0; i < fields.length; i++) { for (let i = 0; i < fields.length; i++) {
const field = fields[i]; const field = fields[i];
@ -968,9 +966,9 @@ import template from './metadataEditor.template.html';
html += '</label>'; html += '</label>';
} }
return html; return html;
} }
function fillMetadataSettings(context, item, lockedFields) { function fillMetadataSettings(context, item, lockedFields) {
const container = context.querySelector('.providerSettingsContainer'); const container = context.querySelector('.providerSettingsContainer');
lockedFields = lockedFields || []; lockedFields = lockedFields || [];
@ -1001,9 +999,9 @@ import template from './metadataEditor.template.html';
html += '<p>' + globalize.translate('HeaderEnabledFieldsHelp') + '</p>'; html += '<p>' + globalize.translate('HeaderEnabledFieldsHelp') + '</p>';
html += getLockedFieldsHtml(lockedFieldsList, lockedFields); html += getLockedFieldsHtml(lockedFieldsList, lockedFields);
container.innerHTML = html; container.innerHTML = html;
} }
function reload(context, itemId, serverId) { function reload(context, itemId, serverId) {
loading.show(); loading.show();
Promise.all([getItem(itemId, serverId), getEditorConfig(itemId, serverId)]).then(function (responses) { Promise.all([getItem(itemId, serverId), getEditorConfig(itemId, serverId)]).then(function (responses) {
@ -1033,16 +1031,16 @@ import template from './metadataEditor.template.html';
loading.hide(); loading.hide();
}); });
} }
function centerFocus(elem, horiz, on) { function centerFocus(elem, horiz, on) {
import('../../scripts/scrollHelper').then((scrollHelper) => { import('../../scripts/scrollHelper').then((scrollHelper) => {
const fn = on ? 'on' : 'off'; const fn = on ? 'on' : 'off';
scrollHelper.centerFocus[fn](elem, horiz); scrollHelper.centerFocus[fn](elem, horiz);
}); });
} }
function show(itemId, serverId, resolve) { function show(itemId, serverId, resolve) {
loading.show(); loading.show();
const dialogOptions = { const dialogOptions = {
@ -1085,9 +1083,9 @@ import template from './metadataEditor.template.html';
init(dlg); init(dlg);
reload(dlg, itemId, serverId); reload(dlg, itemId, serverId);
} }
export default { export default {
show: function (itemId, serverId) { show: function (itemId, serverId) {
return new Promise(resolve => show(itemId, serverId, resolve)); return new Promise(resolve => show(itemId, serverId, resolve));
}, },
@ -1111,6 +1109,5 @@ import template from './metadataEditor.template.html';
focusManager.autoFocus(elem); focusManager.autoFocus(elem);
}); });
} }
}; };
/* eslint-enable indent */

View file

@ -8,16 +8,14 @@ import '../../elements/emby-select/emby-select';
import '../formdialog.scss'; import '../formdialog.scss';
import template from './personEditor.template.html'; import template from './personEditor.template.html';
/* eslint-disable indent */ function centerFocus(elem, horiz, on) {
function centerFocus(elem, horiz, on) {
import('../../scripts/scrollHelper').then((scrollHelper) => { import('../../scripts/scrollHelper').then((scrollHelper) => {
const fn = on ? 'on' : 'off'; const fn = on ? 'on' : 'off';
scrollHelper.centerFocus[fn](elem, horiz); scrollHelper.centerFocus[fn](elem, horiz);
}); });
} }
function show(person) { function show(person) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
const dialogOptions = { const dialogOptions = {
removeOnClose: true, removeOnClose: true,
@ -92,10 +90,9 @@ import template from './personEditor.template.html';
bubbles: true bubbles: true
})); }));
}); });
} }
export default { export default {
show: show show: show
}; };
/* eslint-enable indent */

View file

@ -11,13 +11,11 @@ import confirm from '../confirm/confirm';
import itemHelper from '../itemHelper'; import itemHelper from '../itemHelper';
import datetime from '../../scripts/datetime'; import datetime from '../../scripts/datetime';
/* eslint-disable indent */ let selectedItems = [];
let selectedElements = [];
let currentSelectionCommandsPanel;
let selectedItems = []; function hideSelections() {
let selectedElements = [];
let currentSelectionCommandsPanel;
function hideSelections() {
const selectionCommandsPanel = currentSelectionCommandsPanel; const selectionCommandsPanel = currentSelectionCommandsPanel;
if (selectionCommandsPanel) { if (selectionCommandsPanel) {
selectionCommandsPanel.parentNode.removeChild(selectionCommandsPanel); selectionCommandsPanel.parentNode.removeChild(selectionCommandsPanel);
@ -32,9 +30,9 @@ import datetime from '../../scripts/datetime';
parent.classList.remove('withMultiSelect'); parent.classList.remove('withMultiSelect');
} }
} }
} }
function onItemSelectionPanelClick(e, itemSelectionPanel) { function onItemSelectionPanelClick(e, itemSelectionPanel) {
// toggle the checkbox, if it wasn't clicked on // toggle the checkbox, if it wasn't clicked on
if (!dom.parentWithClass(e.target, 'chkItemSelect')) { if (!dom.parentWithClass(e.target, 'chkItemSelect')) {
const chkItemSelect = itemSelectionPanel.querySelector('.chkItemSelect'); const chkItemSelect = itemSelectionPanel.querySelector('.chkItemSelect');
@ -53,9 +51,9 @@ import datetime from '../../scripts/datetime';
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
return false; return false;
} }
function updateItemSelection(chkItemSelect, selected) { function updateItemSelection(chkItemSelect, selected) {
const id = dom.parentWithAttribute(chkItemSelect, 'data-id').getAttribute('data-id'); const id = dom.parentWithAttribute(chkItemSelect, 'data-id').getAttribute('data-id');
if (selected) { if (selected) {
@ -84,13 +82,13 @@ import datetime from '../../scripts/datetime';
} else { } else {
hideSelections(); hideSelections();
} }
} }
function onSelectionChange() { function onSelectionChange() {
updateItemSelection(this, this.checked); updateItemSelection(this, this.checked);
} }
function showSelection(item, isChecked) { function showSelection(item, isChecked) {
let itemSelectionPanel = item.querySelector('.itemSelectionPanel'); let itemSelectionPanel = item.querySelector('.itemSelectionPanel');
if (!itemSelectionPanel) { if (!itemSelectionPanel) {
@ -112,9 +110,9 @@ import datetime from '../../scripts/datetime';
const chkItemSelect = itemSelectionPanel.querySelector('.chkItemSelect'); const chkItemSelect = itemSelectionPanel.querySelector('.chkItemSelect');
chkItemSelect.addEventListener('change', onSelectionChange); chkItemSelect.addEventListener('change', onSelectionChange);
} }
} }
function showSelectionCommands() { function showSelectionCommands() {
let selectionCommandsPanel = currentSelectionCommandsPanel; let selectionCommandsPanel = currentSelectionCommandsPanel;
if (!selectionCommandsPanel) { if (!selectionCommandsPanel) {
@ -140,15 +138,15 @@ import datetime from '../../scripts/datetime';
dom.addEventListener(btnSelectionPanelOptions, 'click', showMenuForSelectedItems, { passive: true }); dom.addEventListener(btnSelectionPanelOptions, 'click', showMenuForSelectedItems, { passive: true });
} }
} }
function alertText(options) { function alertText(options) {
return new Promise((resolve) => { return new Promise((resolve) => {
alert(options).then(resolve, resolve); alert(options).then(resolve, resolve);
}); });
} }
function deleteItems(apiClient, itemIds) { function deleteItems(apiClient, itemIds) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let msg = globalize.translate('ConfirmDeleteItem'); let msg = globalize.translate('ConfirmDeleteItem');
let title = globalize.translate('HeaderDeleteItem'); let title = globalize.translate('HeaderDeleteItem');
@ -166,9 +164,9 @@ import datetime from '../../scripts/datetime';
}); });
}, reject); }, reject);
}); });
} }
function showMenuForSelectedItems(e) { function showMenuForSelectedItems(e) {
const apiClient = ServerConnections.currentApiClient(); const apiClient = ServerConnections.currentApiClient();
apiClient.getCurrentUser().then(user => { apiClient.getCurrentUser().then(user => {
@ -205,13 +203,6 @@ import datetime from '../../scripts/datetime';
if (user.Policy.EnableContentDownloading && appHost.supports('filedownload')) { if (user.Policy.EnableContentDownloading && appHost.supports('filedownload')) {
// Disabled because there is no callback for this item // Disabled because there is no callback for this item
/*
menuItems.push({
name: globalize.translate('Download'),
id: 'download',
icon: 'file_download'
});
*/
} }
if (user.Policy.IsAdministrator) { if (user.Policy.IsAdministrator) {
@ -267,7 +258,7 @@ import datetime from '../../scripts/datetime';
} }
break; break;
case 'addtocollection': case 'addtocollection':
import('../collectionEditor/collectionEditor').then(({default: CollectionEditor}) => { import('../collectionEditor/collectionEditor').then(({ default: CollectionEditor }) => {
const collectionEditor = new CollectionEditor(); const collectionEditor = new CollectionEditor();
collectionEditor.show({ collectionEditor.show({
items: items, items: items,
@ -308,7 +299,7 @@ import datetime from '../../scripts/datetime';
dispatchNeedsRefresh(); dispatchNeedsRefresh();
break; break;
case 'refresh': case 'refresh':
import('../refreshdialog/refreshdialog').then(({default: refreshDialog}) => { import('../refreshdialog/refreshdialog').then(({ default: refreshDialog }) => {
new refreshDialog({ new refreshDialog({
itemIds: items, itemIds: items,
serverId: serverId serverId: serverId
@ -325,9 +316,9 @@ import datetime from '../../scripts/datetime';
}); });
}); });
}); });
} }
function dispatchNeedsRefresh() { function dispatchNeedsRefresh() {
const elems = []; const elems = [];
[].forEach.call(selectedElements, i => { [].forEach.call(selectedElements, i => {
@ -341,9 +332,9 @@ import datetime from '../../scripts/datetime';
for (let i = 0, length = elems.length; i < length; i++) { for (let i = 0, length = elems.length; i < length; i++) {
elems[i].notifyRefreshNeeded(true); elems[i].notifyRefreshNeeded(true);
} }
} }
function combineVersions(apiClient, selection) { function combineVersions(apiClient, selection) {
if (selection.length < 2) { if (selection.length < 2) {
alert({ alert({
text: globalize.translate('PleaseSelectTwoItems') text: globalize.translate('PleaseSelectTwoItems')
@ -364,9 +355,9 @@ import datetime from '../../scripts/datetime';
hideSelections(); hideSelections();
dispatchNeedsRefresh(); dispatchNeedsRefresh();
}); });
} }
function showSelections(initialCard) { function showSelections(initialCard) {
import('../../elements/emby-checkbox/emby-checkbox').then(() => { import('../../elements/emby-checkbox/emby-checkbox').then(() => {
const cards = document.querySelectorAll('.card'); const cards = document.querySelectorAll('.card');
for (let i = 0, length = cards.length; i < length; i++) { for (let i = 0, length = cards.length; i < length; i++) {
@ -376,9 +367,9 @@ import datetime from '../../scripts/datetime';
showSelectionCommands(); showSelectionCommands();
updateItemSelection(initialCard, true); updateItemSelection(initialCard, true);
}); });
} }
function onContainerClick(e) { function onContainerClick(e) {
const target = e.target; const target = e.target;
if (selectedItems.length) { if (selectedItems.length) {
@ -394,11 +385,11 @@ import datetime from '../../scripts/datetime';
e.stopPropagation(); e.stopPropagation();
return false; return false;
} }
} }
document.addEventListener('viewbeforehide', hideSelections); document.addEventListener('viewbeforehide', hideSelections);
export default function (options) { export default function (options) {
const self = this; const self = this;
const container = options.container; const container = options.container;
@ -571,6 +562,5 @@ import datetime from '../../scripts/datetime';
passive: true passive: true
}); });
}; };
} }
/* eslint-enable indent */

View file

@ -2,6 +2,7 @@ import serverNotifications from '../../scripts/serverNotifications';
import { playbackManager } from '../playback/playbackmanager'; import { playbackManager } from '../playback/playbackmanager';
import Events from '../../utils/events.ts'; import Events from '../../utils/events.ts';
import globalize from '../../scripts/globalize'; import globalize from '../../scripts/globalize';
import { getItems } from '../../utils/jellyfin-apiclient/getItems.ts';
import NotificationIcon from './notificationicon.png'; import NotificationIcon from './notificationicon.png';
@ -130,7 +131,7 @@ function onLibraryChanged(data, apiClient) {
newItems.length = 12; newItems.length = 12;
} }
apiClient.getItems(apiClient.getCurrentUserId(), { getItems(apiClient, apiClient.getCurrentUserId(), {
Recursive: true, Recursive: true,
Limit: 3, Limit: 3,

View file

@ -17,32 +17,30 @@ import './nowPlayingBar.scss';
import '../../elements/emby-slider/emby-slider'; import '../../elements/emby-slider/emby-slider';
import { appRouter } from '../appRouter'; import { appRouter } from '../appRouter';
/* eslint-disable indent */ let currentPlayer;
let currentPlayerSupportedCommands = [];
let currentPlayer; let currentTimeElement;
let currentPlayerSupportedCommands = []; let nowPlayingImageElement;
let nowPlayingImageUrl;
let nowPlayingTextElement;
let nowPlayingUserData;
let muteButton;
let volumeSlider;
let volumeSliderContainer;
let playPauseButtons;
let positionSlider;
let toggleRepeatButton;
let toggleRepeatButtonIcon;
let currentTimeElement; let lastUpdateTime = 0;
let nowPlayingImageElement; let lastPlayerState = {};
let nowPlayingImageUrl; let isEnabled;
let nowPlayingTextElement; let currentRuntimeTicks = 0;
let nowPlayingUserData;
let muteButton;
let volumeSlider;
let volumeSliderContainer;
let playPauseButtons;
let positionSlider;
let toggleRepeatButton;
let toggleRepeatButtonIcon;
let lastUpdateTime = 0; let isVisibilityAllowed = true;
let lastPlayerState = {};
let isEnabled;
let currentRuntimeTicks = 0;
let isVisibilityAllowed = true; function getNowPlayingBarHtml() {
function getNowPlayingBarHtml() {
let html = ''; let html = '';
html += '<div class="nowPlayingBar hide nowPlayingBar-hidden">'; html += '<div class="nowPlayingBar hide nowPlayingBar-hidden">';
@ -99,13 +97,13 @@ import { appRouter } from '../appRouter';
html += '</div>'; html += '</div>';
return html; return html;
} }
function onSlideDownComplete() { function onSlideDownComplete() {
this.classList.add('hide'); this.classList.add('hide');
} }
function slideDown(elem) { function slideDown(elem) {
// trigger reflow // trigger reflow
void elem.offsetWidth; void elem.offsetWidth;
@ -114,9 +112,9 @@ import { appRouter } from '../appRouter';
dom.addEventListener(elem, dom.whichTransitionEvent(), onSlideDownComplete, { dom.addEventListener(elem, dom.whichTransitionEvent(), onSlideDownComplete, {
once: true once: true
}); });
} }
function slideUp(elem) { function slideUp(elem) {
dom.removeEventListener(elem, dom.whichTransitionEvent(), onSlideDownComplete, { dom.removeEventListener(elem, dom.whichTransitionEvent(), onSlideDownComplete, {
once: true once: true
}); });
@ -127,13 +125,13 @@ import { appRouter } from '../appRouter';
void elem.offsetWidth; void elem.offsetWidth;
elem.classList.remove('nowPlayingBar-hidden'); elem.classList.remove('nowPlayingBar-hidden');
} }
function onPlayPauseClick() { function onPlayPauseClick() {
playbackManager.playPause(currentPlayer); playbackManager.playPause(currentPlayer);
} }
function bindEvents(elem) { function bindEvents(elem) {
currentTimeElement = elem.querySelector('.nowPlayingBarCurrentTime'); currentTimeElement = elem.querySelector('.nowPlayingBarCurrentTime');
nowPlayingImageElement = elem.querySelector('.nowPlayingImage'); nowPlayingImageElement = elem.querySelector('.nowPlayingImage');
nowPlayingTextElement = elem.querySelector('.nowPlayingBarText'); nowPlayingTextElement = elem.querySelector('.nowPlayingBarText');
@ -169,19 +167,23 @@ import { appRouter } from '../appRouter';
elem.querySelector('.previousTrackButton').addEventListener('click', function (e) { elem.querySelector('.previousTrackButton').addEventListener('click', function (e) {
if (currentPlayer) { if (currentPlayer) {
if (lastPlayerState.NowPlayingItem.MediaType === 'Audio' && (currentPlayer._currentTime >= 5 || !playbackManager.previousTrack(currentPlayer))) { if (lastPlayerState.NowPlayingItem.MediaType === 'Audio') {
// Cancel this event if doubleclick is fired // Cancel this event if doubleclick is fired. The actual previousTrack will be processed by the 'dblclick' event
if (e.detail > 1 && playbackManager.previousTrack(currentPlayer)) { if (e.detail > 1 ) {
return; return;
} }
// Return to start of track, unless we are already (almost) at the beginning. In the latter case, continue and move
// to the previous track, unless we are at the first track so no previous track exists.
if (currentPlayer._currentTime >= 5 || playbackManager.getCurrentPlaylistIndex(currentPlayer) <= 1) {
playbackManager.seekPercent(0, currentPlayer); playbackManager.seekPercent(0, currentPlayer);
// This is done automatically by playbackManager, however, setting this here gives instant visual feedback. // This is done automatically by playbackManager, however, setting this here gives instant visual feedback.
// TODO: Check why seekPercentage doesn't reflect the changes inmmediately, so we can remove this workaround. // TODO: Check why seekPercentage doesn't reflect the changes inmmediately, so we can remove this workaround.
positionSlider.value = 0; positionSlider.value = 0;
} else { return;
playbackManager.previousTrack(currentPlayer);
} }
} }
playbackManager.previousTrack(currentPlayer);
}
}); });
elem.querySelector('.previousTrackButton').addEventListener('dblclick', function () { elem.querySelector('.previousTrackButton').addEventListener('dblclick', function () {
@ -247,14 +249,14 @@ import { appRouter } from '../appRouter';
showRemoteControl(); showRemoteControl();
} }
}); });
} }
function showRemoteControl() { function showRemoteControl() {
appRouter.showNowPlaying(); appRouter.showNowPlaying();
} }
let nowPlayingBarElement; let nowPlayingBarElement;
function getNowPlayingBar() { function getNowPlayingBar() {
if (nowPlayingBarElement) { if (nowPlayingBarElement) {
return nowPlayingBarElement; return nowPlayingBarElement;
} }
@ -286,17 +288,17 @@ import { appRouter } from '../appRouter';
bindEvents(nowPlayingBarElement); bindEvents(nowPlayingBarElement);
return nowPlayingBarElement; return nowPlayingBarElement;
} }
function showButton(button) { function showButton(button) {
button.classList.remove('hide'); button.classList.remove('hide');
} }
function hideButton(button) { function hideButton(button) {
button.classList.add('hide'); button.classList.add('hide');
} }
function updatePlayPauseState(isPaused) { function updatePlayPauseState(isPaused) {
if (playPauseButtons) { if (playPauseButtons) {
playPauseButtons.forEach((button) => { playPauseButtons.forEach((button) => {
const icon = button.querySelector('.material-icons'); const icon = button.querySelector('.material-icons');
@ -304,9 +306,9 @@ import { appRouter } from '../appRouter';
icon.classList.add(isPaused ? 'play_arrow' : 'pause'); icon.classList.add(isPaused ? 'play_arrow' : 'pause');
}); });
} }
} }
function updatePlayerStateInternal(event, state, player) { function updatePlayerStateInternal(event, state, player) {
showNowPlayingBar(); showNowPlayingBar();
lastPlayerState = state; lastPlayerState = state;
@ -343,9 +345,9 @@ import { appRouter } from '../appRouter';
updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playbackManager.getBufferedRanges(player)); updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playbackManager.getBufferedRanges(player));
updateNowPlayingInfo(state); updateNowPlayingInfo(state);
} }
function updateRepeatModeDisplay(repeatMode) { function updateRepeatModeDisplay(repeatMode) {
toggleRepeatButtonIcon.classList.remove('repeat', 'repeat_one'); toggleRepeatButtonIcon.classList.remove('repeat', 'repeat_one');
const cssClass = 'buttonActive'; const cssClass = 'buttonActive';
@ -364,9 +366,9 @@ import { appRouter } from '../appRouter';
toggleRepeatButton.classList.remove(cssClass); toggleRepeatButton.classList.remove(cssClass);
break; break;
} }
} }
function updateTimeDisplay(positionTicks, runtimeTicks, bufferedRanges) { function updateTimeDisplay(positionTicks, runtimeTicks, bufferedRanges) {
// See bindEvents for why this is necessary // See bindEvents for why this is necessary
if (positionSlider && !positionSlider.dragging) { if (positionSlider && !positionSlider.dragging) {
if (runtimeTicks) { if (runtimeTicks) {
@ -391,9 +393,9 @@ import { appRouter } from '../appRouter';
currentTimeElement.innerHTML = timeText; currentTimeElement.innerHTML = timeText;
} }
} }
function updatePlayerVolumeState(isMuted, volumeLevel) { function updatePlayerVolumeState(isMuted, volumeLevel) {
const supportedCommands = currentPlayerSupportedCommands; const supportedCommands = currentPlayerSupportedCommands;
let showMuteButton = true; let showMuteButton = true;
@ -430,9 +432,9 @@ import { appRouter } from '../appRouter';
volumeSlider.value = volumeLevel || 0; volumeSlider.value = volumeLevel || 0;
} }
} }
} }
function seriesImageUrl(item, options) { function seriesImageUrl(item, options) {
if (!item) { if (!item) {
throw new Error('item cannot be null!'); throw new Error('item cannot be null!');
} }
@ -464,9 +466,9 @@ import { appRouter } from '../appRouter';
} }
return null; return null;
} }
function imageUrl(item, options) { function imageUrl(item, options) {
if (!item) { if (!item) {
throw new Error('item cannot be null!'); throw new Error('item cannot be null!');
} }
@ -485,9 +487,9 @@ import { appRouter } from '../appRouter';
} }
return null; return null;
} }
function updateNowPlayingInfo(state) { function updateNowPlayingInfo(state) {
const nowPlayingItem = state.NowPlayingItem; const nowPlayingItem = state.NowPlayingItem;
const textLines = nowPlayingItem ? nowPlayingHelper.getNowPlayingNames(nowPlayingItem) : []; const textLines = nowPlayingItem ? nowPlayingHelper.getNowPlayingNames(nowPlayingItem) : [];
@ -568,23 +570,23 @@ import { appRouter } from '../appRouter';
} else { } else {
nowPlayingUserData.innerHTML = ''; nowPlayingUserData.innerHTML = '';
} }
} }
function onPlaybackStart(e, state) { function onPlaybackStart(e, state) {
console.debug('nowplaying event: ' + e.type); console.debug('nowplaying event: ' + e.type);
const player = this; const player = this;
onStateChanged.call(player, e, state); onStateChanged.call(player, e, state);
} }
function onRepeatModeChange() { function onRepeatModeChange() {
if (!isEnabled) { if (!isEnabled) {
return; return;
} }
updateRepeatModeDisplay(playbackManager.getRepeatMode()); updateRepeatModeDisplay(playbackManager.getRepeatMode());
} }
function onQueueShuffleModeChange() { function onQueueShuffleModeChange() {
if (!isEnabled) { if (!isEnabled) {
return; return;
} }
@ -602,18 +604,18 @@ import { appRouter } from '../appRouter';
toggleShuffleButton.classList.remove(cssClass); toggleShuffleButton.classList.remove(cssClass);
break; break;
} }
} }
function showNowPlayingBar() { function showNowPlayingBar() {
if (!isVisibilityAllowed) { if (!isVisibilityAllowed) {
hideNowPlayingBar(); hideNowPlayingBar();
return; return;
} }
slideUp(getNowPlayingBar()); slideUp(getNowPlayingBar());
} }
function hideNowPlayingBar() { function hideNowPlayingBar() {
isEnabled = false; isEnabled = false;
// Use a timeout to prevent the bar from hiding and showing quickly // Use a timeout to prevent the bar from hiding and showing quickly
@ -624,9 +626,9 @@ import { appRouter } from '../appRouter';
if (elem) { if (elem) {
slideDown(elem); slideDown(elem);
} }
} }
function onPlaybackStopped(e, state) { function onPlaybackStopped(e, state) {
console.debug('nowplaying event: ' + e.type); console.debug('nowplaying event: ' + e.type);
const player = this; const player = this;
@ -639,18 +641,18 @@ import { appRouter } from '../appRouter';
hideNowPlayingBar(); hideNowPlayingBar();
} }
} }
} }
function onPlayPauseStateChanged() { function onPlayPauseStateChanged() {
if (!isEnabled) { if (!isEnabled) {
return; return;
} }
const player = this; const player = this;
updatePlayPauseState(player.paused()); updatePlayPauseState(player.paused());
} }
function onStateChanged(event, state) { function onStateChanged(event, state) {
if (event.type === 'init') { if (event.type === 'init') {
// skip non-ready state // skip non-ready state
return; return;
@ -678,9 +680,9 @@ import { appRouter } from '../appRouter';
getNowPlayingBar(); getNowPlayingBar();
updatePlayerStateInternal(event, state, player); updatePlayerStateInternal(event, state, player);
} }
function onTimeUpdate() { function onTimeUpdate() {
if (!isEnabled) { if (!isEnabled) {
return; return;
} }
@ -695,9 +697,9 @@ import { appRouter } from '../appRouter';
const player = this; const player = this;
currentRuntimeTicks = playbackManager.duration(player); currentRuntimeTicks = playbackManager.duration(player);
updateTimeDisplay(playbackManager.currentTime(player) * 10000, currentRuntimeTicks, playbackManager.getBufferedRanges(player)); updateTimeDisplay(playbackManager.currentTime(player) * 10000, currentRuntimeTicks, playbackManager.getBufferedRanges(player));
} }
function releaseCurrentPlayer() { function releaseCurrentPlayer() {
const player = currentPlayer; const player = currentPlayer;
if (player) { if (player) {
@ -714,9 +716,9 @@ import { appRouter } from '../appRouter';
currentPlayer = null; currentPlayer = null;
hideNowPlayingBar(); hideNowPlayingBar();
} }
} }
function onVolumeChanged() { function onVolumeChanged() {
if (!isEnabled) { if (!isEnabled) {
return; return;
} }
@ -724,15 +726,15 @@ import { appRouter } from '../appRouter';
const player = this; const player = this;
updatePlayerVolumeState(player.isMuted(), player.getVolume()); updatePlayerVolumeState(player.isMuted(), player.getVolume());
} }
function refreshFromPlayer(player, type) { function refreshFromPlayer(player, type) {
const state = playbackManager.getPlayerState(player); const state = playbackManager.getPlayerState(player);
onStateChanged.call(player, { type }, state); onStateChanged.call(player, { type }, state);
} }
function bindToPlayer(player) { function bindToPlayer(player) {
if (player === currentPlayer) { if (player === currentPlayer) {
return; return;
} }
@ -756,15 +758,15 @@ import { appRouter } from '../appRouter';
Events.on(player, 'pause', onPlayPauseStateChanged); Events.on(player, 'pause', onPlayPauseStateChanged);
Events.on(player, 'unpause', onPlayPauseStateChanged); Events.on(player, 'unpause', onPlayPauseStateChanged);
Events.on(player, 'timeupdate', onTimeUpdate); Events.on(player, 'timeupdate', onTimeUpdate);
} }
Events.on(playbackManager, 'playerchange', function () { Events.on(playbackManager, 'playerchange', function () {
bindToPlayer(playbackManager.getCurrentPlayer()); bindToPlayer(playbackManager.getCurrentPlayer());
}); });
bindToPlayer(playbackManager.getCurrentPlayer()); bindToPlayer(playbackManager.getCurrentPlayer());
document.addEventListener('viewbeforeshow', function (e) { document.addEventListener('viewbeforeshow', function (e) {
if (!e.detail.options.enableMediaControl) { if (!e.detail.options.enableMediaControl) {
if (isVisibilityAllowed) { if (isVisibilityAllowed) {
isVisibilityAllowed = false; isVisibilityAllowed = false;
@ -778,6 +780,5 @@ import { appRouter } from '../appRouter';
hideNowPlayingBar(); hideNowPlayingBar();
} }
} }
}); });
/* eslint-enable indent */

View file

@ -1,8 +1,7 @@
import appSettings from '../scripts/settings/appSettings'; import appSettings from '../scripts/settings/appSettings';
import { pluginManager } from './pluginManager'; import { pluginManager } from './pluginManager';
/* eslint-disable indent */
class PackageManager { class PackageManager {
#packagesList = []; #packagesList = [];
#settingsKey = 'installedpackages1'; #settingsKey = 'installedpackages1';
@ -133,8 +132,6 @@ import { pluginManager } from './pluginManager';
xhr.send(); xhr.send();
}); });
} }
} }
/* eslint-enable indent */
export default new PackageManager(); export default new PackageManager();

View file

@ -4,13 +4,11 @@ import Events from '../../utils/events.ts';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';
import shell from '../../scripts/shell'; import shell from '../../scripts/shell';
/* eslint-disable indent */ // Reports media playback to the device for lock screen control
// Reports media playback to the device for lock screen control let currentPlayer;
let currentPlayer; function seriesImageUrl(item, options = {}) {
function seriesImageUrl(item, options = {}) {
options.type = options.type || 'Primary'; options.type = options.type || 'Primary';
if (item.Type !== 'Episode') { if (item.Type !== 'Episode') {
@ -32,9 +30,9 @@ import shell from '../../scripts/shell';
} }
return null; return null;
} }
function imageUrl(item, options = {}) { function imageUrl(item, options = {}) {
options.type = options.type || 'Primary'; options.type = options.type || 'Primary';
if (item.ImageTags && item.ImageTags[options.type]) { if (item.ImageTags && item.ImageTags[options.type]) {
@ -48,9 +46,9 @@ import shell from '../../scripts/shell';
} }
return null; return null;
} }
function getImageUrl(item, imageOptions = {}) { function getImageUrl(item, imageOptions = {}) {
const url = seriesImageUrl(item, imageOptions) || imageUrl(item, imageOptions); const url = seriesImageUrl(item, imageOptions) || imageUrl(item, imageOptions);
if (url) { if (url) {
@ -63,22 +61,22 @@ import shell from '../../scripts/shell';
} else { } else {
return null; return null;
} }
} }
function getImageUrls(item, imageSizes = [96, 128, 192, 256, 384, 512]) { function getImageUrls(item, imageSizes = [96, 128, 192, 256, 384, 512]) {
const list = []; const list = [];
imageSizes.forEach((size) => { imageSizes.forEach((size) => {
const url = getImageUrl(item, {height: size}); const url = getImageUrl(item, { height: size });
if (url !== null) { if (url !== null) {
list.push(url); list.push(url);
} }
}); });
return list; return list;
} }
function updatePlayerState(player, state, eventName) { function updatePlayerState(player, state, eventName) {
// Don't go crazy reporting position changes // Don't go crazy reporting position changes
if (eventName === 'timeupdate') { if (eventName === 'timeupdate') {
// Only report if this item hasn't been reported yet, or if there's an actual playback change. // Only report if this item hasn't been reported yet, or if there's an actual playback change.
@ -144,27 +142,27 @@ import shell from '../../scripts/shell';
isPaused: isPaused isPaused: isPaused
}); });
} }
} }
function onGeneralEvent(e) { function onGeneralEvent(e) {
const state = playbackManager.getPlayerState(this); const state = playbackManager.getPlayerState(this);
updatePlayerState(this, state, e.type); updatePlayerState(this, state, e.type);
} }
function onStateChanged(e, state) { function onStateChanged(e, state) {
updatePlayerState(this, state, 'statechange'); updatePlayerState(this, state, 'statechange');
} }
function onPlaybackStart(e, state) { function onPlaybackStart(e, state) {
updatePlayerState(this, state, e.type); updatePlayerState(this, state, e.type);
} }
function onPlaybackStopped() { function onPlaybackStopped() {
hideMediaControls(); hideMediaControls();
} }
function releaseCurrentPlayer() { function releaseCurrentPlayer() {
if (currentPlayer) { if (currentPlayer) {
Events.off(currentPlayer, 'playbackstart', onPlaybackStart); Events.off(currentPlayer, 'playbackstart', onPlaybackStart);
Events.off(currentPlayer, 'playbackstop', onPlaybackStopped); Events.off(currentPlayer, 'playbackstop', onPlaybackStopped);
@ -177,18 +175,18 @@ import shell from '../../scripts/shell';
hideMediaControls(); hideMediaControls();
} }
} }
function hideMediaControls() { function hideMediaControls() {
if ('mediaSession' in navigator) { if ('mediaSession' in navigator) {
/* eslint-disable-next-line compat/compat */ /* eslint-disable-next-line compat/compat */
navigator.mediaSession.metadata = null; navigator.mediaSession.metadata = null;
} else { } else {
shell.hideMediaSession(); shell.hideMediaSession();
} }
} }
function bindToPlayer(player) { function bindToPlayer(player) {
releaseCurrentPlayer(); releaseCurrentPlayer();
if (!player) { if (!player) {
@ -206,13 +204,13 @@ import shell from '../../scripts/shell';
Events.on(currentPlayer, 'pause', onGeneralEvent); Events.on(currentPlayer, 'pause', onGeneralEvent);
Events.on(currentPlayer, 'statechange', onStateChanged); Events.on(currentPlayer, 'statechange', onStateChanged);
Events.on(currentPlayer, 'timeupdate', onGeneralEvent); Events.on(currentPlayer, 'timeupdate', onGeneralEvent);
} }
function execute(name) { function execute(name) {
playbackManager[name](currentPlayer); playbackManager[name](currentPlayer);
} }
if ('mediaSession' in navigator) { if ('mediaSession' in navigator) {
/* eslint-disable-next-line compat/compat */ /* eslint-disable-next-line compat/compat */
navigator.mediaSession.setActionHandler('previoustrack', function () { navigator.mediaSession.setActionHandler('previoustrack', function () {
execute('previousTrack'); execute('previousTrack');
@ -251,12 +249,11 @@ import shell from '../../scripts/shell';
const wantedTime = object.seekTime * 1000; const wantedTime = object.seekTime * 1000;
playbackManager.seekPercent(wantedTime / duration * 100, currentPlayer); playbackManager.seekPercent(wantedTime / duration * 100, currentPlayer);
}); });
} }
Events.on(playbackManager, 'playerchange', function () { Events.on(playbackManager, 'playerchange', function () {
bindToPlayer(playbackManager.getCurrentPlayer()); bindToPlayer(playbackManager.getCurrentPlayer());
}); });
bindToPlayer(playbackManager.getCurrentPlayer()); bindToPlayer(playbackManager.getCurrentPlayer());
/* eslint-enable indent */

View file

@ -13,6 +13,7 @@ import ServerConnections from '../ServerConnections';
import alert from '../alert'; import alert from '../alert';
import { PluginType } from '../../types/plugin.ts'; import { PluginType } from '../../types/plugin.ts';
import { includesAny } from '../../utils/container.ts'; import { includesAny } from '../../utils/container.ts';
import { getItems } from '../../utils/jellyfin-apiclient/getItems.ts';
const UNLIMITED_ITEMS = -1; const UNLIMITED_ITEMS = -1;
@ -127,7 +128,7 @@ function getItemsForPlayback(serverId, query) {
query.EnableTotalRecordCount = false; query.EnableTotalRecordCount = false;
query.CollapseBoxSetItems = false; query.CollapseBoxSetItems = false;
return apiClient.getItems(apiClient.getCurrentUserId(), query); return getItems(apiClient, apiClient.getCurrentUserId(), query);
} }
} }
@ -1038,7 +1039,6 @@ class PlaybackManager {
} }
} }
//var mediaType = item.MediaType;
return getPlayer(item, getDefaultPlayOptions()) != null; return getPlayer(item, getDefaultPlayOptions()) != null;
}; };

View file

@ -12,9 +12,7 @@ import ServerConnections from '../ServerConnections';
import toast from '../toast/toast'; import toast from '../toast/toast';
import template from './playbackSettings.template.html'; import template from './playbackSettings.template.html';
/* eslint-disable indent */ function fillSkipLengths(select) {
function fillSkipLengths(select) {
const options = [5, 10, 15, 20, 25, 30]; const options = [5, 10, 15, 20, 25, 30];
select.innerHTML = options.map(option => { select.innerHTML = options.map(option => {
@ -25,9 +23,9 @@ import template from './playbackSettings.template.html';
}).map(o => { }).map(o => {
return `<option value="${o.value}">${o.name}</option>`; return `<option value="${o.value}">${o.name}</option>`;
}).join(''); }).join('');
} }
function populateLanguages(select, languages) { function populateLanguages(select, languages) {
let html = ''; let html = '';
html += `<option value=''>${globalize.translate('AnyLanguage')}</option>`; html += `<option value=''>${globalize.translate('AnyLanguage')}</option>`;
@ -39,9 +37,9 @@ import template from './playbackSettings.template.html';
} }
select.innerHTML = html; select.innerHTML = html;
} }
function fillQuality(select, isInNetwork, mediatype, maxVideoWidth) { function fillQuality(select, isInNetwork, mediatype, maxVideoWidth) {
const options = mediatype === 'Audio' ? qualityoptions.getAudioQualityOptions({ const options = mediatype === 'Audio' ? qualityoptions.getAudioQualityOptions({
currentMaxBitrate: appSettings.maxStreamingBitrate(isInNetwork, mediatype), currentMaxBitrate: appSettings.maxStreamingBitrate(isInNetwork, mediatype),
@ -61,9 +59,9 @@ import template from './playbackSettings.template.html';
// render empty string instead of 0 for the auto option // render empty string instead of 0 for the auto option
return `<option value="${i.bitrate || ''}">${i.name}</option>`; return `<option value="${i.bitrate || ''}">${i.name}</option>`;
}).join(''); }).join('');
} }
function setMaxBitrateIntoField(select, isInNetwork, mediatype) { function setMaxBitrateIntoField(select, isInNetwork, mediatype) {
fillQuality(select, isInNetwork, mediatype); fillQuality(select, isInNetwork, mediatype);
if (appSettings.enableAutomaticBitrateDetection(isInNetwork, mediatype)) { if (appSettings.enableAutomaticBitrateDetection(isInNetwork, mediatype)) {
@ -71,9 +69,9 @@ import template from './playbackSettings.template.html';
} else { } else {
select.value = appSettings.maxStreamingBitrate(isInNetwork, mediatype); select.value = appSettings.maxStreamingBitrate(isInNetwork, mediatype);
} }
} }
function fillChromecastQuality(select, maxVideoWidth) { function fillChromecastQuality(select, maxVideoWidth) {
const options = qualityoptions.getVideoQualityOptions({ const options = qualityoptions.getVideoQualityOptions({
currentMaxBitrate: appSettings.maxChromecastBitrate(), currentMaxBitrate: appSettings.maxChromecastBitrate(),
@ -88,18 +86,18 @@ import template from './playbackSettings.template.html';
}).join(''); }).join('');
select.value = appSettings.maxChromecastBitrate() || ''; select.value = appSettings.maxChromecastBitrate() || '';
} }
function setMaxBitrateFromField(select, isInNetwork, mediatype) { function setMaxBitrateFromField(select, isInNetwork, mediatype) {
if (select.value) { if (select.value) {
appSettings.maxStreamingBitrate(isInNetwork, mediatype, select.value); appSettings.maxStreamingBitrate(isInNetwork, mediatype, select.value);
appSettings.enableAutomaticBitrateDetection(isInNetwork, mediatype, false); appSettings.enableAutomaticBitrateDetection(isInNetwork, mediatype, false);
} else { } else {
appSettings.enableAutomaticBitrateDetection(isInNetwork, mediatype, true); appSettings.enableAutomaticBitrateDetection(isInNetwork, mediatype, true);
} }
} }
function showHideQualityFields(context, user, apiClient) { function showHideQualityFields(context, user, apiClient) {
if (user.Policy.EnableVideoPlaybackTranscoding) { if (user.Policy.EnableVideoPlaybackTranscoding) {
context.querySelector('.videoQualitySection').classList.remove('hide'); context.querySelector('.videoQualitySection').classList.remove('hide');
} else { } else {
@ -137,18 +135,18 @@ import template from './playbackSettings.template.html';
} }
} }
}); });
} }
function showOrHideEpisodesField(context) { function showOrHideEpisodesField(context) {
if (browser.tizen || browser.web0s) { if (browser.tizen || browser.web0s) {
context.querySelector('.fldEpisodeAutoPlay').classList.add('hide'); context.querySelector('.fldEpisodeAutoPlay').classList.add('hide');
return; return;
} }
context.querySelector('.fldEpisodeAutoPlay').classList.remove('hide'); context.querySelector('.fldEpisodeAutoPlay').classList.remove('hide');
} }
function loadForm(context, user, userSettings, apiClient) { function loadForm(context, user, userSettings, apiClient) {
const loggedInUserId = apiClient.getCurrentUserId(); const loggedInUserId = apiClient.getCurrentUserId();
const userId = user.Id; const userId = user.Id;
@ -214,9 +212,9 @@ import template from './playbackSettings.template.html';
showOrHideEpisodesField(context); showOrHideEpisodesField(context);
loading.hide(); loading.hide();
} }
function saveUser(context, user, userSettingsInstance, apiClient) { function saveUser(context, user, userSettingsInstance, apiClient) {
appSettings.enableSystemExternalPlayers(context.querySelector('.chkExternalVideoPlayer').checked); appSettings.enableSystemExternalPlayers(context.querySelector('.chkExternalVideoPlayer').checked);
appSettings.maxChromecastBitrate(context.querySelector('.selectChromecastVideoQuality').value); appSettings.maxChromecastBitrate(context.querySelector('.selectChromecastVideoQuality').value);
@ -241,9 +239,9 @@ import template from './playbackSettings.template.html';
userSettingsInstance.skipBackLength(context.querySelector('.selectSkipBackLength').value); userSettingsInstance.skipBackLength(context.querySelector('.selectSkipBackLength').value);
return apiClient.updateUserConfiguration(user.Id, user.Configuration); return apiClient.updateUserConfiguration(user.Id, user.Configuration);
} }
function save(instance, context, userId, userSettings, apiClient, enableSaveConfirmation) { function save(instance, context, userId, userSettings, apiClient, enableSaveConfirmation) {
loading.show(); loading.show();
apiClient.getUser(userId).then(user => { apiClient.getUser(userId).then(user => {
@ -258,17 +256,17 @@ import template from './playbackSettings.template.html';
loading.hide(); loading.hide();
}); });
}); });
} }
function setSelectValue(select, value, defaultValue) { function setSelectValue(select, value, defaultValue) {
select.value = value; select.value = value;
if (select.selectedIndex < 0) { if (select.selectedIndex < 0) {
select.value = defaultValue; select.value = defaultValue;
} }
} }
function onMaxVideoWidthChange(e) { function onMaxVideoWidthChange(e) {
const context = this.options.element; const context = this.options.element;
const selectVideoInNetworkQuality = context.querySelector('.selectVideoInNetworkQuality'); const selectVideoInNetworkQuality = context.querySelector('.selectVideoInNetworkQuality');
@ -288,9 +286,9 @@ import template from './playbackSettings.template.html';
setSelectValue(selectVideoInNetworkQuality, selectVideoInNetworkQualityValue, ''); setSelectValue(selectVideoInNetworkQuality, selectVideoInNetworkQualityValue, '');
setSelectValue(selectVideoInternetQuality, selectVideoInternetQualityValue, ''); setSelectValue(selectVideoInternetQuality, selectVideoInternetQualityValue, '');
setSelectValue(selectChromecastVideoQuality, selectChromecastVideoQualityValue, ''); setSelectValue(selectChromecastVideoQuality, selectChromecastVideoQualityValue, '');
} }
function onSubmit(e) { function onSubmit(e) {
const self = this; const self = this;
const apiClient = ServerConnections.getApiClient(self.options.serverId); const apiClient = ServerConnections.getApiClient(self.options.serverId);
const userId = self.options.userId; const userId = self.options.userId;
@ -306,9 +304,9 @@ import template from './playbackSettings.template.html';
e.preventDefault(); e.preventDefault();
} }
return false; return false;
} }
function embed(options, self) { function embed(options, self) {
options.element.innerHTML = globalize.translateHtml(template, 'core'); options.element.innerHTML = globalize.translateHtml(template, 'core');
options.element.querySelector('form').addEventListener('submit', onSubmit.bind(self)); options.element.querySelector('form').addEventListener('submit', onSubmit.bind(self));
@ -324,9 +322,9 @@ import template from './playbackSettings.template.html';
if (options.autoFocus) { if (options.autoFocus) {
focusManager.autoFocus(options.element); focusManager.autoFocus(options.element);
} }
} }
class PlaybackSettings { class PlaybackSettings {
constructor(options) { constructor(options) {
this.options = options; this.options = options;
embed(options, this); embed(options, this);
@ -358,7 +356,6 @@ import template from './playbackSettings.template.html';
destroy() { destroy() {
this.options = null; this.options = null;
} }
} }
/* eslint-enable indent */
export default PlaybackSettings; export default PlaybackSettings;

View file

@ -4,13 +4,12 @@ import Events from '../../utils/events.ts';
import layoutManager from '../layoutManager'; import layoutManager from '../layoutManager';
import { playbackManager } from '../playback/playbackmanager'; import { playbackManager } from '../playback/playbackmanager';
import playMethodHelper from '../playback/playmethodhelper'; import playMethodHelper from '../playback/playmethodhelper';
import SyncPlay from '../../plugins/syncPlay/core'; import { pluginManager } from '../pluginManager';
import { PluginType } from '../../types/plugin.ts';
import './playerstats.scss'; import './playerstats.scss';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';
/* eslint-disable indent */ function init(instance) {
function init(instance) {
const parent = document.createElement('div'); const parent = document.createElement('div');
parent.classList.add('playerStats'); parent.classList.add('playerStats');
@ -42,13 +41,13 @@ import ServerConnections from '../ServerConnections';
document.body.appendChild(parent); document.body.appendChild(parent);
instance.element = parent; instance.element = parent;
} }
function onCloseButtonClick() { function onCloseButtonClick() {
this.enabled(false); this.enabled(false);
} }
function renderStats(elem, categories) { function renderStats(elem, categories) {
elem.querySelector('.playerStats-stats').innerHTML = categories.map(function (category) { elem.querySelector('.playerStats-stats').innerHTML = categories.map(function (category) {
let categoryHtml = ''; let categoryHtml = '';
@ -86,9 +85,9 @@ import ServerConnections from '../ServerConnections';
return categoryHtml; return categoryHtml;
}).join(''); }).join('');
} }
function getSession(instance, player) { function getSession(instance, player) {
const now = new Date().getTime(); const now = new Date().getTime();
if ((now - (instance.lastSessionTime || 0)) < 10000) { if ((now - (instance.lastSessionTime || 0)) < 10000) {
@ -107,13 +106,13 @@ import ServerConnections from '../ServerConnections';
}, function () { }, function () {
return Promise.resolve({}); return Promise.resolve({});
}); });
} }
function translateReason(reason) { function translateReason(reason) {
return globalize.translate('' + reason); return globalize.translate('' + reason);
} }
function getTranscodingStats(session, player, displayPlayMethod) { function getTranscodingStats(session, player, displayPlayMethod) {
const sessionStats = []; const sessionStats = [];
let videoCodec; let videoCodec;
@ -182,17 +181,17 @@ import ServerConnections from '../ServerConnections';
} }
return sessionStats; return sessionStats;
} }
function getDisplayBitrate(bitrate) { function getDisplayBitrate(bitrate) {
if (bitrate > 1000000) { if (bitrate > 1000000) {
return (bitrate / 1000000).toFixed(1) + ' Mbps'; return (bitrate / 1000000).toFixed(1) + ' Mbps';
} else { } else {
return Math.floor(bitrate / 1000) + ' kbps'; return Math.floor(bitrate / 1000) + ' kbps';
} }
} }
function getReadableSize(size) { function getReadableSize(size) {
if (size >= 1073741824) { if (size >= 1073741824) {
return parseFloat((size / 1073741824).toFixed(1)) + ' GiB'; return parseFloat((size / 1073741824).toFixed(1)) + ' GiB';
} else if (size >= 1048576) { } else if (size >= 1048576) {
@ -200,9 +199,9 @@ import ServerConnections from '../ServerConnections';
} else { } else {
return Math.floor(size / 1024) + ' KiB'; return Math.floor(size / 1024) + ' KiB';
} }
} }
function getMediaSourceStats(session, player) { function getMediaSourceStats(session, player) {
const sessionStats = []; const sessionStats = [];
const mediaSource = playbackManager.currentMediaSource(player) || {}; const mediaSource = playbackManager.currentMediaSource(player) || {};
@ -322,9 +321,15 @@ import ServerConnections from '../ServerConnections';
} }
return sessionStats; return sessionStats;
}
function getSyncPlayStats() {
const SyncPlay = pluginManager.firstOfType(PluginType.SyncPlay)?.instance;
if (!SyncPlay?.Manager.isSyncPlayEnabled()) {
return [];
} }
function getSyncPlayStats() {
const syncStats = []; const syncStats = [];
const stats = SyncPlay.Manager.getStats(); const stats = SyncPlay.Manager.getStats();
@ -350,9 +355,9 @@ import ServerConnections from '../ServerConnections';
}); });
return syncStats; return syncStats;
} }
function getStats(instance, player) { function getStats(instance, player) {
const statsPromise = player.getStats ? player.getStats() : Promise.resolve({}); const statsPromise = player.getStats ? player.getStats() : Promise.resolve({});
const sessionPromise = getSession(instance, player); const sessionPromise = getSession(instance, player);
@ -422,19 +427,19 @@ import ServerConnections from '../ServerConnections';
name: globalize.translate('LabelOriginalMediaInfo') name: globalize.translate('LabelOriginalMediaInfo')
}); });
const apiClient = ServerConnections.getApiClient(playbackManager.currentItem(player).ServerId); const syncPlayStats = getSyncPlayStats();
if (SyncPlay.Manager.isSyncPlayEnabled() && apiClient.isMinServerVersion('10.6.0')) { if (syncPlayStats.length > 0) {
categories.push({ categories.push({
stats: getSyncPlayStats(), stats: syncPlayStats,
name: globalize.translate('LabelSyncPlayInfo') name: globalize.translate('LabelSyncPlayInfo')
}); });
} }
return Promise.resolve(categories); return Promise.resolve(categories);
}); });
} }
function renderPlayerStats(instance, player) { function renderPlayerStats(instance, player) {
const now = new Date().getTime(); const now = new Date().getTime();
if ((now - (instance.lastRender || 0)) < 700) { if ((now - (instance.lastRender || 0)) < 700) {
@ -451,24 +456,24 @@ import ServerConnections from '../ServerConnections';
renderStats(elem, stats); renderStats(elem, stats);
}); });
} }
function bindEvents(instance, player) { function bindEvents(instance, player) {
const localOnTimeUpdate = function () { const localOnTimeUpdate = function () {
renderPlayerStats(instance, player); renderPlayerStats(instance, player);
}; };
instance.onTimeUpdate = localOnTimeUpdate; instance.onTimeUpdate = localOnTimeUpdate;
Events.on(player, 'timeupdate', localOnTimeUpdate); Events.on(player, 'timeupdate', localOnTimeUpdate);
} }
function unbindEvents(instance, player) { function unbindEvents(instance, player) {
const localOnTimeUpdate = instance.onTimeUpdate; const localOnTimeUpdate = instance.onTimeUpdate;
if (localOnTimeUpdate) { if (localOnTimeUpdate) {
Events.off(player, 'timeupdate', localOnTimeUpdate); Events.off(player, 'timeupdate', localOnTimeUpdate);
} }
} }
class PlayerStats { class PlayerStats {
constructor(options) { constructor(options) {
@ -520,6 +525,4 @@ class PlayerStats {
} }
} }
/* eslint-enable indent */
export default PlayerStats; export default PlayerStats;

View file

@ -4,10 +4,12 @@ import dialogHelper from '../dialogHelper/dialogHelper';
import loading from '../loading/loading'; import loading from '../loading/loading';
import layoutManager from '../layoutManager'; import layoutManager from '../layoutManager';
import { playbackManager } from '../playback/playbackmanager'; import { playbackManager } from '../playback/playbackmanager';
import SyncPlay from '../../plugins/syncPlay/core'; import { pluginManager } from '../pluginManager';
import * as userSettings from '../../scripts/settings/userSettings'; import * as userSettings from '../../scripts/settings/userSettings';
import { appRouter } from '../appRouter'; import { appRouter } from '../appRouter';
import globalize from '../../scripts/globalize'; import globalize from '../../scripts/globalize';
import { PluginType } from '../../types/plugin.ts';
import '../../elements/emby-button/emby-button'; import '../../elements/emby-button/emby-button';
import '../../elements/emby-input/emby-input'; import '../../elements/emby-input/emby-input';
import '../../elements/emby-button/paper-icon-button-light'; import '../../elements/emby-button/paper-icon-button-light';
@ -16,11 +18,9 @@ import 'material-design-icons-iconfont';
import '../formdialog.scss'; import '../formdialog.scss';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';
/* eslint-disable indent */ let currentServerId;
let currentServerId; function onSubmit(e) {
function onSubmit(e) {
const panel = dom.parentWithClass(this, 'dialog'); const panel = dom.parentWithClass(this, 'dialog');
const playlistId = panel.querySelector('#selectPlaylistToAddTo').value; const playlistId = panel.querySelector('#selectPlaylistToAddTo').value;
@ -35,9 +35,9 @@ import ServerConnections from '../ServerConnections';
e.preventDefault(); e.preventDefault();
return false; return false;
} }
function createPlaylist(apiClient, dlg) { function createPlaylist(apiClient, dlg) {
loading.show(); loading.show();
const url = apiClient.getUrl('Playlists', { const url = apiClient.getUrl('Playlists', {
@ -60,13 +60,13 @@ import ServerConnections from '../ServerConnections';
dialogHelper.close(dlg); dialogHelper.close(dlg);
redirectToPlaylist(apiClient, id); redirectToPlaylist(apiClient, id);
}); });
} }
function redirectToPlaylist(apiClient, id) { function redirectToPlaylist(apiClient, id) {
appRouter.showItem(id, apiClient.serverId()); appRouter.showItem(id, apiClient.serverId());
} }
function addToPlaylist(apiClient, dlg, id) { function addToPlaylist(apiClient, dlg, id) {
const itemIds = dlg.querySelector('.fldSelectedItemIds').value || ''; const itemIds = dlg.querySelector('.fldSelectedItemIds').value || '';
if (id === 'queue') { if (id === 'queue') {
@ -96,13 +96,13 @@ import ServerConnections from '../ServerConnections';
dlg.submitted = true; dlg.submitted = true;
dialogHelper.close(dlg); dialogHelper.close(dlg);
}); });
} }
function triggerChange(select) { function triggerChange(select) {
select.dispatchEvent(new CustomEvent('change', {})); select.dispatchEvent(new CustomEvent('change', {}));
} }
function populatePlaylists(editorOptions, panel) { function populatePlaylists(editorOptions, panel) {
const select = panel.querySelector('#selectPlaylistToAddTo'); const select = panel.querySelector('#selectPlaylistToAddTo');
loading.hide(); loading.hide();
@ -117,10 +117,12 @@ import ServerConnections from '../ServerConnections';
}; };
const apiClient = ServerConnections.getApiClient(currentServerId); const apiClient = ServerConnections.getApiClient(currentServerId);
const SyncPlay = pluginManager.firstOfType(PluginType.SyncPlay)?.instance;
apiClient.getItems(apiClient.getCurrentUserId(), options).then(result => { apiClient.getItems(apiClient.getCurrentUserId(), options).then(result => {
let html = ''; let html = '';
if ((editorOptions.enableAddToPlayQueue !== false && playbackManager.isPlaying()) || SyncPlay.Manager.isSyncPlayEnabled()) { if ((editorOptions.enableAddToPlayQueue !== false && playbackManager.isPlaying()) || SyncPlay?.Manager.isSyncPlayEnabled()) {
html += `<option value="queue">${globalize.translate('AddToPlayQueue')}</option>`; html += `<option value="queue">${globalize.translate('AddToPlayQueue')}</option>`;
} }
@ -147,9 +149,9 @@ import ServerConnections from '../ServerConnections';
loading.hide(); loading.hide();
}); });
} }
function getEditorHtml(items) { function getEditorHtml(items) {
let html = ''; let html = '';
html += '<div class="formDialogContent smoothScrollY" style="padding-top:2em;">'; html += '<div class="formDialogContent smoothScrollY" style="padding-top:2em;">';
@ -182,9 +184,9 @@ import ServerConnections from '../ServerConnections';
html += '</div>'; html += '</div>';
return html; return html;
} }
function initEditor(content, options, items) { function initEditor(content, options, items) {
content.querySelector('#selectPlaylistToAddTo').addEventListener('change', function () { content.querySelector('#selectPlaylistToAddTo').addEventListener('change', function () {
if (this.value) { if (this.value) {
content.querySelector('.newPlaylistInfo').classList.add('hide'); content.querySelector('.newPlaylistInfo').classList.add('hide');
@ -210,16 +212,16 @@ import ServerConnections from '../ServerConnections';
selectPlaylistToAddTo.value = ''; selectPlaylistToAddTo.value = '';
triggerChange(selectPlaylistToAddTo); triggerChange(selectPlaylistToAddTo);
} }
} }
function centerFocus(elem, horiz, on) { function centerFocus(elem, horiz, on) {
import('../../scripts/scrollHelper').then((scrollHelper) => { import('../../scripts/scrollHelper').then((scrollHelper) => {
const fn = on ? 'on' : 'off'; const fn = on ? 'on' : 'off';
scrollHelper.centerFocus[fn](elem, horiz); scrollHelper.centerFocus[fn](elem, horiz);
}); });
} }
export class showEditor { export class showEditor {
constructor(options) { constructor(options) {
const items = options.items || {}; const items = options.items || {};
currentServerId = options.serverId; currentServerId = options.serverId;
@ -276,7 +278,6 @@ import ServerConnections from '../ServerConnections';
return Promise.reject(); return Promise.reject();
}); });
} }
} }
/* eslint-enable indent */
export default showEditor; export default showEditor;

View file

@ -119,9 +119,14 @@ class PluginManager {
} }
ofType(type) { ofType(type) {
return this.pluginsList.filter((o) => { return this.pluginsList.filter(plugin => plugin.type === type);
return o.type === type; }
});
firstOfType(type) {
// Get all plugins of the specified type
return this.ofType(type)
// Return the plugin with the "highest" (lowest numeric value) priority
.sort((p1, p2) => (p1.priority || 0) - (p2.priority || 0))[0];
} }
#mapRoute(plugin, route) { #mapRoute(plugin, route) {

View file

@ -141,7 +141,7 @@ function onManageRecordingClick() {
} }
const self = this; const self = this;
import('./recordingeditor').then(({default: recordingEditor}) => { import('./recordingeditor').then(({ default: recordingEditor }) => {
recordingEditor.show(self.TimerId, options.serverId, { recordingEditor.show(self.TimerId, options.serverId, {
enableCancel: false enableCancel: false
}).then(function () { }).then(function () {
@ -159,7 +159,7 @@ function onManageSeriesRecordingClick() {
const self = this; const self = this;
import('./seriesrecordingeditor').then(({default: seriesRecordingEditor}) => { import('./seriesrecordingeditor').then(({ default: seriesRecordingEditor }) => {
seriesRecordingEditor.show(self.SeriesTimerId, options.serverId, { seriesRecordingEditor.show(self.SeriesTimerId, options.serverId, {
enableCancel: false enableCancel: false

View file

@ -325,10 +325,11 @@ export default function () {
if (layoutManager.mobile) { if (layoutManager.mobile) {
const playingVideo = playbackManager.isPlayingVideo() && item !== null; const playingVideo = playbackManager.isPlayingVideo() && item !== null;
const playingAudio = !playbackManager.isPlayingVideo() && item !== null; const playingAudio = !playbackManager.isPlayingVideo() && item !== null;
buttonVisible(context.querySelector('.btnRepeat'), playingAudio); const playingAudioBook = playingAudio && item.Type == 'AudioBook';
buttonVisible(context.querySelector('.btnShuffleQueue'), playingAudio); buttonVisible(context.querySelector('.btnRepeat'), playingAudio && !playingAudioBook);
buttonVisible(context.querySelector('.btnRewind'), playingVideo); buttonVisible(context.querySelector('.btnShuffleQueue'), playingAudio && !playingAudioBook);
buttonVisible(context.querySelector('.btnFastForward'), playingVideo); buttonVisible(context.querySelector('.btnRewind'), playingVideo || playingAudioBook);
buttonVisible(context.querySelector('.btnFastForward'), playingVideo || playingAudioBook);
buttonVisible(context.querySelector('.nowPlayingSecondaryButtons .btnShuffleQueue'), playingVideo); buttonVisible(context.querySelector('.nowPlayingSecondaryButtons .btnShuffleQueue'), playingVideo);
buttonVisible(context.querySelector('.nowPlayingSecondaryButtons .btnRepeat'), playingVideo); buttonVisible(context.querySelector('.nowPlayingSecondaryButtons .btnRepeat'), playingVideo);
} else { } else {
@ -763,19 +764,23 @@ export default function () {
context.querySelector('.btnPreviousTrack').addEventListener('click', function (e) { context.querySelector('.btnPreviousTrack').addEventListener('click', function (e) {
if (currentPlayer) { if (currentPlayer) {
if (lastPlayerState.NowPlayingItem.MediaType === 'Audio' && (currentPlayer._currentTime >= 5 || !playbackManager.previousTrack(currentPlayer))) { if (lastPlayerState.NowPlayingItem.MediaType === 'Audio') {
// Cancel this event if doubleclick is fired // Cancel this event if doubleclick is fired. The actual previousTrack will be processed by the 'dblclick' event
if (e.detail > 1 && playbackManager.previousTrack(currentPlayer)) { if (e.detail > 1 ) {
return; return;
} }
// Return to start of track, unless we are already (almost) at the beginning. In the latter case, continue and move
// to the previous track, unless we are at the first track so no previous track exists.
if (currentPlayer._currentTime >= 5 || playbackManager.getCurrentPlaylistIndex(currentPlayer) <= 1) {
playbackManager.seekPercent(0, currentPlayer); playbackManager.seekPercent(0, currentPlayer);
// This is done automatically by playbackManager. However, setting this here gives instant visual feedback. // This is done automatically by playbackManager, however, setting this here gives instant visual feedback.
// TODO: Check why seekPercentage doesn't reflect the changes inmmediately, so we can remove this workaround. // TODO: Check why seekPercentage doesn't reflect the changes inmmediately, so we can remove this workaround.
positionSlider.value = 0; positionSlider.value = 0;
} else { return;
playbackManager.previousTrack(currentPlayer);
} }
} }
playbackManager.previousTrack(currentPlayer);
}
}); });
context.querySelector('.btnPreviousTrack').addEventListener('dblclick', function () { context.querySelector('.btnPreviousTrack').addEventListener('dblclick', function () {

View file

@ -1,5 +1,3 @@
/* eslint-disable indent */
/** /**
* Module for controlling scroll behavior. * Module for controlling scroll behavior.
* @module components/scrollManager * @module components/scrollManager
@ -9,35 +7,35 @@ import dom from '../scripts/dom';
import browser from '../scripts/browser'; import browser from '../scripts/browser';
import layoutManager from './layoutManager'; import layoutManager from './layoutManager';
/** /**
* Scroll time in ms. * Scroll time in ms.
*/ */
const ScrollTime = 270; const ScrollTime = 270;
/** /**
* Epsilon for comparing values. * Epsilon for comparing values.
*/ */
const Epsilon = 1e-6; const Epsilon = 1e-6;
// FIXME: Need to scroll to top of page to fully show the top menu. This can be solved by some marker of top most elements or their containers // FIXME: Need to scroll to top of page to fully show the top menu. This can be solved by some marker of top most elements or their containers
/** /**
* Returns minimum vertical scroll. * Returns minimum vertical scroll.
* Scroll less than that value will be zeroed. * Scroll less than that value will be zeroed.
* *
* @return {number} Minimum vertical scroll. * @return {number} Minimum vertical scroll.
*/ */
function minimumScrollY() { function minimumScrollY() {
const topMenu = document.querySelector('.headerTop'); const topMenu = document.querySelector('.headerTop');
if (topMenu) { if (topMenu) {
return topMenu.clientHeight; return topMenu.clientHeight;
} }
return 0; return 0;
} }
const supportsSmoothScroll = 'scrollBehavior' in document.documentElement.style; const supportsSmoothScroll = 'scrollBehavior' in document.documentElement.style;
let supportsScrollToOptions = false; let supportsScrollToOptions = false;
try { try {
const elem = document.createElement('div'); const elem = document.createElement('div');
const opts = Object.defineProperty({}, 'behavior', { const opts = Object.defineProperty({}, 'behavior', {
@ -48,11 +46,11 @@ import layoutManager from './layoutManager';
}); });
elem.scrollTo(opts); elem.scrollTo(opts);
} catch (e) { } catch (e) {
console.error('error checking ScrollToOptions support'); console.error('error checking ScrollToOptions support');
} }
/** /**
* Returns value clamped by range [min, max]. * Returns value clamped by range [min, max].
* *
* @param {number} value - Clamped value. * @param {number} value - Clamped value.
@ -60,16 +58,16 @@ import layoutManager from './layoutManager';
* @param {number} max - Ending of range. * @param {number} max - Ending of range.
* @return {number} Clamped value. * @return {number} Clamped value.
*/ */
function clamp(value, min, max) { function clamp(value, min, max) {
if (value <= min) { if (value <= min) {
return min; return min;
} else if (value >= max) { } else if (value >= max) {
return max; return max;
} }
return value; return value;
} }
/** /**
* Returns the required delta to fit range 1 into range 2. * Returns the required delta to fit range 1 into range 2.
* In case of range 1 is bigger than range 2 returns delta to fit most out of range part. * In case of range 1 is bigger than range 2 returns delta to fit most out of range part.
* *
@ -79,7 +77,7 @@ import layoutManager from './layoutManager';
* @param {number} end2 - Ending of range 2. * @param {number} end2 - Ending of range 2.
* @return {number} Delta: <0 move range1 to the left, >0 - to the right. * @return {number} Delta: <0 move range1 to the left, >0 - to the right.
*/ */
function fitRange(begin1, end1, begin2, end2) { function fitRange(begin1, end1, begin2, end2) {
const delta1 = begin1 - begin2; const delta1 = begin1 - begin2;
const delta2 = end2 - end1; const delta2 = end2 - end1;
if (delta1 < 0 && delta1 < delta2) { if (delta1 < 0 && delta1 < delta2) {
@ -88,19 +86,19 @@ import layoutManager from './layoutManager';
return delta2; return delta2;
} }
return 0; return 0;
} }
/** /**
* Ease value. * Ease value.
* *
* @param {number} t - Value in range [0, 1]. * @param {number} t - Value in range [0, 1].
* @return {number} Eased value in range [0, 1]. * @return {number} Eased value in range [0, 1].
*/ */
function ease(t) { function ease(t) {
return t * (2 - t); // easeOutQuad === ease-out return t * (2 - t); // easeOutQuad === ease-out
} }
/** /**
* @typedef {Object} Rect * @typedef {Object} Rect
* @property {number} left - X coordinate of top-left corner. * @property {number} left - X coordinate of top-left corner.
* @property {number} top - Y coordinate of top-left corner. * @property {number} top - Y coordinate of top-left corner.
@ -108,7 +106,7 @@ import layoutManager from './layoutManager';
* @property {number} height - Height. * @property {number} height - Height.
*/ */
/** /**
* Document scroll wrapper helps to unify scrolling and fix issues of some browsers. * Document scroll wrapper helps to unify scrolling and fix issues of some browsers.
* *
* webOS 2 Browser: scrolls documentElement (and window), but body has a scroll size * webOS 2 Browser: scrolls documentElement (and window), but body has a scroll size
@ -121,7 +119,7 @@ import layoutManager from './layoutManager';
* *
* Tizen 5 Browser/Native: scrolls documentElement (and window); has a document.scrollingElement * Tizen 5 Browser/Native: scrolls documentElement (and window); has a document.scrollingElement
*/ */
class DocumentScroller { class DocumentScroller {
/** /**
* Horizontal scroll position. * Horizontal scroll position.
* @type {number} * @type {number}
@ -208,14 +206,14 @@ import layoutManager from './layoutManager';
scrollTo() { scrollTo() {
window.scrollTo.apply(window, arguments); window.scrollTo.apply(window, arguments);
} }
} }
/** /**
* Default (document) scroller. * Default (document) scroller.
*/ */
const documentScroller = new DocumentScroller(); const documentScroller = new DocumentScroller();
const scrollerHints = { const scrollerHints = {
x: { x: {
nameScroll: 'scrollWidth', nameScroll: 'scrollWidth',
nameClient: 'clientWidth', nameClient: 'clientWidth',
@ -228,16 +226,16 @@ import layoutManager from './layoutManager';
nameStyle: 'overflowY', nameStyle: 'overflowY',
nameScrollMode: 'data-scroll-mode-y' nameScrollMode: 'data-scroll-mode-y'
} }
}; };
/** /**
* Returns parent element that can be scrolled. If no such, returns document scroller. * Returns parent element that can be scrolled. If no such, returns document scroller.
* *
* @param {HTMLElement} element - Element for which parent is being searched. * @param {HTMLElement} element - Element for which parent is being searched.
* @param {boolean} vertical - Search for vertical scrollable parent. * @param {boolean} vertical - Search for vertical scrollable parent.
* @param {HTMLElement|DocumentScroller} Parent element that can be scrolled or document scroller. * @param {HTMLElement|DocumentScroller} Parent element that can be scrolled or document scroller.
*/ */
function getScrollableParent(element, vertical) { function getScrollableParent(element, vertical) {
if (element) { if (element) {
const scrollerHint = vertical ? scrollerHints.y : scrollerHints.x; const scrollerHint = vertical ? scrollerHints.y : scrollerHints.x;
@ -269,9 +267,9 @@ import layoutManager from './layoutManager';
} }
return documentScroller; return documentScroller;
} }
/** /**
* @typedef {Object} ScrollerData * @typedef {Object} ScrollerData
* @property {number} scrollPos - Current scroll position. * @property {number} scrollPos - Current scroll position.
* @property {number} scrollSize - Scroll size. * @property {number} scrollSize - Scroll size.
@ -280,14 +278,14 @@ import layoutManager from './layoutManager';
* @property {boolean} custom - Custom scrolling mode. * @property {boolean} custom - Custom scrolling mode.
*/ */
/** /**
* Returns scroller data for specified orientation. * Returns scroller data for specified orientation.
* *
* @param {HTMLElement} scroller - Scroller. * @param {HTMLElement} scroller - Scroller.
* @param {boolean} vertical - Vertical scroller data. * @param {boolean} vertical - Vertical scroller data.
* @return {ScrollerData} Scroller data. * @return {ScrollerData} Scroller data.
*/ */
function getScrollerData(scroller, vertical) { function getScrollerData(scroller, vertical) {
const data = {}; const data = {};
if (!vertical) { if (!vertical) {
@ -305,9 +303,9 @@ import layoutManager from './layoutManager';
data.custom = data.mode === 'custom'; data.custom = data.mode === 'custom';
return data; return data;
} }
/** /**
* Returns position of child of scroller for specified orientation. * Returns position of child of scroller for specified orientation.
* *
* @param {HTMLElement} scroller - Scroller. * @param {HTMLElement} scroller - Scroller.
@ -315,7 +313,7 @@ import layoutManager from './layoutManager';
* @param {boolean} vertical - Vertical scroll. * @param {boolean} vertical - Vertical scroll.
* @return {number} Child position. * @return {number} Child position.
*/ */
function getScrollerChildPos(scroller, element, vertical) { function getScrollerChildPos(scroller, element, vertical) {
const elementRect = element.getBoundingClientRect(); const elementRect = element.getBoundingClientRect();
const scrollerRect = scroller.getBoundingClientRect(); const scrollerRect = scroller.getBoundingClientRect();
@ -324,9 +322,9 @@ import layoutManager from './layoutManager';
} else { } else {
return scroller.scrollTop + elementRect.top - scrollerRect.top; return scroller.scrollTop + elementRect.top - scrollerRect.top;
} }
} }
/** /**
* Returns scroll position for element. * Returns scroll position for element.
* *
* @param {ScrollerData} scrollerData - Scroller data. * @param {ScrollerData} scrollerData - Scroller data.
@ -335,7 +333,7 @@ import layoutManager from './layoutManager';
* @param {boolean} centered - Scroll to center. * @param {boolean} centered - Scroll to center.
* @return {number} Scroll position. * @return {number} Scroll position.
*/ */
function calcScroll(scrollerData, elementPos, elementSize, centered) { function calcScroll(scrollerData, elementPos, elementSize, centered) {
const maxScroll = scrollerData.scrollSize - scrollerData.clientSize; const maxScroll = scrollerData.scrollSize - scrollerData.clientSize;
let scroll; let scroll;
@ -348,15 +346,15 @@ import layoutManager from './layoutManager';
} }
return clamp(Math.round(scroll), 0, maxScroll); return clamp(Math.round(scroll), 0, maxScroll);
} }
/** /**
* Calls scrollTo function in proper way. * Calls scrollTo function in proper way.
* *
* @param {HTMLElement} scroller - Scroller. * @param {HTMLElement} scroller - Scroller.
* @param {ScrollToOptions} options - Scroll options. * @param {ScrollToOptions} options - Scroll options.
*/ */
function scrollToHelper(scroller, options) { function scrollToHelper(scroller, options) {
if ('scrollTo' in scroller) { if ('scrollTo' in scroller) {
if (!supportsScrollToOptions) { if (!supportsScrollToOptions) {
const scrollX = (options.left !== undefined ? options.left : scroller.scrollLeft); const scrollX = (options.left !== undefined ? options.left : scroller.scrollLeft);
@ -373,9 +371,9 @@ import layoutManager from './layoutManager';
scroller.scrollTop = options.top; scroller.scrollTop = options.top;
} }
} }
} }
/** /**
* Performs built-in scroll. * Performs built-in scroll.
* *
* @param {HTMLElement} xScroller - Horizontal scroller. * @param {HTMLElement} xScroller - Horizontal scroller.
@ -384,35 +382,35 @@ import layoutManager from './layoutManager';
* @param {number} scrollY - Vertical coordinate. * @param {number} scrollY - Vertical coordinate.
* @param {boolean} smooth - Smooth scrolling. * @param {boolean} smooth - Smooth scrolling.
*/ */
function builtinScroll(xScroller, scrollX, yScroller, scrollY, smooth) { function builtinScroll(xScroller, scrollX, yScroller, scrollY, smooth) {
const scrollBehavior = smooth ? 'smooth' : 'instant'; const scrollBehavior = smooth ? 'smooth' : 'instant';
if (xScroller !== yScroller) { if (xScroller !== yScroller) {
if (xScroller) { if (xScroller) {
scrollToHelper(xScroller, {left: scrollX, behavior: scrollBehavior}); scrollToHelper(xScroller, { left: scrollX, behavior: scrollBehavior });
} }
if (yScroller) { if (yScroller) {
scrollToHelper(yScroller, {top: scrollY, behavior: scrollBehavior}); scrollToHelper(yScroller, { top: scrollY, behavior: scrollBehavior });
} }
} else if (xScroller) { } else if (xScroller) {
scrollToHelper(xScroller, {left: scrollX, top: scrollY, behavior: scrollBehavior}); scrollToHelper(xScroller, { left: scrollX, top: scrollY, behavior: scrollBehavior });
}
} }
}
/** /**
* Requested frame for animated scroll. * Requested frame for animated scroll.
*/ */
let scrollTimer; let scrollTimer;
/** /**
* Resets scroll timer to stop scrolling. * Resets scroll timer to stop scrolling.
*/ */
function resetScrollTimer() { function resetScrollTimer() {
cancelAnimationFrame(scrollTimer); cancelAnimationFrame(scrollTimer);
scrollTimer = undefined; scrollTimer = undefined;
} }
/** /**
* Performs animated scroll. * Performs animated scroll.
* *
* @param {HTMLElement} xScroller - Horizontal scroller. * @param {HTMLElement} xScroller - Horizontal scroller.
@ -420,7 +418,7 @@ import layoutManager from './layoutManager';
* @param {HTMLElement} yScroller - Vertical scroller. * @param {HTMLElement} yScroller - Vertical scroller.
* @param {number} scrollY - Vertical coordinate. * @param {number} scrollY - Vertical coordinate.
*/ */
function animateScroll(xScroller, scrollX, yScroller, scrollY) { function animateScroll(xScroller, scrollX, yScroller, scrollY) {
const ox = xScroller ? xScroller.scrollLeft : scrollX; const ox = xScroller ? xScroller.scrollLeft : scrollX;
const oy = yScroller ? yScroller.scrollTop : scrollY; const oy = yScroller ? yScroller.scrollTop : scrollY;
const dx = scrollX - ox; const dx = scrollX - ox;
@ -454,9 +452,9 @@ import layoutManager from './layoutManager';
} }
scrollTimer = requestAnimationFrame(scrollAnim); scrollTimer = requestAnimationFrame(scrollAnim);
} }
/** /**
* Performs scroll. * Performs scroll.
* *
* @param {HTMLElement} xScroller - Horizontal scroller. * @param {HTMLElement} xScroller - Horizontal scroller.
@ -465,7 +463,7 @@ import layoutManager from './layoutManager';
* @param {number} scrollY - Vertical coordinate. * @param {number} scrollY - Vertical coordinate.
* @param {boolean} smooth - Smooth scrolling. * @param {boolean} smooth - Smooth scrolling.
*/ */
function doScroll(xScroller, scrollX, yScroller, scrollY, smooth) { function doScroll(xScroller, scrollX, yScroller, scrollY, smooth) {
resetScrollTimer(); resetScrollTimer();
if (smooth && useAnimatedScroll()) { if (smooth && useAnimatedScroll()) {
@ -473,39 +471,39 @@ import layoutManager from './layoutManager';
} else { } else {
builtinScroll(xScroller, scrollX, yScroller, scrollY, smooth); builtinScroll(xScroller, scrollX, yScroller, scrollY, smooth);
} }
} }
/** /**
* Returns true if smooth scroll must be used. * Returns true if smooth scroll must be used.
*/ */
function useSmoothScroll() { function useSmoothScroll() {
return !!browser.tizen; return !!browser.tizen;
} }
/** /**
* Returns true if animated implementation of smooth scroll must be used. * Returns true if animated implementation of smooth scroll must be used.
*/ */
function useAnimatedScroll() { function useAnimatedScroll() {
// Add block to force using (or not) of animated implementation // Add block to force using (or not) of animated implementation
return !supportsSmoothScroll; return !supportsSmoothScroll;
} }
/** /**
* Returns true if scroll manager is enabled. * Returns true if scroll manager is enabled.
*/ */
export function isEnabled() { export function isEnabled() {
return layoutManager.tv; return layoutManager.tv;
} }
/** /**
* Scrolls the document to a given position. * Scrolls the document to a given position.
* *
* @param {number} scrollX - Horizontal coordinate. * @param {number} scrollX - Horizontal coordinate.
* @param {number} scrollY - Vertical coordinate. * @param {number} scrollY - Vertical coordinate.
* @param {boolean} [smooth=false] - Smooth scrolling. * @param {boolean} [smooth=false] - Smooth scrolling.
*/ */
export function scrollTo(scrollX, scrollY, smooth) { export function scrollTo(scrollX, scrollY, smooth) {
smooth = !!smooth; smooth = !!smooth;
// Scroller is document itself by default // Scroller is document itself by default
@ -518,15 +516,15 @@ import layoutManager from './layoutManager';
scrollY = clamp(Math.round(scrollY), 0, yScrollerData.scrollSize - yScrollerData.clientSize); scrollY = clamp(Math.round(scrollY), 0, yScrollerData.scrollSize - yScrollerData.clientSize);
doScroll(scroller, scrollX, scroller, scrollY, smooth); doScroll(scroller, scrollX, scroller, scrollY, smooth);
} }
/** /**
* Scrolls the document to a given element. * Scrolls the document to a given element.
* *
* @param {HTMLElement} element - Target element of scroll task. * @param {HTMLElement} element - Target element of scroll task.
* @param {boolean} [smooth=false] - Smooth scrolling. * @param {boolean} [smooth=false] - Smooth scrolling.
*/ */
export function scrollToElement(element, smooth) { export function scrollToElement(element, smooth) {
smooth = !!smooth; smooth = !!smooth;
let scrollCenterX = true; let scrollCenterX = true;
@ -590,17 +588,15 @@ import layoutManager from './layoutManager';
} }
doScroll(xScroller, scrollX, yScroller, scrollY, smooth); doScroll(xScroller, scrollX, yScroller, scrollY, smooth);
} }
if (isEnabled()) { if (isEnabled()) {
dom.addEventListener(window, 'focusin', function(e) { dom.addEventListener(window, 'focusin', function(e) {
setTimeout(function() { setTimeout(function() {
scrollToElement(e.target, useSmoothScroll()); scrollToElement(e.target, useSmoothScroll());
}, 0); }, 0);
}, {capture: true}); }, { capture: true });
} }
/* eslint-enable indent */
export default { export default {
isEnabled: isEnabled, isEnabled: isEnabled,

View file

@ -85,8 +85,8 @@ const SearchFields: FunctionComponent<SearchFieldsProps> = ({ onSearch = () => {
dangerouslySetInnerHTML={createInputElement()} dangerouslySetInnerHTML={createInputElement()}
/> />
</div> </div>
{layoutManager.tv && !browser.tv && {layoutManager.tv && !browser.tv
<AlphaPicker onAlphaPicked={onAlphaPicked} /> && <AlphaPicker onAlphaPicked={onAlphaPicked} />
} }
</div> </div>
); );

View file

@ -1,5 +1,3 @@
/* eslint-disable indent */
/** /**
* Module shortcuts. * Module shortcuts.
* @module components/shortcuts * @module components/shortcuts
@ -14,7 +12,7 @@ import recordingHelper from './recordingcreator/recordinghelper';
import ServerConnections from './ServerConnections'; import ServerConnections from './ServerConnections';
import toast from './toast/toast'; import toast from './toast/toast';
function playAllFromHere(card, serverId, queue) { function playAllFromHere(card, serverId, queue) {
const parent = card.parentNode; const parent = card.parentNode;
const className = card.classList.length ? (`.${card.classList[0]}`) : ''; const className = card.classList.length ? (`.${card.classList[0]}`) : '';
const cards = parent.querySelectorAll(`${className}[data-id]`); const cards = parent.querySelectorAll(`${className}[data-id]`);
@ -68,15 +66,15 @@ import toast from './toast/toast';
startIndex: startIndex startIndex: startIndex
}); });
} }
} }
function showProgramDialog(item) { function showProgramDialog(item) {
import('./recordingcreator/recordingcreator').then(({default:recordingCreator}) => { import('./recordingcreator/recordingcreator').then(({ default:recordingCreator }) => {
recordingCreator.show(item.Id, item.ServerId); recordingCreator.show(item.Id, item.ServerId);
}); });
} }
function getItem(button) { function getItem(button) {
button = dom.parentWithAttribute(button, 'data-id'); button = dom.parentWithAttribute(button, 'data-id');
const serverId = button.getAttribute('data-serverid'); const serverId = button.getAttribute('data-serverid');
const id = button.getAttribute('data-id'); const id = button.getAttribute('data-id');
@ -91,17 +89,17 @@ import toast from './toast/toast';
return apiClient.getLiveTvSeriesTimer(id); return apiClient.getLiveTvSeriesTimer(id);
} }
return apiClient.getItem(apiClient.getCurrentUserId(), id); return apiClient.getItem(apiClient.getCurrentUserId(), id);
} }
function notifyRefreshNeeded(childElement, itemsContainer) { function notifyRefreshNeeded(childElement, itemsContainer) {
itemsContainer = itemsContainer || dom.parentWithAttribute(childElement, 'is', 'emby-itemscontainer'); itemsContainer = itemsContainer || dom.parentWithAttribute(childElement, 'is', 'emby-itemscontainer');
if (itemsContainer) { if (itemsContainer) {
itemsContainer.notifyRefreshNeeded(true); itemsContainer.notifyRefreshNeeded(true);
} }
} }
function showContextMenu(card, options) { function showContextMenu(card, options) {
getItem(card).then(item => { getItem(card).then(item => {
const playlistId = card.getAttribute('data-playlistid'); const playlistId = card.getAttribute('data-playlistid');
const collectionId = card.getAttribute('data-collectionid'); const collectionId = card.getAttribute('data-collectionid');
@ -133,9 +131,9 @@ import toast from './toast/toast';
}); });
}); });
}); });
} }
function getItemInfoFromCard(card) { function getItemInfoFromCard(card) {
return { return {
Type: card.getAttribute('data-type'), Type: card.getAttribute('data-type'),
Id: card.getAttribute('data-id'), Id: card.getAttribute('data-id'),
@ -153,9 +151,9 @@ import toast from './toast/toast';
PlaybackPositionTicks: parseInt(card.getAttribute('data-positionticks') || '0', 10) PlaybackPositionTicks: parseInt(card.getAttribute('data-positionticks') || '0', 10)
} }
}; };
} }
function showPlayMenu(card, target) { function showPlayMenu(card, target) {
const item = getItemInfoFromCard(card); const item = getItemInfoFromCard(card);
import('./playmenu').then((playMenu) => { import('./playmenu').then((playMenu) => {
@ -165,9 +163,9 @@ import toast from './toast/toast';
positionTo: target positionTo: target
}); });
}); });
} }
function executeAction(card, target, action) { function executeAction(card, target, action) {
target = target || card; target = target || card;
let id = card.getAttribute('data-id'); let id = card.getAttribute('data-id');
@ -269,27 +267,27 @@ import toast from './toast/toast';
bubbles: true bubbles: true
})); }));
} }
} }
function addToPlaylist(item) { function addToPlaylist(item) {
import('./playlisteditor/playlisteditor').then(({default: playlistEditor}) => { import('./playlisteditor/playlisteditor').then(({ default: playlistEditor }) => {
new playlistEditor().show({ new playlistEditor().show({
items: [item.Id], items: [item.Id],
serverId: item.ServerId serverId: item.ServerId
}); });
}); });
} }
function playTrailer(item) { function playTrailer(item) {
const apiClient = ServerConnections.getApiClient(item.ServerId); const apiClient = ServerConnections.getApiClient(item.ServerId);
apiClient.getLocalTrailers(apiClient.getCurrentUserId(), item.Id).then(trailers => { apiClient.getLocalTrailers(apiClient.getCurrentUserId(), item.Id).then(trailers => {
playbackManager.play({ items: trailers }); playbackManager.play({ items: trailers });
}); });
} }
function editItem(item, serverId) { function editItem(item, serverId) {
const apiClient = ServerConnections.getApiClient(serverId); const apiClient = ServerConnections.getApiClient(serverId);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -297,30 +295,30 @@ import toast from './toast/toast';
if (item.Type === 'Timer') { if (item.Type === 'Timer') {
if (item.ProgramId) { if (item.ProgramId) {
import('./recordingcreator/recordingcreator').then(({default: recordingCreator}) => { import('./recordingcreator/recordingcreator').then(({ default: recordingCreator }) => {
recordingCreator.show(item.ProgramId, currentServerId).then(resolve, reject); recordingCreator.show(item.ProgramId, currentServerId).then(resolve, reject);
}); });
} else { } else {
import('./recordingcreator/recordingeditor').then(({default: recordingEditor}) => { import('./recordingcreator/recordingeditor').then(({ default: recordingEditor }) => {
recordingEditor.show(item.Id, currentServerId).then(resolve, reject); recordingEditor.show(item.Id, currentServerId).then(resolve, reject);
}); });
} }
} else { } else {
import('./metadataEditor/metadataEditor').then(({default: metadataEditor}) => { import('./metadataEditor/metadataEditor').then(({ default: metadataEditor }) => {
metadataEditor.show(item.Id, currentServerId).then(resolve, reject); metadataEditor.show(item.Id, currentServerId).then(resolve, reject);
}); });
} }
}); });
} }
function onRecordCommand(serverId, id, type, timerId, seriesTimerId) { function onRecordCommand(serverId, id, type, timerId, seriesTimerId) {
if (type === 'Program' || timerId || seriesTimerId) { if (type === 'Program' || timerId || seriesTimerId) {
const programId = type === 'Program' ? id : null; const programId = type === 'Program' ? id : null;
recordingHelper.toggleRecording(serverId, programId, timerId, seriesTimerId); recordingHelper.toggleRecording(serverId, programId, timerId, seriesTimerId);
} }
} }
export function onClick(e) { export function onClick(e) {
const card = dom.parentWithClass(e.target, 'itemAction'); const card = dom.parentWithClass(e.target, 'itemAction');
if (card) { if (card) {
@ -342,9 +340,9 @@ import toast from './toast/toast';
return false; return false;
} }
} }
} }
function onCommand(e) { function onCommand(e) {
const cmd = e.detail.command; const cmd = e.detail.command;
if (cmd === 'play' || cmd === 'resume' || cmd === 'record' || cmd === 'menu' || cmd === 'info') { if (cmd === 'play' || cmd === 'resume' || cmd === 'record' || cmd === 'menu' || cmd === 'info') {
@ -357,9 +355,9 @@ import toast from './toast/toast';
executeAction(card, card, cmd); executeAction(card, card, cmd);
} }
} }
} }
export function on(context, options) { export function on(context, options) {
options = options || {}; options = options || {};
if (options.click !== false) { if (options.click !== false) {
@ -369,9 +367,9 @@ import toast from './toast/toast';
if (options.command !== false) { if (options.command !== false) {
inputManager.on(context, onCommand); inputManager.on(context, onCommand);
} }
} }
export function off(context, options) { export function off(context, options) {
options = options || {}; options = options || {};
context.removeEventListener('click', onClick); context.removeEventListener('click', onClick);
@ -379,9 +377,9 @@ import toast from './toast/toast';
if (options.command !== false) { if (options.command !== false) {
inputManager.off(context, onCommand); inputManager.off(context, onCommand);
} }
} }
export function getShortcutAttributesHtml(item, serverId) { export function getShortcutAttributesHtml(item, serverId) {
let html = `data-id="${item.Id}" data-serverid="${serverId || item.ServerId}" data-type="${item.Type}" data-mediatype="${item.MediaType}" data-channelid="${item.ChannelId}" data-isfolder="${item.IsFolder}"`; let html = `data-id="${item.Id}" data-serverid="${serverId || item.ServerId}" data-type="${item.Type}" data-mediatype="${item.MediaType}" data-channelid="${item.ChannelId}" data-isfolder="${item.IsFolder}"`;
const collectionType = item.CollectionType; const collectionType = item.CollectionType;
@ -390,9 +388,7 @@ import toast from './toast/toast';
} }
return html; return html;
} }
/* eslint-enable indent */
export default { export default {
on: on, on: on,

View file

@ -342,7 +342,7 @@ function showDownloadOptions(button, context, subtitleId) {
} }
function centerFocus(elem, horiz, on) { function centerFocus(elem, horiz, on) {
import('../../scripts/scrollHelper').then(({default: scrollHelper}) => { import('../../scripts/scrollHelper').then(({ default: scrollHelper }) => {
const fn = on ? 'on' : 'off'; const fn = on ? 'on' : 'off';
scrollHelper.centerFocus[fn](elem, horiz); scrollHelper.centerFocus[fn](elem, horiz);
}); });
@ -353,7 +353,7 @@ function onOpenUploadMenu(e) {
const selectLanguage = dialog.querySelector('#selectLanguage'); const selectLanguage = dialog.querySelector('#selectLanguage');
const apiClient = ServerConnections.getApiClient(currentItem.ServerId); const apiClient = ServerConnections.getApiClient(currentItem.ServerId);
import('../subtitleuploader/subtitleuploader').then(({default: subtitleUploader}) => { import('../subtitleuploader/subtitleuploader').then(({ default: subtitleUploader }) => {
subtitleUploader.show({ subtitleUploader.show({
languages: { languages: {
list: selectLanguage.innerHTML, list: selectLanguage.innerHTML,

View file

@ -94,9 +94,9 @@ function init(instance) {
subtitleSyncSlider.getBubbleHtml = function (value) { subtitleSyncSlider.getBubbleHtml = function (value) {
const newOffset = getOffsetFromPercentage(value); const newOffset = getOffsetFromPercentage(value);
return '<h1 class="sliderBubbleText">' + return '<h1 class="sliderBubbleText">'
(newOffset > 0 ? '+' : '') + parseFloat(newOffset) + 's' + + (newOffset > 0 ? '+' : '') + parseFloat(newOffset) + 's'
'</h1>'; + '</h1>';
}; };
subtitleSyncCloseButton.addEventListener('click', function () { subtitleSyncCloseButton.addEventListener('click', function () {

View file

@ -0,0 +1,114 @@
import { clearBackdrop } from '../backdrop/backdrop';
import * as mainTabsManager from '../maintabsmanager';
import layoutManager from '../layoutManager';
import '../../elements/emby-tabs/emby-tabs';
import LibraryMenu from '../../scripts/libraryMenu';
function onViewDestroy() {
const tabControllers = this.tabControllers;
if (tabControllers) {
tabControllers.forEach(function (t) {
if (t.destroy) {
t.destroy();
}
});
this.tabControllers = null;
}
this.view = null;
this.params = null;
this.currentTabController = null;
this.initialTabIndex = null;
}
class TabbedView {
constructor(view, params) {
this.tabControllers = [];
this.view = view;
this.params = params;
const self = this;
let currentTabIndex = parseInt(params.tab || this.getDefaultTabIndex(params.parentId), 10);
this.initialTabIndex = currentTabIndex;
function validateTabLoad(index) {
return self.validateTabLoad ? self.validateTabLoad(index) : Promise.resolve();
}
function loadTab(index, previousIndex) {
validateTabLoad(index).then(function () {
self.getTabController(index).then(function (controller) {
const refresh = !controller.refreshed;
controller.onResume({
autoFocus: previousIndex == null && layoutManager.tv,
refresh: refresh
});
controller.refreshed = true;
currentTabIndex = index;
self.currentTabController = controller;
});
});
}
function getTabContainers() {
return view.querySelectorAll('.tabContent');
}
function onTabChange(e) {
const newIndex = parseInt(e.detail.selectedTabIndex, 10);
const previousIndex = e.detail.previousIndex;
const previousTabController = previousIndex == null ? null : self.tabControllers[previousIndex];
if (previousTabController && previousTabController.onPause) {
previousTabController.onPause();
}
loadTab(newIndex, previousIndex);
}
view.addEventListener('viewbeforehide', this.onPause.bind(this));
view.addEventListener('viewbeforeshow', function () {
mainTabsManager.setTabs(view, currentTabIndex, self.getTabs, getTabContainers, null, onTabChange, false);
});
view.addEventListener('viewshow', function (e) {
self.onResume(e.detail);
});
view.addEventListener('viewdestroy', onViewDestroy.bind(this));
}
onResume() {
this.setTitle();
clearBackdrop();
const currentTabController = this.currentTabController;
if (!currentTabController) {
mainTabsManager.selectedTabIndex(this.initialTabIndex);
} else if (currentTabController && currentTabController.onResume) {
currentTabController.onResume({});
}
}
onPause() {
const currentTabController = this.currentTabController;
if (currentTabController && currentTabController.onPause) {
currentTabController.onPause();
}
}
setTitle() {
LibraryMenu.setTitle('');
}
}
export default TabbedView;

View file

@ -48,7 +48,7 @@ function refreshTunerDevices(page, providerInfo, devices) {
function onSelectPathClick(e) { function onSelectPathClick(e) {
const page = $(e.target).parents('.xmltvForm')[0]; const page = $(e.target).parents('.xmltvForm')[0];
import('../directorybrowser/directorybrowser').then(({default: DirectoryBrowser}) => { import('../directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser(); const picker = new DirectoryBrowser();
picker.show({ picker.show({
includeFiles: true, includeFiles: true,

View file

@ -10,11 +10,9 @@ import './upnextdialog.scss';
import '../../elements/emby-button/emby-button'; import '../../elements/emby-button/emby-button';
import '../../styles/flexstyles.scss'; import '../../styles/flexstyles.scss';
/* eslint-disable indent */ const transitionEndEventName = dom.whichTransitionEvent();
const transitionEndEventName = dom.whichTransitionEvent(); function getHtml() {
function getHtml() {
let html = ''; let html = '';
html += '<div class="flex flex-direction-column flex-grow">'; html += '<div class="flex flex-direction-column flex-grow">';
@ -43,9 +41,9 @@ import '../../styles/flexstyles.scss';
html += '</div>'; html += '</div>';
return html; return html;
} }
function setNextVideoText() { function setNextVideoText() {
const instance = this; const instance = this;
const elem = instance.options.parent; const elem = instance.options.parent;
@ -61,17 +59,17 @@ import '../../styles/flexstyles.scss';
globalize.translate('HeaderNextVideoPlayingInValue', timeText); globalize.translate('HeaderNextVideoPlayingInValue', timeText);
elem.querySelector('.upNextDialog-nextVideoText').innerHTML = nextVideoText; elem.querySelector('.upNextDialog-nextVideoText').innerHTML = nextVideoText;
} }
function fillItem(item) { function fillItem(item) {
const instance = this; const instance = this;
const elem = instance.options.parent; const elem = instance.options.parent;
elem.querySelector('.upNextDialog-mediainfo').innerHTML = mediaInfo.getPrimaryMediaInfoHtml(item, { elem.querySelector('.upNextDialog-mediainfo').innerHTML = mediaInfo.getPrimaryMediaInfoHtml(item, {
criticRating: false, criticRating: true,
originalAirDate: false, originalAirDate: false,
starRating: false, starRating: true,
subtitles: false subtitles: false
}); });
@ -85,16 +83,16 @@ import '../../styles/flexstyles.scss';
instance.itemType = item.Type; instance.itemType = item.Type;
instance.show(); instance.show();
} }
function clearCountdownTextTimeout(instance) { function clearCountdownTextTimeout(instance) {
if (instance._countdownTextTimeout) { if (instance._countdownTextTimeout) {
clearInterval(instance._countdownTextTimeout); clearInterval(instance._countdownTextTimeout);
instance._countdownTextTimeout = null; instance._countdownTextTimeout = null;
} }
} }
async function onStartNowClick() { async function onStartNowClick() {
const options = this.options; const options = this.options;
if (options) { if (options) {
@ -104,9 +102,9 @@ import '../../styles/flexstyles.scss';
playbackManager.nextTrack(player); playbackManager.nextTrack(player);
} }
} }
function init(instance, options) { function init(instance, options) {
options.parent.innerHTML = getHtml(); options.parent.innerHTML = getHtml();
options.parent.classList.add('hide'); options.parent.classList.add('hide');
@ -117,9 +115,9 @@ import '../../styles/flexstyles.scss';
options.parent.querySelector('.btnHide').addEventListener('click', instance.hide.bind(instance)); options.parent.querySelector('.btnHide').addEventListener('click', instance.hide.bind(instance));
options.parent.querySelector('.btnStartNow').addEventListener('click', onStartNowClick.bind(instance)); options.parent.querySelector('.btnStartNow').addEventListener('click', onStartNowClick.bind(instance));
} }
function clearHideAnimationEventListeners(instance, elem) { function clearHideAnimationEventListeners(instance, elem) {
const fn = instance._onHideAnimationComplete; const fn = instance._onHideAnimationComplete;
if (fn) { if (fn) {
@ -127,9 +125,9 @@ import '../../styles/flexstyles.scss';
once: true once: true
}); });
} }
} }
function onHideAnimationComplete(e) { function onHideAnimationComplete(e) {
const instance = this; const instance = this;
const elem = e.target; const elem = e.target;
@ -137,9 +135,9 @@ import '../../styles/flexstyles.scss';
clearHideAnimationEventListeners(instance, elem); clearHideAnimationEventListeners(instance, elem);
Events.trigger(instance, 'hide'); Events.trigger(instance, 'hide');
} }
async function hideComingUpNext() { async function hideComingUpNext() {
const instance = this; const instance = this;
clearCountdownTextTimeout(this); clearCountdownTextTimeout(this);
@ -174,9 +172,9 @@ import '../../styles/flexstyles.scss';
}); });
instance._onHideAnimationComplete(transitionEvent); instance._onHideAnimationComplete(transitionEvent);
} }
function getTimeRemainingMs(instance) { function getTimeRemainingMs(instance) {
const options = instance.options; const options = instance.options;
if (options) { if (options) {
const runtimeTicks = playbackManager.duration(options.player); const runtimeTicks = playbackManager.duration(options.player);
@ -189,9 +187,9 @@ import '../../styles/flexstyles.scss';
} }
return 0; return 0;
} }
function startComingUpNextHideTimer(instance) { function startComingUpNextHideTimer(instance) {
const timeRemainingMs = getTimeRemainingMs(instance); const timeRemainingMs = getTimeRemainingMs(instance);
if (timeRemainingMs <= 0) { if (timeRemainingMs <= 0) {
@ -202,7 +200,7 @@ import '../../styles/flexstyles.scss';
clearCountdownTextTimeout(instance); clearCountdownTextTimeout(instance);
instance._countdownTextTimeout = setInterval(setNextVideoText.bind(instance), 400); instance._countdownTextTimeout = setInterval(setNextVideoText.bind(instance), 400);
} }
class UpNextDialog { class UpNextDialog {
constructor(options) { constructor(options) {
@ -243,4 +241,3 @@ class UpNextDialog {
export default UpNextDialog; export default UpNextDialog;
/* eslint-enable indent */

View file

@ -2,9 +2,15 @@ import { importModule } from '@uupaa/dynamic-import-polyfill';
import './viewManager/viewContainer.scss'; import './viewManager/viewContainer.scss';
import Dashboard from '../utils/dashboard'; import Dashboard from '../utils/dashboard';
/* eslint-disable indent */ const getMainAnimatedPages = () => {
if (!mainAnimatedPages) {
mainAnimatedPages = document.querySelector('.mainAnimatedPages');
}
function setControllerClass(view, options) { return mainAnimatedPages;
};
function setControllerClass(view, options) {
if (options.controllerFactory) { if (options.controllerFactory) {
return Promise.resolve(); return Promise.resolve();
} }
@ -24,9 +30,9 @@ import Dashboard from '../utils/dashboard';
} }
return Promise.resolve(); return Promise.resolve();
} }
export function loadView(options) { export function loadView(options) {
if (!options.cancel) { if (!options.cancel) {
const selected = selectedPageIndex; const selected = selectedPageIndex;
const previousAnimatable = selected === -1 ? null : allPages[selected]; const previousAnimatable = selected === -1 ? null : allPages[selected];
@ -55,6 +61,11 @@ import Dashboard from '../utils/dashboard';
view.classList.add('mainAnimatedPage'); view.classList.add('mainAnimatedPage');
if (!getMainAnimatedPages()) {
console.warn('[viewContainer] main animated pages element is not present');
return;
}
if (currentPage) { if (currentPage) {
if (newViewInfo.hasScript && window.$) { if (newViewInfo.hasScript && window.$) {
mainAnimatedPages.removeChild(currentPage); mainAnimatedPages.removeChild(currentPage);
@ -110,9 +121,9 @@ import Dashboard from '../utils/dashboard';
return view; return view;
}); });
} }
} }
function parseHtml(html, hasScript) { function parseHtml(html, hasScript) {
if (hasScript) { if (hasScript) {
html = html html = html
.replaceAll('\x3c!--<script', '<script') .replaceAll('\x3c!--<script', '<script')
@ -122,9 +133,9 @@ import Dashboard from '../utils/dashboard';
const wrapper = document.createElement('div'); const wrapper = document.createElement('div');
wrapper.innerHTML = html; wrapper.innerHTML = html;
return wrapper.querySelector('div[data-role="page"]'); return wrapper.querySelector('div[data-role="page"]');
} }
function normalizeNewView(options, isPluginpage) { function normalizeNewView(options, isPluginpage) {
const viewHtml = options.view; const viewHtml = options.view;
if (viewHtml.indexOf('data-role="page"') === -1) { if (viewHtml.indexOf('data-role="page"') === -1) {
@ -155,29 +166,29 @@ import Dashboard from '../utils/dashboard';
hasjQueryChecked: hasjQueryChecked, hasjQueryChecked: hasjQueryChecked,
hasjQuery: hasjQuery hasjQuery: hasjQuery
}; };
} }
function beforeAnimate(allPages, newPageIndex, oldPageIndex) { function beforeAnimate(allPages, newPageIndex, oldPageIndex) {
for (let index = 0, length = allPages.length; index < length; index++) { for (let index = 0, length = allPages.length; index < length; index++) {
if (newPageIndex !== index && oldPageIndex !== index) { if (newPageIndex !== index && oldPageIndex !== index) {
allPages[index].classList.add('hide'); allPages[index].classList.add('hide');
} }
} }
} }
function afterAnimate(allPages, newPageIndex) { function afterAnimate(allPages, newPageIndex) {
for (let index = 0, length = allPages.length; index < length; index++) { for (let index = 0, length = allPages.length; index < length; index++) {
if (newPageIndex !== index) { if (newPageIndex !== index) {
allPages[index].classList.add('hide'); allPages[index].classList.add('hide');
} }
} }
} }
export function setOnBeforeChange(fn) { export function setOnBeforeChange(fn) {
onBeforeChange = fn; onBeforeChange = fn;
} }
export function tryRestoreView(options) { export function tryRestoreView(options) {
const url = options.url; const url = options.url;
const index = currentUrls.indexOf(url); const index = currentUrls.indexOf(url);
@ -216,29 +227,27 @@ import Dashboard from '../utils/dashboard';
} }
return Promise.reject(); return Promise.reject();
} }
function triggerDestroy(view) { function triggerDestroy(view) {
view.dispatchEvent(new CustomEvent('viewdestroy', {})); view.dispatchEvent(new CustomEvent('viewdestroy', {}));
} }
export function reset() { export function reset() {
allPages = []; allPages = [];
currentUrls = []; currentUrls = [];
mainAnimatedPages.innerHTML = ''; if (mainAnimatedPages) mainAnimatedPages.innerHTML = '';
selectedPageIndex = -1; selectedPageIndex = -1;
} }
let onBeforeChange; let onBeforeChange;
const mainAnimatedPages = document.querySelector('.mainAnimatedPages'); let mainAnimatedPages;
let allPages = []; let allPages = [];
let currentUrls = []; let currentUrls = [];
const pageContainerCount = 3; const pageContainerCount = 3;
let selectedPageIndex = -1; let selectedPageIndex = -1;
reset(); reset();
mainAnimatedPages.classList.remove('hide'); getMainAnimatedPages()?.classList.remove('hide');
/* eslint-enable indent */
export default { export default {
loadView: loadView, loadView: loadView,

View file

@ -97,7 +97,7 @@ function dispatchViewEvent(view, eventInfo, eventName, isCancellable) {
return eventResult; return eventResult;
} }
function getViewEventDetail(view, {state, url, options = {}}, isRestored) { function getViewEventDetail(view, { state, url, options = {} }, isRestored) {
const index = url.indexOf('?'); const index = url.indexOf('?');
// eslint-disable-next-line compat/compat // eslint-disable-next-line compat/compat
const searchParams = new URLSearchParams(url.substring(index + 1)); const searchParams = new URLSearchParams(url.substring(index + 1));

View file

@ -6,9 +6,7 @@ import '../../elements/emby-button/emby-button';
import confirm from '../../components/confirm/confirm'; import confirm from '../../components/confirm/confirm';
import { pageIdOn } from '../../utils/dashboard'; import { pageIdOn } from '../../utils/dashboard';
/* eslint-disable indent */ function revoke(page, key) {
function revoke(page, key) {
confirm(globalize.translate('MessageConfirmRevokeApiKey'), globalize.translate('HeaderConfirmRevokeApiKey')).then(function () { confirm(globalize.translate('MessageConfirmRevokeApiKey'), globalize.translate('HeaderConfirmRevokeApiKey')).then(function () {
loading.show(); loading.show();
ApiClient.ajax({ ApiClient.ajax({
@ -18,9 +16,9 @@ import { pageIdOn } from '../../utils/dashboard';
loadData(page); loadData(page);
}); });
}); });
} }
function renderKeys(page, keys) { function renderKeys(page, keys) {
const rows = keys.map(function (item) { const rows = keys.map(function (item) {
let html = ''; let html = '';
html += '<tr class="detailTableBodyRow detailTableBodyRow-shaded">'; html += '<tr class="detailTableBodyRow detailTableBodyRow-shaded">';
@ -42,17 +40,17 @@ import { pageIdOn } from '../../utils/dashboard';
}).join(''); }).join('');
page.querySelector('.resultBody').innerHTML = rows; page.querySelector('.resultBody').innerHTML = rows;
loading.hide(); loading.hide();
} }
function loadData(page) { function loadData(page) {
loading.show(); loading.show();
ApiClient.getJSON(ApiClient.getUrl('Auth/Keys')).then(function (result) { ApiClient.getJSON(ApiClient.getUrl('Auth/Keys')).then(function (result) {
renderKeys(page, result.Items); renderKeys(page, result.Items);
}); });
} }
function showNewKeyPrompt(page) { function showNewKeyPrompt(page) {
import('../../components/prompt/prompt').then(({default: prompt}) => { import('../../components/prompt/prompt').then(({ default: prompt }) => {
prompt({ prompt({
title: globalize.translate('HeaderNewApiKey'), title: globalize.translate('HeaderNewApiKey'),
label: globalize.translate('LabelAppName'), label: globalize.translate('LabelAppName'),
@ -68,9 +66,9 @@ import { pageIdOn } from '../../utils/dashboard';
}); });
}); });
}); });
} }
pageIdOn('pageinit', 'apiKeysPage', function () { pageIdOn('pageinit', 'apiKeysPage', function () {
const page = this; const page = this;
page.querySelector('.btnNewKey').addEventListener('click', function () { page.querySelector('.btnNewKey').addEventListener('click', function () {
showNewKeyPrompt(page); showNewKeyPrompt(page);
@ -82,9 +80,8 @@ import { pageIdOn } from '../../utils/dashboard';
revoke(page, btnRevoke.getAttribute('data-token')); revoke(page, btnRevoke.getAttribute('data-token'));
} }
}); });
}); });
pageIdOn('pagebeforeshow', 'apiKeysPage', function () { pageIdOn('pagebeforeshow', 'apiKeysPage', function () {
loadData(this); loadData(this);
}); });
/* eslint-enable indent */

View file

@ -24,9 +24,7 @@ import ServerConnections from '../../components/ServerConnections';
import alert from '../../components/alert'; import alert from '../../components/alert';
import confirm from '../../components/confirm/confirm'; import confirm from '../../components/confirm/confirm';
/* eslint-disable indent */ function showPlaybackInfo(btn, session) {
function showPlaybackInfo(btn, session) {
let title; let title;
const text = []; const text = [];
const displayPlayMethod = playMethodHelper.getDisplayPlayMethod(session); const displayPlayMethod = playMethodHelper.getDisplayPlayMethod(session);
@ -62,10 +60,10 @@ import confirm from '../../components/confirm/confirm';
text: text.join('<br/>'), text: text.join('<br/>'),
title: title title: title
}); });
} }
function showSendMessageForm(btn, session) { function showSendMessageForm(btn, session) {
import('../../components/prompt/prompt').then(({default: prompt}) => { import('../../components/prompt/prompt').then(({ default: prompt }) => {
prompt({ prompt({
title: globalize.translate('HeaderSendMessage'), title: globalize.translate('HeaderSendMessage'),
label: globalize.translate('LabelMessageText'), label: globalize.translate('LabelMessageText'),
@ -79,10 +77,10 @@ import confirm from '../../components/confirm/confirm';
} }
}); });
}); });
} }
function showOptionsMenu(btn, session) { function showOptionsMenu(btn, session) {
import('../../components/actionSheet/actionSheet').then(({default: actionsheet}) => { import('../../components/actionSheet/actionSheet').then(({ default: actionsheet }) => {
const menuItems = []; const menuItems = [];
if (session.ServerId && session.DeviceId !== ServerConnections.deviceId()) { if (session.ServerId && session.DeviceId !== ServerConnections.deviceId()) {
@ -113,9 +111,9 @@ import confirm from '../../components/confirm/confirm';
} }
}); });
}); });
} }
function onActiveDevicesClick(evt) { function onActiveDevicesClick(evt) {
const btn = dom.parentWithClass(evt.target, 'sessionCardButton'); const btn = dom.parentWithClass(evt.target, 'sessionCardButton');
if (btn) { if (btn) {
@ -142,9 +140,9 @@ import confirm from '../../components/confirm/confirm';
} }
} }
} }
} }
function filterSessions(sessions) { function filterSessions(sessions) {
const list = []; const list = [];
const minActiveDate = new Date().getTime() - 9e5; const minActiveDate = new Date().getTime() - 9e5;
@ -161,9 +159,9 @@ import confirm from '../../components/confirm/confirm';
} }
return list; return list;
} }
function refreshActiveRecordings(view, apiClient) { function refreshActiveRecordings(view, apiClient) {
apiClient.getLiveTvRecordings({ apiClient.getLiveTvRecordings({
UserId: Dashboard.getCurrentUserId(), UserId: Dashboard.getCurrentUserId(),
IsInProgress: true, IsInProgress: true,
@ -197,9 +195,9 @@ import confirm from '../../components/confirm/confirm';
}); });
imageLoader.lazyChildren(itemsContainer); imageLoader.lazyChildren(itemsContainer);
}); });
} }
function reloadSystemInfo(view, apiClient) { function reloadSystemInfo(view, apiClient) {
apiClient.getSystemInfo().then(function (systemInfo) { apiClient.getSystemInfo().then(function (systemInfo) {
view.querySelector('#serverName').innerText = globalize.translate('DashboardServerName', systemInfo.ServerName); view.querySelector('#serverName').innerText = globalize.translate('DashboardServerName', systemInfo.ServerName);
view.querySelector('#versionNumber').innerText = globalize.translate('DashboardVersionNumber', systemInfo.Version); view.querySelector('#versionNumber').innerText = globalize.translate('DashboardVersionNumber', systemInfo.Version);
@ -216,15 +214,15 @@ import confirm from '../../components/confirm/confirm';
view.querySelector('#metadataPath').innerText = systemInfo.InternalMetadataPath; view.querySelector('#metadataPath').innerText = systemInfo.InternalMetadataPath;
view.querySelector('#webPath').innerText = systemInfo.WebPath; view.querySelector('#webPath').innerText = systemInfo.WebPath;
}); });
} }
function renderInfo(view, sessions) { function renderInfo(view, sessions) {
sessions = filterSessions(sessions); sessions = filterSessions(sessions);
renderActiveConnections(view, sessions); renderActiveConnections(view, sessions);
loading.hide(); loading.hide();
} }
function pollForInfo(view, apiClient) { function pollForInfo(view, apiClient) {
apiClient.getSessions({ apiClient.getSessions({
ActiveWithinSeconds: 960 ActiveWithinSeconds: 960
}).then(function (sessions) { }).then(function (sessions) {
@ -233,9 +231,9 @@ import confirm from '../../components/confirm/confirm';
apiClient.getScheduledTasks().then(function (tasks) { apiClient.getScheduledTasks().then(function (tasks) {
renderRunningTasks(view, tasks); renderRunningTasks(view, tasks);
}); });
} }
function renderActiveConnections(view, sessions) { function renderActiveConnections(view, sessions) {
let html = ''; let html = '';
DashboardPage.sessionsList = sessions; DashboardPage.sessionsList = sessions;
const parentElement = view.querySelector('.activeDevices'); const parentElement = view.querySelector('.activeDevices');
@ -343,9 +341,9 @@ import confirm from '../../components/confirm/confirm';
if (deadSessionElem) { if (deadSessionElem) {
deadSessionElem.parentNode.removeChild(deadSessionElem); deadSessionElem.parentNode.removeChild(deadSessionElem);
} }
} }
function renderRunningTasks(view, tasks) { function renderRunningTasks(view, tasks) {
let html = ''; let html = '';
tasks = tasks.filter(function (task) { tasks = tasks.filter(function (task) {
if (task.State != 'Idle') { if (task.State != 'Idle') {
@ -381,9 +379,9 @@ import confirm from '../../components/confirm/confirm';
} }
view.querySelector('#divRunningTasks').innerHTML = html; view.querySelector('#divRunningTasks').innerHTML = html;
} }
window.DashboardPage = { window.DashboardPage = {
startInterval: function (apiClient) { startInterval: function (apiClient) {
apiClient.sendMessage('SessionsStart', '0,1500'); apiClient.sendMessage('SessionsStart', '0,1500');
apiClient.sendMessage('ScheduledTasksInfoStart', '0,1000'); apiClient.sendMessage('ScheduledTasksInfoStart', '0,1000');
@ -731,8 +729,8 @@ import confirm from '../../components/confirm/confirm';
ApiClient.shutdownServer(); ApiClient.shutdownServer();
}); });
} }
}; };
export default function (view) { export default function (view) {
function onRestartRequired(evt, apiClient) { function onRestartRequired(evt, apiClient) {
console.debug('onRestartRequired not implemented', evt, apiClient); console.debug('onRestartRequired not implemented', evt, apiClient);
} }
@ -844,6 +842,5 @@ import confirm from '../../components/confirm/confirm';
serverActivityLog.destroy(); serverActivityLog.destroy();
} }
}); });
} }
/* eslint-enable indent */

View file

@ -5,14 +5,12 @@ import '../../../elements/emby-button/emby-button';
import Dashboard from '../../../utils/dashboard'; import Dashboard from '../../../utils/dashboard';
import { getParameterByName } from '../../../utils/url.ts'; import { getParameterByName } from '../../../utils/url.ts';
/* eslint-disable indent */ function load(page, device, deviceOptions) {
function load(page, device, deviceOptions) {
page.querySelector('#txtCustomName', page).value = deviceOptions.CustomName || ''; page.querySelector('#txtCustomName', page).value = deviceOptions.CustomName || '';
page.querySelector('.reportedName', page).innerText = device.Name || ''; page.querySelector('.reportedName', page).innerText = device.Name || '';
} }
function loadData() { function loadData() {
const page = this; const page = this;
loading.show(); loading.show();
const id = getParameterByName('id'); const id = getParameterByName('id');
@ -26,9 +24,9 @@ import { getParameterByName } from '../../../utils/url.ts';
load(page, responses[0], responses[1]); load(page, responses[0], responses[1]);
loading.hide(); loading.hide();
}); });
} }
function save(page) { function save(page) {
const id = getParameterByName('id'); const id = getParameterByName('id');
ApiClient.ajax({ ApiClient.ajax({
url: ApiClient.getUrl('Devices/Options', { url: ApiClient.getUrl('Devices/Options', {
@ -40,18 +38,17 @@ import { getParameterByName } from '../../../utils/url.ts';
}), }),
contentType: 'application/json' contentType: 'application/json'
}).then(Dashboard.processServerConfigurationUpdateResult); }).then(Dashboard.processServerConfigurationUpdateResult);
} }
function onSubmit(e) { function onSubmit(e) {
const form = this; const form = this;
save(dom.parentWithClass(form, 'page')); save(dom.parentWithClass(form, 'page'));
e.preventDefault(); e.preventDefault();
return false; return false;
} }
export default function (view) { export default function (view) {
view.querySelector('form').addEventListener('submit', onSubmit); view.querySelector('form').addEventListener('submit', onSubmit);
view.addEventListener('viewshow', loadData); view.addEventListener('viewshow', loadData);
} }
/* eslint-enable indent */

View file

@ -12,16 +12,14 @@ import '../../../components/cardbuilder/card.scss';
import Dashboard from '../../../utils/dashboard'; import Dashboard from '../../../utils/dashboard';
import confirm from '../../../components/confirm/confirm'; import confirm from '../../../components/confirm/confirm';
/* eslint-disable indent */ // Local cache of loaded
let deviceIds = [];
// Local cache of loaded function canDelete(deviceId) {
let deviceIds = [];
function canDelete(deviceId) {
return deviceId !== ApiClient.deviceId(); return deviceId !== ApiClient.deviceId();
} }
function deleteAllDevices(page) { function deleteAllDevices(page) {
const msg = globalize.translate('DeleteDevicesConfirmation'); const msg = globalize.translate('DeleteDevicesConfirmation');
confirm({ confirm({
@ -36,9 +34,9 @@ import confirm from '../../../components/confirm/confirm';
); );
loadData(page); loadData(page);
}); });
} }
function deleteDevice(page, id) { function deleteDevice(page, id) {
const msg = globalize.translate('DeleteDeviceConfirmation'); const msg = globalize.translate('DeleteDeviceConfirmation');
confirm({ confirm({
@ -51,9 +49,9 @@ import confirm from '../../../components/confirm/confirm';
await ApiClient.deleteDevice(id); await ApiClient.deleteDevice(id);
loadData(page); loadData(page);
}); });
} }
function showDeviceMenu(view, btn, deviceId) { function showDeviceMenu(view, btn, deviceId) {
const menuItems = [{ const menuItems = [{
name: globalize.translate('Edit'), name: globalize.translate('Edit'),
id: 'open', id: 'open',
@ -68,7 +66,7 @@ import confirm from '../../../components/confirm/confirm';
}); });
} }
import('../../../components/actionSheet/actionSheet').then(({default: actionsheet}) => { import('../../../components/actionSheet/actionSheet').then(({ default: actionsheet }) => {
actionsheet.show({ actionsheet.show({
items: menuItems, items: menuItems,
positionTo: btn, positionTo: btn,
@ -84,9 +82,9 @@ import confirm from '../../../components/confirm/confirm';
} }
}); });
}); });
} }
function load(page, devices) { function load(page, devices) {
const localeWithSuffix = getLocaleWithSuffix(); const localeWithSuffix = getLocaleWithSuffix();
let html = ''; let html = '';
@ -140,18 +138,18 @@ import confirm from '../../../components/confirm/confirm';
return deviceHtml; return deviceHtml;
}).join(''); }).join('');
page.querySelector('.devicesList').innerHTML = html; page.querySelector('.devicesList').innerHTML = html;
} }
function loadData(page) { function loadData(page) {
loading.show(); loading.show();
ApiClient.getJSON(ApiClient.getUrl('Devices')).then(function (result) { ApiClient.getJSON(ApiClient.getUrl('Devices')).then(function (result) {
load(page, result.Items); load(page, result.Items);
deviceIds = result.Items.map((device) => device.Id); deviceIds = result.Items.map((device) => device.Id);
loading.hide(); loading.hide();
}); });
} }
export default function (view) { export default function (view) {
view.querySelector('.devicesList').addEventListener('click', function (e) { view.querySelector('.devicesList').addEventListener('click', function (e) {
const btnDeviceMenu = dom.parentWithClass(e.target, 'btnDeviceMenu'); const btnDeviceMenu = dom.parentWithClass(e.target, 'btnDeviceMenu');
@ -166,5 +164,5 @@ import confirm from '../../../components/confirm/confirm';
view.querySelector('#deviceDeleteAll').addEventListener('click', function() { view.querySelector('#deviceDeleteAll').addEventListener('click', function() {
deleteAllDevices(view); deleteAllDevices(view);
}); });
} }
/* eslint-enable indent */

View file

@ -11,9 +11,7 @@ import Dashboard from '../../../utils/dashboard';
import toast from '../../../components/toast/toast'; import toast from '../../../components/toast/toast';
import { getParameterByName } from '../../../utils/url.ts'; import { getParameterByName } from '../../../utils/url.ts';
/* eslint-disable indent */ function loadProfile(page) {
function loadProfile(page) {
loading.show(); loading.show();
const promise1 = getProfile(); const promise1 = getProfile();
const promise2 = ApiClient.getUsers(); const promise2 = ApiClient.getUsers();
@ -22,15 +20,15 @@ import { getParameterByName } from '../../../utils/url.ts';
renderProfile(page, currentProfile, responses[1]); renderProfile(page, currentProfile, responses[1]);
loading.hide(); loading.hide();
}); });
} }
function getProfile() { function getProfile() {
const id = getParameterByName('id'); const id = getParameterByName('id');
const url = id ? 'Dlna/Profiles/' + id : 'Dlna/Profiles/Default'; const url = id ? 'Dlna/Profiles/' + id : 'Dlna/Profiles/Default';
return ApiClient.getJSON(ApiClient.getUrl(url)); return ApiClient.getJSON(ApiClient.getUrl(url));
} }
function renderProfile(page, profile, users) { function renderProfile(page, profile, users) {
$('#txtName', page).val(profile.Name); $('#txtName', page).val(profile.Name);
$('.chkMediaType', page).each(function () { $('.chkMediaType', page).each(function () {
this.checked = (profile.SupportedMediaTypes || '').split(',').indexOf(this.getAttribute('data-value')) != -1; this.checked = (profile.SupportedMediaTypes || '').split(',').indexOf(this.getAttribute('data-value')) != -1;
@ -82,9 +80,9 @@ import { getParameterByName } from '../../../utils/url.ts';
}).join(''); }).join('');
$('#selectUser', page).html(usersHtml).val(profile.UserId || ''); $('#selectUser', page).html(usersHtml).val(profile.UserId || '');
renderSubProfiles(page, profile); renderSubProfiles(page, profile);
} }
function renderIdentificationHeaders(page, headers) { function renderIdentificationHeaders(page, headers) {
let index = 0; let index = 0;
const html = '<div class="paperList">' + headers.map(function (h) { const html = '<div class="paperList">' + headers.map(function (h) {
let li = '<div class="listItem">'; let li = '<div class="listItem">';
@ -104,17 +102,17 @@ import { getParameterByName } from '../../../utils/url.ts';
currentProfile.Identification.Headers.splice(itemIndex, 1); currentProfile.Identification.Headers.splice(itemIndex, 1);
renderIdentificationHeaders(page, currentProfile.Identification.Headers); renderIdentificationHeaders(page, currentProfile.Identification.Headers);
}); });
} }
function openPopup(elem) { function openPopup(elem) {
elem.classList.remove('hide'); elem.classList.remove('hide');
} }
function closePopup(elem) { function closePopup(elem) {
elem.classList.add('hide'); elem.classList.add('hide');
} }
function editIdentificationHeader(page, header) { function editIdentificationHeader(page, header) {
isSubProfileNew = header == null; isSubProfileNew = header == null;
header = header || {}; header = header || {};
currentSubProfile = header; currentSubProfile = header;
@ -123,9 +121,9 @@ import { getParameterByName } from '../../../utils/url.ts';
$('#txtIdentificationHeaderValue', popup).val(header.Value || ''); $('#txtIdentificationHeaderValue', popup).val(header.Value || '');
$('#selectMatchType', popup).val(header.Match || 'Equals'); $('#selectMatchType', popup).val(header.Match || 'Equals');
openPopup(popup[0]); openPopup(popup[0]);
} }
function saveIdentificationHeader(page) { function saveIdentificationHeader(page) {
currentSubProfile.Name = $('#txtIdentificationHeaderName', page).val(); currentSubProfile.Name = $('#txtIdentificationHeaderName', page).val();
currentSubProfile.Value = $('#txtIdentificationHeaderValue', page).val(); currentSubProfile.Value = $('#txtIdentificationHeaderValue', page).val();
currentSubProfile.Match = $('#selectMatchType', page).val(); currentSubProfile.Match = $('#selectMatchType', page).val();
@ -139,9 +137,9 @@ import { getParameterByName } from '../../../utils/url.ts';
renderIdentificationHeaders(page, currentProfile.Identification.Headers); renderIdentificationHeaders(page, currentProfile.Identification.Headers);
currentSubProfile = null; currentSubProfile = null;
closePopup($('#identificationHeaderPopup', page)[0]); closePopup($('#identificationHeaderPopup', page)[0]);
} }
function renderXmlDocumentAttributes(page, attribute) { function renderXmlDocumentAttributes(page, attribute) {
const html = '<div class="paperList">' + attribute.map(function (h) { const html = '<div class="paperList">' + attribute.map(function (h) {
let li = '<div class="listItem">'; let li = '<div class="listItem">';
li += '<span class="material-icons listItemIcon info" aria-hidden="true"></span>'; li += '<span class="material-icons listItemIcon info" aria-hidden="true"></span>';
@ -158,9 +156,9 @@ import { getParameterByName } from '../../../utils/url.ts';
currentProfile.XmlRootAttributes.splice(itemIndex, 1); currentProfile.XmlRootAttributes.splice(itemIndex, 1);
renderXmlDocumentAttributes(page, currentProfile.XmlRootAttributes); renderXmlDocumentAttributes(page, currentProfile.XmlRootAttributes);
}); });
} }
function editXmlDocumentAttribute(page, attribute) { function editXmlDocumentAttribute(page, attribute) {
isSubProfileNew = attribute == null; isSubProfileNew = attribute == null;
attribute = attribute || {}; attribute = attribute || {};
currentSubProfile = attribute; currentSubProfile = attribute;
@ -168,9 +166,9 @@ import { getParameterByName } from '../../../utils/url.ts';
$('#txtXmlAttributeName', popup).val(attribute.Name || ''); $('#txtXmlAttributeName', popup).val(attribute.Name || '');
$('#txtXmlAttributeValue', popup).val(attribute.Value || ''); $('#txtXmlAttributeValue', popup).val(attribute.Value || '');
openPopup(popup[0]); openPopup(popup[0]);
} }
function saveXmlDocumentAttribute(page) { function saveXmlDocumentAttribute(page) {
currentSubProfile.Name = $('#txtXmlAttributeName', page).val(); currentSubProfile.Name = $('#txtXmlAttributeName', page).val();
currentSubProfile.Value = $('#txtXmlAttributeValue', page).val(); currentSubProfile.Value = $('#txtXmlAttributeValue', page).val();
@ -181,9 +179,9 @@ import { getParameterByName } from '../../../utils/url.ts';
renderXmlDocumentAttributes(page, currentProfile.XmlRootAttributes); renderXmlDocumentAttributes(page, currentProfile.XmlRootAttributes);
currentSubProfile = null; currentSubProfile = null;
closePopup($('#xmlAttributePopup', page)[0]); closePopup($('#xmlAttributePopup', page)[0]);
} }
function renderSubtitleProfiles(page, profiles) { function renderSubtitleProfiles(page, profiles) {
let index = 0; let index = 0;
const html = '<div class="paperList">' + profiles.map(function (h) { const html = '<div class="paperList">' + profiles.map(function (h) {
let li = '<div class="listItem lnkEditSubProfile" data-index="' + index + '">'; let li = '<div class="listItem lnkEditSubProfile" data-index="' + index + '">';
@ -206,9 +204,9 @@ import { getParameterByName } from '../../../utils/url.ts';
const itemIndex = parseInt(this.getAttribute('data-index'), 10); const itemIndex = parseInt(this.getAttribute('data-index'), 10);
editSubtitleProfile(page, currentProfile.SubtitleProfiles[itemIndex]); editSubtitleProfile(page, currentProfile.SubtitleProfiles[itemIndex]);
}); });
} }
function editSubtitleProfile(page, profile) { function editSubtitleProfile(page, profile) {
isSubProfileNew = profile == null; isSubProfileNew = profile == null;
profile = profile || {}; profile = profile || {};
currentSubProfile = profile; currentSubProfile = profile;
@ -217,9 +215,9 @@ import { getParameterByName } from '../../../utils/url.ts';
$('#selectSubtitleProfileMethod', popup).val(profile.Method || ''); $('#selectSubtitleProfileMethod', popup).val(profile.Method || '');
$('#selectSubtitleProfileDidlMode', popup).val(profile.DidlMode || ''); $('#selectSubtitleProfileDidlMode', popup).val(profile.DidlMode || '');
openPopup(popup[0]); openPopup(popup[0]);
} }
function saveSubtitleProfile(page) { function saveSubtitleProfile(page) {
currentSubProfile.Format = $('#txtSubtitleProfileFormat', page).val(); currentSubProfile.Format = $('#txtSubtitleProfileFormat', page).val();
currentSubProfile.Method = $('#selectSubtitleProfileMethod', page).val(); currentSubProfile.Method = $('#selectSubtitleProfileMethod', page).val();
currentSubProfile.DidlMode = $('#selectSubtitleProfileDidlMode', page).val(); currentSubProfile.DidlMode = $('#selectSubtitleProfileDidlMode', page).val();
@ -231,17 +229,17 @@ import { getParameterByName } from '../../../utils/url.ts';
renderSubtitleProfiles(page, currentProfile.SubtitleProfiles); renderSubtitleProfiles(page, currentProfile.SubtitleProfiles);
currentSubProfile = null; currentSubProfile = null;
closePopup($('#subtitleProfilePopup', page)[0]); closePopup($('#subtitleProfilePopup', page)[0]);
} }
function renderSubProfiles(page, profile) { function renderSubProfiles(page, profile) {
renderDirectPlayProfiles(page, profile.DirectPlayProfiles); renderDirectPlayProfiles(page, profile.DirectPlayProfiles);
renderTranscodingProfiles(page, profile.TranscodingProfiles); renderTranscodingProfiles(page, profile.TranscodingProfiles);
renderContainerProfiles(page, profile.ContainerProfiles); renderContainerProfiles(page, profile.ContainerProfiles);
renderCodecProfiles(page, profile.CodecProfiles); renderCodecProfiles(page, profile.CodecProfiles);
renderResponseProfiles(page, profile.ResponseProfiles); renderResponseProfiles(page, profile.ResponseProfiles);
} }
function saveDirectPlayProfile(page) { function saveDirectPlayProfile(page) {
currentSubProfile.Type = $('#selectDirectPlayProfileType', page).val(); currentSubProfile.Type = $('#selectDirectPlayProfileType', page).val();
currentSubProfile.Container = $('#txtDirectPlayContainer', page).val(); currentSubProfile.Container = $('#txtDirectPlayContainer', page).val();
currentSubProfile.AudioCodec = $('#txtDirectPlayAudioCodec', page).val(); currentSubProfile.AudioCodec = $('#txtDirectPlayAudioCodec', page).val();
@ -254,9 +252,9 @@ import { getParameterByName } from '../../../utils/url.ts';
renderSubProfiles(page, currentProfile); renderSubProfiles(page, currentProfile);
currentSubProfile = null; currentSubProfile = null;
closePopup($('#popupEditDirectPlayProfile', page)[0]); closePopup($('#popupEditDirectPlayProfile', page)[0]);
} }
function renderDirectPlayProfiles(page, profiles) { function renderDirectPlayProfiles(page, profiles) {
let html = ''; let html = '';
html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">'; html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
let currentType; let currentType;
@ -295,14 +293,14 @@ import { getParameterByName } from '../../../utils/url.ts';
const index = parseInt(this.getAttribute('data-profileindex'), 10); const index = parseInt(this.getAttribute('data-profileindex'), 10);
editDirectPlayProfile(page, currentProfile.DirectPlayProfiles[index]); editDirectPlayProfile(page, currentProfile.DirectPlayProfiles[index]);
}); });
} }
function deleteDirectPlayProfile(page, index) { function deleteDirectPlayProfile(page, index) {
currentProfile.DirectPlayProfiles.splice(index, 1); currentProfile.DirectPlayProfiles.splice(index, 1);
renderDirectPlayProfiles(page, currentProfile.DirectPlayProfiles); renderDirectPlayProfiles(page, currentProfile.DirectPlayProfiles);
} }
function editDirectPlayProfile(page, directPlayProfile) { function editDirectPlayProfile(page, directPlayProfile) {
isSubProfileNew = directPlayProfile == null; isSubProfileNew = directPlayProfile == null;
directPlayProfile = directPlayProfile || {}; directPlayProfile = directPlayProfile || {};
currentSubProfile = directPlayProfile; currentSubProfile = directPlayProfile;
@ -312,9 +310,9 @@ import { getParameterByName } from '../../../utils/url.ts';
$('#txtDirectPlayAudioCodec', popup).val(directPlayProfile.AudioCodec || ''); $('#txtDirectPlayAudioCodec', popup).val(directPlayProfile.AudioCodec || '');
$('#txtDirectPlayVideoCodec', popup).val(directPlayProfile.VideoCodec || ''); $('#txtDirectPlayVideoCodec', popup).val(directPlayProfile.VideoCodec || '');
openPopup(popup[0]); openPopup(popup[0]);
} }
function renderTranscodingProfiles(page, profiles) { function renderTranscodingProfiles(page, profiles) {
let html = ''; let html = '';
html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">'; html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
let currentType; let currentType;
@ -356,9 +354,9 @@ import { getParameterByName } from '../../../utils/url.ts';
const index = parseInt(this.getAttribute('data-profileindex'), 10); const index = parseInt(this.getAttribute('data-profileindex'), 10);
editTranscodingProfile(page, currentProfile.TranscodingProfiles[index]); editTranscodingProfile(page, currentProfile.TranscodingProfiles[index]);
}); });
} }
function editTranscodingProfile(page, transcodingProfile) { function editTranscodingProfile(page, transcodingProfile) {
isSubProfileNew = transcodingProfile == null; isSubProfileNew = transcodingProfile == null;
transcodingProfile = transcodingProfile || {}; transcodingProfile = transcodingProfile || {};
currentSubProfile = transcodingProfile; currentSubProfile = transcodingProfile;
@ -373,14 +371,14 @@ import { getParameterByName } from '../../../utils/url.ts';
$('#chkReportByteRangeRequests', popup).prop('checked', transcodingProfile.TranscodeSeekInfo == 'Bytes'); $('#chkReportByteRangeRequests', popup).prop('checked', transcodingProfile.TranscodeSeekInfo == 'Bytes');
$('.radioTabButton:first', popup).trigger('click'); $('.radioTabButton:first', popup).trigger('click');
openPopup(popup[0]); openPopup(popup[0]);
} }
function deleteTranscodingProfile(page, index) { function deleteTranscodingProfile(page, index) {
currentProfile.TranscodingProfiles.splice(index, 1); currentProfile.TranscodingProfiles.splice(index, 1);
renderTranscodingProfiles(page, currentProfile.TranscodingProfiles); renderTranscodingProfiles(page, currentProfile.TranscodingProfiles);
} }
function saveTranscodingProfile(page) { function saveTranscodingProfile(page) {
currentSubProfile.Type = $('#selectTranscodingProfileType', page).val(); currentSubProfile.Type = $('#selectTranscodingProfileType', page).val();
currentSubProfile.Container = $('#txtTranscodingContainer', page).val(); currentSubProfile.Container = $('#txtTranscodingContainer', page).val();
currentSubProfile.AudioCodec = $('#txtTranscodingAudioCodec', page).val(); currentSubProfile.AudioCodec = $('#txtTranscodingAudioCodec', page).val();
@ -398,9 +396,9 @@ import { getParameterByName } from '../../../utils/url.ts';
renderSubProfiles(page, currentProfile); renderSubProfiles(page, currentProfile);
currentSubProfile = null; currentSubProfile = null;
closePopup($('#transcodingProfilePopup', page)[0]); closePopup($('#transcodingProfilePopup', page)[0]);
} }
function renderContainerProfiles(page, profiles) { function renderContainerProfiles(page, profiles) {
let html = ''; let html = '';
html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">'; html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
let currentType; let currentType;
@ -440,14 +438,14 @@ import { getParameterByName } from '../../../utils/url.ts';
const index = parseInt(this.getAttribute('data-profileindex'), 10); const index = parseInt(this.getAttribute('data-profileindex'), 10);
editContainerProfile(page, currentProfile.ContainerProfiles[index]); editContainerProfile(page, currentProfile.ContainerProfiles[index]);
}); });
} }
function deleteContainerProfile(page, index) { function deleteContainerProfile(page, index) {
currentProfile.ContainerProfiles.splice(index, 1); currentProfile.ContainerProfiles.splice(index, 1);
renderContainerProfiles(page, currentProfile.ContainerProfiles); renderContainerProfiles(page, currentProfile.ContainerProfiles);
} }
function editContainerProfile(page, containerProfile) { function editContainerProfile(page, containerProfile) {
isSubProfileNew = containerProfile == null; isSubProfileNew = containerProfile == null;
containerProfile = containerProfile || {}; containerProfile = containerProfile || {};
currentSubProfile = containerProfile; currentSubProfile = containerProfile;
@ -456,9 +454,9 @@ import { getParameterByName } from '../../../utils/url.ts';
$('#txtContainerProfileContainer', popup).val(containerProfile.Container || ''); $('#txtContainerProfileContainer', popup).val(containerProfile.Container || '');
$('.radioTabButton:first', popup).trigger('click'); $('.radioTabButton:first', popup).trigger('click');
openPopup(popup[0]); openPopup(popup[0]);
} }
function saveContainerProfile(page) { function saveContainerProfile(page) {
currentSubProfile.Type = $('#selectContainerProfileType', page).val(); currentSubProfile.Type = $('#selectContainerProfileType', page).val();
currentSubProfile.Container = $('#txtContainerProfileContainer', page).val(); currentSubProfile.Container = $('#txtContainerProfileContainer', page).val();
@ -469,9 +467,9 @@ import { getParameterByName } from '../../../utils/url.ts';
renderSubProfiles(page, currentProfile); renderSubProfiles(page, currentProfile);
currentSubProfile = null; currentSubProfile = null;
closePopup($('#containerProfilePopup', page)[0]); closePopup($('#containerProfilePopup', page)[0]);
} }
function renderCodecProfiles(page, profiles) { function renderCodecProfiles(page, profiles) {
let html = ''; let html = '';
html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">'; html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
let currentType; let currentType;
@ -512,14 +510,14 @@ import { getParameterByName } from '../../../utils/url.ts';
const index = parseInt(this.getAttribute('data-profileindex'), 10); const index = parseInt(this.getAttribute('data-profileindex'), 10);
editCodecProfile(page, currentProfile.CodecProfiles[index]); editCodecProfile(page, currentProfile.CodecProfiles[index]);
}); });
} }
function deleteCodecProfile(page, index) { function deleteCodecProfile(page, index) {
currentProfile.CodecProfiles.splice(index, 1); currentProfile.CodecProfiles.splice(index, 1);
renderCodecProfiles(page, currentProfile.CodecProfiles); renderCodecProfiles(page, currentProfile.CodecProfiles);
} }
function editCodecProfile(page, codecProfile) { function editCodecProfile(page, codecProfile) {
isSubProfileNew = codecProfile == null; isSubProfileNew = codecProfile == null;
codecProfile = codecProfile || {}; codecProfile = codecProfile || {};
currentSubProfile = codecProfile; currentSubProfile = codecProfile;
@ -528,9 +526,9 @@ import { getParameterByName } from '../../../utils/url.ts';
$('#txtCodecProfileCodec', popup).val(codecProfile.Codec || ''); $('#txtCodecProfileCodec', popup).val(codecProfile.Codec || '');
$('.radioTabButton:first', popup).trigger('click'); $('.radioTabButton:first', popup).trigger('click');
openPopup(popup[0]); openPopup(popup[0]);
} }
function saveCodecProfile(page) { function saveCodecProfile(page) {
currentSubProfile.Type = $('#selectCodecProfileType', page).val(); currentSubProfile.Type = $('#selectCodecProfileType', page).val();
currentSubProfile.Codec = $('#txtCodecProfileCodec', page).val(); currentSubProfile.Codec = $('#txtCodecProfileCodec', page).val();
@ -541,9 +539,9 @@ import { getParameterByName } from '../../../utils/url.ts';
renderSubProfiles(page, currentProfile); renderSubProfiles(page, currentProfile);
currentSubProfile = null; currentSubProfile = null;
closePopup($('#codecProfilePopup', page)[0]); closePopup($('#codecProfilePopup', page)[0]);
} }
function renderResponseProfiles(page, profiles) { function renderResponseProfiles(page, profiles) {
let html = ''; let html = '';
html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">'; html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
let currentType; let currentType;
@ -592,14 +590,14 @@ import { getParameterByName } from '../../../utils/url.ts';
const index = parseInt(this.getAttribute('data-profileindex'), 10); const index = parseInt(this.getAttribute('data-profileindex'), 10);
editResponseProfile(page, currentProfile.ResponseProfiles[index]); editResponseProfile(page, currentProfile.ResponseProfiles[index]);
}); });
} }
function deleteResponseProfile(page, index) { function deleteResponseProfile(page, index) {
currentProfile.ResponseProfiles.splice(index, 1); currentProfile.ResponseProfiles.splice(index, 1);
renderResponseProfiles(page, currentProfile.ResponseProfiles); renderResponseProfiles(page, currentProfile.ResponseProfiles);
} }
function editResponseProfile(page, responseProfile) { function editResponseProfile(page, responseProfile) {
isSubProfileNew = responseProfile == null; isSubProfileNew = responseProfile == null;
responseProfile = responseProfile || {}; responseProfile = responseProfile || {};
currentSubProfile = responseProfile; currentSubProfile = responseProfile;
@ -610,9 +608,9 @@ import { getParameterByName } from '../../../utils/url.ts';
$('#txtResponseProfileVideoCodec', popup).val(responseProfile.VideoCodec || ''); $('#txtResponseProfileVideoCodec', popup).val(responseProfile.VideoCodec || '');
$('.radioTabButton:first', popup).trigger('click'); $('.radioTabButton:first', popup).trigger('click');
openPopup(popup[0]); openPopup(popup[0]);
} }
function saveResponseProfile(page) { function saveResponseProfile(page) {
currentSubProfile.Type = $('#selectResponseProfileType', page).val(); currentSubProfile.Type = $('#selectResponseProfileType', page).val();
currentSubProfile.Container = $('#txtResponseProfileContainer', page).val(); currentSubProfile.Container = $('#txtResponseProfileContainer', page).val();
currentSubProfile.AudioCodec = $('#txtResponseProfileAudioCodec', page).val(); currentSubProfile.AudioCodec = $('#txtResponseProfileAudioCodec', page).val();
@ -625,9 +623,9 @@ import { getParameterByName } from '../../../utils/url.ts';
renderSubProfiles(page, currentProfile); renderSubProfiles(page, currentProfile);
currentSubProfile = null; currentSubProfile = null;
closePopup($('#responseProfilePopup', page)[0]); closePopup($('#responseProfilePopup', page)[0]);
} }
function saveProfile(page, profile) { function saveProfile(page, profile) {
updateProfile(page, profile); updateProfile(page, profile);
const id = getParameterByName('id'); const id = getParameterByName('id');
@ -652,9 +650,9 @@ import { getParameterByName } from '../../../utils/url.ts';
} }
loading.hide(); loading.hide();
} }
function updateProfile(page, profile) { function updateProfile(page, profile) {
profile.Name = $('#txtName', page).val(); profile.Name = $('#txtName', page).val();
profile.EnableAlbumArtInDidl = $('#chkEnableAlbumArtInDidl', page).is(':checked'); profile.EnableAlbumArtInDidl = $('#chkEnableAlbumArtInDidl', page).is(':checked');
profile.EnableSingleAlbumArtLimit = $('#chkEnableSingleImageLimit', page).is(':checked'); profile.EnableSingleAlbumArtLimit = $('#chkEnableSingleImageLimit', page).is(':checked');
@ -694,14 +692,14 @@ import { getParameterByName } from '../../../utils/url.ts';
profile.XDlnaDoc = $('#txtXDlnaDoc', page).val(); profile.XDlnaDoc = $('#txtXDlnaDoc', page).val();
profile.SonyAggregationFlags = $('#txtSonyAggregationFlags', page).val(); profile.SonyAggregationFlags = $('#txtSonyAggregationFlags', page).val();
profile.UserId = $('#selectUser', page).val(); profile.UserId = $('#selectUser', page).val();
} }
let currentProfile; let currentProfile;
let currentSubProfile; let currentSubProfile;
let isSubProfileNew; let isSubProfileNew;
const allText = globalize.translate('All'); const allText = globalize.translate('All');
$(document).on('pageinit', '#dlnaProfilePage', function () { $(document).on('pageinit', '#dlnaProfilePage', function () {
const page = this; const page = this;
$('.radioTabButton', page).on('click', function () { $('.radioTabButton', page).on('click', function () {
$(this).siblings().removeClass('ui-btn-active'); $(this).siblings().removeClass('ui-btn-active');
@ -791,12 +789,12 @@ import { getParameterByName } from '../../../utils/url.ts';
$('.identificationHeaderForm').off('submit', DlnaProfilePage.onIdentificationHeaderFormSubmit).on('submit', DlnaProfilePage.onIdentificationHeaderFormSubmit); $('.identificationHeaderForm').off('submit', DlnaProfilePage.onIdentificationHeaderFormSubmit).on('submit', DlnaProfilePage.onIdentificationHeaderFormSubmit);
$('.xmlAttributeForm').off('submit', DlnaProfilePage.onXmlAttributeFormSubmit).on('submit', DlnaProfilePage.onXmlAttributeFormSubmit); $('.xmlAttributeForm').off('submit', DlnaProfilePage.onXmlAttributeFormSubmit).on('submit', DlnaProfilePage.onXmlAttributeFormSubmit);
$('.subtitleProfileForm').off('submit', DlnaProfilePage.onSubtitleProfileFormSubmit).on('submit', DlnaProfilePage.onSubtitleProfileFormSubmit); $('.subtitleProfileForm').off('submit', DlnaProfilePage.onSubtitleProfileFormSubmit).on('submit', DlnaProfilePage.onSubtitleProfileFormSubmit);
}).on('pageshow', '#dlnaProfilePage', function () { }).on('pageshow', '#dlnaProfilePage', function () {
const page = this; const page = this;
$('#radioInfo', page).trigger('click'); $('#radioInfo', page).trigger('click');
loadProfile(page); loadProfile(page);
}); });
window.DlnaProfilePage = { window.DlnaProfilePage = {
onSubmit: function () { onSubmit: function () {
loading.show(); loading.show();
saveProfile($(this).parents('.page'), currentProfile); saveProfile($(this).parents('.page'), currentProfile);
@ -834,6 +832,5 @@ import { getParameterByName } from '../../../utils/url.ts';
saveSubtitleProfile($(this).parents('.page')); saveSubtitleProfile($(this).parents('.page'));
return false; return false;
} }
}; };
/* eslint-enable indent */

View file

@ -7,30 +7,28 @@ import '../../../components/listview/listview.scss';
import '../../../elements/emby-button/emby-button'; import '../../../elements/emby-button/emby-button';
import confirm from '../../../components/confirm/confirm'; import confirm from '../../../components/confirm/confirm';
/* eslint-disable indent */ function loadProfiles(page) {
function loadProfiles(page) {
loading.show(); loading.show();
ApiClient.getJSON(ApiClient.getUrl('Dlna/ProfileInfos')).then(function (result) { ApiClient.getJSON(ApiClient.getUrl('Dlna/ProfileInfos')).then(function (result) {
renderUserProfiles(page, result); renderUserProfiles(page, result);
renderSystemProfiles(page, result); renderSystemProfiles(page, result);
loading.hide(); loading.hide();
}); });
} }
function renderUserProfiles(page, profiles) { function renderUserProfiles(page, profiles) {
renderProfiles(page, page.querySelector('.customProfiles'), profiles.filter(function (p) { renderProfiles(page, page.querySelector('.customProfiles'), profiles.filter(function (p) {
return p.Type == 'User'; return p.Type == 'User';
})); }));
} }
function renderSystemProfiles(page, profiles) { function renderSystemProfiles(page, profiles) {
renderProfiles(page, page.querySelector('.systemProfiles'), profiles.filter(function (p) { renderProfiles(page, page.querySelector('.systemProfiles'), profiles.filter(function (p) {
return p.Type == 'System'; return p.Type == 'System';
})); }));
} }
function renderProfiles(page, element, profiles) { function renderProfiles(page, element, profiles) {
let html = ''; let html = '';
if (profiles.length) { if (profiles.length) {
@ -63,9 +61,9 @@ import confirm from '../../../components/confirm/confirm';
const id = this.getAttribute('data-profileid'); const id = this.getAttribute('data-profileid');
deleteProfile(page, id); deleteProfile(page, id);
}); });
} }
function deleteProfile(page, id) { function deleteProfile(page, id) {
confirm(globalize.translate('MessageConfirmProfileDeletion'), globalize.translate('HeaderConfirmProfileDeletion')).then(function () { confirm(globalize.translate('MessageConfirmProfileDeletion'), globalize.translate('HeaderConfirmProfileDeletion')).then(function () {
loading.show(); loading.show();
ApiClient.ajax({ ApiClient.ajax({
@ -76,9 +74,9 @@ import confirm from '../../../components/confirm/confirm';
loadProfiles(page); loadProfiles(page);
}); });
}); });
} }
function getTabs() { function getTabs() {
return [{ return [{
href: '#/dlnasettings.html', href: '#/dlnasettings.html',
name: globalize.translate('Settings') name: globalize.translate('Settings')
@ -86,11 +84,10 @@ import confirm from '../../../components/confirm/confirm';
href: '#/dlnaprofiles.html', href: '#/dlnaprofiles.html',
name: globalize.translate('TabProfiles') name: globalize.translate('TabProfiles')
}]; }];
} }
$(document).on('pageshow', '#dlnaProfilesPage', function () { $(document).on('pageshow', '#dlnaProfilesPage', function () {
libraryMenu.setTabs('dlna', 1, getTabs); libraryMenu.setTabs('dlna', 1, getTabs);
loadProfiles(this); loadProfiles(this);
}); });
/* eslint-enable indent */

View file

@ -5,9 +5,7 @@ import libraryMenu from '../../../scripts/libraryMenu';
import globalize from '../../../scripts/globalize'; import globalize from '../../../scripts/globalize';
import Dashboard from '../../../utils/dashboard'; import Dashboard from '../../../utils/dashboard';
/* eslint-disable indent */ function loadPage(page, config, users) {
function loadPage(page, config, users) {
page.querySelector('#chkEnablePlayTo').checked = config.EnablePlayTo; page.querySelector('#chkEnablePlayTo').checked = config.EnablePlayTo;
page.querySelector('#chkEnableDlnaDebugLogging').checked = config.EnableDebugLog; page.querySelector('#chkEnableDlnaDebugLogging').checked = config.EnableDebugLog;
$('#txtClientDiscoveryInterval', page).val(config.ClientDiscoveryIntervalSeconds); $('#txtClientDiscoveryInterval', page).val(config.ClientDiscoveryIntervalSeconds);
@ -19,9 +17,9 @@ import Dashboard from '../../../utils/dashboard';
}).join(''); }).join('');
$('#selectUser', page).html(usersHtml).val(config.DefaultUserId || ''); $('#selectUser', page).html(usersHtml).val(config.DefaultUserId || '');
loading.hide(); loading.hide();
} }
function onSubmit() { function onSubmit() {
loading.show(); loading.show();
const form = this; const form = this;
ApiClient.getNamedConfiguration('dlna').then(function (config) { ApiClient.getNamedConfiguration('dlna').then(function (config) {
@ -35,9 +33,9 @@ import Dashboard from '../../../utils/dashboard';
ApiClient.updateNamedConfiguration('dlna', config).then(Dashboard.processServerConfigurationUpdateResult); ApiClient.updateNamedConfiguration('dlna', config).then(Dashboard.processServerConfigurationUpdateResult);
}); });
return false; return false;
} }
function getTabs() { function getTabs() {
return [{ return [{
href: '#/dlnasettings.html', href: '#/dlnasettings.html',
name: globalize.translate('Settings') name: globalize.translate('Settings')
@ -45,11 +43,11 @@ import Dashboard from '../../../utils/dashboard';
href: '#/dlnaprofiles.html', href: '#/dlnaprofiles.html',
name: globalize.translate('TabProfiles') name: globalize.translate('TabProfiles')
}]; }];
} }
$(document).on('pageinit', '#dlnaSettingsPage', function () { $(document).on('pageinit', '#dlnaSettingsPage', function () {
$('.dlnaSettingsForm').off('submit', onSubmit).on('submit', onSubmit); $('.dlnaSettingsForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#dlnaSettingsPage', function () { }).on('pageshow', '#dlnaSettingsPage', function () {
libraryMenu.setTabs('dlna', 0, getTabs); libraryMenu.setTabs('dlna', 0, getTabs);
loading.show(); loading.show();
const page = this; const page = this;
@ -58,6 +56,5 @@ import Dashboard from '../../../utils/dashboard';
Promise.all([promise1, promise2]).then(function (responses) { Promise.all([promise1, promise2]).then(function (responses) {
loadPage(page, responses[0], responses[1]); loadPage(page, responses[0], responses[1]);
}); });
}); });
/* eslint-enable indent */

View file

@ -111,7 +111,7 @@
<span>${EnableIntelLowPowerHevcHwEncoder}</span> <span>${EnableIntelLowPowerHevcHwEncoder}</span>
</label> </label>
<div class="fieldDescription"> <div class="fieldDescription">
<a is="emby-linkbutton" rel="noopener noreferrer" class="button-link" href="https://01.org/linuxgraphics/downloads/firmware" target="_blank">${IntelLowPowerEncHelp}</a> <a is="emby-linkbutton" rel="noopener noreferrer" class="button-link" href="https://jellyfin.org/docs/general/administration/hardware-acceleration/intel#configure-and-verify-lp-mode-on-linux" target="_blank">${IntelLowPowerEncHelp}</a>
</div> </div>
</div> </div>
</div> </div>
@ -253,6 +253,13 @@
</label> </label>
<div class="fieldDescription checkboxFieldDescription">${EnableFallbackFontHelp}</div> <div class="fieldDescription checkboxFieldDescription">${EnableFallbackFontHelp}</div>
</div> </div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="chkEnableAudioVbr" />
<span>${LabelEnableAudioVbr}</span>
</label>
<div class="fieldDescription checkboxFieldDescription">${LabelEnableAudioVbrHelp}</div>
</div>
<div class="inputContainer"> <div class="inputContainer">
<input is="emby-input" type="number" id="txtDownMixAudioBoost" pattern="[0-9]*" required="required" min=".5" max="3" step=".1" label="${LabelDownMixAudioScale}" /> <input is="emby-input" type="number" id="txtDownMixAudioBoost" pattern="[0-9]*" required="required" min=".5" max="3" step=".1" label="${LabelDownMixAudioScale}" />
<div class="fieldDescription">${LabelDownMixAudioScaleHelp}</div> <div class="fieldDescription">${LabelDownMixAudioScaleHelp}</div>

View file

@ -6,9 +6,7 @@ import libraryMenu from '../../scripts/libraryMenu';
import Dashboard from '../../utils/dashboard'; import Dashboard from '../../utils/dashboard';
import alert from '../../components/alert'; import alert from '../../components/alert';
/* eslint-disable indent */ function loadPage(page, config, systemInfo) {
function loadPage(page, config, systemInfo) {
Array.prototype.forEach.call(page.querySelectorAll('.chkDecodeCodec'), function (c) { Array.prototype.forEach.call(page.querySelectorAll('.chkDecodeCodec'), function (c) {
c.checked = (config.HardwareDecodingCodecs || []).indexOf(c.getAttribute('data-codec')) !== -1; c.checked = (config.HardwareDecodingCodecs || []).indexOf(c.getAttribute('data-codec')) !== -1;
}); });
@ -22,6 +20,7 @@ import alert from '../../components/alert';
page.querySelector('#chkAllowHevcEncoding').checked = config.AllowHevcEncoding; page.querySelector('#chkAllowHevcEncoding').checked = config.AllowHevcEncoding;
$('#selectVideoDecoder', page).val(config.HardwareAccelerationType); $('#selectVideoDecoder', page).val(config.HardwareAccelerationType);
$('#selectThreadCount', page).val(config.EncodingThreadCount); $('#selectThreadCount', page).val(config.EncodingThreadCount);
page.querySelector('#chkEnableAudioVbr').checked = config.EnableAudioVbr;
$('#txtDownMixAudioBoost', page).val(config.DownMixAudioBoost); $('#txtDownMixAudioBoost', page).val(config.DownMixAudioBoost);
$('#selectStereoDownmixAlgorithm').val(config.DownMixStereoAlgorithm || 'None'); $('#selectStereoDownmixAlgorithm').val(config.DownMixStereoAlgorithm || 'None');
page.querySelector('#txtMaxMuxingQueueSize').value = config.MaxMuxingQueueSize || ''; page.querySelector('#txtMaxMuxingQueueSize').value = config.MaxMuxingQueueSize || '';
@ -51,14 +50,14 @@ import alert from '../../components/alert';
bubbles: true bubbles: true
})); }));
loading.hide(); loading.hide();
} }
function onSaveEncodingPathFailure() { function onSaveEncodingPathFailure() {
loading.hide(); loading.hide();
alert(globalize.translate('FFmpegSavePathNotFound')); alert(globalize.translate('FFmpegSavePathNotFound'));
} }
function updateEncoder(form) { function updateEncoder(form) {
return ApiClient.getSystemInfo().then(function () { return ApiClient.getSystemInfo().then(function () {
return ApiClient.ajax({ return ApiClient.ajax({
url: ApiClient.getUrl('System/MediaEncoder/Path'), url: ApiClient.getUrl('System/MediaEncoder/Path'),
@ -70,14 +69,15 @@ import alert from '../../components/alert';
contentType: 'application/json' contentType: 'application/json'
}).then(Dashboard.processServerConfigurationUpdateResult, onSaveEncodingPathFailure); }).then(Dashboard.processServerConfigurationUpdateResult, onSaveEncodingPathFailure);
}); });
} }
function onSubmit() { function onSubmit() {
const form = this; const form = this;
const onDecoderConfirmed = function () { const onDecoderConfirmed = function () {
loading.show(); loading.show();
ApiClient.getNamedConfiguration('encoding').then(function (config) { ApiClient.getNamedConfiguration('encoding').then(function (config) {
config.EnableAudioVbr = form.querySelector('#chkEnableAudioVbr').checked;
config.DownMixAudioBoost = $('#txtDownMixAudioBoost', form).val(); config.DownMixAudioBoost = $('#txtDownMixAudioBoost', form).val();
config.DownMixStereoAlgorithm = $('#selectStereoDownmixAlgorithm', form).val() || 'None'; config.DownMixStereoAlgorithm = $('#selectStereoDownmixAlgorithm', form).val() || 'None';
config.MaxMuxingQueueSize = form.querySelector('#txtMaxMuxingQueueSize').value; config.MaxMuxingQueueSize = form.querySelector('#txtMaxMuxingQueueSize').value;
@ -136,9 +136,9 @@ import alert from '../../components/alert';
} }
return false; return false;
} }
function setDecodingCodecsVisible(context, value) { function setDecodingCodecsVisible(context, value) {
value = value || ''; value = value || '';
let any; let any;
Array.prototype.forEach.call(context.querySelectorAll('.chkDecodeCodec'), function (c) { Array.prototype.forEach.call(context.querySelectorAll('.chkDecodeCodec'), function (c) {
@ -155,9 +155,9 @@ import alert from '../../components/alert';
} else { } else {
context.querySelector('.decodingCodecsList').classList.add('hide'); context.querySelector('.decodingCodecsList').classList.add('hide');
} }
} }
function getTabs() { function getTabs() {
return [{ return [{
href: '#/encodingsettings.html', href: '#/encodingsettings.html',
name: globalize.translate('Transcoding') name: globalize.translate('Transcoding')
@ -168,19 +168,19 @@ import alert from '../../components/alert';
href: '#/streamingsettings.html', href: '#/streamingsettings.html',
name: globalize.translate('TabStreaming') name: globalize.translate('TabStreaming')
}]; }];
} }
let systemInfo; let systemInfo;
function getSystemInfo() { function getSystemInfo() {
return systemInfo ? Promise.resolve(systemInfo) : ApiClient.getPublicSystemInfo().then( return systemInfo ? Promise.resolve(systemInfo) : ApiClient.getPublicSystemInfo().then(
info => { info => {
systemInfo = info; systemInfo = info;
return info; return info;
} }
); );
} }
$(document).on('pageinit', '#encodingSettingsPage', function () { $(document).on('pageinit', '#encodingSettingsPage', function () {
const page = this; const page = this;
getSystemInfo(); getSystemInfo();
page.querySelector('#selectVideoDecoder').addEventListener('change', function () { page.querySelector('#selectVideoDecoder').addEventListener('change', function () {
@ -237,7 +237,7 @@ import alert from '../../components/alert';
setDecodingCodecsVisible(page, this.value); setDecodingCodecsVisible(page, this.value);
}); });
$('#btnSelectEncoderPath', page).on('click.selectDirectory', function () { $('#btnSelectEncoderPath', page).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({default: DirectoryBrowser}) => { import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser(); const picker = new DirectoryBrowser();
picker.show({ picker.show({
includeFiles: true, includeFiles: true,
@ -252,7 +252,7 @@ import alert from '../../components/alert';
}); });
}); });
$('#btnSelectTranscodingTempPath', page).on('click.selectDirectory', function () { $('#btnSelectTranscodingTempPath', page).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({default: DirectoryBrowser}) => { import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser(); const picker = new DirectoryBrowser();
picker.show({ picker.show({
callback: function (path) { callback: function (path) {
@ -269,7 +269,7 @@ import alert from '../../components/alert';
}); });
}); });
$('#btnSelectFallbackFontPath', page).on('click.selectDirectory', function () { $('#btnSelectFallbackFontPath', page).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({default: DirectoryBrowser}) => { import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser(); const picker = new DirectoryBrowser();
picker.show({ picker.show({
includeDirectories: true, includeDirectories: true,
@ -286,7 +286,7 @@ import alert from '../../components/alert';
}); });
}); });
$('.encodingSettingsForm').off('submit', onSubmit).on('submit', onSubmit); $('.encodingSettingsForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#encodingSettingsPage', function () { }).on('pageshow', '#encodingSettingsPage', function () {
loading.show(); loading.show();
libraryMenu.setTabs('playback', 0, getTabs); libraryMenu.setTabs('playback', 0, getTabs);
const page = this; const page = this;
@ -295,6 +295,5 @@ import alert from '../../components/alert';
loadPage(page, config, fetchedSystemInfo); loadPage(page, config, fetchedSystemInfo);
}); });
}); });
}); });
/* eslint-enable indent */

View file

@ -10,9 +10,7 @@ import '../../elements/emby-button/emby-button';
import Dashboard from '../../utils/dashboard'; import Dashboard from '../../utils/dashboard';
import alert from '../../components/alert'; import alert from '../../components/alert';
/* eslint-disable indent */ function loadPage(page, config, languageOptions, systemInfo) {
function loadPage(page, config, languageOptions, systemInfo) {
page.querySelector('#txtServerName').value = systemInfo.ServerName; page.querySelector('#txtServerName').value = systemInfo.ServerName;
page.querySelector('#txtCachePath').value = systemInfo.CachePath || ''; page.querySelector('#txtCachePath').value = systemInfo.CachePath || '';
page.querySelector('#chkQuickConnectAvailable').checked = config.QuickConnectAvailable === true; page.querySelector('#chkQuickConnectAvailable').checked = config.QuickConnectAvailable === true;
@ -24,9 +22,9 @@ import alert from '../../components/alert';
page.querySelector('#txtParallelImageEncodingLimit').value = config.ParallelImageEncodingLimit || ''; page.querySelector('#txtParallelImageEncodingLimit').value = config.ParallelImageEncodingLimit || '';
loading.hide(); loading.hide();
} }
function onSubmit() { function onSubmit() {
loading.show(); loading.show();
const form = this; const form = this;
$(form).parents('.page'); $(form).parents('.page');
@ -55,12 +53,12 @@ import alert from '../../components/alert';
}); });
}); });
return false; return false;
} }
const brandingConfigKey = 'branding'; const brandingConfigKey = 'branding';
export default function (view) { export default function (view) {
$('#btnSelectCachePath', view).on('click.selectDirectory', function () { $('#btnSelectCachePath', view).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({default: DirectoryBrowser}) => { import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser(); const picker = new DirectoryBrowser();
picker.show({ picker.show({
callback: function (path) { callback: function (path) {
@ -77,7 +75,7 @@ import alert from '../../components/alert';
}); });
}); });
$('#btnSelectMetadataPath', view).on('click.selectDirectory', function () { $('#btnSelectMetadataPath', view).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({default: DirectoryBrowser}) => { import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser(); const picker = new DirectoryBrowser();
picker.show({ picker.show({
path: $('#txtMetadataPath', view).val(), path: $('#txtMetadataPath', view).val(),
@ -114,6 +112,5 @@ import alert from '../../components/alert';
view.querySelector('#chkSplashScreenAvailable').checked = config.SplashscreenEnabled === true; view.querySelector('#chkSplashScreenAvailable').checked = config.SplashscreenEnabled === true;
}); });
}); });
} }
/* eslint-enable indent */

View file

@ -12,10 +12,8 @@ import Dashboard, { pageClassOn, pageIdOn } from '../../utils/dashboard';
import confirm from '../../components/confirm/confirm'; import confirm from '../../components/confirm/confirm';
import cardBuilder from '../../components/cardbuilder/cardBuilder'; import cardBuilder from '../../components/cardbuilder/cardBuilder';
/* eslint-disable indent */ function addVirtualFolder(page) {
import('../../components/mediaLibraryCreator/mediaLibraryCreator').then(({ default: medialibrarycreator }) => {
function addVirtualFolder(page) {
import('../../components/mediaLibraryCreator/mediaLibraryCreator').then(({default: medialibrarycreator}) => {
new medialibrarycreator({ new medialibrarycreator({
collectionTypeOptions: getCollectionTypeOptions().filter(function (f) { collectionTypeOptions: getCollectionTypeOptions().filter(function (f) {
return !f.hidden; return !f.hidden;
@ -27,10 +25,10 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
} }
}); });
}); });
} }
function editVirtualFolder(page, virtualFolder) { function editVirtualFolder(page, virtualFolder) {
import('../../components/mediaLibraryEditor/mediaLibraryEditor').then(({default: medialibraryeditor}) => { import('../../components/mediaLibraryEditor/mediaLibraryEditor').then(({ default: medialibraryeditor }) => {
new medialibraryeditor({ new medialibraryeditor({
refresh: shouldRefreshLibraryAfterChanges(page), refresh: shouldRefreshLibraryAfterChanges(page),
library: virtualFolder library: virtualFolder
@ -40,9 +38,9 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
} }
}); });
}); });
} }
function deleteVirtualFolder(page, virtualFolder) { function deleteVirtualFolder(page, virtualFolder) {
let msg = globalize.translate('MessageAreYouSureYouWishToRemoveMediaFolder'); let msg = globalize.translate('MessageAreYouSureYouWishToRemoveMediaFolder');
if (virtualFolder.Locations.length) { if (virtualFolder.Locations.length) {
@ -61,20 +59,20 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
reloadLibrary(page); reloadLibrary(page);
}); });
}); });
} }
function refreshVirtualFolder(page, virtualFolder) { function refreshVirtualFolder(page, virtualFolder) {
import('../../components/refreshdialog/refreshdialog').then(({default: refreshDialog}) => { import('../../components/refreshdialog/refreshdialog').then(({ default: refreshDialog }) => {
new refreshDialog({ new refreshDialog({
itemIds: [virtualFolder.ItemId], itemIds: [virtualFolder.ItemId],
serverId: ApiClient.serverId(), serverId: ApiClient.serverId(),
mode: 'scan' mode: 'scan'
}).show(); }).show();
}); });
} }
function renameVirtualFolder(page, virtualFolder) { function renameVirtualFolder(page, virtualFolder) {
import('../../components/prompt/prompt').then(({default: prompt}) => { import('../../components/prompt/prompt').then(({ default: prompt }) => {
prompt({ prompt({
label: globalize.translate('LabelNewName'), label: globalize.translate('LabelNewName'),
description: globalize.translate('MessageRenameMediaFolder'), description: globalize.translate('MessageRenameMediaFolder'),
@ -88,9 +86,9 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
} }
}); });
}); });
} }
function showCardMenu(page, elem, virtualFolders) { function showCardMenu(page, elem, virtualFolders) {
const card = dom.parentWithClass(elem, 'card'); const card = dom.parentWithClass(elem, 'card');
const index = parseInt(card.getAttribute('data-index'), 10); const index = parseInt(card.getAttribute('data-index'), 10);
const virtualFolder = virtualFolders[index]; const virtualFolder = virtualFolders[index];
@ -149,20 +147,20 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
} }
}); });
}); });
} }
function reloadLibrary(page) { function reloadLibrary(page) {
loading.show(); loading.show();
ApiClient.getVirtualFolders().then(function (result) { ApiClient.getVirtualFolders().then(function (result) {
reloadVirtualFolders(page, result); reloadVirtualFolders(page, result);
}); });
} }
function shouldRefreshLibraryAfterChanges(page) { function shouldRefreshLibraryAfterChanges(page) {
return page.id === 'mediaLibraryPage'; return page.id === 'mediaLibraryPage';
} }
function reloadVirtualFolders(page, virtualFolders) { function reloadVirtualFolders(page, virtualFolders) {
let html = ''; let html = '';
virtualFolders.push({ virtualFolders.push({
Name: globalize.translate('ButtonAddMediaLibrary'), Name: globalize.translate('ButtonAddMediaLibrary'),
@ -200,9 +198,9 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
} }
}); });
loading.hide(); loading.hide();
} }
function editImages(page, virtualFolder) { function editImages(page, virtualFolder) {
import('../../components/imageeditor/imageeditor').then((imageEditor) => { import('../../components/imageeditor/imageeditor').then((imageEditor) => {
imageEditor.show({ imageEditor.show({
itemId: virtualFolder.ItemId, itemId: virtualFolder.ItemId,
@ -211,13 +209,13 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
reloadLibrary(page); reloadLibrary(page);
}); });
}); });
} }
function getLink(text, url) { function getLink(text, url) {
return globalize.translate(text, '<a is="emby-linkbutton" class="button-link" href="' + url + '" target="_blank" data-autohide="true">', '</a>'); return globalize.translate(text, '<a is="emby-linkbutton" class="button-link" href="' + url + '" target="_blank" data-autohide="true">', '</a>');
} }
function getCollectionTypeOptions() { function getCollectionTypeOptions() {
return [{ return [{
name: '', name: '',
value: '' value: ''
@ -248,9 +246,9 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
value: 'mixed', value: 'mixed',
message: globalize.translate('MessageUnsetContentHelp') message: globalize.translate('MessageUnsetContentHelp')
}]; }];
} }
function getVirtualFolderHtml(page, virtualFolder, index) { function getVirtualFolderHtml(page, virtualFolder, index) {
let html = ''; let html = '';
let style = ''; let style = '';
@ -360,9 +358,9 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
html += '</div>'; html += '</div>';
html += '</div>'; html += '</div>';
return html; return html;
} }
function getTabs() { function getTabs() {
return [{ return [{
href: '#/library.html', href: '#/library.html',
name: globalize.translate('HeaderLibraries') name: globalize.translate('HeaderLibraries')
@ -376,17 +374,17 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
href: '#/metadatanfo.html', href: '#/metadatanfo.html',
name: globalize.translate('TabNfoSettings') name: globalize.translate('TabNfoSettings')
}]; }];
} }
window.WizardLibraryPage = { window.WizardLibraryPage = {
next: function () { next: function () {
Dashboard.navigate('wizardsettings.html'); Dashboard.navigate('wizardsettings.html');
} }
}; };
pageClassOn('pageshow', 'mediaLibraryPage', function () { pageClassOn('pageshow', 'mediaLibraryPage', function () {
reloadLibrary(this); reloadLibrary(this);
}); });
pageIdOn('pageshow', 'mediaLibraryPage', function () { pageIdOn('pageshow', 'mediaLibraryPage', function () {
libraryMenu.setTabs('librarysetup', 0, getTabs); libraryMenu.setTabs('librarysetup', 0, getTabs);
const page = this; const page = this;
@ -396,8 +394,8 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
taskKey: 'RefreshLibrary', taskKey: 'RefreshLibrary',
button: page.querySelector('.btnRefresh') button: page.querySelector('.btnRefresh')
}); });
}); });
pageIdOn('pagebeforehide', 'mediaLibraryPage', function () { pageIdOn('pagebeforehide', 'mediaLibraryPage', function () {
const page = this; const page = this;
taskButton({ taskButton({
mode: 'off', mode: 'off',
@ -405,6 +403,5 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
taskKey: 'RefreshLibrary', taskKey: 'RefreshLibrary',
button: page.querySelector('.btnRefresh') button: page.querySelector('.btnRefresh')
}); });
}); });
/* eslint-enable indent */

Some files were not shown because too many files have changed in this diff Show more