mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge branch 'master' into jassub
This commit is contained in:
commit
4c7c2067f9
116 changed files with 1269 additions and 982 deletions
|
@ -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']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
8
.github/workflows/codeql-analysis.yml
vendored
8
.github/workflows/codeql-analysis.yml
vendored
|
@ -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@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7
|
uses: github/codeql-action/init@04df1262e6247151b5ac09cd2c303ac36ad3f62b # v2.2.9
|
||||||
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@04df1262e6247151b5ac09cd2c303ac36ad3f62b # v2.2.9
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7
|
uses: github/codeql-action/analyze@04df1262e6247151b5ac09cd2c303ac36ad3f62b # v2.2.9
|
||||||
|
|
2
.github/workflows/commands.yml
vendored
2
.github/workflows/commands.yml
vendored
|
@ -18,7 +18,7 @@ jobs:
|
||||||
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@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.JF_BOT_TOKEN }}
|
token: ${{ secrets.JF_BOT_TOKEN }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
8
.github/workflows/lint.yml
vendored
8
.github/workflows/lint.yml
vendored
|
@ -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@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0
|
||||||
|
|
||||||
- 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@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0
|
||||||
|
|
||||||
- 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@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0
|
||||||
|
|
||||||
- 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@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0
|
||||||
|
|
||||||
- name: Setup node environment
|
- name: Setup node environment
|
||||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
||||||
|
|
4
.github/workflows/repo-stale.yaml
vendored
4
.github/workflows/repo-stale.yaml
vendored
|
@ -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
|
||||||
|
|
2
.github/workflows/tsc.yml
vendored
2
.github/workflows/tsc.yml
vendored
|
@ -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@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0
|
||||||
|
|
||||||
- name: Setup node environment
|
- name: Setup node environment
|
||||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
||||||
|
|
1125
package-lock.json
generated
1125
package-lock.json
generated
File diff suppressed because it is too large
Load diff
48
package.json
48
package.json
|
@ -5,8 +5,8 @@
|
||||||
"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.3",
|
||||||
"@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",
|
||||||
|
@ -16,13 +16,13 @@
|
||||||
"@babel/preset-typescript": "7.21.0",
|
"@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.53",
|
||||||
"@types/react-dom": "17.0.19",
|
"@types/react-dom": "17.0.19",
|
||||||
"@typescript-eslint/eslint-plugin": "5.54.1",
|
"@typescript-eslint/eslint-plugin": "5.56.0",
|
||||||
"@typescript-eslint/parser": "5.54.1",
|
"@typescript-eslint/parser": "5.56.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",
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
"css-loader": "6.7.3",
|
"css-loader": "6.7.3",
|
||||||
"cssnano": "5.1.15",
|
"cssnano": "5.1.15",
|
||||||
"es-check": "7.1.0",
|
"es-check": "7.1.0",
|
||||||
"eslint": "8.35.0",
|
"eslint": "8.36.0",
|
||||||
"eslint-plugin-compat": "4.1.2",
|
"eslint-plugin-compat": "4.1.2",
|
||||||
"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",
|
||||||
|
@ -40,29 +40,29 @@
|
||||||
"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.1.0",
|
||||||
"postcss-preset-env": "8.0.1",
|
"postcss-preset-env": "8.0.1",
|
||||||
"postcss-scss": "4.0.6",
|
"postcss-scss": "4.0.6",
|
||||||
"sass": "1.58.3",
|
"sass": "1.59.3",
|
||||||
"sass-loader": "13.2.0",
|
"sass-loader": "13.2.1",
|
||||||
"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.3.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.5.0",
|
||||||
"ts-loader": "9.4.2",
|
"ts-loader": "9.4.2",
|
||||||
"typescript": "4.9.5",
|
"typescript": "5.0.2",
|
||||||
"webpack": "5.76.0",
|
"webpack": "5.76.3",
|
||||||
"webpack-cli": "5.0.1",
|
"webpack-cli": "5.0.1",
|
||||||
"webpack-dev-server": "4.11.1",
|
"webpack-dev-server": "4.13.1",
|
||||||
"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"
|
||||||
|
@ -79,10 +79,10 @@
|
||||||
"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.29.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",
|
"event-target-polyfill": "github:ThaUnknown/event-target-polyfill",
|
||||||
"fast-text-encoding": "1.0.6",
|
"fast-text-encoding": "1.0.6",
|
||||||
|
@ -93,17 +93,17 @@
|
||||||
"intersection-observer": "0.12.2",
|
"intersection-observer": "0.12.2",
|
||||||
"jassub": "1.5.12",
|
"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": "2.16.105",
|
||||||
"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.9.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",
|
||||||
|
|
|
@ -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()
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
|
@ -37,7 +37,7 @@ import template from './accessSchedule.template.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;
|
||||||
|
|
|
@ -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 {};
|
||||||
|
|
|
@ -896,13 +896,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 || '');
|
||||||
|
|
|
@ -28,7 +28,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] || {};
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ 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, {
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ 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';
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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'>
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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'>
|
||||||
|
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,8 +26,8 @@ import Events from '../utils/events.ts';
|
||||||
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) {
|
||||||
|
@ -201,8 +201,8 @@ import Events from '../utils/events.ts';
|
||||||
.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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,7 +282,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({
|
||||||
|
@ -353,7 +353,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,
|
||||||
|
|
|
@ -326,7 +326,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 +335,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 +408,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 +464,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;
|
||||||
|
@ -535,7 +535,7 @@ import toast from './toast/toast';
|
||||||
}
|
}
|
||||||
|
|
||||||
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)();
|
||||||
|
@ -544,7 +544,7 @@ import toast from './toast/toast';
|
||||||
}
|
}
|
||||||
|
|
||||||
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)();
|
||||||
});
|
});
|
||||||
|
@ -585,15 +585,15 @@ import toast from './toast/toast';
|
||||||
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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -614,7 +614,7 @@ import toast from './toast/toast';
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|
|
@ -167,7 +167,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/>');
|
||||||
|
|
|
@ -316,7 +316,7 @@ import template from './libraryoptionseditor.template.html';
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = {
|
||||||
|
|
|
@ -65,7 +65,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);
|
||||||
|
|
|
@ -25,7 +25,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,7 +62,7 @@ import template from './mediaLibraryCreator.template.html';
|
||||||
isCreating = false;
|
isCreating = false;
|
||||||
loading.hide();
|
loading.hide();
|
||||||
});
|
});
|
||||||
return false;
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCollectionTypeOptionsHtml(collectionTypeOptions) {
|
function getCollectionTypeOptionsHtml(collectionTypeOptions) {
|
||||||
|
@ -96,14 +96,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,
|
||||||
|
|
|
@ -1,37 +1,39 @@
|
||||||
<div class="formDialogHeader">
|
<form class="addLibraryForm" style="max-width:100%;">
|
||||||
<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>
|
<div class="formDialogHeader">
|
||||||
<h3 class="formDialogHeaderTitle">${ButtonAddMediaLibrary}</h3>
|
<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>
|
||||||
</div>
|
<h3 class="formDialogHeaderTitle">${ButtonAddMediaLibrary}</h3>
|
||||||
|
|
||||||
<div class="formDialogContent scrollY" style="padding-top:2em;">
|
|
||||||
<div class="dialogContentInner dialog-content-centered">
|
|
||||||
|
|
||||||
<div id="fldCollectionType" class="selectContainer">
|
|
||||||
<select is="emby-select" id="selectCollectionType" data-mini="true" required="required" label="${LabelContentType}"></select>
|
|
||||||
<div class="collectionTypeFieldDescription fieldDescription">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="inputContainer">
|
|
||||||
<input is="emby-input" type="text" id="txtValue" required="required" label="${LabelDisplayName}" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="folders">
|
|
||||||
<div style="display: flex; align-items: center;">
|
|
||||||
<h1 style="margin: .5em 0;">${Folders}</h1>
|
|
||||||
<button is="emby-button" type="button" class="fab btnAddFolder submit" title="${Add}">
|
|
||||||
<span class="material-icons add" aria-hidden="true"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="paperList folderList hide" style="margin-bottom:2em;"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="libraryOptions"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="formDialogFooter">
|
<div class="formDialogContent scrollY" style="padding-top:2em;">
|
||||||
<button is="emby-button" type="button" class="raised btnSubmit button-submit block formDialogFooterItem">
|
<div class="dialogContentInner dialog-content-centered">
|
||||||
<span>${ButtonOk}</span>
|
|
||||||
</button>
|
<div id="fldCollectionType" class="selectContainer">
|
||||||
</div>
|
<select is="emby-select" id="selectCollectionType" data-mini="true" required="required" label="${LabelContentType}"></select>
|
||||||
|
<div class="collectionTypeFieldDescription fieldDescription">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="inputContainer">
|
||||||
|
<input is="emby-input" type="text" id="txtValue" required="required" label="${LabelDisplayName}" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="folders">
|
||||||
|
<div style="display: flex; align-items: center;">
|
||||||
|
<h1 style="margin: .5em 0;">${Folders}</h1>
|
||||||
|
<button is="emby-button" type="button" class="fab btnAddFolder submit" title="${Add}">
|
||||||
|
<span class="material-icons add" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="paperList folderList hide" style="margin-bottom:2em;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="libraryOptions"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="formDialogFooter">
|
||||||
|
<button is="emby-button" type="submit" class="raised btnSubmit button-submit block formDialogFooterItem">
|
||||||
|
<span>${ButtonOk}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
|
@ -164,7 +164,7 @@ import template from './mediaLibraryEditor.template.html';
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|
|
@ -177,13 +177,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 +253,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);
|
||||||
|
|
|
@ -211,7 +211,7 @@ import template from './metadataEditor.template.html';
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -229,7 +229,7 @@ import template from './metadataEditor.template.html';
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ import template from './metadataEditor.template.html';
|
||||||
}
|
}
|
||||||
|
|
||||||
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({
|
||||||
|
@ -588,12 +588,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);
|
||||||
|
|
|
@ -267,7 +267,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 +308,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
|
||||||
|
|
|
@ -69,7 +69,7 @@ import shell from '../../scripts/shell';
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@ 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';
|
||||||
|
|
||||||
|
@ -325,6 +326,12 @@ import ServerConnections from '../ServerConnections';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSyncPlayStats() {
|
function getSyncPlayStats() {
|
||||||
|
const SyncPlay = pluginManager.firstOfType(PluginType.SyncPlay)?.instance;
|
||||||
|
|
||||||
|
if (!SyncPlay?.Manager.isSyncPlayEnabled()) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const syncStats = [];
|
const syncStats = [];
|
||||||
const stats = SyncPlay.Manager.getStats();
|
const stats = SyncPlay.Manager.getStats();
|
||||||
|
|
||||||
|
@ -422,10 +429,10 @@ 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')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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';
|
||||||
|
@ -117,10 +119,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>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -389,13 +389,13 @@ import layoutManager from './layoutManager';
|
||||||
|
|
||||||
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 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,7 +597,7 @@ import layoutManager from './layoutManager';
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
scrollToElement(e.target, useSmoothScroll());
|
scrollToElement(e.target, useSmoothScroll());
|
||||||
}, 0);
|
}, 0);
|
||||||
}, {capture: true});
|
}, { capture: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eslint-enable indent */
|
/* eslint-enable indent */
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -71,7 +71,7 @@ import toast from './toast/toast';
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,7 @@ import toast from './toast/toast';
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
@ -297,16 +297,16 @@ 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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 () {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -52,7 +52,7 @@ import { pageIdOn } from '../../utils/dashboard';
|
||||||
}
|
}
|
||||||
|
|
||||||
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'),
|
||||||
|
|
|
@ -65,7 +65,7 @@ import confirm from '../../components/confirm/confirm';
|
||||||
}
|
}
|
||||||
|
|
||||||
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'),
|
||||||
|
@ -82,7 +82,7 @@ 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()) {
|
||||||
|
|
|
@ -68,7 +68,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,
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -22,6 +22,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 || '';
|
||||||
|
@ -78,6 +79,7 @@ import alert from '../../components/alert';
|
||||||
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;
|
||||||
|
@ -237,7 +239,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 +254,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 +271,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,
|
||||||
|
|
|
@ -60,7 +60,7 @@ import alert from '../../components/alert';
|
||||||
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 +77,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(),
|
||||||
|
|
|
@ -15,7 +15,7 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
function addVirtualFolder(page) {
|
function addVirtualFolder(page) {
|
||||||
import('../../components/mediaLibraryCreator/mediaLibraryCreator').then(({default: medialibrarycreator}) => {
|
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;
|
||||||
|
@ -30,7 +30,7 @@ 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
|
||||||
|
@ -64,7 +64,7 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
|
||||||
}
|
}
|
||||||
|
|
||||||
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(),
|
||||||
|
@ -74,7 +74,7 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
|
||||||
}
|
}
|
||||||
|
|
||||||
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'),
|
||||||
|
|
|
@ -181,7 +181,7 @@ import alert from '../../components/alert';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
view.querySelector('#btnSelectCertPath').addEventListener('click', function () {
|
view.querySelector('#btnSelectCertPath').addEventListener('click', 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,
|
||||||
|
|
|
@ -349,7 +349,7 @@ import LibraryMenu from '../scripts/libraryMenu';
|
||||||
function showViewSettingsMenu() {
|
function showViewSettingsMenu() {
|
||||||
const instance = this;
|
const instance = this;
|
||||||
|
|
||||||
import('../components/viewSettings/viewSettings').then(({default: ViewSettings}) => {
|
import('../components/viewSettings/viewSettings').then(({ default: ViewSettings }) => {
|
||||||
new ViewSettings().show({
|
new ViewSettings().show({
|
||||||
settingsKey: instance.getSettingsKey(),
|
settingsKey: instance.getSettingsKey(),
|
||||||
settings: instance.getViewSettings(),
|
settings: instance.getViewSettings(),
|
||||||
|
@ -364,7 +364,7 @@ import LibraryMenu from '../scripts/libraryMenu';
|
||||||
function showFilterMenu() {
|
function showFilterMenu() {
|
||||||
const instance = this;
|
const instance = this;
|
||||||
|
|
||||||
import('../components/filtermenu/filtermenu').then(({default: FilterMenu}) => {
|
import('../components/filtermenu/filtermenu').then(({ default: FilterMenu }) => {
|
||||||
new FilterMenu().show({
|
new FilterMenu().show({
|
||||||
settingsKey: instance.getSettingsKey(),
|
settingsKey: instance.getSettingsKey(),
|
||||||
settings: instance.getFilters(),
|
settings: instance.getFilters(),
|
||||||
|
@ -383,7 +383,7 @@ import LibraryMenu from '../scripts/libraryMenu';
|
||||||
function showSortMenu() {
|
function showSortMenu() {
|
||||||
const instance = this;
|
const instance = this;
|
||||||
|
|
||||||
import('../components/sortmenu/sortmenu').then(({default: SortMenu}) => {
|
import('../components/sortmenu/sortmenu').then(({ default: SortMenu }) => {
|
||||||
new SortMenu().show({
|
new SortMenu().show({
|
||||||
settingsKey: instance.getSettingsKey(),
|
settingsKey: instance.getSettingsKey(),
|
||||||
settings: instance.getSortValues(),
|
settings: instance.getSortValues(),
|
||||||
|
@ -401,7 +401,7 @@ import LibraryMenu from '../scripts/libraryMenu';
|
||||||
function onNewItemClick() {
|
function onNewItemClick() {
|
||||||
const instance = this;
|
const instance = this;
|
||||||
|
|
||||||
import('../components/playlisteditor/playlisteditor').then(({default: playlistEditor}) => {
|
import('../components/playlisteditor/playlisteditor').then(({ default: playlistEditor }) => {
|
||||||
new playlistEditor({
|
new playlistEditor({
|
||||||
items: [],
|
items: [],
|
||||||
serverId: instance.params.serverId
|
serverId: instance.params.serverId
|
||||||
|
@ -772,7 +772,7 @@ class ItemsView {
|
||||||
}
|
}
|
||||||
|
|
||||||
function autoFocus() {
|
function autoFocus() {
|
||||||
import('../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(view);
|
autoFocuser.autoFocus(view);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ export default function (view, params, tabContent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function showFilterMenu(context) {
|
function showFilterMenu(context) {
|
||||||
import('../../components/filterdialog/filterdialog').then(({default: FilterDialog}) => {
|
import('../../components/filterdialog/filterdialog').then(({ default: FilterDialog }) => {
|
||||||
const filterDialog = new FilterDialog({
|
const filterDialog = new FilterDialog({
|
||||||
query: getQuery(),
|
query: getQuery(),
|
||||||
mode: 'livetvchannels',
|
mode: 'livetvchannels',
|
||||||
|
@ -124,7 +124,7 @@ export default function (view, params, tabContent) {
|
||||||
loading.hide();
|
loading.hide();
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
|
||||||
import('../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(context);
|
autoFocuser.autoFocus(context);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -61,7 +61,7 @@ function loadRecommendedPrograms(page) {
|
||||||
});
|
});
|
||||||
loading.hide();
|
loading.hide();
|
||||||
|
|
||||||
import('../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(page);
|
autoFocuser.autoFocus(page);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -273,7 +273,7 @@ export default function (view, params) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
import(`../livetv/${depends}`).then(({default: controllerFactory}) => {
|
import(`../livetv/${depends}`).then(({ default: controllerFactory }) => {
|
||||||
let tabContent;
|
let tabContent;
|
||||||
|
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ function onListingsSubmitted() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function init(page, type, providerId) {
|
function init(page, type, providerId) {
|
||||||
import(`../components/tvproviders/${type}`).then(({default: factory}) => {
|
import(`../components/tvproviders/${type}`).then(({ default: factory }) => {
|
||||||
const instance = new factory(page, providerId, {});
|
const instance = new factory(page, providerId, {});
|
||||||
Events.on(instance, 'submitted', onListingsSubmitted);
|
Events.on(instance, 'submitted', onListingsSubmitted);
|
||||||
instance.init();
|
instance.init();
|
||||||
|
@ -17,7 +17,7 @@ function init(page, type, providerId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadTemplate(page, type, providerId) {
|
function loadTemplate(page, type, providerId) {
|
||||||
import(`../components/tvproviders/${type}.template.html`).then(({default: html}) => {
|
import(`../components/tvproviders/${type}.template.html`).then(({ default: html }) => {
|
||||||
page.querySelector('.providerTemplate').innerHTML = globalize.translateHtml(html);
|
page.querySelector('.providerTemplate').innerHTML = globalize.translateHtml(html);
|
||||||
init(page, type, providerId);
|
init(page, type, providerId);
|
||||||
});
|
});
|
||||||
|
|
|
@ -64,7 +64,7 @@ $(document).on('pageinit', '#liveTvSettingsPage', function () {
|
||||||
const page = this;
|
const page = this;
|
||||||
$('.liveTvSettingsForm').off('submit', onSubmit).on('submit', onSubmit);
|
$('.liveTvSettingsForm').off('submit', onSubmit).on('submit', onSubmit);
|
||||||
$('#btnSelectRecordingPath', page).on('click.selectDirectory', function () {
|
$('#btnSelectRecordingPath', 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) {
|
||||||
|
@ -79,7 +79,7 @@ $(document).on('pageinit', '#liveTvSettingsPage', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$('#btnSelectMovieRecordingPath', page).on('click.selectDirectory', function () {
|
$('#btnSelectMovieRecordingPath', 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) {
|
||||||
|
@ -94,7 +94,7 @@ $(document).on('pageinit', '#liveTvSettingsPage', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$('#btnSelectSeriesRecordingPath', page).on('click.selectDirectory', function () {
|
$('#btnSelectSeriesRecordingPath', 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) {
|
||||||
|
@ -109,7 +109,7 @@ $(document).on('pageinit', '#liveTvSettingsPage', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$('#btnSelectPostProcessorPath', page).on('click.selectDirectory', function () {
|
$('#btnSelectPostProcessorPath', 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,
|
||||||
|
|
|
@ -147,7 +147,7 @@ function showProviderOptions(page, providerId, button) {
|
||||||
id: 'map'
|
id: 'map'
|
||||||
});
|
});
|
||||||
|
|
||||||
import('../components/actionSheet/actionSheet').then(({default: actionsheet}) => {
|
import('../components/actionSheet/actionSheet').then(({ default: actionsheet }) => {
|
||||||
actionsheet.show({
|
actionsheet.show({
|
||||||
items: items,
|
items: items,
|
||||||
positionTo: button
|
positionTo: button
|
||||||
|
@ -165,7 +165,7 @@ function showProviderOptions(page, providerId, button) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapChannels(page, providerId) {
|
function mapChannels(page, providerId) {
|
||||||
import('../components/channelMapper/channelMapper').then(({default: channelMapper}) => {
|
import('../components/channelMapper/channelMapper').then(({ default: channelMapper }) => {
|
||||||
new channelMapper({
|
new channelMapper({
|
||||||
serverId: ApiClient.serverInfo().Id,
|
serverId: ApiClient.serverInfo().Id,
|
||||||
providerId: providerId
|
providerId: providerId
|
||||||
|
@ -237,7 +237,7 @@ function addProvider(button) {
|
||||||
id: 'xmltv'
|
id: 'xmltv'
|
||||||
});
|
});
|
||||||
|
|
||||||
import('../components/actionSheet/actionSheet').then(({default: actionsheet}) => {
|
import('../components/actionSheet/actionSheet').then(({ default: actionsheet }) => {
|
||||||
actionsheet.show({
|
actionsheet.show({
|
||||||
items: menuItems,
|
items: menuItems,
|
||||||
positionTo: button,
|
positionTo: button,
|
||||||
|
@ -263,7 +263,7 @@ function showDeviceMenu(button, tunerDeviceId) {
|
||||||
id: 'edit'
|
id: 'edit'
|
||||||
});
|
});
|
||||||
|
|
||||||
import('../components/actionSheet/actionSheet').then(({default: actionsheet}) => {
|
import('../components/actionSheet/actionSheet').then(({ default: actionsheet }) => {
|
||||||
actionsheet.show({
|
actionsheet.show({
|
||||||
items: items,
|
items: items,
|
||||||
positionTo: button
|
positionTo: button
|
||||||
|
|
|
@ -106,7 +106,7 @@ function submitForm(page) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDetectedDevice() {
|
function getDetectedDevice() {
|
||||||
return import('../components/tunerPicker').then(({default: tunerPicker}) => {
|
return import('../components/tunerPicker').then(({ default: tunerPicker }) => {
|
||||||
return new tunerPicker().show({
|
return new tunerPicker().show({
|
||||||
serverId: ApiClient.serverId()
|
serverId: ApiClient.serverId()
|
||||||
});
|
});
|
||||||
|
@ -222,7 +222,7 @@ export default function (view, params) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
view.querySelector('.btnSelectPath').addEventListener('click', function () {
|
view.querySelector('.btnSelectPath').addEventListener('click', 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,
|
||||||
|
|
|
@ -180,7 +180,7 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
||||||
loading.hide();
|
loading.hide();
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
|
||||||
import('../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(tabContent);
|
autoFocuser.autoFocus(tabContent);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -191,7 +191,7 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
||||||
let isLoading = false;
|
let isLoading = false;
|
||||||
|
|
||||||
this.showFilterMenu = function () {
|
this.showFilterMenu = function () {
|
||||||
import('../../components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => {
|
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
|
||||||
const filterDialog = new filterDialogFactory({
|
const filterDialog = new filterDialogFactory({
|
||||||
query: getQuery(),
|
query: getQuery(),
|
||||||
mode: 'albums',
|
mode: 'albums',
|
||||||
|
|
|
@ -162,7 +162,7 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
||||||
loading.hide();
|
loading.hide();
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
|
||||||
import('../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(tabContent);
|
autoFocuser.autoFocus(tabContent);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -172,7 +172,7 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
||||||
let isLoading = false;
|
let isLoading = false;
|
||||||
|
|
||||||
this.showFilterMenu = function () {
|
this.showFilterMenu = function () {
|
||||||
import('../../components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => {
|
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
|
||||||
const filterDialog = new filterDialogFactory({
|
const filterDialog = new filterDialogFactory({
|
||||||
query: getQuery(tabContent),
|
query: getQuery(tabContent),
|
||||||
mode: this.mode,
|
mode: this.mode,
|
||||||
|
|
|
@ -92,7 +92,7 @@ import loading from '../../components/loading/loading';
|
||||||
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
|
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
|
||||||
loading.hide();
|
loading.hide();
|
||||||
|
|
||||||
import('../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(context);
|
autoFocuser.autoFocus(context);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -63,7 +63,7 @@ import loading from '../../components/loading/loading';
|
||||||
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
|
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
|
||||||
loading.hide();
|
loading.hide();
|
||||||
|
|
||||||
import('../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(context);
|
autoFocuser.autoFocus(context);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -75,7 +75,7 @@ import Dashboard from '../../utils/dashboard';
|
||||||
imageLoader.lazyChildren(elem);
|
imageLoader.lazyChildren(elem);
|
||||||
loading.hide();
|
loading.hide();
|
||||||
|
|
||||||
import('../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(page);
|
autoFocuser.autoFocus(page);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -171,7 +171,7 @@ import Dashboard from '../../utils/dashboard';
|
||||||
loadRecentlyPlayed(tabContent, parentId);
|
loadRecentlyPlayed(tabContent, parentId);
|
||||||
loadFrequentlyPlayed(tabContent, parentId);
|
loadFrequentlyPlayed(tabContent, parentId);
|
||||||
|
|
||||||
import('../../components/favoriteitems').then(({default: favoriteItems}) => {
|
import('../../components/favoriteitems').then(({ default: favoriteItems }) => {
|
||||||
favoriteItems.render(tabContent, ApiClient.getCurrentUserId(), parentId, ['favoriteArtists', 'favoriteAlbums', 'favoriteSongs']);
|
favoriteItems.render(tabContent, ApiClient.getCurrentUserId(), parentId, ['favoriteArtists', 'favoriteAlbums', 'favoriteSongs']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -290,7 +290,7 @@ import Dashboard from '../../utils/dashboard';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
import(`../music/${depends}`).then(({default: controllerFactory}) => {
|
import(`../music/${depends}`).then(({ default: controllerFactory }) => {
|
||||||
let tabContent;
|
let tabContent;
|
||||||
|
|
||||||
if (index == 1) {
|
if (index == 1) {
|
||||||
|
|
|
@ -124,7 +124,7 @@ export default function (view, params, tabContent) {
|
||||||
loading.hide();
|
loading.hide();
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
|
||||||
import('../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(page);
|
autoFocuser.autoFocus(page);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -135,7 +135,7 @@ export default function (view, params, tabContent) {
|
||||||
let isLoading = false;
|
let isLoading = false;
|
||||||
|
|
||||||
self.showFilterMenu = function () {
|
self.showFilterMenu = function () {
|
||||||
import('../../components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => {
|
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
|
||||||
const filterDialog = new filterDialogFactory({
|
const filterDialog = new filterDialogFactory({
|
||||||
query: getQuery(tabContent),
|
query: getQuery(tabContent),
|
||||||
mode: 'songs',
|
mode: 'songs',
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import escapeHtml from 'escape-html';
|
import escapeHtml from 'escape-html';
|
||||||
import { playbackManager } from '../../../components/playback/playbackmanager';
|
import { playbackManager } from '../../../components/playback/playbackmanager';
|
||||||
import SyncPlay from '../../../plugins/syncPlay/core';
|
|
||||||
import browser from '../../../scripts/browser';
|
import browser from '../../../scripts/browser';
|
||||||
import dom from '../../../scripts/dom';
|
import dom from '../../../scripts/dom';
|
||||||
import inputManager from '../../../scripts/inputManager';
|
import inputManager from '../../../scripts/inputManager';
|
||||||
|
@ -25,6 +24,8 @@ import SubtitleSync from '../../../components/subtitlesync/subtitlesync';
|
||||||
import { appRouter } from '../../../components/appRouter';
|
import { appRouter } from '../../../components/appRouter';
|
||||||
import LibraryMenu from '../../../scripts/libraryMenu';
|
import LibraryMenu from '../../../scripts/libraryMenu';
|
||||||
import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components/backdrop/backdrop';
|
import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components/backdrop/backdrop';
|
||||||
|
import { pluginManager } from '../../../components/pluginManager';
|
||||||
|
import { PluginType } from '../../../types/plugin.ts';
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
const TICKS_PER_MINUTE = 600000000;
|
const TICKS_PER_MINUTE = 600000000;
|
||||||
|
@ -64,7 +65,7 @@ import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components
|
||||||
|
|
||||||
ServerConnections.getApiClient(item.ServerId).getCurrentUser().then(function (user) {
|
ServerConnections.getApiClient(item.ServerId).getCurrentUser().then(function (user) {
|
||||||
if (user.Policy.EnableLiveTvManagement) {
|
if (user.Policy.EnableLiveTvManagement) {
|
||||||
import('../../../components/recordingcreator/recordingbutton').then(({default: RecordingButton}) => {
|
import('../../../components/recordingcreator/recordingbutton').then(({ default: RecordingButton }) => {
|
||||||
if (recordingButtonManager) {
|
if (recordingButtonManager) {
|
||||||
recordingButtonManager.refreshItem(item);
|
recordingButtonManager.refreshItem(item);
|
||||||
return;
|
return;
|
||||||
|
@ -216,7 +217,7 @@ import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components
|
||||||
let title = itemName;
|
let title = itemName;
|
||||||
if (item.PremiereDate) {
|
if (item.PremiereDate) {
|
||||||
try {
|
try {
|
||||||
const year = datetime.toLocaleString(datetime.parseISO8601Date(item.PremiereDate).getFullYear(), {useGrouping: false});
|
const year = datetime.toLocaleString(datetime.parseISO8601Date(item.PremiereDate).getFullYear(), { useGrouping: false });
|
||||||
title += ` (${year})`;
|
title += ` (${year})`;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -622,7 +623,7 @@ import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components
|
||||||
}
|
}
|
||||||
|
|
||||||
function showComingUpNext(player) {
|
function showComingUpNext(player) {
|
||||||
import('../../../components/upnextdialog/upnextdialog').then(({default: UpNextDialog}) => {
|
import('../../../components/upnextdialog/upnextdialog').then(({ default: UpNextDialog }) => {
|
||||||
if (!(currentVisibleMenu || currentUpNextDialog)) {
|
if (!(currentVisibleMenu || currentUpNextDialog)) {
|
||||||
currentVisibleMenu = 'upnext';
|
currentVisibleMenu = 'upnext';
|
||||||
comingUpNextDisplayed = true;
|
comingUpNextDisplayed = true;
|
||||||
|
@ -896,8 +897,8 @@ import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components
|
||||||
const state = playbackManager.getPlayerState(player);
|
const state = playbackManager.getPlayerState(player);
|
||||||
|
|
||||||
// show subtitle offset feature only if player and media support it
|
// show subtitle offset feature only if player and media support it
|
||||||
const showSubOffset = playbackManager.supportSubtitleOffset(player) &&
|
const showSubOffset = playbackManager.supportSubtitleOffset(player)
|
||||||
playbackManager.canHandleOffsetOnCurrentSubtitle(player);
|
&& playbackManager.canHandleOffsetOnCurrentSubtitle(player);
|
||||||
|
|
||||||
playerSettingsMenu.show({
|
playerSettingsMenu.show({
|
||||||
mediaType: 'Video',
|
mediaType: 'Video',
|
||||||
|
@ -929,7 +930,7 @@ import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleStats() {
|
function toggleStats() {
|
||||||
import('../../../components/playerstats/playerstats').then(({default: PlayerStats}) => {
|
import('../../../components/playerstats/playerstats').then(({ default: PlayerStats }) => {
|
||||||
const player = currentPlayer;
|
const player = currentPlayer;
|
||||||
|
|
||||||
if (player) {
|
if (player) {
|
||||||
|
@ -969,7 +970,7 @@ import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components
|
||||||
});
|
});
|
||||||
const positionTo = this;
|
const positionTo = this;
|
||||||
|
|
||||||
import('../../../components/actionSheet/actionSheet').then(({default: actionsheet}) => {
|
import('../../../components/actionSheet/actionSheet').then(({ default: actionsheet }) => {
|
||||||
actionsheet.show({
|
actionsheet.show({
|
||||||
items: menuItems,
|
items: menuItems,
|
||||||
title: globalize.translate('Audio'),
|
title: globalize.translate('Audio'),
|
||||||
|
@ -1086,7 +1087,7 @@ import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components
|
||||||
|
|
||||||
const positionTo = this;
|
const positionTo = this;
|
||||||
|
|
||||||
import('../../../components/actionSheet/actionSheet').then(({default: actionsheet}) => {
|
import('../../../components/actionSheet/actionSheet').then(({ default: actionsheet }) => {
|
||||||
actionsheet.show({
|
actionsheet.show({
|
||||||
title: globalize.translate('Subtitles'),
|
title: globalize.translate('Subtitles'),
|
||||||
items: menuItems,
|
items: menuItems,
|
||||||
|
@ -1774,38 +1775,39 @@ import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components
|
||||||
}, iconVisibilityTime);
|
}, iconVisibilityTime);
|
||||||
};
|
};
|
||||||
|
|
||||||
Events.on(SyncPlay.Manager, 'enabled', (event, enabled) => {
|
const SyncPlay = pluginManager.firstOfType(PluginType.SyncPlay)?.instance;
|
||||||
if (enabled) {
|
if (SyncPlay) {
|
||||||
// SyncPlay enabled
|
Events.on(SyncPlay.Manager, 'enabled', (_event, enabled) => {
|
||||||
} else {
|
if (!enabled) {
|
||||||
const syncPlayIcon = view.querySelector('#syncPlayIcon');
|
const syncPlayIcon = view.querySelector('#syncPlayIcon');
|
||||||
syncPlayIcon.style.visibility = 'hidden';
|
syncPlayIcon.style.visibility = 'hidden';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.on(SyncPlay.Manager, 'notify-osd', (event, action) => {
|
Events.on(SyncPlay.Manager, 'notify-osd', (_event, action) => {
|
||||||
showIcon(action);
|
showIcon(action);
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.on(SyncPlay.Manager, 'group-state-update', (event, state, reason) => {
|
Events.on(SyncPlay.Manager, 'group-state-update', (_event, state, reason) => {
|
||||||
if (state === 'Playing' && reason === 'Unpause') {
|
if (state === 'Playing' && reason === 'Unpause') {
|
||||||
showIcon('schedule-play');
|
showIcon('schedule-play');
|
||||||
} else if (state === 'Playing' && reason === 'Ready') {
|
} else if (state === 'Playing' && reason === 'Ready') {
|
||||||
showIcon('schedule-play');
|
showIcon('schedule-play');
|
||||||
} else if (state === 'Paused' && reason === 'Pause') {
|
} else if (state === 'Paused' && reason === 'Pause') {
|
||||||
showIcon('pause');
|
showIcon('pause');
|
||||||
} else if (state === 'Paused' && reason === 'Ready') {
|
} else if (state === 'Paused' && reason === 'Ready') {
|
||||||
showIcon('clear');
|
showIcon('clear');
|
||||||
} else if (state === 'Waiting' && reason === 'Seek') {
|
} else if (state === 'Waiting' && reason === 'Seek') {
|
||||||
showIcon('seek');
|
showIcon('seek');
|
||||||
} else if (state === 'Waiting' && reason === 'Buffer') {
|
} else if (state === 'Waiting' && reason === 'Buffer') {
|
||||||
showIcon('buffering');
|
showIcon('buffering');
|
||||||
} else if (state === 'Waiting' && reason === 'Pause') {
|
} else if (state === 'Waiting' && reason === 'Pause') {
|
||||||
showIcon('wait-pause');
|
showIcon('wait-pause');
|
||||||
} else if (state === 'Waiting' && reason === 'Unpause') {
|
} else if (state === 'Waiting' && reason === 'Unpause') {
|
||||||
showIcon('wait-unpause');
|
showIcon('wait-unpause');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eslint-enable indent */
|
/* eslint-enable indent */
|
||||||
|
|
|
@ -54,7 +54,7 @@ import { ConnectionState } from '../../../utils/jellyfin-apiclient/ConnectionSta
|
||||||
view.querySelector('.addServerForm').addEventListener('submit', onServerSubmit);
|
view.querySelector('.addServerForm').addEventListener('submit', onServerSubmit);
|
||||||
view.querySelector('.btnCancel').addEventListener('click', goBack);
|
view.querySelector('.btnCancel').addEventListener('click', goBack);
|
||||||
|
|
||||||
import('../../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(view);
|
autoFocuser.autoFocus(view);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ import { ConnectionState } from '../../../utils/jellyfin-apiclient/ConnectionSta
|
||||||
}
|
}
|
||||||
|
|
||||||
function goBack() {
|
function goBack() {
|
||||||
import('../../../components/appRouter').then(({appRouter}) => {
|
import('../../../components/appRouter').then(({ appRouter }) => {
|
||||||
appRouter.back();
|
appRouter.back();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,7 @@ import './login.scss';
|
||||||
view.querySelector('.manualLoginForm').classList.add('hide');
|
view.querySelector('.manualLoginForm').classList.add('hide');
|
||||||
view.querySelector('.btnManual').classList.remove('hide');
|
view.querySelector('.btnManual').classList.remove('hide');
|
||||||
|
|
||||||
import('../../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(view);
|
autoFocuser.autoFocus(view);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
||||||
loading.hide();
|
loading.hide();
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
|
||||||
import('../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(page);
|
autoFocuser.autoFocus(page);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -173,7 +173,7 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
||||||
let isLoading = false;
|
let isLoading = false;
|
||||||
|
|
||||||
self.showFilterMenu = function () {
|
self.showFilterMenu = function () {
|
||||||
import('../../components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => {
|
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
|
||||||
const filterDialog = new filterDialogFactory({
|
const filterDialog = new filterDialogFactory({
|
||||||
query: getQuery(tabContent),
|
query: getQuery(tabContent),
|
||||||
mode: 'episodes',
|
mode: 'episodes',
|
||||||
|
|
|
@ -269,7 +269,7 @@ import autoFocuser from '../../components/autoFocuser';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
import(`../shows/${depends}`).then(({default: controllerFactory}) => {
|
import(`../shows/${depends}`).then(({ default: controllerFactory }) => {
|
||||||
let tabContent;
|
let tabContent;
|
||||||
|
|
||||||
if (index === 1) {
|
if (index === 1) {
|
||||||
|
|
|
@ -191,7 +191,7 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
||||||
loading.hide();
|
loading.hide();
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
|
||||||
import('../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(page);
|
autoFocuser.autoFocus(page);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -201,7 +201,7 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
||||||
let isLoading = false;
|
let isLoading = false;
|
||||||
|
|
||||||
this.showFilterMenu = function () {
|
this.showFilterMenu = function () {
|
||||||
import('../../components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => {
|
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
|
||||||
const filterDialog = new filterDialogFactory({
|
const filterDialog = new filterDialogFactory({
|
||||||
query: getQuery(tabContent),
|
query: getQuery(tabContent),
|
||||||
mode: 'series',
|
mode: 'series',
|
||||||
|
|
|
@ -50,7 +50,7 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
|
||||||
});
|
});
|
||||||
loading.hide();
|
loading.hide();
|
||||||
|
|
||||||
import('../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(context);
|
autoFocuser.autoFocus(context);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,7 +21,7 @@ export default function (view) {
|
||||||
view.querySelector('form').addEventListener('submit', submit);
|
view.querySelector('form').addEventListener('submit', submit);
|
||||||
view.querySelector('.btnSave').classList.remove('hide');
|
view.querySelector('.btnSave').classList.remove('hide');
|
||||||
|
|
||||||
import('../../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(view);
|
autoFocuser.autoFocus(view);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -68,7 +68,7 @@ export default function (view, params) {
|
||||||
page.querySelector('.lnkControlsPreferences').classList.add('hide');
|
page.querySelector('.lnkControlsPreferences').classList.add('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
import('../../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(view);
|
autoFocuser.autoFocus(view);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,7 +13,7 @@ type IProps = {
|
||||||
isLinkVisible?: boolean;
|
isLinkVisible?: boolean;
|
||||||
url?: string;
|
url?: string;
|
||||||
}
|
}
|
||||||
const SectionTitleContainer: FunctionComponent<IProps> = ({SectionClassName, title, isBtnVisible = false, btnId, btnClassName, btnTitle, btnIcon, isLinkVisible = true, url}: IProps) => {
|
const SectionTitleContainer: FunctionComponent<IProps> = ({ SectionClassName, title, isBtnVisible = false, btnId, btnClassName, btnTitle, btnIcon, isLinkVisible = true, url }: IProps) => {
|
||||||
return (
|
return (
|
||||||
<div className={`${SectionClassName} sectionTitleContainer flex align-items-center`}>
|
<div className={`${SectionClassName} sectionTitleContainer flex align-items-center`}>
|
||||||
<h2 className='sectionTitle'>
|
<h2 className='sectionTitle'>
|
||||||
|
|
|
@ -72,7 +72,7 @@ import Sortable from 'sortablejs';
|
||||||
}
|
}
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
import('../../components/multiSelect/multiSelect').then(({default: MultiSelect}) => {
|
import('../../components/multiSelect/multiSelect').then(({ default: MultiSelect }) => {
|
||||||
self.multiSelect = new MultiSelect({
|
self.multiSelect = new MultiSelect({
|
||||||
container: self,
|
container: self,
|
||||||
bindOnClick: false
|
bindOnClick: false
|
||||||
|
|
|
@ -229,8 +229,8 @@ const Scroller: FC<ScrollerProps> = ({
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{
|
{
|
||||||
showControls && scrollState.scrollWidth > scrollState.scrollSize + 20 &&
|
showControls && scrollState.scrollWidth > scrollState.scrollSize + 20
|
||||||
<ScrollButtons
|
&& <ScrollButtons
|
||||||
scrollRef={scrollRef}
|
scrollRef={scrollRef}
|
||||||
scrollerFactoryRef={scrollerFactoryRef}
|
scrollerFactoryRef={scrollerFactoryRef}
|
||||||
scrollState={scrollState}
|
scrollState={scrollState}
|
||||||
|
|
|
@ -25,7 +25,7 @@ class BackdropScreensaver {
|
||||||
const apiClient = ServerConnections.currentApiClient();
|
const apiClient = ServerConnections.currentApiClient();
|
||||||
apiClient.getItems(apiClient.getCurrentUserId(), query).then((result) => {
|
apiClient.getItems(apiClient.getCurrentUserId(), query).then((result) => {
|
||||||
if (result.Items.length) {
|
if (result.Items.length) {
|
||||||
import('../../components/slideshow/slideshow').then(({default: Slideshow}) => {
|
import('../../components/slideshow/slideshow').then(({ default: Slideshow }) => {
|
||||||
const newSlideShow = new Slideshow({
|
const newSlideShow = new Slideshow({
|
||||||
showTitle: true,
|
showTitle: true,
|
||||||
cover: true,
|
cover: true,
|
||||||
|
|
|
@ -17,15 +17,31 @@ import '../../elements/emby-button/paper-icon-button-light';
|
||||||
import html from './template.html';
|
import html from './template.html';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
|
const THEMES = {
|
||||||
|
'dark': { 'body': { 'color': '#d8dadc', 'background': '#000', 'font-size': 'medium' } },
|
||||||
|
'sepia': { 'body': { 'color': '#d8a262', 'background': '#000', 'font-size': 'medium' } },
|
||||||
|
'light': { 'body': { 'color': '#000', 'background': '#fff', 'font-size': 'medium' } }
|
||||||
|
};
|
||||||
|
const THEME_ORDER = ['dark', 'sepia', 'light'];
|
||||||
|
const FONT_SIZES = ['x-small', 'small', 'medium', 'large', 'x-large'];
|
||||||
|
|
||||||
export class BookPlayer {
|
export class BookPlayer {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.name = 'Book Player';
|
this.name = 'Book Player';
|
||||||
this.type = PluginType.MediaPlayer;
|
this.type = PluginType.MediaPlayer;
|
||||||
this.id = 'bookplayer';
|
this.id = 'bookplayer';
|
||||||
this.priority = 1;
|
this.priority = 1;
|
||||||
|
if (!userSettings.theme() || userSettings.theme() === 'dark') {
|
||||||
|
this.theme = 'dark';
|
||||||
|
} else {
|
||||||
|
this.theme = 'light';
|
||||||
|
}
|
||||||
|
this.fontSize = 'medium';
|
||||||
this.onDialogClosed = this.onDialogClosed.bind(this);
|
this.onDialogClosed = this.onDialogClosed.bind(this);
|
||||||
this.openTableOfContents = this.openTableOfContents.bind(this);
|
this.openTableOfContents = this.openTableOfContents.bind(this);
|
||||||
|
this.rotateTheme = this.rotateTheme.bind(this);
|
||||||
|
this.increaseFontSize = this.increaseFontSize.bind(this);
|
||||||
|
this.decreaseFontSize = this.decreaseFontSize.bind(this);
|
||||||
this.previous = this.previous.bind(this);
|
this.previous = this.previous.bind(this);
|
||||||
this.next = this.next.bind(this);
|
this.next = this.next.bind(this);
|
||||||
this.onWindowKeyUp = this.onWindowKeyUp.bind(this);
|
this.onWindowKeyUp = this.onWindowKeyUp.bind(this);
|
||||||
|
@ -164,6 +180,9 @@ export class BookPlayer {
|
||||||
elem.querySelector('#btnBookplayerExit').addEventListener('click', this.onDialogClosed, { once: true });
|
elem.querySelector('#btnBookplayerExit').addEventListener('click', this.onDialogClosed, { once: true });
|
||||||
elem.querySelector('#btnBookplayerToc').addEventListener('click', this.openTableOfContents);
|
elem.querySelector('#btnBookplayerToc').addEventListener('click', this.openTableOfContents);
|
||||||
elem.querySelector('#btnBookplayerFullscreen').addEventListener('click', this.toggleFullscreen);
|
elem.querySelector('#btnBookplayerFullscreen').addEventListener('click', this.toggleFullscreen);
|
||||||
|
elem.querySelector('#btnBookplayerRotateTheme').addEventListener('click', this.rotateTheme);
|
||||||
|
elem.querySelector('#btnBookplayerIncreaseFontSize').addEventListener('click', this.increaseFontSize);
|
||||||
|
elem.querySelector('#btnBookplayerDecreaseFontSize').addEventListener('click', this.decreaseFontSize);
|
||||||
elem.querySelector('#btnBookplayerPrev')?.addEventListener('click', this.previous);
|
elem.querySelector('#btnBookplayerPrev')?.addEventListener('click', this.previous);
|
||||||
elem.querySelector('#btnBookplayerNext')?.addEventListener('click', this.next);
|
elem.querySelector('#btnBookplayerNext')?.addEventListener('click', this.next);
|
||||||
}
|
}
|
||||||
|
@ -184,6 +203,9 @@ export class BookPlayer {
|
||||||
elem.querySelector('#btnBookplayerExit').removeEventListener('click', this.onDialogClosed);
|
elem.querySelector('#btnBookplayerExit').removeEventListener('click', this.onDialogClosed);
|
||||||
elem.querySelector('#btnBookplayerToc').removeEventListener('click', this.openTableOfContents);
|
elem.querySelector('#btnBookplayerToc').removeEventListener('click', this.openTableOfContents);
|
||||||
elem.querySelector('#btnBookplayerFullscreen').removeEventListener('click', this.toggleFullscreen);
|
elem.querySelector('#btnBookplayerFullscreen').removeEventListener('click', this.toggleFullscreen);
|
||||||
|
elem.querySelector('#btnBookplayerRotateTheme').removeEventListener('click', this.rotateTheme);
|
||||||
|
elem.querySelector('#btnBookplayerIncreaseFontSize').removeEventListener('click', this.increaseFontSize);
|
||||||
|
elem.querySelector('#btnBookplayerDecreaseFontSize').removeEventListener('click', this.decreaseFontSize);
|
||||||
elem.querySelector('#btnBookplayerPrev')?.removeEventListener('click', this.previous);
|
elem.querySelector('#btnBookplayerPrev')?.removeEventListener('click', this.previous);
|
||||||
elem.querySelector('#btnBookplayerNext')?.removeEventListener('click', this.next);
|
elem.querySelector('#btnBookplayerNext')?.removeEventListener('click', this.next);
|
||||||
}
|
}
|
||||||
|
@ -214,6 +236,31 @@ export class BookPlayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rotateTheme() {
|
||||||
|
if (this.loaded) {
|
||||||
|
const newTheme = THEME_ORDER[(THEME_ORDER.indexOf(this.theme) + 1) % THEME_ORDER.length];
|
||||||
|
this.rendition.themes.register('default', THEMES[newTheme]);
|
||||||
|
this.rendition.themes.update('default');
|
||||||
|
this.theme = newTheme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
increaseFontSize() {
|
||||||
|
if (this.loaded && this.fontSize !== FONT_SIZES[FONT_SIZES.length - 1]) {
|
||||||
|
const newFontSize = FONT_SIZES[(FONT_SIZES.indexOf(this.fontSize) + 1)];
|
||||||
|
this.rendition.themes.fontSize(newFontSize);
|
||||||
|
this.fontSize = newFontSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
decreaseFontSize() {
|
||||||
|
if (this.loaded && this.fontSize !== FONT_SIZES[0]) {
|
||||||
|
const newFontSize = FONT_SIZES[(FONT_SIZES.indexOf(this.fontSize) - 1)];
|
||||||
|
this.rendition.themes.fontSize(newFontSize);
|
||||||
|
this.fontSize = newFontSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
previous(e) {
|
previous(e) {
|
||||||
e?.preventDefault();
|
e?.preventDefault();
|
||||||
if (this.rendition) {
|
if (this.rendition) {
|
||||||
|
@ -296,11 +343,8 @@ export class BookPlayer {
|
||||||
this.currentSrc = downloadHref;
|
this.currentSrc = downloadHref;
|
||||||
this.rendition = rendition;
|
this.rendition = rendition;
|
||||||
|
|
||||||
rendition.themes.register('dark', { 'body': { 'color': '#fff' } });
|
rendition.themes.register('default', THEMES[this.theme]);
|
||||||
|
rendition.themes.select('default');
|
||||||
if (userSettings.theme(undefined) === 'dark' || userSettings.theme(undefined) === null) {
|
|
||||||
rendition.themes.select('dark');
|
|
||||||
}
|
|
||||||
|
|
||||||
return rendition.display().then(() => {
|
return rendition.display().then(() => {
|
||||||
const epubElem = document.querySelector('.epub-container');
|
const epubElem = document.querySelector('.epub-container');
|
||||||
|
|
|
@ -23,8 +23,8 @@ export default class TableOfContents {
|
||||||
bindEvents() {
|
bindEvents() {
|
||||||
const elem = this.elem;
|
const elem = this.elem;
|
||||||
|
|
||||||
elem.addEventListener('close', this.onDialogClosed, {once: true});
|
elem.addEventListener('close', this.onDialogClosed, { once: true });
|
||||||
elem.querySelector('.btnBookplayerTocClose').addEventListener('click', this.onDialogClosed, {once: true});
|
elem.querySelector('.btnBookplayerTocClose').addEventListener('click', this.onDialogClosed, { once: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
unbindEvents() {
|
unbindEvents() {
|
||||||
|
|
|
@ -11,6 +11,15 @@
|
||||||
<button is="paper-icon-button-light" id="btnBookplayerExit" class="autoSize bookplayerButton hide-mouse-idle-tv" tabindex="-1">
|
<button is="paper-icon-button-light" id="btnBookplayerExit" class="autoSize bookplayerButton hide-mouse-idle-tv" tabindex="-1">
|
||||||
<span class="material-icons bookplayerButtonIcon close" aria-hidden="true"></span>
|
<span class="material-icons bookplayerButtonIcon close" aria-hidden="true"></span>
|
||||||
</button>
|
</button>
|
||||||
|
<button is="paper-icon-button-light" id="btnBookplayerRotateTheme" class="autoSize bookplayerButton hide-mouse-idle-tv" tabindex="-1">
|
||||||
|
<span class="material-icons bookplayerButtonIcon remove_red_eye" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button is="paper-icon-button-light" id="btnBookplayerDecreaseFontSize" class="autoSize bookplayerButton hide-mouse-idle-tv" tabindex="-1">
|
||||||
|
<span class="material-icons bookplayerButtonIcon text_decrease" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button is="paper-icon-button-light" id="btnBookplayerIncreaseFontSize" class="autoSize bookplayerButton hide-mouse-idle-tv" tabindex="-1">
|
||||||
|
<span class="material-icons bookplayerButtonIcon text_increase" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
<button is="paper-icon-button-light" id="btnBookplayerFullscreen" class="autoSize bookplayerButton hide-mouse-idle-tv" tabindex="-1">
|
<button is="paper-icon-button-light" id="btnBookplayerFullscreen" class="autoSize bookplayerButton hide-mouse-idle-tv" tabindex="-1">
|
||||||
<span class="material-icons bookplayerButtonIcon fullscreen" aria-hidden="true"></span>
|
<span class="material-icons bookplayerButtonIcon fullscreen" aria-hidden="true"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -107,7 +107,7 @@ function tryRemoveElement(elem) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function requireHlsPlayer(callback) {
|
function requireHlsPlayer(callback) {
|
||||||
import('hls.js').then(({default: hls}) => {
|
import('hls.js').then(({ default: hls }) => {
|
||||||
hls.DefaultConfig.lowLatencyMode = false;
|
hls.DefaultConfig.lowLatencyMode = false;
|
||||||
hls.DefaultConfig.backBufferLength = Infinity;
|
hls.DefaultConfig.backBufferLength = Infinity;
|
||||||
hls.DefaultConfig.liveBackBufferLength = 90;
|
hls.DefaultConfig.liveBackBufferLength = 90;
|
||||||
|
@ -396,7 +396,7 @@ function tryRemoveElement(elem) {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
setSrcWithFlvJs(elem, options, url) {
|
setSrcWithFlvJs(elem, options, url) {
|
||||||
return import('flv.js').then(({default: flvjs}) => {
|
return import('flv.js').then(({ default: flvjs }) => {
|
||||||
const flvPlayer = flvjs.createPlayer({
|
const flvPlayer = flvjs.createPlayer({
|
||||||
type: 'flv',
|
type: 'flv',
|
||||||
url: url
|
url: url
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default class PhotoPlayer {
|
||||||
|
|
||||||
play(options) {
|
play(options) {
|
||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
import('../../components/slideshow/slideshow').then(({default: Slideshow}) => {
|
import('../../components/slideshow/slideshow').then(({ default: Slideshow }) => {
|
||||||
const index = options.startIndex || 0;
|
const index = options.startIndex || 0;
|
||||||
|
|
||||||
const apiClient = ServerConnections.currentApiClient();
|
const apiClient = ServerConnections.currentApiClient();
|
||||||
|
|
|
@ -133,9 +133,9 @@ class PlaybackCore {
|
||||||
*/
|
*/
|
||||||
async sendBufferingRequest(isBuffering = true) {
|
async sendBufferingRequest(isBuffering = true) {
|
||||||
const playerWrapper = this.manager.getPlayerWrapper();
|
const playerWrapper = this.manager.getPlayerWrapper();
|
||||||
const currentPosition = (playerWrapper.currentTimeAsync
|
const currentPosition = (playerWrapper.currentTimeAsync ?
|
||||||
? await playerWrapper.currentTimeAsync()
|
await playerWrapper.currentTimeAsync() :
|
||||||
: playerWrapper.currentTime());
|
playerWrapper.currentTime());
|
||||||
const currentPositionTicks = Math.round(currentPosition * Helper.TicksPerMillisecond);
|
const currentPositionTicks = Math.round(currentPosition * Helper.TicksPerMillisecond);
|
||||||
const isPlaying = playerWrapper.isPlaying();
|
const isPlaying = playerWrapper.isPlaying();
|
||||||
|
|
||||||
|
@ -172,11 +172,11 @@ class PlaybackCore {
|
||||||
*/
|
*/
|
||||||
async applyCommand(command) {
|
async applyCommand(command) {
|
||||||
// Check if duplicate.
|
// Check if duplicate.
|
||||||
if (this.lastCommand &&
|
if (this.lastCommand
|
||||||
this.lastCommand.When.getTime() === command.When.getTime() &&
|
&& this.lastCommand.When.getTime() === command.When.getTime()
|
||||||
this.lastCommand.PositionTicks === command.PositionTicks &&
|
&& this.lastCommand.PositionTicks === command.PositionTicks
|
||||||
this.lastCommand.Command === command.Command &&
|
&& this.lastCommand.Command === command.Command
|
||||||
this.lastCommand.PlaylistItemId === command.PlaylistItemId
|
&& this.lastCommand.PlaylistItemId === command.PlaylistItemId
|
||||||
) {
|
) {
|
||||||
// Duplicate command found, check playback state and correct if needed.
|
// Duplicate command found, check playback state and correct if needed.
|
||||||
console.debug('SyncPlay applyCommand: duplicate command received!', command);
|
console.debug('SyncPlay applyCommand: duplicate command received!', command);
|
||||||
|
@ -192,9 +192,9 @@ class PlaybackCore {
|
||||||
} else {
|
} else {
|
||||||
// Check if playback state matches requested command.
|
// Check if playback state matches requested command.
|
||||||
const playerWrapper = this.manager.getPlayerWrapper();
|
const playerWrapper = this.manager.getPlayerWrapper();
|
||||||
const currentPositionTicks = Math.round((playerWrapper.currentTimeAsync
|
const currentPositionTicks = Math.round((playerWrapper.currentTimeAsync ?
|
||||||
? await playerWrapper.currentTimeAsync()
|
await playerWrapper.currentTimeAsync() :
|
||||||
: playerWrapper.currentTime()) * Helper.TicksPerMillisecond);
|
playerWrapper.currentTime()) * Helper.TicksPerMillisecond);
|
||||||
const isPlaying = playerWrapper.isPlaying();
|
const isPlaying = playerWrapper.isPlaying();
|
||||||
|
|
||||||
switch (command.Command) {
|
switch (command.Command) {
|
||||||
|
@ -279,9 +279,9 @@ class PlaybackCore {
|
||||||
const playAtTimeLocal = this.timeSyncCore.remoteDateToLocal(playAtTime);
|
const playAtTimeLocal = this.timeSyncCore.remoteDateToLocal(playAtTime);
|
||||||
|
|
||||||
const playerWrapper = this.manager.getPlayerWrapper();
|
const playerWrapper = this.manager.getPlayerWrapper();
|
||||||
const currentPositionTicks = (playerWrapper.currentTimeAsync
|
const currentPositionTicks = (playerWrapper.currentTimeAsync ?
|
||||||
? await playerWrapper.currentTimeAsync()
|
await playerWrapper.currentTimeAsync() :
|
||||||
: playerWrapper.currentTime()) * Helper.TicksPerMillisecond;
|
playerWrapper.currentTime()) * Helper.TicksPerMillisecond;
|
||||||
|
|
||||||
if (playAtTimeLocal > currentTime) {
|
if (playAtTimeLocal > currentTime) {
|
||||||
const playTimeout = playAtTimeLocal - currentTime;
|
const playTimeout = playAtTimeLocal - currentTime;
|
||||||
|
|
|
@ -174,9 +174,9 @@ class QueueCore {
|
||||||
|
|
||||||
const currentTime = new Date();
|
const currentTime = new Date();
|
||||||
const now = this.manager.timeSyncCore.localDateToRemote(currentTime);
|
const now = this.manager.timeSyncCore.localDateToRemote(currentTime);
|
||||||
const currentPosition = (playerWrapper.currentTimeAsync
|
const currentPosition = (playerWrapper.currentTimeAsync ?
|
||||||
? await playerWrapper.currentTimeAsync()
|
await playerWrapper.currentTimeAsync() :
|
||||||
: playerWrapper.currentTime());
|
playerWrapper.currentTime());
|
||||||
const currentPositionTicks = Math.round(currentPosition * Helper.TicksPerMillisecond);
|
const currentPositionTicks = Math.round(currentPosition * Helper.TicksPerMillisecond);
|
||||||
const isPlaying = playerWrapper.isPlaying();
|
const isPlaying = playerWrapper.isPlaying();
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ class SyncPlayPlugin implements Plugin {
|
||||||
id: string;
|
id: string;
|
||||||
type: string;
|
type: string;
|
||||||
priority: number;
|
priority: number;
|
||||||
|
instance: typeof SyncPlay;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.name = 'SyncPlay Plugin';
|
this.name = 'SyncPlay Plugin';
|
||||||
|
@ -21,6 +22,8 @@ class SyncPlayPlugin implements Plugin {
|
||||||
this.type = PluginType.SyncPlay;
|
this.type = PluginType.SyncPlay;
|
||||||
this.priority = 1;
|
this.priority = 1;
|
||||||
|
|
||||||
|
this.instance = SyncPlay;
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import SyncPlay from '../core';
|
|
||||||
import SyncPlaySettingsEditor from './settings/SettingsEditor';
|
import SyncPlaySettingsEditor from './settings/SettingsEditor';
|
||||||
import loading from '../../../components/loading/loading';
|
import loading from '../../../components/loading/loading';
|
||||||
import toast from '../../../components/toast/toast';
|
import toast from '../../../components/toast/toast';
|
||||||
import actionsheet from '../../../components/actionSheet/actionSheet';
|
import actionsheet from '../../../components/actionSheet/actionSheet';
|
||||||
import globalize from '../../../scripts/globalize';
|
import globalize from '../../../scripts/globalize';
|
||||||
import playbackPermissionManager from './playbackPermissionManager';
|
import playbackPermissionManager from './playbackPermissionManager';
|
||||||
|
import { pluginManager } from '../../../components/pluginManager';
|
||||||
import ServerConnections from '../../../components/ServerConnections';
|
import ServerConnections from '../../../components/ServerConnections';
|
||||||
|
import { PluginType } from '../../../types/plugin.ts';
|
||||||
import Events from '../../../utils/events.ts';
|
import Events from '../../../utils/events.ts';
|
||||||
|
|
||||||
import './groupSelectionMenu.scss';
|
import './groupSelectionMenu.scss';
|
||||||
|
@ -17,8 +18,22 @@ class GroupSelectionMenu {
|
||||||
constructor() {
|
constructor() {
|
||||||
// Register to SyncPlay events.
|
// Register to SyncPlay events.
|
||||||
this.syncPlayEnabled = false;
|
this.syncPlayEnabled = false;
|
||||||
Events.on(SyncPlay.Manager, 'enabled', (e, enabled) => {
|
this.SyncPlay = pluginManager.firstOfType(PluginType.SyncPlay)?.instance;
|
||||||
this.syncPlayEnabled = enabled;
|
|
||||||
|
if (this.SyncPlay) {
|
||||||
|
Events.on(this.SyncPlay.Manager, 'enabled', (_event, enabled) => {
|
||||||
|
this.syncPlayEnabled = enabled;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Events.on(pluginManager, 'registered', (_event0, plugin) => {
|
||||||
|
if (plugin.type === PluginType.SyncPlay) {
|
||||||
|
this.SyncPlay = plugin.instance;
|
||||||
|
|
||||||
|
Events.on(plugin.instance.Manager, 'enabled', (_event1, enabled) => {
|
||||||
|
this.syncPlayEnabled = enabled;
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,10 +118,11 @@ class GroupSelectionMenu {
|
||||||
* @param {Object} apiClient - ApiClient.
|
* @param {Object} apiClient - ApiClient.
|
||||||
*/
|
*/
|
||||||
showLeaveGroupSelection(button, user, apiClient) {
|
showLeaveGroupSelection(button, user, apiClient) {
|
||||||
const groupInfo = SyncPlay.Manager.getGroupInfo();
|
const groupInfo = this.SyncPlay?.Manager.getGroupInfo();
|
||||||
const menuItems = [];
|
const menuItems = [];
|
||||||
|
|
||||||
if (!SyncPlay.Manager.isPlaylistEmpty() && !SyncPlay.Manager.isPlaybackActive()) {
|
if (!this.SyncPlay?.Manager.isPlaylistEmpty()
|
||||||
|
&& !this.SyncPlay?.Manager.isPlaybackActive()) {
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
name: globalize.translate('LabelSyncPlayResumePlayback'),
|
name: globalize.translate('LabelSyncPlayResumePlayback'),
|
||||||
icon: 'play_circle_filled',
|
icon: 'play_circle_filled',
|
||||||
|
@ -114,7 +130,7 @@ class GroupSelectionMenu {
|
||||||
selected: false,
|
selected: false,
|
||||||
secondaryText: globalize.translate('LabelSyncPlayResumePlaybackDescription')
|
secondaryText: globalize.translate('LabelSyncPlayResumePlaybackDescription')
|
||||||
});
|
});
|
||||||
} else if (SyncPlay.Manager.isPlaybackActive()) {
|
} else if (this.SyncPlay?.Manager.isPlaybackActive()) {
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
name: globalize.translate('LabelSyncPlayHaltPlayback'),
|
name: globalize.translate('LabelSyncPlayHaltPlayback'),
|
||||||
icon: 'pause_circle_filled',
|
icon: 'pause_circle_filled',
|
||||||
|
@ -149,15 +165,15 @@ class GroupSelectionMenu {
|
||||||
border: true
|
border: true
|
||||||
};
|
};
|
||||||
|
|
||||||
actionsheet.show(menuOptions).then(function (id) {
|
actionsheet.show(menuOptions).then((id) => {
|
||||||
if (id == 'resume-playback') {
|
if (id == 'resume-playback') {
|
||||||
SyncPlay.Manager.resumeGroupPlayback(apiClient);
|
this.SyncPlay?.Manager.resumeGroupPlayback(apiClient);
|
||||||
} else if (id == 'halt-playback') {
|
} else if (id == 'halt-playback') {
|
||||||
SyncPlay.Manager.haltGroupPlayback(apiClient);
|
this.SyncPlay?.Manager.haltGroupPlayback(apiClient);
|
||||||
} else if (id == 'leave-group') {
|
} else if (id == 'leave-group') {
|
||||||
apiClient.leaveSyncPlayGroup();
|
apiClient.leaveSyncPlayGroup();
|
||||||
} else if (id == 'settings') {
|
} else if (id == 'settings') {
|
||||||
new SyncPlaySettingsEditor(apiClient, SyncPlay.Manager.getTimeSyncCore(), { groupInfo: groupInfo })
|
new SyncPlaySettingsEditor(apiClient, this.SyncPlay?.Manager.getTimeSyncCore(), { groupInfo: groupInfo })
|
||||||
.embed()
|
.embed()
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|
|
@ -3,13 +3,14 @@
|
||||||
* @module components/syncPlay/settings/SettingsEditor
|
* @module components/syncPlay/settings/SettingsEditor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import SyncPlay from '../../core';
|
|
||||||
import { setSetting } from '../../core/Settings';
|
import { setSetting } from '../../core/Settings';
|
||||||
import dialogHelper from '../../../../components/dialogHelper/dialogHelper';
|
import dialogHelper from '../../../../components/dialogHelper/dialogHelper';
|
||||||
import layoutManager from '../../../../components/layoutManager';
|
import layoutManager from '../../../../components/layoutManager';
|
||||||
|
import { pluginManager } from '../../../../components/pluginManager';
|
||||||
import loading from '../../../../components/loading/loading';
|
import loading from '../../../../components/loading/loading';
|
||||||
import toast from '../../../../components/toast/toast';
|
import toast from '../../../../components/toast/toast';
|
||||||
import globalize from '../../../../scripts/globalize';
|
import globalize from '../../../../scripts/globalize';
|
||||||
|
import { PluginType } from '../../../../types/plugin.ts';
|
||||||
import Events from '../../../../utils/events.ts';
|
import Events from '../../../../utils/events.ts';
|
||||||
|
|
||||||
import 'material-design-icons-iconfont';
|
import 'material-design-icons-iconfont';
|
||||||
|
@ -36,6 +37,7 @@ class SettingsEditor {
|
||||||
this.apiClient = apiClient;
|
this.apiClient = apiClient;
|
||||||
this.timeSyncCore = timeSyncCore;
|
this.timeSyncCore = timeSyncCore;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
this.SyncPlay = pluginManager.firstOfType(PluginType.SyncPlay)?.instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
async embed() {
|
async embed() {
|
||||||
|
@ -95,14 +97,14 @@ class SettingsEditor {
|
||||||
async initEditor() {
|
async initEditor() {
|
||||||
const { context } = this;
|
const { context } = this;
|
||||||
|
|
||||||
context.querySelector('#txtExtraTimeOffset').value = SyncPlay.Manager.timeSyncCore.extraTimeOffset;
|
context.querySelector('#txtExtraTimeOffset').value = this.SyncPlay?.Manager.timeSyncCore.extraTimeOffset;
|
||||||
context.querySelector('#chkSyncCorrection').checked = SyncPlay.Manager.playbackCore.enableSyncCorrection;
|
context.querySelector('#chkSyncCorrection').checked = this.SyncPlay?.Manager.playbackCore.enableSyncCorrection;
|
||||||
context.querySelector('#txtMinDelaySpeedToSync').value = SyncPlay.Manager.playbackCore.minDelaySpeedToSync;
|
context.querySelector('#txtMinDelaySpeedToSync').value = this.SyncPlay?.Manager.playbackCore.minDelaySpeedToSync;
|
||||||
context.querySelector('#txtMaxDelaySpeedToSync').value = SyncPlay.Manager.playbackCore.maxDelaySpeedToSync;
|
context.querySelector('#txtMaxDelaySpeedToSync').value = this.SyncPlay?.Manager.playbackCore.maxDelaySpeedToSync;
|
||||||
context.querySelector('#txtSpeedToSyncDuration').value = SyncPlay.Manager.playbackCore.speedToSyncDuration;
|
context.querySelector('#txtSpeedToSyncDuration').value = this.SyncPlay?.Manager.playbackCore.speedToSyncDuration;
|
||||||
context.querySelector('#txtMinDelaySkipToSync').value = SyncPlay.Manager.playbackCore.minDelaySkipToSync;
|
context.querySelector('#txtMinDelaySkipToSync').value = this.SyncPlay?.Manager.playbackCore.minDelaySkipToSync;
|
||||||
context.querySelector('#chkSpeedToSync').checked = SyncPlay.Manager.playbackCore.useSpeedToSync;
|
context.querySelector('#chkSpeedToSync').checked = this.SyncPlay?.Manager.playbackCore.useSpeedToSync;
|
||||||
context.querySelector('#chkSkipToSync').checked = SyncPlay.Manager.playbackCore.useSkipToSync;
|
context.querySelector('#chkSkipToSync').checked = this.SyncPlay?.Manager.playbackCore.useSkipToSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
|
@ -139,7 +141,7 @@ class SettingsEditor {
|
||||||
setSetting('useSpeedToSync', useSpeedToSync);
|
setSetting('useSpeedToSync', useSpeedToSync);
|
||||||
setSetting('useSkipToSync', useSkipToSync);
|
setSetting('useSkipToSync', useSkipToSync);
|
||||||
|
|
||||||
Events.trigger(SyncPlay.Manager, 'settings-update');
|
Events.trigger(this.SyncPlay?.Manager, 'settings-update');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import RecommendationContainer from '../../components/common/RecommendationConta
|
||||||
import SectionContainer from '../../components/common/SectionContainer';
|
import SectionContainer from '../../components/common/SectionContainer';
|
||||||
import { LibraryViewProps } from '../../types/interface';
|
import { LibraryViewProps } from '../../types/interface';
|
||||||
|
|
||||||
const SuggestionsView: FC<LibraryViewProps> = ({topParentId}) => {
|
const SuggestionsView: FC<LibraryViewProps> = ({ topParentId }) => {
|
||||||
const [ latestItems, setLatestItems ] = useState<BaseItemDto[]>([]);
|
const [ latestItems, setLatestItems ] = useState<BaseItemDto[]>([]);
|
||||||
const [ resumeResult, setResumeResult ] = useState<BaseItemDtoQueryResult>({});
|
const [ resumeResult, setResumeResult ] = useState<BaseItemDtoQueryResult>({});
|
||||||
const [ recommendations, setRecommendations ] = useState<RecommendationDto[]>([]);
|
const [ recommendations, setRecommendations ] = useState<RecommendationDto[]>([]);
|
||||||
|
@ -28,7 +28,7 @@ const SuggestionsView: FC<LibraryViewProps> = ({topParentId}) => {
|
||||||
}, [enableScrollX]);
|
}, [enableScrollX]);
|
||||||
|
|
||||||
const autoFocus = useCallback((page) => {
|
const autoFocus = useCallback((page) => {
|
||||||
import('../../components/autoFocuser').then(({default: autoFocuser}) => {
|
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||||
autoFocuser.autoFocus(page);
|
autoFocuser.autoFocus(page);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
|
@ -19,8 +19,8 @@ const Search: FunctionComponent = () => {
|
||||||
className='mainAnimatedPage libraryPage allLibraryPage noSecondaryNavPage'
|
className='mainAnimatedPage libraryPage allLibraryPage noSecondaryNavPage'
|
||||||
>
|
>
|
||||||
<SearchFields onSearch={setQuery} />
|
<SearchFields onSearch={setQuery} />
|
||||||
{!query &&
|
{!query
|
||||||
<SearchSuggestions
|
&& <SearchSuggestions
|
||||||
parentId={searchParams.get('parentId')}
|
parentId={searchParams.get('parentId')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,7 @@ const UserEdit: FunctionComponent = () => {
|
||||||
(page.querySelector('.chkForceRemoteSourceTranscoding') as HTMLInputElement).checked = user.Policy.ForceRemoteSourceTranscoding;
|
(page.querySelector('.chkForceRemoteSourceTranscoding') as HTMLInputElement).checked = user.Policy.ForceRemoteSourceTranscoding;
|
||||||
(page.querySelector('.chkRemoteAccess') as HTMLInputElement).checked = user.Policy.EnableRemoteAccess == null || user.Policy.EnableRemoteAccess;
|
(page.querySelector('.chkRemoteAccess') as HTMLInputElement).checked = user.Policy.EnableRemoteAccess == null || user.Policy.EnableRemoteAccess;
|
||||||
(page.querySelector('#txtRemoteClientBitrateLimit') as HTMLInputElement).value = user.Policy.RemoteClientBitrateLimit > 0 ?
|
(page.querySelector('#txtRemoteClientBitrateLimit') as HTMLInputElement).value = user.Policy.RemoteClientBitrateLimit > 0 ?
|
||||||
(user.Policy.RemoteClientBitrateLimit / 1e6).toLocaleString(undefined, {maximumFractionDigits: 6}) : '';
|
(user.Policy.RemoteClientBitrateLimit / 1e6).toLocaleString(undefined, { maximumFractionDigits: 6 }) : '';
|
||||||
(page.querySelector('#txtLoginAttemptsBeforeLockout') as HTMLInputElement).value = user.Policy.LoginAttemptsBeforeLockout || '0';
|
(page.querySelector('#txtLoginAttemptsBeforeLockout') as HTMLInputElement).value = user.Policy.LoginAttemptsBeforeLockout || '0';
|
||||||
(page.querySelector('#txtMaxActiveSessions') as HTMLInputElement).value = user.Policy.MaxActiveSessions || '0';
|
(page.querySelector('#txtMaxActiveSessions') as HTMLInputElement).value = user.Policy.MaxActiveSessions || '0';
|
||||||
if (window.ApiClient.isMinServerVersion('10.6.0')) {
|
if (window.ApiClient.isMinServerVersion('10.6.0')) {
|
||||||
|
@ -314,7 +314,7 @@ const UserEdit: FunctionComponent = () => {
|
||||||
<SectionTabs activeTab='useredit'/>
|
<SectionTabs activeTab='useredit'/>
|
||||||
<div
|
<div
|
||||||
className='lnkEditUserPreferencesContainer'
|
className='lnkEditUserPreferencesContainer'
|
||||||
style={{paddingBottom: '1em'}}
|
style={{ paddingBottom: '1em' }}
|
||||||
>
|
>
|
||||||
<LinkEditUserPreferences
|
<LinkEditUserPreferences
|
||||||
className= 'lnkEditUserPreferences button-link'
|
className= 'lnkEditUserPreferences button-link'
|
||||||
|
@ -327,7 +327,7 @@ const UserEdit: FunctionComponent = () => {
|
||||||
<div>
|
<div>
|
||||||
{globalize.translate('HeaderThisUserIsCurrentlyDisabled')}
|
{globalize.translate('HeaderThisUserIsCurrentlyDisabled')}
|
||||||
</div>
|
</div>
|
||||||
<div style={{marginTop: 5}}>
|
<div style={{ marginTop: 5 }}>
|
||||||
{globalize.translate('MessageReenableUser')}
|
{globalize.translate('MessageReenableUser')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -386,7 +386,7 @@ const UserEdit: FunctionComponent = () => {
|
||||||
<h2 className='paperListLabel'>
|
<h2 className='paperListLabel'>
|
||||||
{globalize.translate('HeaderFeatureAccess')}
|
{globalize.translate('HeaderFeatureAccess')}
|
||||||
</h2>
|
</h2>
|
||||||
<div className='checkboxList paperList' style={{padding: '.5em 1em'}}>
|
<div className='checkboxList paperList' style={{ padding: '.5em 1em' }}>
|
||||||
<CheckBoxElement
|
<CheckBoxElement
|
||||||
className='chkEnableLiveTvAccess'
|
className='chkEnableLiveTvAccess'
|
||||||
title='OptionAllowBrowsingLiveTv'
|
title='OptionAllowBrowsingLiveTv'
|
||||||
|
@ -401,7 +401,7 @@ const UserEdit: FunctionComponent = () => {
|
||||||
<h2 className='paperListLabel'>
|
<h2 className='paperListLabel'>
|
||||||
{globalize.translate('HeaderPlayback')}
|
{globalize.translate('HeaderPlayback')}
|
||||||
</h2>
|
</h2>
|
||||||
<div className='checkboxList paperList' style={{padding: '.5em 1em'}}>
|
<div className='checkboxList paperList' style={{ padding: '.5em 1em' }}>
|
||||||
<CheckBoxElement
|
<CheckBoxElement
|
||||||
className='chkEnableMediaPlayback'
|
className='chkEnableMediaPlayback'
|
||||||
title='OptionAllowMediaPlayback'
|
title='OptionAllowMediaPlayback'
|
||||||
|
@ -458,7 +458,7 @@ const UserEdit: FunctionComponent = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='verticalSection'>
|
<div className='verticalSection'>
|
||||||
<h2 className='checkboxListLabel' style={{marginBottom: '1em'}}>
|
<h2 className='checkboxListLabel' style={{ marginBottom: '1em' }}>
|
||||||
{globalize.translate('HeaderAllowMediaDeletionFrom')}
|
{globalize.translate('HeaderAllowMediaDeletionFrom')}
|
||||||
</h2>
|
</h2>
|
||||||
<div className='checkboxList paperList checkboxList-paperList'>
|
<div className='checkboxList paperList checkboxList-paperList'>
|
||||||
|
@ -484,7 +484,7 @@ const UserEdit: FunctionComponent = () => {
|
||||||
<h2 className='checkboxListLabel'>
|
<h2 className='checkboxListLabel'>
|
||||||
{globalize.translate('HeaderRemoteControl')}
|
{globalize.translate('HeaderRemoteControl')}
|
||||||
</h2>
|
</h2>
|
||||||
<div className='checkboxList paperList' style={{padding: '.5em 1em'}}>
|
<div className='checkboxList paperList' style={{ padding: '.5em 1em' }}>
|
||||||
<CheckBoxElement
|
<CheckBoxElement
|
||||||
className='chkEnableRemoteControlOtherUsers'
|
className='chkEnableRemoteControlOtherUsers'
|
||||||
title='OptionAllowRemoteControlOthers'
|
title='OptionAllowRemoteControlOthers'
|
||||||
|
|
|
@ -239,7 +239,7 @@ const UserParentalControl: FunctionComponent = () => {
|
||||||
|
|
||||||
const showSchedulePopup = (schedule: AccessSchedule, index: number) => {
|
const showSchedulePopup = (schedule: AccessSchedule, index: number) => {
|
||||||
schedule = schedule || {};
|
schedule = schedule || {};
|
||||||
import('../../components/accessSchedule/accessSchedule').then(({default: accessschedule}) => {
|
import('../../components/accessSchedule/accessSchedule').then(({ default: accessschedule }) => {
|
||||||
accessschedule.show({
|
accessschedule.show({
|
||||||
schedule: schedule
|
schedule: schedule
|
||||||
}).then(function (updatedSchedule) {
|
}).then(function (updatedSchedule) {
|
||||||
|
@ -272,7 +272,7 @@ const UserParentalControl: FunctionComponent = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const showBlockedTagPopup = () => {
|
const showBlockedTagPopup = () => {
|
||||||
import('../../components/prompt/prompt').then(({default: prompt}) => {
|
import('../../components/prompt/prompt').then(({ default: prompt }) => {
|
||||||
prompt({
|
prompt({
|
||||||
label: globalize.translate('LabelTag')
|
label: globalize.translate('LabelTag')
|
||||||
}).then(function (value) {
|
}).then(function (value) {
|
||||||
|
@ -367,7 +367,7 @@ const UserParentalControl: FunctionComponent = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<div className='verticalSection' style={{marginBottom: '2em'}}>
|
<div className='verticalSection' style={{ marginBottom: '2em' }}>
|
||||||
<SectionTitleContainer
|
<SectionTitleContainer
|
||||||
SectionClassName='detailSectionHeader'
|
SectionClassName='detailSectionHeader'
|
||||||
title={globalize.translate('LabelBlockContentWithTags')}
|
title={globalize.translate('LabelBlockContentWithTags')}
|
||||||
|
@ -378,7 +378,7 @@ const UserParentalControl: FunctionComponent = () => {
|
||||||
btnIcon='add'
|
btnIcon='add'
|
||||||
isLinkVisible={false}
|
isLinkVisible={false}
|
||||||
/>
|
/>
|
||||||
<div className='blockedTags' style={{marginTop: '.5em'}}>
|
<div className='blockedTags' style={{ marginTop: '.5em' }}>
|
||||||
{blockedTags.map(tag => {
|
{blockedTags.map(tag => {
|
||||||
return <BlockedTagList
|
return <BlockedTagList
|
||||||
key={tag}
|
key={tag}
|
||||||
|
@ -387,7 +387,7 @@ const UserParentalControl: FunctionComponent = () => {
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='accessScheduleSection verticalSection' style={{marginBottom: '2em'}}>
|
<div className='accessScheduleSection verticalSection' style={{ marginBottom: '2em' }}>
|
||||||
<SectionTitleContainer
|
<SectionTitleContainer
|
||||||
title={globalize.translate('HeaderAccessSchedule')}
|
title={globalize.translate('HeaderAccessSchedule')}
|
||||||
isBtnVisible={true}
|
isBtnVisible={true}
|
||||||
|
|
|
@ -153,25 +153,25 @@ const UserProfile: FunctionComponent = () => {
|
||||||
<div ref={element} className='padded-left padded-right padded-bottom-page'>
|
<div ref={element} className='padded-left padded-right padded-bottom-page'>
|
||||||
<div
|
<div
|
||||||
className='readOnlyContent'
|
className='readOnlyContent'
|
||||||
style={{margin: '0 auto', marginBottom: '1.8em', padding: '0 1em', display: 'flex', flexDirection: 'row', alignItems: 'center'}}
|
style={{ margin: '0 auto', marginBottom: '1.8em', padding: '0 1em', display: 'flex', flexDirection: 'row', alignItems: 'center' }}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className='imagePlaceHolder'
|
className='imagePlaceHolder'
|
||||||
style={{position: 'relative', display: 'inline-block', maxWidth: 200 }}
|
style={{ position: 'relative', display: 'inline-block', maxWidth: 200 }}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
id='uploadImage'
|
id='uploadImage'
|
||||||
type='file'
|
type='file'
|
||||||
accept='image/*'
|
accept='image/*'
|
||||||
style={{position: 'absolute', right: 0, width: '100%', height: '100%', opacity: 0, cursor: 'pointer'}}
|
style={{ position: 'absolute', right: 0, width: '100%', height: '100%', opacity: 0, cursor: 'pointer' }}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
id='image'
|
id='image'
|
||||||
style={{width: 200, height: 200, backgroundRepeat: 'no-repeat', backgroundPosition: 'center', borderRadius: '100%', backgroundSize: 'cover'}}
|
style={{ width: 200, height: 200, backgroundRepeat: 'no-repeat', backgroundPosition: 'center', borderRadius: '100%', backgroundSize: 'cover' }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style={{verticalAlign: 'top', margin: '1em 2em', display: 'flex', flexDirection: 'column', alignItems: 'center'}}>
|
<div style={{ verticalAlign: 'top', margin: '1em 2em', display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
|
||||||
<h2 className='username' style={{margin: 0, fontSize: 'xx-large'}}>
|
<h2 className='username' style={{ margin: 0, fontSize: 'xx-large' }}>
|
||||||
{userName}
|
{userName}
|
||||||
</h2>
|
</h2>
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import type { UserDto } from '@jellyfin/sdk/lib/generated-client';
|
import type { UserDto } from '@jellyfin/sdk/lib/generated-client';
|
||||||
import React, {FunctionComponent, useEffect, useState, useRef} from 'react';
|
import React, { FunctionComponent, useEffect, useState, useRef } from 'react';
|
||||||
import Dashboard from '../../utils/dashboard';
|
import Dashboard from '../../utils/dashboard';
|
||||||
import globalize from '../../scripts/globalize';
|
import globalize from '../../scripts/globalize';
|
||||||
import loading from '../../components/loading/loading';
|
import loading from '../../components/loading/loading';
|
||||||
|
@ -75,7 +75,7 @@ const UserProfiles: FunctionComponent = () => {
|
||||||
icon: 'delete'
|
icon: 'delete'
|
||||||
});
|
});
|
||||||
|
|
||||||
import('../../components/actionSheet/actionSheet').then(({default: actionsheet}) => {
|
import('../../components/actionSheet/actionSheet').then(({ default: actionsheet }) => {
|
||||||
actionsheet.show({
|
actionsheet.show({
|
||||||
items: menuItems,
|
items: menuItems,
|
||||||
positionTo: card,
|
positionTo: card,
|
||||||
|
|
|
@ -187,25 +187,25 @@ function supportsCssAnimation(allowPrefix) {
|
||||||
const uaMatch = function (ua) {
|
const uaMatch = function (ua) {
|
||||||
ua = ua.toLowerCase();
|
ua = ua.toLowerCase();
|
||||||
|
|
||||||
const match = /(edg)[ /]([\w.]+)/.exec(ua) ||
|
const match = /(edg)[ /]([\w.]+)/.exec(ua)
|
||||||
/(edga)[ /]([\w.]+)/.exec(ua) ||
|
|| /(edga)[ /]([\w.]+)/.exec(ua)
|
||||||
/(edgios)[ /]([\w.]+)/.exec(ua) ||
|
|| /(edgios)[ /]([\w.]+)/.exec(ua)
|
||||||
/(edge)[ /]([\w.]+)/.exec(ua) ||
|
|| /(edge)[ /]([\w.]+)/.exec(ua)
|
||||||
/(opera)[ /]([\w.]+)/.exec(ua) ||
|
|| /(opera)[ /]([\w.]+)/.exec(ua)
|
||||||
/(opr)[ /]([\w.]+)/.exec(ua) ||
|
|| /(opr)[ /]([\w.]+)/.exec(ua)
|
||||||
/(chrome)[ /]([\w.]+)/.exec(ua) ||
|
|| /(chrome)[ /]([\w.]+)/.exec(ua)
|
||||||
/(safari)[ /]([\w.]+)/.exec(ua) ||
|
|| /(safari)[ /]([\w.]+)/.exec(ua)
|
||||||
/(firefox)[ /]([\w.]+)/.exec(ua) ||
|
|| /(firefox)[ /]([\w.]+)/.exec(ua)
|
||||||
ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
|
|| ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua)
|
||||||
[];
|
|| [];
|
||||||
|
|
||||||
const versionMatch = /(version)[ /]([\w.]+)/.exec(ua);
|
const versionMatch = /(version)[ /]([\w.]+)/.exec(ua);
|
||||||
|
|
||||||
let platform_match = /(ipad)/.exec(ua) ||
|
let platform_match = /(ipad)/.exec(ua)
|
||||||
/(iphone)/.exec(ua) ||
|
|| /(iphone)/.exec(ua)
|
||||||
/(windows)/.exec(ua) ||
|
|| /(windows)/.exec(ua)
|
||||||
/(android)/.exec(ua) ||
|
|| /(android)/.exec(ua)
|
||||||
[];
|
|| [];
|
||||||
|
|
||||||
let browser = match[1] || '';
|
let browser = match[1] || '';
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,11 @@ import browser from './browser';
|
||||||
}
|
}
|
||||||
|
|
||||||
// hevc main level 4.0
|
// hevc main level 4.0
|
||||||
return !!videoTestElement.canPlayType &&
|
return !!videoTestElement.canPlayType
|
||||||
(videoTestElement.canPlayType('video/mp4; codecs="hvc1.1.L120"').replace(/no/, '') ||
|
&& (videoTestElement.canPlayType('video/mp4; codecs="hvc1.1.L120"').replace(/no/, '')
|
||||||
videoTestElement.canPlayType('video/mp4; codecs="hev1.1.L120"').replace(/no/, '') ||
|
|| videoTestElement.canPlayType('video/mp4; codecs="hev1.1.L120"').replace(/no/, '')
|
||||||
videoTestElement.canPlayType('video/mp4; codecs="hvc1.1.0.L120"').replace(/no/, '') ||
|
|| videoTestElement.canPlayType('video/mp4; codecs="hvc1.1.0.L120"').replace(/no/, '')
|
||||||
videoTestElement.canPlayType('video/mp4; codecs="hev1.1.0.L120"').replace(/no/, ''));
|
|| videoTestElement.canPlayType('video/mp4; codecs="hev1.1.0.L120"').replace(/no/, ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
let _supportsTextTracks;
|
let _supportsTextTracks;
|
||||||
|
@ -53,8 +53,8 @@ import browser from './browser';
|
||||||
}
|
}
|
||||||
|
|
||||||
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/, ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
function canPlayHlsWithMSE() {
|
function canPlayHlsWithMSE() {
|
||||||
|
@ -96,8 +96,8 @@ import browser from './browser';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (videoTestElement.canPlayType) {
|
if (videoTestElement.canPlayType) {
|
||||||
return videoTestElement.canPlayType('application/x-mpegurl; codecs="avc1.42E01E, ac-3"').replace(/no/, '') ||
|
return videoTestElement.canPlayType('application/x-mpegurl; codecs="avc1.42E01E, ac-3"').replace(/no/, '')
|
||||||
videoTestElement.canPlayType('application/vnd.apple.mpegURL; codecs="avc1.42E01E, ac-3"').replace(/no/, '');
|
|| videoTestElement.canPlayType('application/vnd.apple.mpegURL; codecs="avc1.42E01E, ac-3"').replace(/no/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -146,8 +146,8 @@ import browser from './browser';
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (videoTestElement.canPlayType('video/x-matroska').replace(/no/, '') ||
|
if (videoTestElement.canPlayType('video/x-matroska').replace(/no/, '')
|
||||||
videoTestElement.canPlayType('video/mkv').replace(/no/, '')) {
|
|| videoTestElement.canPlayType('video/mkv').replace(/no/, '')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,19 +815,19 @@ export function canPlaySecondaryAudio(videoTestElement) {
|
||||||
let maxH264Level = 42;
|
let maxH264Level = 42;
|
||||||
let h264Profiles = 'high|main|baseline|constrained baseline';
|
let h264Profiles = 'high|main|baseline|constrained baseline';
|
||||||
|
|
||||||
if (browser.tizen || browser.web0s ||
|
if (browser.tizen || browser.web0s
|
||||||
videoTestElement.canPlayType('video/mp4; codecs="avc1.640833"').replace(/no/, '')) {
|
|| videoTestElement.canPlayType('video/mp4; codecs="avc1.640833"').replace(/no/, '')) {
|
||||||
maxH264Level = 51;
|
maxH264Level = 51;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Support H264 Level 52 (Tizen 5.0) - app only
|
// Support H264 Level 52 (Tizen 5.0) - app only
|
||||||
if ((browser.tizenVersion >= 5 && window.NativeShell) ||
|
if ((browser.tizenVersion >= 5 && window.NativeShell)
|
||||||
videoTestElement.canPlayType('video/mp4; codecs="avc1.640834"').replace(/no/, '')) {
|
|| videoTestElement.canPlayType('video/mp4; codecs="avc1.640834"').replace(/no/, '')) {
|
||||||
maxH264Level = 52;
|
maxH264Level = 52;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((browser.tizen ||
|
if ((browser.tizen
|
||||||
videoTestElement.canPlayType('video/mp4; codecs="avc1.6e0033"').replace(/no/, ''))
|
|| videoTestElement.canPlayType('video/mp4; codecs="avc1.6e0033"').replace(/no/, ''))
|
||||||
// These tests are passing in safari, but playback is failing
|
// These tests are passing in safari, but playback is failing
|
||||||
&& !browser.safari && !browser.iOS && !browser.web0s && !browser.edge && !browser.mobile
|
&& !browser.safari && !browser.iOS && !browser.web0s && !browser.edge && !browser.mobile
|
||||||
) {
|
) {
|
||||||
|
@ -838,28 +838,28 @@ export function canPlaySecondaryAudio(videoTestElement) {
|
||||||
let hevcProfiles = 'main';
|
let hevcProfiles = 'main';
|
||||||
|
|
||||||
// hevc main level 4.1
|
// hevc main level 4.1
|
||||||
if (videoTestElement.canPlayType('video/mp4; codecs="hvc1.1.4.L123"').replace(/no/, '') ||
|
if (videoTestElement.canPlayType('video/mp4; codecs="hvc1.1.4.L123"').replace(/no/, '')
|
||||||
videoTestElement.canPlayType('video/mp4; codecs="hev1.1.4.L123"').replace(/no/, '')) {
|
|| videoTestElement.canPlayType('video/mp4; codecs="hev1.1.4.L123"').replace(/no/, '')) {
|
||||||
maxHevcLevel = 123;
|
maxHevcLevel = 123;
|
||||||
}
|
}
|
||||||
|
|
||||||
// hevc main10 level 4.1
|
// hevc main10 level 4.1
|
||||||
if (videoTestElement.canPlayType('video/mp4; codecs="hvc1.2.4.L123"').replace(/no/, '') ||
|
if (videoTestElement.canPlayType('video/mp4; codecs="hvc1.2.4.L123"').replace(/no/, '')
|
||||||
videoTestElement.canPlayType('video/mp4; codecs="hev1.2.4.L123"').replace(/no/, '')) {
|
|| videoTestElement.canPlayType('video/mp4; codecs="hev1.2.4.L123"').replace(/no/, '')) {
|
||||||
maxHevcLevel = 123;
|
maxHevcLevel = 123;
|
||||||
hevcProfiles = 'main|main 10';
|
hevcProfiles = 'main|main 10';
|
||||||
}
|
}
|
||||||
|
|
||||||
// hevc main10 level 5.1
|
// hevc main10 level 5.1
|
||||||
if (videoTestElement.canPlayType('video/mp4; codecs="hvc1.2.4.L153"').replace(/no/, '') ||
|
if (videoTestElement.canPlayType('video/mp4; codecs="hvc1.2.4.L153"').replace(/no/, '')
|
||||||
videoTestElement.canPlayType('video/mp4; codecs="hev1.2.4.L153"').replace(/no/, '')) {
|
|| videoTestElement.canPlayType('video/mp4; codecs="hev1.2.4.L153"').replace(/no/, '')) {
|
||||||
maxHevcLevel = 153;
|
maxHevcLevel = 153;
|
||||||
hevcProfiles = 'main|main 10';
|
hevcProfiles = 'main|main 10';
|
||||||
}
|
}
|
||||||
|
|
||||||
// hevc main10 level 6.1
|
// hevc main10 level 6.1
|
||||||
if (videoTestElement.canPlayType('video/mp4; codecs="hvc1.2.4.L183"').replace(/no/, '') ||
|
if (videoTestElement.canPlayType('video/mp4; codecs="hvc1.2.4.L183"').replace(/no/, '')
|
||||||
videoTestElement.canPlayType('video/mp4; codecs="hev1.2.4.L183"').replace(/no/, '')) {
|
|| videoTestElement.canPlayType('video/mp4; codecs="hev1.2.4.L183"').replace(/no/, '')) {
|
||||||
maxHevcLevel = 183;
|
maxHevcLevel = 183;
|
||||||
hevcProfiles = 'main|main 10';
|
hevcProfiles = 'main|main 10';
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue