1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Merge remote-tracking branch 'upstream/master' into fix-sonar-issues

This commit is contained in:
Bill Thornton 2022-10-04 10:00:37 -04:00
commit 7d2850f6a3
67 changed files with 527 additions and 627 deletions

View file

@ -72,7 +72,6 @@ module.exports = {
'sonarjs/cognitive-complexity': ['warn'], 'sonarjs/cognitive-complexity': ['warn'],
// TODO: Enable the following rules and fix issues // TODO: Enable the following rules and fix issues
'sonarjs/no-collapsible-if': ['off'],
'sonarjs/no-duplicate-string': ['off'], 'sonarjs/no-duplicate-string': ['off'],
'sonarjs/no-duplicated-branches': ['off'], 'sonarjs/no-duplicated-branches': ['off'],
'sonarjs/no-identical-functions': ['off'], 'sonarjs/no-identical-functions': ['off'],

View file

@ -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@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2 uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3.1.0
with: with:
token: ${{ secrets.JF_BOT_TOKEN }} token: ${{ secrets.JF_BOT_TOKEN }}
fetch-depth: 0 fetch-depth: 0

164
package-lock.json generated
View file

@ -66,8 +66,8 @@
"@types/lodash-es": "4.17.6", "@types/lodash-es": "4.17.6",
"@types/react": "17.0.50", "@types/react": "17.0.50",
"@types/react-dom": "17.0.17", "@types/react-dom": "17.0.17",
"@typescript-eslint/eslint-plugin": "5.38.0", "@typescript-eslint/eslint-plugin": "5.38.1",
"@typescript-eslint/parser": "5.38.0", "@typescript-eslint/parser": "5.38.1",
"@uupaa/dynamic-import-polyfill": "1.0.2", "@uupaa/dynamic-import-polyfill": "1.0.2",
"autoprefixer": "10.4.12", "autoprefixer": "10.4.12",
"babel-loader": "8.2.5", "babel-loader": "8.2.5",
@ -2972,14 +2972,14 @@
} }
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.1.tgz",
"integrity": "sha512-GgHi/GNuUbTOeoJiEANi0oI6fF3gBQc3bGFYj40nnAPCbhrtEDf2rjBmefFadweBmO1Du1YovHeDP2h5JLhtTQ==", "integrity": "sha512-ky7EFzPhqz3XlhS7vPOoMDaQnQMn+9o5ICR9CPr/6bw8HrFkzhMSxuA3gRfiJVvs7geYrSeawGJjZoZQKCOglQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.38.0", "@typescript-eslint/scope-manager": "5.38.1",
"@typescript-eslint/type-utils": "5.38.0", "@typescript-eslint/type-utils": "5.38.1",
"@typescript-eslint/utils": "5.38.0", "@typescript-eslint/utils": "5.38.1",
"debug": "^4.3.4", "debug": "^4.3.4",
"ignore": "^5.2.0", "ignore": "^5.2.0",
"regexpp": "^3.2.0", "regexpp": "^3.2.0",
@ -3019,14 +3019,14 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.38.1.tgz",
"integrity": "sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==", "integrity": "sha512-LDqxZBVFFQnQRz9rUZJhLmox+Ep5kdUmLatLQnCRR6523YV+XhRjfYzStQ4MheFA8kMAfUlclHSbu+RKdRwQKw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.38.0", "@typescript-eslint/scope-manager": "5.38.1",
"@typescript-eslint/types": "5.38.0", "@typescript-eslint/types": "5.38.1",
"@typescript-eslint/typescript-estree": "5.38.0", "@typescript-eslint/typescript-estree": "5.38.1",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -3046,13 +3046,13 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz",
"integrity": "sha512-ByhHIuNyKD9giwkkLqzezZ9y5bALW8VNY6xXcP+VxoH4JBDKjU5WNnsiD4HJdglHECdV+lyaxhvQjTUbRboiTA==", "integrity": "sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.38.0", "@typescript-eslint/types": "5.38.1",
"@typescript-eslint/visitor-keys": "5.38.0" "@typescript-eslint/visitor-keys": "5.38.1"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -3063,13 +3063,13 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.38.1.tgz",
"integrity": "sha512-iZq5USgybUcj/lfnbuelJ0j3K9dbs1I3RICAJY9NZZpDgBYXmuUlYQGzftpQA9wC8cKgtS6DASTvF3HrXwwozA==", "integrity": "sha512-UU3j43TM66gYtzo15ivK2ZFoDFKKP0k03MItzLdq0zV92CeGCXRfXlfQX5ILdd4/DSpHkSjIgLLLh1NtkOJOAw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "5.38.0", "@typescript-eslint/typescript-estree": "5.38.1",
"@typescript-eslint/utils": "5.38.0", "@typescript-eslint/utils": "5.38.1",
"debug": "^4.3.4", "debug": "^4.3.4",
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
}, },
@ -3090,9 +3090,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz",
"integrity": "sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA==", "integrity": "sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -3103,13 +3103,13 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz",
"integrity": "sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg==", "integrity": "sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.38.0", "@typescript-eslint/types": "5.38.1",
"@typescript-eslint/visitor-keys": "5.38.0", "@typescript-eslint/visitor-keys": "5.38.1",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -3174,15 +3174,15 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.1.tgz",
"integrity": "sha512-6sdeYaBgk9Fh7N2unEXGz+D+som2QCQGPAf1SxrkEr+Z32gMreQ0rparXTNGRRfYUWk/JzbGdcM8NSSd6oqnTA==", "integrity": "sha512-oIuUiVxPBsndrN81oP8tXnFa/+EcZ03qLqPDfSZ5xIJVm7A9V0rlkQwwBOAGtrdN70ZKDlKv+l1BeT4eSFxwXA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.38.0", "@typescript-eslint/scope-manager": "5.38.1",
"@typescript-eslint/types": "5.38.0", "@typescript-eslint/types": "5.38.1",
"@typescript-eslint/typescript-estree": "5.38.0", "@typescript-eslint/typescript-estree": "5.38.1",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0" "eslint-utils": "^3.0.0"
}, },
@ -3198,12 +3198,12 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz",
"integrity": "sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w==", "integrity": "sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.38.0", "@typescript-eslint/types": "5.38.1",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
}, },
"engines": { "engines": {
@ -20589,14 +20589,14 @@
} }
}, },
"@typescript-eslint/eslint-plugin": { "@typescript-eslint/eslint-plugin": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.1.tgz",
"integrity": "sha512-GgHi/GNuUbTOeoJiEANi0oI6fF3gBQc3bGFYj40nnAPCbhrtEDf2rjBmefFadweBmO1Du1YovHeDP2h5JLhtTQ==", "integrity": "sha512-ky7EFzPhqz3XlhS7vPOoMDaQnQMn+9o5ICR9CPr/6bw8HrFkzhMSxuA3gRfiJVvs7geYrSeawGJjZoZQKCOglQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/scope-manager": "5.38.0", "@typescript-eslint/scope-manager": "5.38.1",
"@typescript-eslint/type-utils": "5.38.0", "@typescript-eslint/type-utils": "5.38.1",
"@typescript-eslint/utils": "5.38.0", "@typescript-eslint/utils": "5.38.1",
"debug": "^4.3.4", "debug": "^4.3.4",
"ignore": "^5.2.0", "ignore": "^5.2.0",
"regexpp": "^3.2.0", "regexpp": "^3.2.0",
@ -20616,53 +20616,53 @@
} }
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.38.1.tgz",
"integrity": "sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==", "integrity": "sha512-LDqxZBVFFQnQRz9rUZJhLmox+Ep5kdUmLatLQnCRR6523YV+XhRjfYzStQ4MheFA8kMAfUlclHSbu+RKdRwQKw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/scope-manager": "5.38.0", "@typescript-eslint/scope-manager": "5.38.1",
"@typescript-eslint/types": "5.38.0", "@typescript-eslint/types": "5.38.1",
"@typescript-eslint/typescript-estree": "5.38.0", "@typescript-eslint/typescript-estree": "5.38.1",
"debug": "^4.3.4" "debug": "^4.3.4"
} }
}, },
"@typescript-eslint/scope-manager": { "@typescript-eslint/scope-manager": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz",
"integrity": "sha512-ByhHIuNyKD9giwkkLqzezZ9y5bALW8VNY6xXcP+VxoH4JBDKjU5WNnsiD4HJdglHECdV+lyaxhvQjTUbRboiTA==", "integrity": "sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.38.0", "@typescript-eslint/types": "5.38.1",
"@typescript-eslint/visitor-keys": "5.38.0" "@typescript-eslint/visitor-keys": "5.38.1"
} }
}, },
"@typescript-eslint/type-utils": { "@typescript-eslint/type-utils": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.38.1.tgz",
"integrity": "sha512-iZq5USgybUcj/lfnbuelJ0j3K9dbs1I3RICAJY9NZZpDgBYXmuUlYQGzftpQA9wC8cKgtS6DASTvF3HrXwwozA==", "integrity": "sha512-UU3j43TM66gYtzo15ivK2ZFoDFKKP0k03MItzLdq0zV92CeGCXRfXlfQX5ILdd4/DSpHkSjIgLLLh1NtkOJOAw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/typescript-estree": "5.38.0", "@typescript-eslint/typescript-estree": "5.38.1",
"@typescript-eslint/utils": "5.38.0", "@typescript-eslint/utils": "5.38.1",
"debug": "^4.3.4", "debug": "^4.3.4",
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
} }
}, },
"@typescript-eslint/types": { "@typescript-eslint/types": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz",
"integrity": "sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA==", "integrity": "sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==",
"dev": true "dev": true
}, },
"@typescript-eslint/typescript-estree": { "@typescript-eslint/typescript-estree": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz",
"integrity": "sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg==", "integrity": "sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.38.0", "@typescript-eslint/types": "5.38.1",
"@typescript-eslint/visitor-keys": "5.38.0", "@typescript-eslint/visitor-keys": "5.38.1",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -20702,26 +20702,26 @@
} }
}, },
"@typescript-eslint/utils": { "@typescript-eslint/utils": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.1.tgz",
"integrity": "sha512-6sdeYaBgk9Fh7N2unEXGz+D+som2QCQGPAf1SxrkEr+Z32gMreQ0rparXTNGRRfYUWk/JzbGdcM8NSSd6oqnTA==", "integrity": "sha512-oIuUiVxPBsndrN81oP8tXnFa/+EcZ03qLqPDfSZ5xIJVm7A9V0rlkQwwBOAGtrdN70ZKDlKv+l1BeT4eSFxwXA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.38.0", "@typescript-eslint/scope-manager": "5.38.1",
"@typescript-eslint/types": "5.38.0", "@typescript-eslint/types": "5.38.1",
"@typescript-eslint/typescript-estree": "5.38.0", "@typescript-eslint/typescript-estree": "5.38.1",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0" "eslint-utils": "^3.0.0"
} }
}, },
"@typescript-eslint/visitor-keys": { "@typescript-eslint/visitor-keys": {
"version": "5.38.0", "version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz",
"integrity": "sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w==", "integrity": "sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.38.0", "@typescript-eslint/types": "5.38.1",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
}, },
"dependencies": { "dependencies": {

View file

@ -18,8 +18,8 @@
"@types/lodash-es": "4.17.6", "@types/lodash-es": "4.17.6",
"@types/react": "17.0.50", "@types/react": "17.0.50",
"@types/react-dom": "17.0.17", "@types/react-dom": "17.0.17",
"@typescript-eslint/eslint-plugin": "5.38.0", "@typescript-eslint/eslint-plugin": "5.38.1",
"@typescript-eslint/parser": "5.38.0", "@typescript-eslint/parser": "5.38.1",
"@uupaa/dynamic-import-polyfill": "1.0.2", "@uupaa/dynamic-import-polyfill": "1.0.2",
"autoprefixer": "10.4.12", "autoprefixer": "10.4.12",
"babel-loader": "8.2.5", "babel-loader": "8.2.5",

View file

@ -87,12 +87,10 @@ class AppRouter {
path = path.replace(this.baseUrl(), ''); path = path.replace(this.baseUrl(), '');
if (this.currentRouteInfo && this.currentRouteInfo.path === path) { // can't use this with home right now due to the back menu
// can't use this with home right now due to the back menu if (this.currentRouteInfo?.path === path && this.currentRouteInfo.route.type !== 'home') {
if (this.currentRouteInfo.route.type !== 'home') { loading.hide();
loading.hide(); return Promise.resolve();
return Promise.resolve();
}
} }
this.promiseShow = new Promise((resolve) => { this.promiseShow = new Promise((resolve) => {
@ -351,15 +349,13 @@ class AppRouter {
onRequestFail(_e, data) { onRequestFail(_e, data) {
const apiClient = this; const apiClient = this;
if (data.status === 403) { if (data.status === 403 && data.errorCode === 'ParentalControl') {
if (data.errorCode === 'ParentalControl') { const isCurrentAllowed = appRouter.currentRouteInfo ? (appRouter.currentRouteInfo.route.anonymous || appRouter.currentRouteInfo.route.startup) : true;
const isCurrentAllowed = appRouter.currentRouteInfo ? (appRouter.currentRouteInfo.route.anonymous || appRouter.currentRouteInfo.route.startup) : true;
// Bounce to the login screen, but not if a password entry fails, obviously // Bounce to the login screen, but not if a password entry fails, obviously
if (!isCurrentAllowed) { if (!isCurrentAllowed) {
appRouter.showForcedLogoutMessage(globalize.translate('AccessRestrictedTryAgainLater')); appRouter.showForcedLogoutMessage(globalize.translate('AccessRestrictedTryAgainLater'));
appRouter.showLocalLogin(apiClient.serverId()); appRouter.showLocalLogin(apiClient.serverId());
}
} }
} }
} }

View file

@ -790,10 +790,8 @@ import { appRouter } from '../appRouter';
const showOtherText = isOuterFooter ? !overlayText : overlayText; const showOtherText = isOuterFooter ? !overlayText : overlayText;
if (isOuterFooter && options.cardLayout && layoutManager.mobile) { if (isOuterFooter && options.cardLayout && layoutManager.mobile && options.cardFooterAside !== 'none') {
if (options.cardFooterAside !== 'none') { html += `<button is="paper-icon-button-light" class="itemAction btnCardOptions cardText-secondary" data-action="menu" title="${globalize.translate('ButtonMore')}"><span class="material-icons more_vert" aria-hidden="true"></span></button>`;
html += `<button is="paper-icon-button-light" class="itemAction btnCardOptions cardText-secondary" data-action="menu" title="${globalize.translate('ButtonMore')}"><span class="material-icons more_vert" aria-hidden="true"></span></button>`;
}
} }
const cssClass = options.centerText ? 'cardText cardTextCentered' : 'cardText'; const cssClass = options.centerText ? 'cardText cardTextCentered' : 'cardText';
@ -803,33 +801,31 @@ import { appRouter } from '../appRouter';
const parentTitleUnderneath = item.Type === 'MusicAlbum' || item.Type === 'Audio' || item.Type === 'MusicVideo'; const parentTitleUnderneath = item.Type === 'MusicAlbum' || item.Type === 'Audio' || item.Type === 'MusicVideo';
let titleAdded; let titleAdded;
if (showOtherText) { if (showOtherText && (options.showParentTitle || options.showParentTitleOrTitle) && !parentTitleUnderneath) {
if ((options.showParentTitle || options.showParentTitleOrTitle) && !parentTitleUnderneath) { if (isOuterFooter && item.Type === 'Episode' && item.SeriesName) {
if (isOuterFooter && item.Type === 'Episode' && item.SeriesName) { if (item.SeriesId) {
if (item.SeriesId) { lines.push(getTextActionButton({
lines.push(getTextActionButton({ Id: item.SeriesId,
Id: item.SeriesId, ServerId: serverId,
ServerId: serverId, Name: item.SeriesName,
Name: item.SeriesName, Type: 'Series',
Type: 'Series', IsFolder: true
IsFolder: true }));
})); } else {
} else { lines.push(escapeHtml(item.SeriesName));
lines.push(escapeHtml(item.SeriesName)); }
} else {
if (isUsingLiveTvNaming(item)) {
lines.push(escapeHtml(item.Name));
if (!item.EpisodeTitle && !item.IndexNumber) {
titleAdded = true;
} }
} else { } else {
if (isUsingLiveTvNaming(item)) { const parentTitle = item.SeriesName || item.Series || item.Album || item.AlbumArtist || '';
lines.push(escapeHtml(item.Name));
if (!item.EpisodeTitle && !item.IndexNumber) { if (parentTitle || showTitle) {
titleAdded = true; lines.push(escapeHtml(parentTitle));
}
} else {
const parentTitle = item.SeriesName || item.Series || item.Album || item.AlbumArtist || '';
if (parentTitle || showTitle) {
lines.push(escapeHtml(parentTitle));
}
} }
} }
} }
@ -986,10 +982,8 @@ import { appRouter } from '../appRouter';
} }
} }
if (options.showPersonRoleOrType) { if (options.showPersonRoleOrType && item.Role) {
if (item.Role) { lines.push(globalize.translate('PersonRole', escapeHtml(item.Role)));
lines.push(globalize.translate('PersonRole', escapeHtml(item.Role)));
}
} }
} }
@ -1009,13 +1003,11 @@ import { appRouter } from '../appRouter';
html += progressHtml; html += progressHtml;
} }
if (html) { if (html && (!isOuterFooter || logoUrl || options.cardLayout)) {
if (!isOuterFooter || logoUrl || options.cardLayout) { html = '<div class="' + footerClass + '">' + html;
html = '<div class="' + footerClass + '">' + html;
//cardFooter //cardFooter
html += '</div>'; html += '</div>';
}
} }
return html; return html;

View file

@ -34,10 +34,8 @@ import ServerConnections from '../ServerConnections';
let shape = (options.backdropShape || 'backdrop'); let shape = (options.backdropShape || 'backdrop');
if (videoStream.Width && videoStream.Height) { if (videoStream.Width && videoStream.Height && (videoStream.Width / videoStream.Height) <= 1.2) {
if ((videoStream.Width / videoStream.Height) <= 1.2) { shape = (options.squareShape || 'square');
shape = (options.squareShape || 'square');
}
} }
className += ` ${shape}Card`; className += ` ${shape}Card`;

View file

@ -57,6 +57,7 @@ import '../../assets/css/scrollstyles.scss';
if ((shouldClose || !isOpened(dlg)) && unlisten) { if ((shouldClose || !isOpened(dlg)) && unlisten) {
unlisten(); unlisten();
unlisten = null;
} }
if (shouldClose) { if (shouldClose) {
@ -64,6 +65,22 @@ import '../../assets/css/scrollstyles.scss';
} }
} }
function finishClose() {
if (unlisten) {
unlisten();
unlisten = null;
}
dlg.dispatchEvent(new CustomEvent('close', {
bubbles: false,
cancelable: false
}));
resolve({
element: dlg
});
}
function onBackCommand(e) { function onBackCommand(e) {
if (e.detail.command === 'back') { if (e.detail.command === 'back') {
e.preventDefault(); e.preventDefault();
@ -79,6 +96,7 @@ import '../../assets/css/scrollstyles.scss';
if (unlisten) { if (unlisten) {
unlisten(); unlisten();
unlisten = null;
} }
removeBackdrop(dlg); removeBackdrop(dlg);
@ -92,9 +110,13 @@ import '../../assets/css/scrollstyles.scss';
const state = history.location.state || {}; const state = history.location.state || {};
if (state.dialogs?.length > 0) { if (state.dialogs?.length > 0) {
if (state.dialogs[state.dialogs.length - 1] === hash) { if (state.dialogs[state.dialogs.length - 1] === hash) {
unlisten = history.listen(finishClose);
history.back(); history.back();
} else if (state.dialogs.includes(hash)) { } else if (state.dialogs.includes(hash)) {
console.warn('[dialogHelper] dialog "%s" was closed, but is not the last dialog opened', hash); console.warn('[dialogHelper] dialog "%s" was closed, but is not the last dialog opened', hash);
unlisten = history.listen(finishClose);
// Remove the closed dialog hash from the history state // Remove the closed dialog hash from the history state
history.replace( history.replace(
`${history.location.pathname}${history.location.search}`, `${history.location.pathname}${history.location.search}`,
@ -123,18 +145,9 @@ import '../../assets/css/scrollstyles.scss';
} }
} }
//resolve(); if (!unlisten) {
// if we just called history.back(), then use a timeout to allow the history events to fire first finishClose();
setTimeout(() => { }
dlg.dispatchEvent(new CustomEvent('close', {
bubbles: false,
cancelable: false
}));
resolve({
element: dlg
});
}, 1);
} }
dlg.addEventListener('_close', onDialogClosed); dlg.addEventListener('_close', onDialogClosed);

View file

@ -384,10 +384,11 @@ import scrollManager from './scrollManager';
// See if there's a focusable container, and if so, send the focus command to that // See if there's a focusable container, and if so, send the focus command to that
if (activeElement) { if (activeElement) {
const nearestElementFocusableParent = dom.parentWithClass(nearestElement, 'focusable'); const nearestElementFocusableParent = dom.parentWithClass(nearestElement, 'focusable');
if (nearestElementFocusableParent && nearestElementFocusableParent !== nearestElement) { if (nearestElementFocusableParent
if (focusableContainer !== nearestElementFocusableParent) { && nearestElementFocusableParent !== nearestElement
nearestElement = nearestElementFocusableParent; && focusableContainer !== nearestElementFocusableParent
} ) {
nearestElement = nearestElementFocusableParent;
} }
} }
focus(nearestElement); focus(nearestElement);

View file

@ -72,26 +72,25 @@ import toast from './toast/toast';
} }
} }
if (item.IsFolder || item.Type === 'MusicArtist' || item.Type === 'MusicGenre') { if ((item.IsFolder || item.Type === 'MusicArtist' || item.Type === 'MusicGenre')
if (item.CollectionType !== 'livetv') { && item.CollectionType !== 'livetv'
if (options.shuffle !== false) { && options.shuffle !== false
commands.push({ ) {
name: globalize.translate('Shuffle'), commands.push({
id: 'shuffle', name: globalize.translate('Shuffle'),
icon: 'shuffle' id: 'shuffle',
}); icon: 'shuffle'
} });
}
} }
if (item.MediaType === 'Audio' || item.Type === 'MusicAlbum' || item.Type === 'MusicArtist' || item.Type === 'MusicGenre') { if ((item.MediaType === 'Audio' || item.Type === 'MusicAlbum' || item.Type === 'MusicArtist' || item.Type === 'MusicGenre')
if (options.instantMix !== false && !itemHelper.isLocalItem(item)) { && options.instantMix !== false && !itemHelper.isLocalItem(item)
commands.push({ ) {
name: globalize.translate('InstantMix'), commands.push({
id: 'instantmix', name: globalize.translate('InstantMix'),
icon: 'explore' id: 'instantmix',
}); icon: 'explore'
} });
} }
if (commands.length) { if (commands.length) {
@ -180,57 +179,49 @@ import toast from './toast/toast';
} }
const canEdit = itemHelper.canEdit(user, item); const canEdit = itemHelper.canEdit(user, item);
if (canEdit) { if (canEdit && options.edit !== false && item.Type !== 'SeriesTimer') {
if (options.edit !== false && item.Type !== 'SeriesTimer') { const text = (item.Type === 'Timer' || item.Type === 'SeriesTimer') ? globalize.translate('Edit') : globalize.translate('EditMetadata');
const text = (item.Type === 'Timer' || item.Type === 'SeriesTimer') ? globalize.translate('Edit') : globalize.translate('EditMetadata'); commands.push({
commands.push({ name: text,
name: text, id: 'edit',
id: 'edit', icon: 'edit'
icon: 'edit' });
});
}
} }
if (itemHelper.canEditImages(user, item)) { if (itemHelper.canEditImages(user, item) && options.editImages !== false) {
if (options.editImages !== false) { commands.push({
commands.push({ name: globalize.translate('EditImages'),
name: globalize.translate('EditImages'), id: 'editimages',
id: 'editimages', icon: 'image'
icon: 'image' });
});
}
} }
if (canEdit) { if (canEdit && item.MediaType === 'Video' && item.Type !== 'TvChannel' && item.Type !== 'Program'
if (item.MediaType === 'Video' && item.Type !== 'TvChannel' && item.Type !== 'Program' && item.LocationType !== 'Virtual' && !(item.Type === 'Recording' && item.Status !== 'Completed')) { && item.LocationType !== 'Virtual'
if (options.editSubtitles !== false) { && !(item.Type === 'Recording' && item.Status !== 'Completed')
commands.push({ && options.editSubtitles !== false
name: globalize.translate('EditSubtitles'), ) {
id: 'editsubtitles', commands.push({
icon: 'closed_caption' name: globalize.translate('EditSubtitles'),
}); id: 'editsubtitles',
} icon: 'closed_caption'
} });
} }
if (options.identify !== false) { if (options.identify !== false && itemHelper.canIdentify(user, item)) {
if (itemHelper.canIdentify(user, item)) { commands.push({
commands.push({ name: globalize.translate('Identify'),
name: globalize.translate('Identify'), id: 'identify',
id: 'identify', icon: 'edit'
icon: 'edit' });
});
}
} }
if (item.MediaSources) { if (item.MediaSources && options.moremediainfo !== false) {
if (options.moremediainfo !== false) { commands.push({
commands.push({ name: globalize.translate('MoreMediaInfo'),
name: globalize.translate('MoreMediaInfo'), id: 'moremediainfo',
id: 'moremediainfo', icon: 'info'
icon: 'info' });
});
}
} }
if (item.Type === 'Program' && options.record !== false) { if (item.Type === 'Program' && options.record !== false) {
@ -240,11 +231,7 @@ import toast from './toast/toast';
id: 'record', id: 'record',
icon: 'fiber_manual_record' icon: 'fiber_manual_record'
}); });
} } else {
}
if (item.Type === 'Program' && options.record !== false) {
if (!item.TimerId) {
commands.push({ commands.push({
name: globalize.translate('Record'), name: globalize.translate('Record'),
id: 'record', id: 'record',
@ -277,26 +264,20 @@ import toast from './toast/toast';
}); });
} }
if (!restrictOptions) { if (!restrictOptions && options.share === true && itemHelper.canShare(item, user)) {
if (options.share === true) { commands.push({
if (itemHelper.canShare(item, user)) { name: globalize.translate('Share'),
commands.push({ id: 'share',
name: globalize.translate('Share'), icon: 'share'
id: 'share', });
icon: 'share'
});
}
}
} }
if (options.sync !== false) { if (options.sync !== false && itemHelper.canSync(user, item)) {
if (itemHelper.canSync(user, item)) { commands.push({
commands.push({ name: globalize.translate('Sync'),
name: globalize.translate('Sync'), id: 'sync',
id: 'sync', icon: 'sync'
icon: 'sync' });
});
}
} }
if (options.openAlbum !== false && item.AlbumId && item.MediaType !== 'Photo') { if (options.openAlbum !== false && item.AlbumId && item.MediaType !== 'Photo') {

View file

@ -48,10 +48,8 @@ export function getDisplayName(item, options = {}) {
export function supportsAddingToCollection(item) { export function supportsAddingToCollection(item) {
const invalidTypes = ['Genre', 'MusicGenre', 'Studio', 'UserView', 'CollectionFolder', 'Audio', 'Program', 'Timer', 'SeriesTimer']; const invalidTypes = ['Genre', 'MusicGenre', 'Studio', 'UserView', 'CollectionFolder', 'Audio', 'Program', 'Timer', 'SeriesTimer'];
if (item.Type === 'Recording') { if (item.Type === 'Recording' && item.Status !== 'Completed') {
if (item.Status !== 'Completed') { return false;
return false;
}
} }
return !item.CollectionType && invalidTypes.indexOf(item.Type) === -1 && item.MediaType !== 'Photo' && !isLocalItem(item); return !item.CollectionType && invalidTypes.indexOf(item.Type) === -1 && item.MediaType !== 'Photo' && !isLocalItem(item);
@ -74,10 +72,8 @@ export function supportsAddingToPlaylist(item) {
return false; return false;
} }
if (item.Type === 'Recording') { if (item.Type === 'Recording' && item.Status !== 'Completed') {
if (item.Status !== 'Completed') { return false;
return false;
}
} }
if (isLocalItem(item)) { if (isLocalItem(item)) {
@ -109,10 +105,8 @@ export function canEdit(user, item) {
return false; return false;
} }
if (item.Type === 'Recording') { if (item.Type === 'Recording' && item.Status !== 'Completed') {
if (item.Status !== 'Completed') { return false;
return false;
}
} }
if (isLocalItem(item)) { if (isLocalItem(item)) {
@ -133,23 +127,17 @@ export function isLocalItem(item) {
export function canIdentify (user, item) { export function canIdentify (user, item) {
const itemType = item.Type; const itemType = item.Type;
if (itemType === 'Movie' || return (itemType === 'Movie'
itemType === 'Trailer' || || itemType === 'Trailer'
itemType === 'Series' || || itemType === 'Series'
itemType === 'BoxSet' || || itemType === 'BoxSet'
itemType === 'Person' || || itemType === 'Person'
itemType === 'Book' || || itemType === 'Book'
itemType === 'MusicAlbum' || || itemType === 'MusicAlbum'
itemType === 'MusicArtist' || || itemType === 'MusicArtist'
itemType === 'MusicVideo') { || itemType === 'MusicVideo')
if (user.Policy.IsAdministrator) { && user.Policy.IsAdministrator
if (!isLocalItem(item)) { && !isLocalItem(item);
return true;
}
}
}
return false;
} }
export function canEditImages (user, item) { export function canEditImages (user, item) {
@ -167,10 +155,8 @@ export function canEditImages (user, item) {
return false; return false;
} }
if (item.Type === 'Recording') { if (item.Type === 'Recording' && item.Status !== 'Completed') {
if (item.Status !== 'Completed') { return false;
return false;
}
} }
return itemType !== 'Timer' && itemType !== 'SeriesTimer' && canEdit(user, item) && !isLocalItem(item); return itemType !== 'Timer' && itemType !== 'SeriesTimer' && canEdit(user, item) && !isLocalItem(item);
@ -201,10 +187,8 @@ export function canShare (item, user) {
if (item.Type === 'SeriesTimer') { if (item.Type === 'SeriesTimer') {
return false; return false;
} }
if (item.Type === 'Recording') { if (item.Type === 'Recording' && item.Status !== 'Completed') {
if (item.Status !== 'Completed') { return false;
return false;
}
} }
if (isLocalItem(item)) { if (isLocalItem(item)) {
return false; return false;
@ -301,11 +285,10 @@ export function canRefreshMetadata (item, user) {
return false; return false;
} }
if (item.Type !== 'Timer' && item.Type !== 'SeriesTimer' && item.Type !== 'Program' && item.Type !== 'TvChannel' && !(item.Type === 'Recording' && item.Status !== 'Completed')) { return item.Type !== 'Timer' && item.Type !== 'SeriesTimer' && item.Type !== 'Program'
if (!isLocalItem(item)) { && item.Type !== 'TvChannel'
return true; && !(item.Type === 'Recording' && item.Status !== 'Completed')
} && !isLocalItem(item);
}
} }
return false; return false;

View file

@ -94,16 +94,14 @@ function onPlaybackStopped(e, stopInfo) {
const state = stopInfo.state; const state = stopInfo.state;
const eventsToMonitor = getEventsToMonitor(instance); const eventsToMonitor = getEventsToMonitor(instance);
if (state.NowPlayingItem && state.NowPlayingItem.MediaType === 'Video') { if (state.NowPlayingItem?.MediaType === 'Video') {
if (eventsToMonitor.indexOf('videoplayback') !== -1) { if (eventsToMonitor.indexOf('videoplayback') !== -1) {
instance.notifyRefreshNeeded(true); instance.notifyRefreshNeeded(true);
return; return;
} }
} else if (state.NowPlayingItem && state.NowPlayingItem.MediaType === 'Audio') { } else if (state.NowPlayingItem?.MediaType === 'Audio' && eventsToMonitor.indexOf('audioplayback') !== -1) {
if (eventsToMonitor.indexOf('audioplayback') !== -1) { instance.notifyRefreshNeeded(true);
instance.notifyRefreshNeeded(true); return;
return;
}
} }
} }

View file

@ -328,10 +328,8 @@ import ServerConnections from '../ServerConnections';
textlines.push(datetime.getDisplayTime(datetime.parseISO8601Date(item.StartDate))); textlines.push(datetime.getDisplayTime(datetime.parseISO8601Date(item.StartDate)));
} }
if (options.showChannel) { if (options.showChannel && item.ChannelName) {
if (item.ChannelName) { textlines.push(item.ChannelName);
textlines.push(item.ChannelName);
}
} }
let parentTitle = null; let parentTitle = null;
@ -370,10 +368,8 @@ import ServerConnections from '../ServerConnections';
} }
if (item.IsFolder) { if (item.IsFolder) {
if (options.artist !== false) { if (options.artist !== false && item.AlbumArtist && item.Type === 'MusicAlbum') {
if (item.AlbumArtist && item.Type === 'MusicAlbum') {
textlines.push(item.AlbumArtist); textlines.push(item.AlbumArtist);
}
} }
} else { } else {
if (options.artist) { if (options.artist) {
@ -386,10 +382,8 @@ import ServerConnections from '../ServerConnections';
} }
} }
if (item.Type === 'TvChannel') { if (item.Type === 'TvChannel' && item.CurrentProgram) {
if (item.CurrentProgram) { textlines.push(itemHelper.getDisplayName(item.CurrentProgram));
textlines.push(itemHelper.getDisplayName(item.CurrentProgram));
}
} }
cssClass = 'listItemBody'; cssClass = 'listItemBody';
@ -405,19 +399,17 @@ import ServerConnections from '../ServerConnections';
html += getTextLinesHtml(textlines, isLargeStyle); html += getTextLinesHtml(textlines, isLargeStyle);
if (options.mediaInfo !== false) { if (options.mediaInfo !== false && !enableSideMediaInfo) {
if (!enableSideMediaInfo) { const mediaInfoClass = 'secondary listItemMediaInfo listItemBodyText';
const mediaInfoClass = 'secondary listItemMediaInfo listItemBodyText';
html += `<div class="${mediaInfoClass}">`; html += `<div class="${mediaInfoClass}">`;
html += mediaInfo.getPrimaryMediaInfoHtml(item, { html += mediaInfo.getPrimaryMediaInfoHtml(item, {
episodeTitle: false, episodeTitle: false,
originalAirDate: false, originalAirDate: false,
subtitles: false subtitles: false
}); });
html += '</div>'; html += '</div>';
}
} }
if (enableOverview && item.Overview) { if (enableOverview && item.Overview) {
@ -428,20 +420,18 @@ import ServerConnections from '../ServerConnections';
html += '</div>'; html += '</div>';
if (options.mediaInfo !== false) { if (options.mediaInfo !== false && enableSideMediaInfo) {
if (enableSideMediaInfo) { html += '<div class="secondary listItemMediaInfo">';
html += '<div class="secondary listItemMediaInfo">'; html += mediaInfo.getPrimaryMediaInfoHtml(item, {
html += mediaInfo.getPrimaryMediaInfoHtml(item, {
year: false, year: false,
container: false, container: false,
episodeTitle: false, episodeTitle: false,
criticRating: false, criticRating: false,
endsAt: false endsAt: false
}); });
html += '</div>'; html += '</div>';
}
} }
if (!options.recordButton && (item.Type === 'Timer' || item.Type === 'Program')) { if (!options.recordButton && (item.Type === 'Timer' || item.Type === 'Program')) {

View file

@ -129,17 +129,18 @@ import '../../elements/emby-button/emby-button';
} }
} }
if ((item.Type === 'Episode' || item.MediaType === 'Photo') && options.originalAirDate !== false) { if ((item.Type === 'Episode' || item.MediaType === 'Photo')
if (item.PremiereDate) { && options.originalAirDate !== false
try { && item.PremiereDate
//don't modify date to locale if episode. Only Dates (not times) are stored, or editable in the edit metadata dialog ) {
date = datetime.parseISO8601Date(item.PremiereDate, item.Type !== 'Episode'); try {
//don't modify date to locale if episode. Only Dates (not times) are stored, or editable in the edit metadata dialog
date = datetime.parseISO8601Date(item.PremiereDate, item.Type !== 'Episode');
text = datetime.toLocaleDateString(date); text = datetime.toLocaleDateString(date);
miscInfo.push(text); miscInfo.push(text);
} catch (e) { } catch (e) {
console.error('error parsing date:', item.PremiereDate); console.error('error parsing date:', item.PremiereDate);
}
} }
} }
@ -239,17 +240,17 @@ import '../../elements/emby-button/emby-button';
} }
} }
if (options.year !== false) { if (options.year !== false && item.Type !== 'Series' && item.Type !== 'Episode' && item.Type !== 'Person'
if (item.Type !== 'Series' && item.Type !== 'Episode' && item.Type !== 'Person' && item.MediaType !== 'Photo' && item.Type !== 'Program' && item.Type !== 'Season') { && item.MediaType !== 'Photo' && item.Type !== 'Program' && item.Type !== 'Season'
if (item.ProductionYear) { ) {
miscInfo.push(item.ProductionYear); if (item.ProductionYear) {
} else if (item.PremiereDate) { miscInfo.push(item.ProductionYear);
try { } else if (item.PremiereDate) {
text = datetime.parseISO8601Date(item.PremiereDate).getFullYear(); try {
miscInfo.push(text); text = datetime.parseISO8601Date(item.PremiereDate).getFullYear();
} catch (e) { miscInfo.push(text);
console.error('error parsing date:', item.PremiereDate); } catch (e) {
} console.error('error parsing date:', item.PremiereDate);
} }
} }
} }
@ -314,14 +315,12 @@ import '../../elements/emby-button/emby-button';
} }
export function getEndsAt(item) { export function getEndsAt(item) {
if (item.MediaType === 'Video' && item.RunTimeTicks) { if (item.MediaType === 'Video' && item.RunTimeTicks && !item.StartDate) {
if (!item.StartDate) { let endDate = new Date().getTime() + (item.RunTimeTicks / 10000);
let endDate = new Date().getTime() + (item.RunTimeTicks / 10000); endDate = new Date(endDate);
endDate = new Date(endDate);
const displayTime = datetime.getDisplayTime(endDate); const displayTime = datetime.getDisplayTime(endDate);
return globalize.translate('EndsAtValue', displayTime); return globalize.translate('EndsAtValue', displayTime);
}
} }
return null; return null;

View file

@ -444,12 +444,10 @@ import { appRouter } from '../appRouter';
options = options || {}; options = options || {};
options.type = options.type || 'Primary'; options.type = options.type || 'Primary';
if (options.type === 'Primary') { if (options.type === 'Primary' && item.SeriesPrimaryImageTag) {
if (item.SeriesPrimaryImageTag) { options.tag = item.SeriesPrimaryImageTag;
options.tag = item.SeriesPrimaryImageTag;
return ServerConnections.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); return ServerConnections.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options);
}
} }
if (options.type === 'Thumb') { if (options.type === 'Thumb') {

View file

@ -44,10 +44,8 @@ function triggerPlayerChange(playbackManagerInstance, newPlayer, newTarget, prev
return; return;
} }
if (newTarget && previousTargetInfo) { if (newTarget && previousTargetInfo && newTarget.id === previousTargetInfo.id) {
if (newTarget.id === previousTargetInfo.id) { return;
return;
}
} }
Events.trigger(playbackManagerInstance, 'playerchange', [newPlayer, newTarget, previousPlayer]); Events.trigger(playbackManagerInstance, 'playerchange', [newPlayer, newTarget, previousPlayer]);
@ -501,10 +499,10 @@ function getPlaybackInfo(player,
} }
// lastly, enforce player overrides for special situations // lastly, enforce player overrides for special situations
if (query.EnableDirectStream !== false) { if (query.EnableDirectStream !== false
if (player.supportsPlayMethod && !player.supportsPlayMethod('DirectStream', item)) { && player.supportsPlayMethod && !player.supportsPlayMethod('DirectStream', item)
query.EnableDirectStream = false; ) {
} query.EnableDirectStream = false;
} }
if (player.getDirectPlayProtocols) { if (player.getDirectPlayProtocols) {
@ -569,10 +567,10 @@ function getLiveStream(player, apiClient, item, playSessionId, deviceProfile, ma
} }
// lastly, enforce player overrides for special situations // lastly, enforce player overrides for special situations
if (query.EnableDirectStream !== false) { if (query.EnableDirectStream !== false
if (player.supportsPlayMethod && !player.supportsPlayMethod('DirectStream', item)) { && player.supportsPlayMethod && !player.supportsPlayMethod('DirectStream', item)
query.EnableDirectStream = false; ) {
} query.EnableDirectStream = false;
} }
return apiClient.ajax({ return apiClient.ajax({
@ -963,10 +961,8 @@ class PlaybackManager {
self.isPlaying = function (player) { self.isPlaying = function (player) {
player = player || self._currentPlayer; player = player || self._currentPlayer;
if (player) { if (player?.isPlaying) {
if (player.isPlaying) { return player.isPlaying();
return player.isPlaying();
}
} }
return player != null && player.currentSrc() != null; return player != null && player.currentSrc() != null;
@ -975,10 +971,8 @@ class PlaybackManager {
self.isPlayingMediaType = function (mediaType, player) { self.isPlayingMediaType = function (mediaType, player) {
player = player || self._currentPlayer; player = player || self._currentPlayer;
if (player) { if (player?.isPlaying) {
if (player.isPlaying) { return player.isPlaying(mediaType);
return player.isPlaying(mediaType);
}
} }
if (self.isPlaying(player)) { if (self.isPlaying(player)) {
@ -1027,10 +1021,8 @@ class PlaybackManager {
return true; return true;
} }
if (item.LocationType === 'Virtual') { if (item.LocationType === 'Virtual' && itemType !== 'Program') {
if (itemType !== 'Program') { return false;
return false;
}
} }
if (itemType === 'Program') { if (itemType === 'Program') {
@ -3300,10 +3292,10 @@ class PlaybackManager {
reportPlayback(self, state, player, reportPlaylist, serverId, 'reportPlaybackProgress', progressEventName); reportPlayback(self, state, player, reportPlaylist, serverId, 'reportPlaybackProgress', progressEventName);
} }
if (streamInfo && streamInfo.liveStreamId) { if (streamInfo?.liveStreamId
if (new Date().getTime() - (streamInfo.lastMediaInfoQuery || 0) >= 600000) { && (new Date().getTime() - (streamInfo.lastMediaInfoQuery || 0) >= 600000)
getLiveStreamMediaInfo(player, streamInfo, self.currentMediaSource(player), streamInfo.liveStreamId, serverId); ) {
} getLiveStreamMediaInfo(player, streamInfo, self.currentMediaSource(player), streamInfo.liveStreamId, serverId);
} }
} }
} }
@ -3568,10 +3560,8 @@ class PlaybackManager {
} }
getBufferedRanges(player = this._currentPlayer) { getBufferedRanges(player = this._currentPlayer) {
if (player) { if (player?.getBufferedRanges) {
if (player.getBufferedRanges) { return player.getBufferedRanges();
return player.getBufferedRanges();
}
} }
return []; return [];
@ -3842,19 +3832,15 @@ class PlaybackManager {
removeActivePlayer(name) { removeActivePlayer(name) {
const playerInfo = this.getPlayerInfo(); const playerInfo = this.getPlayerInfo();
if (playerInfo) { if (playerInfo?.name === name) {
if (playerInfo.name === name) { this.setDefaultPlayerActive();
this.setDefaultPlayerActive();
}
} }
} }
removeActiveTarget(id) { removeActiveTarget(id) {
const playerInfo = this.getPlayerInfo(); const playerInfo = this.getPlayerInfo();
if (playerInfo) { if (playerInfo?.id === id) {
if (playerInfo.id === id) { this.setDefaultPlayerActive();
this.setDefaultPlayerActive();
}
} }
} }

View file

@ -29,10 +29,8 @@ function mirrorIfEnabled(info) {
if (info && playbackManager.enableDisplayMirroring()) { if (info && playbackManager.enableDisplayMirroring()) {
const getPlayerInfo = playbackManager.getPlayerInfo(); const getPlayerInfo = playbackManager.getPlayerInfo();
if (getPlayerInfo) { if (getPlayerInfo && !getPlayerInfo.isLocalPlayer && getPlayerInfo.supportedCommands.indexOf('DisplayContent') !== -1) {
if (!getPlayerInfo.isLocalPlayer && getPlayerInfo.supportedCommands.indexOf('DisplayContent') !== -1) { mirrorItem(info, playbackManager.getCurrentPlayer());
mirrorItem(info, playbackManager.getCurrentPlayer());
}
} }
} }
} }
@ -85,11 +83,9 @@ function getIcon(target) {
export function show(button) { export function show(button) {
const currentPlayerInfo = playbackManager.getPlayerInfo(); const currentPlayerInfo = playbackManager.getPlayerInfo();
if (currentPlayerInfo) { if (currentPlayerInfo && !currentPlayerInfo.isLocalPlayer) {
if (!currentPlayerInfo.isLocalPlayer) { showActivePlayerMenu(currentPlayerInfo);
showActivePlayerMenu(currentPlayerInfo); return;
return;
}
} }
const currentPlayerId = currentPlayerInfo ? currentPlayerInfo.id : null; const currentPlayerId = currentPlayerInfo ? currentPlayerInfo.id : null;

View file

@ -238,7 +238,6 @@ function showWithUser(options, player, user) {
return actionsheet.show({ return actionsheet.show({
items: menuItems, items: menuItems,
resolveOnClick: true,
positionTo: options.positionTo positionTo: options.positionTo
}).then(function (id) { }).then(function (id) {
return handleSelectedOption(id, options, player); return handleSelectedOption(id, options, player);

View file

@ -4,7 +4,7 @@ import globalize from '../../scripts/globalize';
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 '../../components/syncPlay/core'; import SyncPlay from '../../plugins/syncPlay/core';
import './playerstats.scss'; import './playerstats.scss';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';

View file

@ -4,7 +4,7 @@ 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 '../../components/syncPlay/core'; import SyncPlay from '../../plugins/syncPlay/core';
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';

View file

@ -106,10 +106,8 @@ function getIndicatorIcon(item) {
return 'fiber_manual_record'; return 'fiber_manual_record';
} }
if (item.SeriesTimerId) { if (item.SeriesTimerId && status !== 'Cancelled') {
if (status !== 'Cancelled') { return 'fiber_smart_record';
return 'fiber_smart_record';
}
} }
return 'fiber_manual_record'; return 'fiber_manual_record';

View file

@ -63,15 +63,10 @@ function onTimerChangedExternally(e, apiClient, data) {
const options = this.options; const options = this.options;
let refresh = false; let refresh = false;
if (data.Id) { if (data.Id && this.TimerId === data.Id) {
if (this.TimerId === data.Id) { refresh = true;
refresh = true; } else if (data.ProgramId && options && options.programId === data.ProgramId) {
} refresh = true;
}
if (data.ProgramId && options) {
if (options.programId === data.ProgramId) {
refresh = true;
}
} }
if (refresh) { if (refresh) {
@ -83,15 +78,11 @@ function onSeriesTimerChangedExternally(e, apiClient, data) {
const options = this.options; const options = this.options;
let refresh = false; let refresh = false;
if (data.Id) { if (data.Id && this.SeriesTimerId === data.Id) {
if (this.SeriesTimerId === data.Id) { refresh = true;
refresh = true;
}
} }
if (data.ProgramId && options) { if (data.ProgramId && options && options.programId === data.ProgramId) {
if (options.programId === data.ProgramId) { refresh = true;
refresh = true;
}
} }
if (refresh) { if (refresh) {

View file

@ -46,11 +46,9 @@ function getImageUrl(item, options, apiClient) {
return apiClient.getScaledImageUrl(item.Id, options); return apiClient.getScaledImageUrl(item.Id, options);
} }
if (options.type === 'Primary') { if (options.type === 'Primary' && item.AlbumId && item.AlbumPrimaryImageTag) {
if (item.AlbumId && item.AlbumPrimaryImageTag) { options.tag = item.AlbumPrimaryImageTag;
options.tag = item.AlbumPrimaryImageTag; return apiClient.getScaledImageUrl(item.AlbumId, options);
return apiClient.getScaledImageUrl(item.AlbumId, options);
}
} }
return null; return null;

View file

@ -114,10 +114,8 @@ function fillSubtitleList(context, item) {
itemHtml += '</a>'; itemHtml += '</a>';
itemHtml += '</div>'; itemHtml += '</div>';
if (!layoutManager.tv) { if (!layoutManager.tv && s.Path) {
if (s.Path) { itemHtml += '<button is="paper-icon-button-light" data-index="' + s.Index + '" title="' + globalize.translate('Delete') + '" class="btnDelete listItemButton"><span class="material-icons delete" aria-hidden="true"></span></button>';
itemHtml += '<button is="paper-icon-button-light" data-index="' + s.Index + '" title="' + globalize.translate('Delete') + '" class="btnDelete listItemButton"><span class="material-icons delete" aria-hidden="true"></span></button>';
}
} }
itemHtml += '</' + tagName + '>'; itemHtml += '</' + tagName + '>';

View file

@ -44,6 +44,7 @@
"pdfPlayer/plugin", "pdfPlayer/plugin",
"logoScreensaver/plugin", "logoScreensaver/plugin",
"sessionPlayer/plugin", "sessionPlayer/plugin",
"chromecastPlayer/plugin" "chromecastPlayer/plugin",
"syncPlay/plugin"
] ]
} }

View file

@ -800,13 +800,11 @@ import confirm from '../../components/confirm/confirm';
}); });
} }
if (ApiClient.isMinServerVersion('3.4.1.25')) { if (!page.serverActivityLog) {
if (!page.serverActivityLog) { page.serverActivityLog = new ActivityLog({
page.serverActivityLog = new ActivityLog({ serverId: ApiClient.serverId(),
serverId: ApiClient.serverId(), element: page.querySelector('.serverActivityItems')
element: page.querySelector('.serverActivityItems') });
});
}
} }
refreshActiveRecordings(view, apiClient); refreshActiveRecordings(view, apiClient);

View file

@ -1,6 +1,6 @@
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 '../../../components/syncPlay/core'; 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';

View file

@ -85,13 +85,9 @@ import 'webcomponents.js/webcomponents-lite';
passive: true passive: true
}); });
if (browser.orsay) { //Make sure the IME pops up if this is the first/default element on the page
if (this === document.activeElement) { if (browser.orsay && this === document.activeElement && document.attachIME) {
//Make sure the IME pops up if this is the first/default element on the page document.attachIME(this);
if (document.attachIME) {
document.attachIME(this);
}
}
} }
}; };

View file

@ -21,10 +21,8 @@ import Sortable from 'sortablejs';
const itemsContainer = this; const itemsContainer = this;
const multiSelect = itemsContainer.multiSelect; const multiSelect = itemsContainer.multiSelect;
if (multiSelect) { if (multiSelect?.onContainerClick.call(itemsContainer, e) === false) {
if (multiSelect.onContainerClick.call(itemsContainer, e) === false) { return;
return;
}
} }
itemShortcuts.onClick.call(itemsContainer, e); itemShortcuts.onClick.call(itemsContainer, e);
@ -259,11 +257,9 @@ import Sortable from 'sortablejs';
itemsContainer.notifyRefreshNeeded(true); itemsContainer.notifyRefreshNeeded(true);
return; return;
} }
} else if (state.NowPlayingItem && state.NowPlayingItem.MediaType === 'Audio') { } else if (state.NowPlayingItem?.MediaType === 'Audio' && eventsToMonitor.indexOf('audioplayback') !== -1) {
if (eventsToMonitor.indexOf('audioplayback') !== -1) { itemsContainer.notifyRefreshNeeded(true);
itemsContainer.notifyRefreshNeeded(true); return;
return;
}
} }
} }
@ -298,10 +294,8 @@ import Sortable from 'sortablejs';
} }
} }
if (layoutManager.desktop || layoutManager.mobile) { if (layoutManager.desktop || layoutManager.mobile && this.getAttribute('data-multiselect') !== 'false') {
if (this.getAttribute('data-multiselect') !== 'false') { this.enableMultiSelect(true);
this.enableMultiSelect(true);
}
} }
if (layoutManager.tv) { if (layoutManager.tv) {

View file

@ -443,10 +443,8 @@ import '../emby-input/emby-input';
} }
for (const range of ranges) { for (const range of ranges) {
if (position != null) { if (position != null && position >= range.end) {
if (position >= range.end) { continue;
continue;
}
} }
setRange(elem, range.start, range.end); setRange(elem, range.start, range.end);

View file

@ -272,10 +272,8 @@ import '../../assets/css/scrollstyles.scss';
let sibling = elem[method]; let sibling = elem[method];
while (sibling) { while (sibling) {
if (sibling.classList.contains(buttonClass)) { if (sibling.classList.contains(buttonClass) && !sibling.classList.contains('hide')) {
if (!sibling.classList.contains('hide')) { return sibling;
return sibling;
}
} }
sibling = sibling[method]; sibling = sibling[method];

View file

@ -35,11 +35,6 @@ import './legacy/domParserTextHtml';
import './legacy/focusPreventScroll'; import './legacy/focusPreventScroll';
import './legacy/htmlMediaElement'; import './legacy/htmlMediaElement';
import './legacy/vendorStyles'; import './legacy/vendorStyles';
import SyncPlay from './components/syncPlay/core';
import { playbackManager } from './components/playback/playbackmanager';
import SyncPlayNoActivePlayer from './components/syncPlay/ui/players/NoActivePlayer';
import SyncPlayHtmlVideoPlayer from './components/syncPlay/ui/players/HtmlVideoPlayer';
import SyncPlayHtmlAudioPlayer from './components/syncPlay/ui/players/HtmlAudioPlayer';
import { currentSettings } from './scripts/settings/userSettings'; import { currentSettings } from './scripts/settings/userSettings';
import taskButton from './scripts/taskbutton'; import taskButton from './scripts/taskbutton';
import { HistoryRouter } from './components/HistoryRouter.tsx'; import { HistoryRouter } from './components/HistoryRouter.tsx';
@ -84,10 +79,10 @@ function init() {
} }
function onGlobalizeInit() { function onGlobalizeInit() {
if (window.appMode === 'android') { if (window.appMode === 'android'
if (window.location.href.toString().toLowerCase().indexOf('start=backgroundsync') !== -1) { && window.location.href.toString().toLowerCase().indexOf('start=backgroundsync') !== -1
return onAppReady(); ) {
} return onAppReady();
} }
document.title = globalize.translateHtml(document.title, 'core'); document.title = globalize.translateHtml(document.title, 'core');
@ -102,10 +97,7 @@ function onGlobalizeInit() {
import('./assets/css/librarybrowser.scss'); import('./assets/css/librarybrowser.scss');
loadPlugins().then(function () { loadPlugins().then(onAppReady);
initSyncPlay();
onAppReady();
});
} }
function loadPlugins() { function loadPlugins() {
@ -137,27 +129,6 @@ function loadPlugins() {
}); });
} }
function initSyncPlay() {
// Register player wrappers.
SyncPlay.PlayerFactory.setDefaultWrapper(SyncPlayNoActivePlayer);
SyncPlay.PlayerFactory.registerWrapper(SyncPlayHtmlVideoPlayer);
SyncPlay.PlayerFactory.registerWrapper(SyncPlayHtmlAudioPlayer);
// Listen for player changes.
Events.on(playbackManager, 'playerchange', (event, newPlayer, newTarget, oldPlayer) => {
SyncPlay.Manager.onPlayerChange(newPlayer, newTarget, oldPlayer);
});
// Start SyncPlay.
const apiClient = ServerConnections.currentApiClient();
if (apiClient) SyncPlay.Manager.init(apiClient);
// FIXME: Multiple apiClients?
Events.on(ServerConnections, 'apiclientcreated', (e, newApiClient) => SyncPlay.Manager.init(newApiClient));
Events.on(ServerConnections, 'localusersignedin', () => SyncPlay.Manager.updateApiClient(ServerConnections.currentApiClient()));
Events.on(ServerConnections, 'localusersignedout', () => SyncPlay.Manager.updateApiClient(ServerConnections.currentApiClient()));
}
async function onAppReady() { async function onAppReady() {
console.debug('begin onAppReady'); console.debug('begin onAppReady');

View file

@ -289,34 +289,32 @@ class NavDrawer {
setEdgeSwipeEnabled(enabled) { setEdgeSwipeEnabled(enabled) {
const options = this.options; const options = this.options;
if (!options.disableEdgeSwipe) { if (!options.disableEdgeSwipe && browser.touch) {
if (browser.touch) { if (enabled) {
if (enabled) { if (!this._edgeSwipeEnabled) {
if (!this._edgeSwipeEnabled) { this._edgeSwipeEnabled = true;
this._edgeSwipeEnabled = true; dom.addEventListener(this.edgeContainer, 'touchstart', this.onEdgeTouchStart, {
dom.addEventListener(this.edgeContainer, 'touchstart', this.onEdgeTouchStart, { passive: true
passive: true });
}); dom.addEventListener(this.edgeContainer, 'touchend', this.onEdgeTouchEnd, {
dom.addEventListener(this.edgeContainer, 'touchend', this.onEdgeTouchEnd, { passive: true
passive: true });
}); dom.addEventListener(this.edgeContainer, 'touchcancel', this.onEdgeTouchEnd, {
dom.addEventListener(this.edgeContainer, 'touchcancel', this.onEdgeTouchEnd, { passive: true
passive: true });
}); }
} } else {
} else { if (this._edgeSwipeEnabled) {
if (this._edgeSwipeEnabled) { this._edgeSwipeEnabled = false;
this._edgeSwipeEnabled = false; dom.removeEventListener(this.edgeContainer, 'touchstart', this.onEdgeTouchStart, {
dom.removeEventListener(this.edgeContainer, 'touchstart', this.onEdgeTouchStart, { passive: true
passive: true });
}); dom.removeEventListener(this.edgeContainer, 'touchend', this.onEdgeTouchEnd, {
dom.removeEventListener(this.edgeContainer, 'touchend', this.onEdgeTouchEnd, { passive: true
passive: true });
}); dom.removeEventListener(this.edgeContainer, 'touchcancel', this.onEdgeTouchEnd, {
dom.removeEventListener(this.edgeContainer, 'touchcancel', this.onEdgeTouchEnd, { passive: true
passive: true });
});
}
} }
} }
} }

View file

@ -279,10 +279,8 @@ const scrollerFactory = function (frame, options) {
const now = new Date().getTime(); const now = new Date().getTime();
if (o.autoImmediate) { if (o.autoImmediate && !immediate && (now - (lastAnimate || 0)) <= 50) {
if (!immediate && (now - (lastAnimate || 0)) <= 50) { immediate = true;
immediate = true;
}
} }
if (!immediate && o.skipSlideToWhenVisible && fullItemPos && fullItemPos.isVisible) { if (!immediate && o.skipSlideToWhenVisible && fullItemPos && fullItemPos.isVisible) {
@ -787,15 +785,13 @@ const scrollerFactory = function (frame, options) {
passive: true passive: true
}); });
} }
} else if (o.horizontal) { } else if (o.horizontal && o.mouseWheel) {
// Don't bind to mouse events with vertical scroll since the mouse wheel can handle this natively // Don't bind to mouse events with vertical scroll since the mouse wheel can handle this natively
if (o.mouseWheel) { // Scrolling navigation
// Scrolling navigation dom.addEventListener(scrollSource, wheelEvent, scrollHandler, {
dom.addEventListener(scrollSource, wheelEvent, scrollHandler, { passive: true
passive: true });
});
}
} }
dom.addEventListener(frame, 'click', onFrameClick, { dom.addEventListener(frame, 'click', onFrameClick, {

View file

@ -452,11 +452,9 @@ function normalizeImages(state) {
if (state && state.NowPlayingItem) { if (state && state.NowPlayingItem) {
const item = state.NowPlayingItem; const item = state.NowPlayingItem;
if (!item.ImageTags || !item.ImageTags.Primary) { if ((!item.ImageTags || !item.ImageTags.Primary) && item.PrimaryImageTag) {
if (item.PrimaryImageTag) { item.ImageTags = item.ImageTags || {};
item.ImageTags = item.ImageTags || {}; item.ImageTags.Primary = item.PrimaryImageTag;
item.ImageTags.Primary = item.PrimaryImageTag;
}
} }
if (item.BackdropImageTag && item.BackdropItemId === item.Id) { if (item.BackdropImageTag && item.BackdropItemId === item.Id) {
item.BackdropImageTags = [item.BackdropImageTag]; item.BackdropImageTags = [item.BackdropImageTag];

View file

@ -67,16 +67,12 @@ function tryRemoveElement(elem) {
} }
function enableNativeTrackSupport(currentSrc, track) { function enableNativeTrackSupport(currentSrc, track) {
if (track) { if (track?.DeliveryMethod === 'Embed') {
if (track.DeliveryMethod === 'Embed') { return true;
return true;
}
} }
if (browser.firefox) { if (browser.firefox && (currentSrc || '').toLowerCase().includes('.m3u8')) {
if ((currentSrc || '').toLowerCase().includes('.m3u8')) { return false;
return false;
}
} }
if (browser.ps4) { if (browser.ps4) {
@ -92,11 +88,9 @@ function tryRemoveElement(elem) {
return false; return false;
} }
if (browser.iOS) { if (browser.iOS && (browser.iosVersion || 10) < 10) {
// works in the browser but not the native app // works in the browser but not the native app
if ((browser.iosVersion || 10) < 10) { return false;
return false;
}
} }
if (track) { if (track) {
@ -1500,10 +1494,11 @@ function tryRemoveElement(elem) {
|| document.pictureInPictureEnabled || document.pictureInPictureEnabled
) { ) {
list.push('PictureInPicture'); list.push('PictureInPicture');
} else if (window.Windows) { } else if (window.Windows
if (Windows.UI.ViewManagement.ApplicationView.getForCurrentView().isViewModeSupported(Windows.UI.ViewManagement.ApplicationViewMode.compactOverlay)) { && Windows.UI.ViewManagement.ApplicationView.getForCurrentView()
.isViewModeSupported(Windows.UI.ViewManagement.ApplicationViewMode.compactOverlay)
) {
list.push('PictureInPicture'); list.push('PictureInPicture');
}
} }
if (browser.safari || browser.iOS || browser.iPad) { if (browser.safari || browser.iOS || browser.iPad) {
@ -1564,13 +1559,7 @@ function tryRemoveElement(elem) {
} }
const video = this.#mediaElement; const video = this.#mediaElement;
if (video) { return !!video?.audioTracks;
if (video.audioTracks) {
return true;
}
}
return false;
} }
static onPictureInPictureError(err) { static onPictureInPictureError(err) {

View file

@ -159,11 +159,9 @@ function normalizeImages(state, apiClient) {
if (state && state.NowPlayingItem) { if (state && state.NowPlayingItem) {
const item = state.NowPlayingItem; const item = state.NowPlayingItem;
if (!item.ImageTags || !item.ImageTags.Primary) { if (!item.ImageTags || !item.ImageTags.Primary && item.PrimaryImageTag) {
if (item.PrimaryImageTag) { item.ImageTags = item.ImageTags || {};
item.ImageTags = item.ImageTags || {}; item.ImageTags.Primary = item.PrimaryImageTag;
item.ImageTags.Primary = item.PrimaryImageTag;
}
} }
if (item.BackdropImageTag && item.BackdropItemId === item.Id) { if (item.BackdropImageTag && item.BackdropItemId === item.Id) {
item.BackdropImageTags = [item.BackdropImageTag]; item.BackdropImageTags = [item.BackdropImageTag];

View file

@ -9,7 +9,7 @@ import TimeSyncCore from './timeSync/TimeSyncCore';
import PlaybackCore from './PlaybackCore'; import PlaybackCore from './PlaybackCore';
import QueueCore from './QueueCore'; import QueueCore from './QueueCore';
import Controller from './Controller'; import Controller from './Controller';
import toast from '../../toast/toast'; import toast from '../../../components/toast/toast';
import globalize from '../../../scripts/globalize'; import globalize from '../../../scripts/globalize';
/** /**

View file

@ -4,7 +4,7 @@
*/ */
import globalize from '../../../scripts/globalize'; import globalize from '../../../scripts/globalize';
import toast from '../../toast/toast'; import toast from '../../../components/toast/toast';
import * as Helper from './Helper'; import * as Helper from './Helper';
/** /**

View file

@ -16,7 +16,7 @@ class PlayerFactory {
/** /**
* Registers a wrapper to the list of players that can be managed. * Registers a wrapper to the list of players that can be managed.
* @param {GenericPlayer} wrapperClass The wrapper to register. * @param {typeof GenericPlayer} wrapperClass The wrapper to register.
*/ */
registerWrapper(wrapperClass) { registerWrapper(wrapperClass) {
console.debug('SyncPlay WrapperFactory registerWrapper:', wrapperClass.type); console.debug('SyncPlay WrapperFactory registerWrapper:', wrapperClass.type);
@ -25,7 +25,7 @@ class PlayerFactory {
/** /**
* Sets the default player wrapper. * Sets the default player wrapper.
* @param {GenericPlayer} wrapperClass The wrapper. * @param {typeof GenericPlayer} wrapperClass The wrapper.
*/ */
setDefaultWrapper(wrapperClass) { setDefaultWrapper(wrapperClass) {
console.debug('SyncPlay WrapperFactory setDefaultWrapper:', wrapperClass.type); console.debug('SyncPlay WrapperFactory setDefaultWrapper:', wrapperClass.type);

View file

@ -0,0 +1,49 @@
import { Events } from 'jellyfin-apiclient';
import { playbackManager } from '../../components/playback/playbackmanager';
import ServerConnections from '../../components/ServerConnections';
import SyncPlay from './core';
import SyncPlayNoActivePlayer from './ui/players/NoActivePlayer';
import SyncPlayHtmlVideoPlayer from './ui/players/HtmlVideoPlayer';
import SyncPlayHtmlAudioPlayer from './ui/players/HtmlAudioPlayer';
class SyncPlayPlugin {
name: string;
id: string;
type: string;
priority: number;
constructor() {
this.name = 'SyncPlay Plugin';
this.id = 'syncplay';
// NOTE: This should probably be a "mediaplayer" so the playback manager can handle playback logic, but
// SyncPlay needs refactored so it does not have an independent playback manager.
this.type = 'syncplay';
this.priority = 1;
this.init();
}
init() {
// Register player wrappers.
SyncPlay.PlayerFactory.setDefaultWrapper(SyncPlayNoActivePlayer);
SyncPlay.PlayerFactory.registerWrapper(SyncPlayHtmlVideoPlayer);
SyncPlay.PlayerFactory.registerWrapper(SyncPlayHtmlAudioPlayer);
// Listen for player changes.
Events.on(playbackManager, 'playerchange', (_, newPlayer) => {
SyncPlay.Manager.onPlayerChange(newPlayer);
});
// Start SyncPlay.
const apiClient = ServerConnections.currentApiClient();
if (apiClient) SyncPlay.Manager.init(apiClient);
// FIXME: Multiple apiClients?
Events.on(ServerConnections, 'apiclientcreated', (_, newApiClient) => SyncPlay.Manager.init(newApiClient));
Events.on(ServerConnections, 'localusersignedin', () => SyncPlay.Manager.updateApiClient(ServerConnections.currentApiClient()));
Events.on(ServerConnections, 'localusersignedout', () => SyncPlay.Manager.updateApiClient(ServerConnections.currentApiClient()));
}
}
export default SyncPlayPlugin;

View file

@ -1,12 +1,12 @@
import { Events } from 'jellyfin-apiclient'; import { Events } from 'jellyfin-apiclient';
import SyncPlay from '../core'; import SyncPlay from '../core';
import SyncPlaySettingsEditor from './settings/SettingsEditor'; import SyncPlaySettingsEditor from './settings/SettingsEditor';
import loading from '../../loading/loading'; import loading from '../../../components/loading/loading';
import toast from '../../toast/toast'; import toast from '../../../components/toast/toast';
import actionsheet from '../../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 ServerConnections from '../../ServerConnections'; import ServerConnections from '../../../components/ServerConnections';
import './groupSelectionMenu.scss'; import './groupSelectionMenu.scss';
/** /**

View file

@ -1,4 +1,4 @@
import { appHost } from '../../apphost'; import { appHost } from '../../../components/apphost';
/** /**
* Creates an audio element that plays a silent sound. * Creates an audio element that plays a silent sound.

View file

@ -3,7 +3,7 @@
* @module components/syncPlay/ui/players/NoActivePlayer * @module components/syncPlay/ui/players/NoActivePlayer
*/ */
import { playbackManager } from '../../../playback/playbackmanager'; import { playbackManager } from '../../../../components/playback/playbackmanager';
import SyncPlay from '../../core'; import SyncPlay from '../../core';
import QueueManager from './QueueManager'; import QueueManager from './QueueManager';

View file

@ -6,10 +6,10 @@
import { Events } from 'jellyfin-apiclient'; import { Events } from 'jellyfin-apiclient';
import SyncPlay from '../../core'; import SyncPlay from '../../core';
import { setSetting } from '../../core/Settings'; import { setSetting } from '../../core/Settings';
import dialogHelper from '../../../dialogHelper/dialogHelper'; import dialogHelper from '../../../../components/dialogHelper/dialogHelper';
import layoutManager from '../../../layoutManager'; import layoutManager from '../../../../components/layoutManager';
import loading from '../../../loading/loading'; import loading from '../../../../components/loading/loading';
import toast from '../../../toast/toast'; import toast from '../../../../components/toast/toast';
import globalize from '../../../../scripts/globalize'; import globalize from '../../../../scripts/globalize';
import 'material-design-icons-iconfont'; import 'material-design-icons-iconfont';
@ -18,8 +18,8 @@ import '../../../../elements/emby-select/emby-select';
import '../../../../elements/emby-button/emby-button'; import '../../../../elements/emby-button/emby-button';
import '../../../../elements/emby-button/paper-icon-button-light'; import '../../../../elements/emby-button/paper-icon-button-light';
import '../../../../elements/emby-checkbox/emby-checkbox'; import '../../../../elements/emby-checkbox/emby-checkbox';
import '../../../listview/listview.scss'; import '../../../../components/listview/listview.scss';
import '../../../formdialog.scss'; import '../../../../components/formdialog.scss';
function centerFocus(elem, horiz, on) { function centerFocus(elem, horiz, on) {
import('../../../../scripts/scrollHelper').then((scrollHelper) => { import('../../../../scripts/scrollHelper').then((scrollHelper) => {

View file

@ -333,10 +333,8 @@ class YoutubePlayer {
setVolume(val) { setVolume(val) {
const currentYoutubePlayer = this.currentYoutubePlayer; const currentYoutubePlayer = this.currentYoutubePlayer;
if (currentYoutubePlayer) { if (currentYoutubePlayer && val != null) {
if (val != null) { currentYoutubePlayer.setVolume(val);
currentYoutubePlayer.setVolume(val);
}
} }
} }
getVolume() { getVolume() {

View file

@ -324,11 +324,9 @@ if (browser.mobile || browser.tv) {
browser.slow = true; browser.slow = true;
} }
if (typeof document !== 'undefined') { /* eslint-disable-next-line compat/compat */
/* eslint-disable-next-line compat/compat */ if (typeof document !== 'undefined' && ('ontouchstart' in window) || (navigator.maxTouchPoints > 0)) {
if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0)) { browser.touch = true;
browser.touch = true;
}
} }
browser.keyboard = hasKeyboard(browser); browser.keyboard = hasKeyboard(browser);

View file

@ -822,12 +822,12 @@ import browser from './browser';
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
if (!browser.safari && !browser.iOS && !browser.web0s && !browser.edge && !browser.mobile) { && !browser.safari && !browser.iOS && !browser.web0s && !browser.edge && !browser.mobile
h264Profiles += '|high 10'; ) {
} h264Profiles += '|high 10';
} }
let maxHevcLevel = 120; let maxHevcLevel = 120;

View file

@ -68,10 +68,8 @@ export function showLayoutMenu (button, currentLayout, views) {
cancelable: false cancelable: false
})); }));
if (!dispatchEvent) { if (!dispatchEvent && window.$) {
if (window.$) { $(button).trigger('layoutchange', [id]);
$(button).trigger('layoutchange', [id]);
}
} }
} }
}); });

View file

@ -9,7 +9,8 @@ import viewManager from '../components/viewManager/viewManager';
import { appRouter } from '../components/appRouter'; import { appRouter } from '../components/appRouter';
import { appHost } from '../components/apphost'; import { appHost } from '../components/apphost';
import { playbackManager } from '../components/playback/playbackmanager'; import { playbackManager } from '../components/playback/playbackmanager';
import groupSelectionMenu from '../components/syncPlay/ui/groupSelectionMenu'; import { pluginManager } from '../components/pluginManager';
import groupSelectionMenu from '../plugins/syncPlay/ui/groupSelectionMenu';
import browser from './browser'; import browser from './browser';
import globalize from './globalize'; import globalize from './globalize';
import imageHelper from './imagehelper'; import imageHelper from './imagehelper';
@ -154,8 +155,14 @@ import '../assets/css/flexstyles.scss';
const policy = user.Policy ? user.Policy : user.localUser.Policy; const policy = user.Policy ? user.Policy : user.localUser.Policy;
const apiClient = getCurrentApiClient(); if (
if (headerSyncButton && policy?.SyncPlayAccess !== 'None' && apiClient.isMinServerVersion('10.6.0')) { // Button is present
headerSyncButton
// SyncPlay plugin is loaded
&& pluginManager.plugins.filter(plugin => plugin.id === 'syncplay').length > 0
// SyncPlay enabled for user
&& policy?.SyncPlayAccess !== 'None'
) {
headerSyncButton.classList.remove('hide'); headerSyncButton.classList.remove('hide');
} }
} else { } else {

View file

@ -88,12 +88,10 @@ import dom from '../scripts/dom';
function onPointerEnter(e) { function onPointerEnter(e) {
const pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'); const pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
if (pointerType === 'mouse') { if (pointerType === 'mouse' && !isMouseIdle) {
if (!isMouseIdle) { const parent = focusManager.focusableParent(e.target);
const parent = focusManager.focusableParent(e.target); if (parent) {
if (parent) { focusManager.focus(parent);
focusManager.focus(parent);
}
} }
} }
} }

View file

@ -1,5 +1,5 @@
import { playbackManager } from '../components/playback/playbackmanager'; import { playbackManager } from '../components/playback/playbackmanager';
import SyncPlay from '../components/syncPlay/core'; import SyncPlay from '../plugins/syncPlay/core';
import { Events } from 'jellyfin-apiclient'; import { Events } from 'jellyfin-apiclient';
import inputManager from '../scripts/inputManager'; import inputManager from '../scripts/inputManager';
import focusManager from '../components/focusManager'; import focusManager from '../components/focusManager';

View file

@ -914,7 +914,7 @@
"QuickConnectActivationSuccessful": "Başarıyla etkinleştirildi", "QuickConnectActivationSuccessful": "Başarıyla etkinleştirildi",
"QuickConnect": "Hızlı Bağlantı", "QuickConnect": "Hızlı Bağlantı",
"LabelQuickConnectCode": "Hızlı Bağlantı kodu:", "LabelQuickConnectCode": "Hızlı Bağlantı kodu:",
"SubtitleAppearanceSettingsAlsoPassedToCastDevices": "Bu ayarlar, bu cihaz tarafından başlatılan herhangi bir Chromecast oynatma için de geçerlidir.", "SubtitleAppearanceSettingsAlsoPassedToCastDevices": "Bu ayarlar, bu cihaz tarafından başlatılan herhangi bir ChromeCast oynatma için de geçerlidir.",
"StopPlayback": "Oynatmayı durdur", "StopPlayback": "Oynatmayı durdur",
"SyncPlayAccessHelp": "SyncPlay özelliği, oynatmayı diğer cihazlarla senkronize etmeyi sağlar. Bu kullanıcının SyncPlay sahip olduğu erişim düzeyini seçin.", "SyncPlayAccessHelp": "SyncPlay özelliği, oynatmayı diğer cihazlarla senkronize etmeyi sağlar. Bu kullanıcının SyncPlay sahip olduğu erişim düzeyini seçin.",
"TitlePlayback": "Oynatma", "TitlePlayback": "Oynatma",
@ -1670,5 +1670,8 @@
"RememberSubtitleSelectionsHelp": "Altyazı dilini, son videoya en yakın eşleşmeye göre ayarlamayı dene.", "RememberSubtitleSelectionsHelp": "Altyazı dilini, son videoya en yakın eşleşmeye göre ayarlamayı dene.",
"RememberAudioSelectionsHelp": "Ses dilini, son videoya en yakın eşleşmeye göre ayarlamayı dene.", "RememberAudioSelectionsHelp": "Ses dilini, son videoya en yakın eşleşmeye göre ayarlamayı dene.",
"RememberAudioSelections": "Ses dilini önceki öğeye göre ayarla", "RememberAudioSelections": "Ses dilini önceki öğeye göre ayarla",
"RememberSubtitleSelections": "Altyazı dilini önceki öğeye göre ayarla" "RememberSubtitleSelections": "Altyazı dilini önceki öğeye göre ayarla",
"TabContainers": "Barındırıcılar",
"OptionDateShowAdded": "Dizi Eklenme Tarihi",
"OptionDateEpisodeAdded": "Bölüm Eklenme Tarihi"
} }