From 227f473d948345d5d06ca54f06eff73cc099d8cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 14:15:19 +0000 Subject: [PATCH 001/112] Update fedora Docker tag to v39 --- deployment/Dockerfile.fedora | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/Dockerfile.fedora b/deployment/Dockerfile.fedora index 9248c209d7..5e44024f2e 100644 --- a/deployment/Dockerfile.fedora +++ b/deployment/Dockerfile.fedora @@ -1,4 +1,4 @@ -FROM fedora:38 +FROM fedora:39 # Docker build arguments ARG SOURCE_DIR=/jellyfin From 745913c8705fb1eb27c719332188132c1848008c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 22 Apr 2023 18:31:43 +0000 Subject: [PATCH 002/112] Update Webpack --- package-lock.json | 28 ++++++++++++++-------------- package.json | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index c2ad0dffb8..56eaa40b01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -92,7 +92,7 @@ "eslint-plugin-sonarjs": "0.19.0", "expose-loader": "4.1.0", "html-loader": "4.2.0", - "html-webpack-plugin": "5.5.0", + "html-webpack-plugin": "5.5.1", "mini-css-extract-plugin": "2.7.5", "postcss": "8.4.21", "postcss-loader": "7.2.4", @@ -111,7 +111,7 @@ "typescript": "5.0.4", "webpack": "5.79.0", "webpack-cli": "5.0.1", - "webpack-dev-server": "4.13.2", + "webpack-dev-server": "4.13.3", "webpack-merge": "5.8.0", "workbox-webpack-plugin": "6.5.4", "worker-loader": "3.0.8" @@ -9066,9 +9066,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz", + "integrity": "sha512-cTUzZ1+NqjGEKjmVgZKLMdiFg3m9MdRXkZW2OEe69WYVi5ONLMmlnSZdXzGGMOq0C8jGDrL6EWyEDDUioHO/pA==", "dev": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -19308,9 +19308,9 @@ "dev": true }, "node_modules/webpack-dev-server": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.13.2.tgz", - "integrity": "sha512-5i6TrGBRxG4vnfDpB6qSQGfnB6skGBXNL5/542w2uRGLimX6qeE5BQMLrzIC3JYV/xlGOv+s+hTleI9AZKUQNw==", + "version": "4.13.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.13.3.tgz", + "integrity": "sha512-KqqzrzMRSRy5ePz10VhjyL27K2dxqwXQLP5rAKwRJBPUahe7Z2bBWzHw37jeb8GCPKxZRO79ZdQUAPesMh/Nug==", "dev": true, "dependencies": { "@types/bonjour": "^3.5.9", @@ -26653,9 +26653,9 @@ "dev": true }, "html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz", + "integrity": "sha512-cTUzZ1+NqjGEKjmVgZKLMdiFg3m9MdRXkZW2OEe69WYVi5ONLMmlnSZdXzGGMOq0C8jGDrL6EWyEDDUioHO/pA==", "dev": true, "requires": { "@types/html-minifier-terser": "^6.0.0", @@ -34327,9 +34327,9 @@ } }, "webpack-dev-server": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.13.2.tgz", - "integrity": "sha512-5i6TrGBRxG4vnfDpB6qSQGfnB6skGBXNL5/542w2uRGLimX6qeE5BQMLrzIC3JYV/xlGOv+s+hTleI9AZKUQNw==", + "version": "4.13.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.13.3.tgz", + "integrity": "sha512-KqqzrzMRSRy5ePz10VhjyL27K2dxqwXQLP5rAKwRJBPUahe7Z2bBWzHw37jeb8GCPKxZRO79ZdQUAPesMh/Nug==", "dev": true, "requires": { "@types/bonjour": "^3.5.9", diff --git a/package.json b/package.json index 823812e8be..edca125b2e 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "eslint-plugin-sonarjs": "0.19.0", "expose-loader": "4.1.0", "html-loader": "4.2.0", - "html-webpack-plugin": "5.5.0", + "html-webpack-plugin": "5.5.1", "mini-css-extract-plugin": "2.7.5", "postcss": "8.4.21", "postcss-loader": "7.2.4", @@ -61,7 +61,7 @@ "typescript": "5.0.4", "webpack": "5.79.0", "webpack-cli": "5.0.1", - "webpack-dev-server": "4.13.2", + "webpack-dev-server": "4.13.3", "webpack-merge": "5.8.0", "workbox-webpack-plugin": "6.5.4", "worker-loader": "3.0.8" From bff59b501aca30edb92c4d272d2941c9a7370c35 Mon Sep 17 00:00:00 2001 From: Franco Castillo Date: Sat, 22 Apr 2023 21:47:58 +0000 Subject: [PATCH 003/112] Translated using Weblate (Spanish (Argentina)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es_AR/ --- src/strings/es-ar.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/strings/es-ar.json b/src/strings/es-ar.json index 9608c9bf8a..36a100d7da 100644 --- a/src/strings/es-ar.json +++ b/src/strings/es-ar.json @@ -1695,5 +1695,14 @@ "LabelDummyChapterCount": "Límite", "LabelDummyChapterCountHelp": "El número máximo de imágenes de capítulos que se extraerán para cada archivo multimedia.", "LabelChapterImageResolution": "Resolución", - "LabelChapterImageResolutionHelp": "La resolución de las imágenes de los capítulos extraídos." + "LabelChapterImageResolutionHelp": "La resolución de las imágenes de los capítulos extraídos.", + "LabelParallelImageEncodingLimitHelp": "Cantidad máxima de codificaciones de imágenes que pueden ejecutarse en paralelo. Establecer esto en 0 elegirá un límite basado en las especificaciones de su sistema.", + "PreferEmbeddedExtrasTitlesOverFileNames": "Prefiere títulos incrustados sobre nombres de archivo para extras", + "PreferEmbeddedExtrasTitlesOverFileNamesHelp": "Los extras a menudo tienen el mismo nombre incrustado que el padre, marque esto para usar títulos incrustados para ellos de todos modos.", + "SaveRecordingNFO": "Guardar la grabación de metadatos de EPG en NFO", + "LabelEnableAudioVbr": "Habilitar la codificación de audio VBR", + "LabelEnableAudioVbrHelp": "La tasa de bits variable ofrece una mejor relación entre calidad y tasa de bits promedio, pero en algunos casos raros puede causar problemas de almacenamiento en búfer y compatibilidad.", + "LabelParallelImageEncodingLimit": "Límite de codificación de imágenes en paralelo", + "ResolutionMatchSource": "Fuente de coincidencia", + "HeaderPerformance": "Rendimiento" } From 2d0a50223f0626f24e204b1aeb7c24de8047c7d2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 23 Apr 2023 03:57:34 +0000 Subject: [PATCH 004/112] Update dependency stylelint to v15.5.0 --- package-lock.json | 34 +++++++++++++++++----------------- package.json | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 56eaa40b01..aca6167c9a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -102,7 +102,7 @@ "sass-loader": "13.2.2", "source-map-loader": "4.0.1", "style-loader": "3.3.2", - "stylelint": "15.4.0", + "stylelint": "15.5.0", "stylelint-config-rational-order": "0.1.2", "stylelint-no-browser-hacks": "1.2.1", "stylelint-order": "6.0.3", @@ -9054,9 +9054,9 @@ } }, "node_modules/html-tags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", - "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "dev": true, "engines": { "node": ">=8" @@ -15450,14 +15450,14 @@ } }, "node_modules/stylelint": { - "version": "15.4.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.4.0.tgz", - "integrity": "sha512-TlOvpG3MbcFwHmK0q2ykhmpKo7Dq892beJit0NPdpyY9b1tFah/hGhqnAz/bRm2PDhDbJLKvjzkEYYBEz7Dxcg==", + "version": "15.5.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.5.0.tgz", + "integrity": "sha512-jyMO3R1QtE5mUS4v40+Gg+sIQBqe7CF1xPslxycDzNVkIBCUD4O+5F1vLPq16VmunUTv4qG9o2rUKLnU5KkVeQ==", "dev": true, "dependencies": { "@csstools/css-parser-algorithms": "^2.1.0", "@csstools/css-tokenizer": "^2.1.0", - "@csstools/media-query-list-parser": "^2.0.1", + "@csstools/media-query-list-parser": "^2.0.2", "@csstools/selector-specificity": "^2.2.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", @@ -15471,7 +15471,7 @@ "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", - "html-tags": "^3.2.0", + "html-tags": "^3.3.1", "ignore": "^5.2.4", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", @@ -26647,9 +26647,9 @@ } }, "html-tags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", - "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "dev": true }, "html-webpack-plugin": { @@ -31325,14 +31325,14 @@ } }, "stylelint": { - "version": "15.4.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.4.0.tgz", - "integrity": "sha512-TlOvpG3MbcFwHmK0q2ykhmpKo7Dq892beJit0NPdpyY9b1tFah/hGhqnAz/bRm2PDhDbJLKvjzkEYYBEz7Dxcg==", + "version": "15.5.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.5.0.tgz", + "integrity": "sha512-jyMO3R1QtE5mUS4v40+Gg+sIQBqe7CF1xPslxycDzNVkIBCUD4O+5F1vLPq16VmunUTv4qG9o2rUKLnU5KkVeQ==", "dev": true, "requires": { "@csstools/css-parser-algorithms": "^2.1.0", "@csstools/css-tokenizer": "^2.1.0", - "@csstools/media-query-list-parser": "^2.0.1", + "@csstools/media-query-list-parser": "^2.0.2", "@csstools/selector-specificity": "^2.2.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", @@ -31346,7 +31346,7 @@ "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", - "html-tags": "^3.2.0", + "html-tags": "^3.3.1", "ignore": "^5.2.4", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", diff --git a/package.json b/package.json index edca125b2e..8f6e80b49a 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "sass-loader": "13.2.2", "source-map-loader": "4.0.1", "style-loader": "3.3.2", - "stylelint": "15.4.0", + "stylelint": "15.5.0", "stylelint-config-rational-order": "0.1.2", "stylelint-no-browser-hacks": "1.2.1", "stylelint-order": "6.0.3", From 3e1a76fe205f6440c91119bd0bf7369d7cb8bf03 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 23 Apr 2023 16:04:23 +0000 Subject: [PATCH 005/112] Update dependency postcss to v8.4.22 --- package-lock.json | 40 +++++++++++++++++++++++++--------------- package.json | 2 +- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index aca6167c9a..12d58bb317 100644 --- a/package-lock.json +++ b/package-lock.json @@ -94,7 +94,7 @@ "html-loader": "4.2.0", "html-webpack-plugin": "5.5.1", "mini-css-extract-plugin": "2.7.5", - "postcss": "8.4.21", + "postcss": "8.4.22", "postcss-loader": "7.2.4", "postcss-preset-env": "8.3.1", "postcss-scss": "4.0.6", @@ -11042,10 +11042,16 @@ "optional": true }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -11887,9 +11893,9 @@ } }, "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.22.tgz", + "integrity": "sha512-XseknLAfRHzVWjCEtdviapiBtfLdgyzExD50Rg2ePaucEesyh8Wv4VPdW0nbyDa1ydbrAxV19jvMT4+LFmcNUA==", "dev": true, "funding": [ { @@ -11899,10 +11905,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -28120,9 +28130,9 @@ "optional": true }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "dev": true }, "nanomatch": { @@ -28767,12 +28777,12 @@ "dev": true }, "postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.22.tgz", + "integrity": "sha512-XseknLAfRHzVWjCEtdviapiBtfLdgyzExD50Rg2ePaucEesyh8Wv4VPdW0nbyDa1ydbrAxV19jvMT4+LFmcNUA==", "dev": true, "requires": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } diff --git a/package.json b/package.json index 8f6e80b49a..c85ccea6da 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "html-loader": "4.2.0", "html-webpack-plugin": "5.5.1", "mini-css-extract-plugin": "2.7.5", - "postcss": "8.4.21", + "postcss": "8.4.22", "postcss-loader": "7.2.4", "postcss-preset-env": "8.3.1", "postcss-scss": "4.0.6", From 8008b8b6f23b456e2017d2431c2b79ce6d6b96a1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 10:58:49 +0000 Subject: [PATCH 006/112] Update dependency postcss-preset-env to v8.3.2 --- package-lock.json | 32 +++++++++++++++++++------------- package.json | 2 +- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 12d58bb317..d25c9d2dac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -96,7 +96,7 @@ "mini-css-extract-plugin": "2.7.5", "postcss": "8.4.22", "postcss-loader": "7.2.4", - "postcss-preset-env": "8.3.1", + "postcss-preset-env": "8.3.2", "postcss-scss": "4.0.6", "sass": "1.62.0", "sass-loader": "13.2.2", @@ -13154,16 +13154,26 @@ } }, "node_modules/postcss-preset-env": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-8.3.1.tgz", - "integrity": "sha512-k3Y8BXbVLBAufrla3CNmQJhMS1iRuT9LFlysYvzs1rU5E78+ShX2u0EUL6KpMi0pDJO3wZcuVYSR8cgukfoRtg==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-8.3.2.tgz", + "integrity": "sha512-VSAOsfxTXzO/gX5QljC8x8hN3ABbD9iqqLgqHqohBdNI5FhJptwpl96kpu+kYvvzK7BWwaHYou0IeYrp+NqmcQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { "@csstools/postcss-cascade-layers": "^3.0.1", "@csstools/postcss-color-function": "^2.2.1", "@csstools/postcss-color-mix-function": "^1.0.1", "@csstools/postcss-font-format-keywords": "^2.0.2", - "@csstools/postcss-gradients-interpolation-method": "^3.0.3", + "@csstools/postcss-gradients-interpolation-method": "^3.0.4", "@csstools/postcss-hwb-function": "^2.2.1", "@csstools/postcss-ic-unit": "^2.0.2", "@csstools/postcss-is-pseudo-class": "^3.2.0", @@ -13218,10 +13228,6 @@ "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } @@ -29575,16 +29581,16 @@ } }, "postcss-preset-env": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-8.3.1.tgz", - "integrity": "sha512-k3Y8BXbVLBAufrla3CNmQJhMS1iRuT9LFlysYvzs1rU5E78+ShX2u0EUL6KpMi0pDJO3wZcuVYSR8cgukfoRtg==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-8.3.2.tgz", + "integrity": "sha512-VSAOsfxTXzO/gX5QljC8x8hN3ABbD9iqqLgqHqohBdNI5FhJptwpl96kpu+kYvvzK7BWwaHYou0IeYrp+NqmcQ==", "dev": true, "requires": { "@csstools/postcss-cascade-layers": "^3.0.1", "@csstools/postcss-color-function": "^2.2.1", "@csstools/postcss-color-mix-function": "^1.0.1", "@csstools/postcss-font-format-keywords": "^2.0.2", - "@csstools/postcss-gradients-interpolation-method": "^3.0.3", + "@csstools/postcss-gradients-interpolation-method": "^3.0.4", "@csstools/postcss-hwb-function": "^2.2.1", "@csstools/postcss-ic-unit": "^2.0.2", "@csstools/postcss-is-pseudo-class": "^3.2.0", diff --git a/package.json b/package.json index c85ccea6da..f5da6c8dde 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "mini-css-extract-plugin": "2.7.5", "postcss": "8.4.22", "postcss-loader": "7.2.4", - "postcss-preset-env": "8.3.1", + "postcss-preset-env": "8.3.2", "postcss-scss": "4.0.6", "sass": "1.62.0", "sass-loader": "13.2.2", From 257b44ba1330e456b4d69d63e66c06f79cd96678 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 11:40:16 +0000 Subject: [PATCH 007/112] Update dependency postcss to v8.4.23 --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index d25c9d2dac..bd05653ad1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -94,7 +94,7 @@ "html-loader": "4.2.0", "html-webpack-plugin": "5.5.1", "mini-css-extract-plugin": "2.7.5", - "postcss": "8.4.22", + "postcss": "8.4.23", "postcss-loader": "7.2.4", "postcss-preset-env": "8.3.2", "postcss-scss": "4.0.6", @@ -11893,9 +11893,9 @@ } }, "node_modules/postcss": { - "version": "8.4.22", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.22.tgz", - "integrity": "sha512-XseknLAfRHzVWjCEtdviapiBtfLdgyzExD50Rg2ePaucEesyh8Wv4VPdW0nbyDa1ydbrAxV19jvMT4+LFmcNUA==", + "version": "8.4.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", + "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", "dev": true, "funding": [ { @@ -28783,9 +28783,9 @@ "dev": true }, "postcss": { - "version": "8.4.22", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.22.tgz", - "integrity": "sha512-XseknLAfRHzVWjCEtdviapiBtfLdgyzExD50Rg2ePaucEesyh8Wv4VPdW0nbyDa1ydbrAxV19jvMT4+LFmcNUA==", + "version": "8.4.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", + "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", "dev": true, "requires": { "nanoid": "^3.3.6", diff --git a/package.json b/package.json index f5da6c8dde..6e1baacb00 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "html-loader": "4.2.0", "html-webpack-plugin": "5.5.1", "mini-css-extract-plugin": "2.7.5", - "postcss": "8.4.22", + "postcss": "8.4.23", "postcss-loader": "7.2.4", "postcss-preset-env": "8.3.2", "postcss-scss": "4.0.6", From 4fe6bb5b42827b41460815f266c1857d062d1f20 Mon Sep 17 00:00:00 2001 From: robert-hamilton36 Date: Mon, 27 Mar 2023 09:36:09 +1300 Subject: [PATCH 008/112] Add external startMultiSelect function --- src/components/multiSelect/multiSelect.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/multiSelect/multiSelect.js b/src/components/multiSelect/multiSelect.js index 142a31a5d7..989a421cdb 100644 --- a/src/components/multiSelect/multiSelect.js +++ b/src/components/multiSelect/multiSelect.js @@ -564,3 +564,6 @@ export default function (options) { }; } +export const startMultiSelect = (card) => { + showSelections(card); +}; From 447b6f5582521cbc2d2696f3407bbbc640f45b17 Mon Sep 17 00:00:00 2001 From: robert-hamilton36 Date: Mon, 27 Mar 2023 09:38:32 +1300 Subject: [PATCH 009/112] Add select option --- src/components/itemContextMenu.js | 17 +++++++++++++++++ src/strings/en-us.json | 1 + 2 files changed, 18 insertions(+) diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index a90effb336..28dc31226c 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -1,5 +1,6 @@ import browser from '../scripts/browser'; import { copy } from '../scripts/clipboard'; +import dom from '../scripts/dom'; import globalize from '../scripts/globalize'; import actionsheet from './actionSheet/actionSheet'; import { appHost } from './apphost'; @@ -115,6 +116,16 @@ export function getCommands(options) { } } + // Multiselect is currrently only ran on long clicks of card components + // This disables Select on any context menu not originating from a card i.e songs + if (options.positionTo && (dom.parentWithClass(options.positionTo, 'card') !== null)) { + commands.push({ + name: globalize.translate('Select'), + id: 'multiSelect', + icon: 'library_add_check' + }); + } + if ((item.Type === 'Timer') && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) { commands.push({ name: globalize.translate('CancelRecording'), @@ -432,6 +443,12 @@ function executeCommand(item, id, options) { itemMediaInfo.show(itemId, serverId).then(getResolveFunction(resolve, id), getResolveFunction(resolve, id)); }); break; + case 'multiSelect': + import('./multiSelect/multiSelect').then(({ startMultiSelect: startMultiSelect }) => { + const card = dom.parentWithClass(options.positionTo, 'card'); + startMultiSelect(card); + }); + break; case 'refresh': refresh(apiClient, item); getResolveFunction(resolve, id)(); diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 44e82f2e5c..e2b39af691 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1685,6 +1685,7 @@ "Interview": "Interview", "Scene": "Scene", "Sample": "Sample", + "Select": "Select", "ThemeSong": "Theme Song", "ThemeVideo": "Theme Video", "EnableEnhancedNvdecDecoderHelp": "Experimental NVDEC implementation, do not enable this option unless you encounter decoding errors.", From a83e3b121b0dec3db3c770193a584005c10c9000 Mon Sep 17 00:00:00 2001 From: robert-hamilton36 Date: Mon, 24 Apr 2023 11:44:56 +1200 Subject: [PATCH 010/112] Remove Select option from tvs --- src/components/itemContextMenu.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index 28dc31226c..1e33d66af7 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -99,6 +99,16 @@ export function getCommands(options) { } if (!browser.tv) { + // Multiselect is currrently only ran on long clicks of card components + // This disables Select on any context menu not originating from a card i.e songs + if (options.positionTo && (dom.parentWithClass(options.positionTo, 'card') !== null)) { + commands.push({ + name: globalize.translate('Select'), + id: 'multiSelect', + icon: 'library_add_check' + }); + } + if (itemHelper.supportsAddingToCollection(item) && options.EnableCollectionManagement) { commands.push({ name: globalize.translate('AddToCollection'), @@ -116,16 +126,6 @@ export function getCommands(options) { } } - // Multiselect is currrently only ran on long clicks of card components - // This disables Select on any context menu not originating from a card i.e songs - if (options.positionTo && (dom.parentWithClass(options.positionTo, 'card') !== null)) { - commands.push({ - name: globalize.translate('Select'), - id: 'multiSelect', - icon: 'library_add_check' - }); - } - if ((item.Type === 'Timer') && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) { commands.push({ name: globalize.translate('CancelRecording'), From 591f51fbf56bc74de95481468240f49687fd88c0 Mon Sep 17 00:00:00 2001 From: sleepycatcoding Date: Mon, 24 Apr 2023 13:42:20 +0000 Subject: [PATCH 011/112] Translated using Weblate (Estonian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/et/ --- src/strings/et.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/strings/et.json b/src/strings/et.json index c978ebe267..62442bdd45 100644 --- a/src/strings/et.json +++ b/src/strings/et.json @@ -1647,5 +1647,10 @@ "BehindTheScenes": "Kulisside taga", "DeletedScene": "Kustutatud stseen", "Interview": "Intervjuu", - "EnableSplashScreen": "Luba käivituskuva" + "EnableSplashScreen": "Luba käivituskuva", + "DownloadAll": "Lae kõik alla", + "Experimental": "Eksperimentaalne", + "HeaderRecordingMetadataSaving": "Salvestise metaandmed", + "HeaderPerformance": "Jõudlus", + "IgnoreDts": "Ignoreeri DTS-i (dekodeerimise ajatempel)" } From 9d5030d97e7f8eb09d458ca61e0a95bf7d58a25a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 15:45:32 +0000 Subject: [PATCH 012/112] Update dependency swiper to v9 --- package-lock.json | 33 +++++++-------------------------- package.json | 2 +- 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index bd05653ad1..99b4d138b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,7 @@ "resize-observer-polyfill": "1.5.1", "screenfull": "6.0.2", "sortablejs": "1.15.0", - "swiper": "8.4.7", + "swiper": "9.2.3", "webcomponents.js": "0.7.24", "whatwg-fetch": "3.6.2", "workbox-core": "6.5.4", @@ -6309,14 +6309,6 @@ } ] }, - "node_modules/dom7": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/dom7/-/dom7-4.0.4.tgz", - "integrity": "sha512-DSSgBzQ4rJWQp1u6o+3FVwMNnT5bzQbMb+o31TjYYeRi05uAcpF8koxdfzeoe5ElzPmua7W7N28YJhF7iEKqIw==", - "dependencies": { - "ssr-window": "^4.0.0" - } - }, "node_modules/domelementtype": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", @@ -18157,9 +18149,9 @@ } }, "node_modules/swiper": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/swiper/-/swiper-8.4.7.tgz", - "integrity": "sha512-VwO/KU3i9IV2Sf+W2NqyzwWob4yX9Qdedq6vBtS0rFqJ6Fa5iLUJwxQkuD4I38w0WDJwmFl8ojkdcRFPHWD+2g==", + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.2.3.tgz", + "integrity": "sha512-hxqcjIsYPP1fv+KIXPqGywl6ik8RBp0y0i9+TOIh55ca6SpZ5FrgNJ4QXPhsl6mlSBMEYPmh5zOKtZpI8zpWeQ==", "funding": [ { "type": "patreon", @@ -18170,9 +18162,7 @@ "url": "http://opencollective.com/swiper" } ], - "hasInstallScript": true, "dependencies": { - "dom7": "^4.0.4", "ssr-window": "^4.0.2" }, "engines": { @@ -24557,14 +24547,6 @@ } } }, - "dom7": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/dom7/-/dom7-4.0.4.tgz", - "integrity": "sha512-DSSgBzQ4rJWQp1u6o+3FVwMNnT5bzQbMb+o31TjYYeRi05uAcpF8koxdfzeoe5ElzPmua7W7N28YJhF7iEKqIw==", - "requires": { - "ssr-window": "^4.0.0" - } - }, "domelementtype": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", @@ -33451,11 +33433,10 @@ } }, "swiper": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/swiper/-/swiper-8.4.7.tgz", - "integrity": "sha512-VwO/KU3i9IV2Sf+W2NqyzwWob4yX9Qdedq6vBtS0rFqJ6Fa5iLUJwxQkuD4I38w0WDJwmFl8ojkdcRFPHWD+2g==", + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.2.3.tgz", + "integrity": "sha512-hxqcjIsYPP1fv+KIXPqGywl6ik8RBp0y0i9+TOIh55ca6SpZ5FrgNJ4QXPhsl6mlSBMEYPmh5zOKtZpI8zpWeQ==", "requires": { - "dom7": "^4.0.4", "ssr-window": "^4.0.2" } }, diff --git a/package.json b/package.json index 6e1baacb00..5ecdfd22a3 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "resize-observer-polyfill": "1.5.1", "screenfull": "6.0.2", "sortablejs": "1.15.0", - "swiper": "8.4.7", + "swiper": "9.2.3", "webcomponents.js": "0.7.24", "whatwg-fetch": "3.6.2", "workbox-core": "6.5.4", From c6bcee3b26daab93c87383d8115a88db16027d83 Mon Sep 17 00:00:00 2001 From: Daan Vankerkom Date: Wed, 9 Nov 2022 00:45:53 +0100 Subject: [PATCH 013/112] Reduce TV card scale size Reduced the transform scale from 10% to 7% to increase readability and reduce cognitive overload. --- src/components/cardbuilder/card.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/cardbuilder/card.scss b/src/components/cardbuilder/card.scss index e43b488dbe..28f55abe2d 100644 --- a/src/components/cardbuilder/card.scss +++ b/src/components/cardbuilder/card.scss @@ -114,7 +114,7 @@ button::-moz-focus-inner { } .card.show-animation:focus > .cardBox { - transform: scale(1.18, 1.18); + transform: scale(1.07, 1.07); } .cardBox-bottompadded { From 11b83556257694b95f31a33c3f1930d424b68b39 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 21:35:52 +0000 Subject: [PATCH 014/112] Update Linters to v5.59.0 --- package-lock.json | 164 +++++++++++++++++++++++----------------------- package.json | 4 +- 2 files changed, 84 insertions(+), 84 deletions(-) diff --git a/package-lock.json b/package-lock.json index bd05653ad1..8513ac3a67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,8 +68,8 @@ "@types/lodash-es": "4.17.7", "@types/react": "17.0.58", "@types/react-dom": "17.0.19", - "@typescript-eslint/eslint-plugin": "5.58.0", - "@typescript-eslint/parser": "5.58.0", + "@typescript-eslint/eslint-plugin": "5.59.0", + "@typescript-eslint/parser": "5.59.0", "@uupaa/dynamic-import-polyfill": "1.0.2", "autoprefixer": "10.4.14", "babel-loader": "9.1.2", @@ -3410,15 +3410,15 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.58.0.tgz", - "integrity": "sha512-vxHvLhH0qgBd3/tW6/VccptSfc8FxPQIkmNTVLWcCOVqSBvqpnKkBTYrhcGlXfSnd78azwe+PsjYFj0X34/njA==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.0.tgz", + "integrity": "sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.58.0", - "@typescript-eslint/type-utils": "5.58.0", - "@typescript-eslint/utils": "5.58.0", + "@typescript-eslint/scope-manager": "5.59.0", + "@typescript-eslint/type-utils": "5.59.0", + "@typescript-eslint/utils": "5.59.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -3459,14 +3459,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.58.0.tgz", - "integrity": "sha512-ixaM3gRtlfrKzP8N6lRhBbjTow1t6ztfBvQNGuRM8qH1bjFFXIJ35XY+FC0RRBKn3C6cT+7VW1y8tNm7DwPHDQ==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.0.tgz", + "integrity": "sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.58.0", - "@typescript-eslint/types": "5.58.0", - "@typescript-eslint/typescript-estree": "5.58.0", + "@typescript-eslint/scope-manager": "5.59.0", + "@typescript-eslint/types": "5.59.0", + "@typescript-eslint/typescript-estree": "5.59.0", "debug": "^4.3.4" }, "engines": { @@ -3486,13 +3486,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.58.0.tgz", - "integrity": "sha512-b+w8ypN5CFvrXWQb9Ow9T4/6LC2MikNf1viLkYTiTbkQl46CnR69w7lajz1icW0TBsYmlpg+mRzFJ4LEJ8X9NA==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.0.tgz", + "integrity": "sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.58.0", - "@typescript-eslint/visitor-keys": "5.58.0" + "@typescript-eslint/types": "5.59.0", + "@typescript-eslint/visitor-keys": "5.59.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3503,13 +3503,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.58.0.tgz", - "integrity": "sha512-FF5vP/SKAFJ+LmR9PENql7fQVVgGDOS+dq3j+cKl9iW/9VuZC/8CFmzIP0DLKXfWKpRHawJiG70rVH+xZZbp8w==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.0.tgz", + "integrity": "sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.58.0", - "@typescript-eslint/utils": "5.58.0", + "@typescript-eslint/typescript-estree": "5.59.0", + "@typescript-eslint/utils": "5.59.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -3530,9 +3530,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.58.0.tgz", - "integrity": "sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.0.tgz", + "integrity": "sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3543,13 +3543,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.58.0.tgz", - "integrity": "sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.0.tgz", + "integrity": "sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.58.0", - "@typescript-eslint/visitor-keys": "5.58.0", + "@typescript-eslint/types": "5.59.0", + "@typescript-eslint/visitor-keys": "5.59.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3614,17 +3614,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.58.0.tgz", - "integrity": "sha512-gAmLOTFXMXOC+zP1fsqm3VceKSBQJNzV385Ok3+yzlavNHZoedajjS4UyS21gabJYcobuigQPs/z71A9MdJFqQ==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.0.tgz", + "integrity": "sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.58.0", - "@typescript-eslint/types": "5.58.0", - "@typescript-eslint/typescript-estree": "5.58.0", + "@typescript-eslint/scope-manager": "5.59.0", + "@typescript-eslint/types": "5.59.0", + "@typescript-eslint/typescript-estree": "5.59.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -3655,12 +3655,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.58.0.tgz", - "integrity": "sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.0.tgz", + "integrity": "sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/types": "5.59.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -22413,15 +22413,15 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.58.0.tgz", - "integrity": "sha512-vxHvLhH0qgBd3/tW6/VccptSfc8FxPQIkmNTVLWcCOVqSBvqpnKkBTYrhcGlXfSnd78azwe+PsjYFj0X34/njA==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.0.tgz", + "integrity": "sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.58.0", - "@typescript-eslint/type-utils": "5.58.0", - "@typescript-eslint/utils": "5.58.0", + "@typescript-eslint/scope-manager": "5.59.0", + "@typescript-eslint/type-utils": "5.59.0", + "@typescript-eslint/utils": "5.59.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -22442,53 +22442,53 @@ } }, "@typescript-eslint/parser": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.58.0.tgz", - "integrity": "sha512-ixaM3gRtlfrKzP8N6lRhBbjTow1t6ztfBvQNGuRM8qH1bjFFXIJ35XY+FC0RRBKn3C6cT+7VW1y8tNm7DwPHDQ==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.0.tgz", + "integrity": "sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.58.0", - "@typescript-eslint/types": "5.58.0", - "@typescript-eslint/typescript-estree": "5.58.0", + "@typescript-eslint/scope-manager": "5.59.0", + "@typescript-eslint/types": "5.59.0", + "@typescript-eslint/typescript-estree": "5.59.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.58.0.tgz", - "integrity": "sha512-b+w8ypN5CFvrXWQb9Ow9T4/6LC2MikNf1viLkYTiTbkQl46CnR69w7lajz1icW0TBsYmlpg+mRzFJ4LEJ8X9NA==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.0.tgz", + "integrity": "sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.58.0", - "@typescript-eslint/visitor-keys": "5.58.0" + "@typescript-eslint/types": "5.59.0", + "@typescript-eslint/visitor-keys": "5.59.0" } }, "@typescript-eslint/type-utils": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.58.0.tgz", - "integrity": "sha512-FF5vP/SKAFJ+LmR9PENql7fQVVgGDOS+dq3j+cKl9iW/9VuZC/8CFmzIP0DLKXfWKpRHawJiG70rVH+xZZbp8w==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.0.tgz", + "integrity": "sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.58.0", - "@typescript-eslint/utils": "5.58.0", + "@typescript-eslint/typescript-estree": "5.59.0", + "@typescript-eslint/utils": "5.59.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.58.0.tgz", - "integrity": "sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.0.tgz", + "integrity": "sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.58.0.tgz", - "integrity": "sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.0.tgz", + "integrity": "sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.58.0", - "@typescript-eslint/visitor-keys": "5.58.0", + "@typescript-eslint/types": "5.59.0", + "@typescript-eslint/visitor-keys": "5.59.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -22528,17 +22528,17 @@ } }, "@typescript-eslint/utils": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.58.0.tgz", - "integrity": "sha512-gAmLOTFXMXOC+zP1fsqm3VceKSBQJNzV385Ok3+yzlavNHZoedajjS4UyS21gabJYcobuigQPs/z71A9MdJFqQ==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.0.tgz", + "integrity": "sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.58.0", - "@typescript-eslint/types": "5.58.0", - "@typescript-eslint/typescript-estree": "5.58.0", + "@typescript-eslint/scope-manager": "5.59.0", + "@typescript-eslint/types": "5.59.0", + "@typescript-eslint/typescript-estree": "5.59.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -22555,12 +22555,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.58.0.tgz", - "integrity": "sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==", + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.0.tgz", + "integrity": "sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/types": "5.59.0", "eslint-visitor-keys": "^3.3.0" }, "dependencies": { diff --git a/package.json b/package.json index 6e1baacb00..f5a6951c9b 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "@types/lodash-es": "4.17.7", "@types/react": "17.0.58", "@types/react-dom": "17.0.19", - "@typescript-eslint/eslint-plugin": "5.58.0", - "@typescript-eslint/parser": "5.58.0", + "@typescript-eslint/eslint-plugin": "5.59.0", + "@typescript-eslint/parser": "5.59.0", "@uupaa/dynamic-import-polyfill": "1.0.2", "autoprefixer": "10.4.14", "babel-loader": "9.1.2", From 70d2eb0e83b50d7395f5083442009801e9d1f4fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Kucharczyk?= Date: Mon, 24 Apr 2023 18:37:09 +0000 Subject: [PATCH 015/112] Translated using Weblate (Czech) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/cs/ --- src/strings/cs.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/strings/cs.json b/src/strings/cs.json index 9f68e61494..9a186bda61 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -1721,5 +1721,6 @@ "LabelParallelImageEncodingLimit": "Počet paralelních kódování obrázků", "LabelParallelImageEncodingLimitHelp": "Maximální počet kódování obrázků, které mohou běžet zároveň. Nastavením na 0 bude limit nastaven dle parametrů systému.", "LabelEnableAudioVbr": "Povolit kódování zvuku VBR", - "LabelEnableAudioVbrHelp": "Proměnlivý bitový tok (VBR) nabízí lepší poměr mezi kvalitou a průměrným bitovým tokem, ale někdy může způsobit dodatečné načítání či problémy s kompatibilitou." + "LabelEnableAudioVbrHelp": "Proměnlivý bitový tok (VBR) nabízí lepší poměr mezi kvalitou a průměrným bitovým tokem, ale někdy může způsobit dodatečné načítání či problémy s kompatibilitou.", + "Select": "Vybrat" } From 23d122698414e20e1b1193a3f742030b94b4010a Mon Sep 17 00:00:00 2001 From: NeonCube Date: Mon, 24 Apr 2023 20:05:01 +0000 Subject: [PATCH 016/112] Translated using Weblate (Persian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fa/ --- src/strings/fa.json | 49 +++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/strings/fa.json b/src/strings/fa.json index 257efea1cb..a20a849ed0 100644 --- a/src/strings/fa.json +++ b/src/strings/fa.json @@ -825,21 +825,21 @@ "LabelImageFetchersHelp": "فعالسازی و رتبه بندی دریافت کننده های تصاویر شما به ترتیب الویت.", "LabelInNetworkSignInWithEasyPassword": "فعالسازی ورود با پین کد آسان من داخل شبکه", "Off": "خاموش", - "OneChannel": "", + "OneChannel": "یک کانال", "OnlyForcedSubtitles": "", "OnlyForcedSubtitlesHelp": "", "OnlyImageFormats": "", "Option3D": "3D", "OptionAdminUsers": "مدیران سیستم", - "OptionAllUsers": "", + "OptionAllUsers": "همه کاربران", "OptionAllowAudioPlaybackTranscoding": "", "OptionForceRemoteSourceTranscoding": "", - "OptionAllowBrowsingLiveTv": "", + "OptionAllowBrowsingLiveTv": "اجازه دسترسی به تلویزیون زنده", "OptionAllowContentDownloading": "Allow media downloading and syncing", "OptionAllowLinkSharing": "", "OptionAllowLinkSharingHelp": "", "OptionAllowManageLiveTv": "", - "OptionAllowMediaPlayback": "", + "OptionAllowMediaPlayback": "اجازه پخش محتوا", "OptionAllowMediaPlaybackTranscodingHelp": "محدود کردن دسترسی به رمزگذاری ممکن است به دلیل پشتیبانی نکردن از قالب های رسانه ای ، منجر به خرابی پخش در مشتریان شود.", "OptionAllowRemoteControlOthers": "", "OptionAllowRemoteSharedDevices": "", @@ -1137,7 +1137,7 @@ "LanNetworksHelp": "ویرگول لیست آدرس \"IP\" ها یا \"IP/زیر شبکه\" های وارد شده برای شبکه هایی که شبکه محلی در نظر گرفته میشوند برای زمانی که محدودیت پهنای باند اعمال میشود را جدا کرده است. اگر تنظیم کنید، تمام آدرس IP های دیگر روی شبکه خارجی در نظر گرفته میشوند و مشمول محدودیت های پهنای باند خارجی میشود. در صورت خالی بودن، تنها زیر شبکه سرور در شبکه محلی در نظر گرفته می شود.", "LearnHowYouCanContribute": "یاد بگیرید چگونه می‌توانید مشارکت کنید.", "LeaveBlankToNotSetAPassword": "می توانید این خانه را خالی بگذارید تا کلمه عبوری تنظیم نشود.", - "List": "", + "List": "لیست", "Live": "پخش زنده", "LiveBroadcasts": "پخش زنده", "LiveTV": "پخش تلویزیون زنده", @@ -1194,7 +1194,7 @@ "MessageFileReadError": "در خواندن فایل خطایی وجود داشت. لطفا دوباره تلاش کنید.", "MessageForgotPasswordFileCreated": "", "MessageForgotPasswordInNetworkRequired": "", - "MessageImageFileTypeAllowed": "", + "MessageImageFileTypeAllowed": "فقط فایل های JPEG و PNG پشتیبانی می شوند.", "MessageImageTypeNotSelected": "", "MessageLeaveEmptyToInherit": "", "MessageNoCollectionsAvailable": "", @@ -1257,28 +1257,28 @@ "MessageYouHaveVersionInstalled": "", "MessageSyncPlayEnabled": "فعال شد SyncPlay.", "MessageSyncPlayDisabled": "SyncPlay غیرفعال شد.", - "MessageSyncPlayUserJoined": "", - "MessageSyncPlayUserLeft": "", + "MessageSyncPlayUserJoined": "{0} به گروه پیوست.", + "MessageSyncPlayUserLeft": "{0} از گروه خارج شد.", "MessageSyncPlayGroupWait": "{0} در حال بافر است …", - "MessageSyncPlayNoGroupsAvailable": "", + "MessageSyncPlayNoGroupsAvailable": "هیچ گروهی در دسترس نیست. اول پخش چیزی را شروع کنید.", "MessageSyncPlayPlaybackPermissionRequired": "", "MessageSyncPlayGroupDoesNotExist": "", "MessageSyncPlayCreateGroupDenied": "", "MessageSyncPlayJoinGroupDenied": "عضو شدن در گروه امکان پذیر نیست.", - "MessageSyncPlayLibraryAccessDenied": "", - "MessageSyncPlayErrorAccessingGroups": "", + "MessageSyncPlayLibraryAccessDenied": "دسترسی به این محتوا محدود شده است.", + "MessageSyncPlayErrorAccessingGroups": "خطایی هنگام دسترسی به لیست گروه ها رخ داد.", "MessageSyncPlayErrorNoActivePlayer": "", "MessageSyncPlayErrorMissingSession": "", "MessageSyncPlayErrorMedia": "", - "Metadata": "", - "MetadataManager": "", + "Metadata": "فراداده", + "MetadataManager": "مدیر فراداده", "MetadataSettingChangeHelp": "تغییر تنظیمات ابرداده بر محتوای جدید اضافه شده در آینده تأثیر می گذارد. برای تازه سازی محتوای موجود ، صفحه جزئیات را باز کنید و روی دکمه 'تازه سازی' کلیک کنید، یا با استفاده از 'مدیریت ابرداده' تازه سازی های عمده را انجام دهید.", - "MinutesAfter": "", + "MinutesAfter": "دقیقه بعد", "MinutesBefore": "", "Mobile": "دستگاه همراه", "Monday": "دوشنبه", - "MoreFromValue": "", - "MoreMediaInfo": "", + "MoreFromValue": "بیشتر از {0}", + "MoreMediaInfo": "اطلاعات محتوا", "MoveLeft": "", "MoveRight": "", "MovieLibraryHelp": "", @@ -1286,10 +1286,10 @@ "NewCollectionHelp": "", "NoCreatedLibraries": "", "NoNewDevicesFound": "", - "NoSubtitlesHelp": "", + "NoSubtitlesHelp": "زیرنویس ها به صورت پیش فرض بارگذاری نخواهند شد. آنها را هنوز میتوان هنگام پخش روشن کرد.", "None": "هیچ یک", "Normal": "طبیعی", - "NumLocationsValue": "", + "NumLocationsValue": "{0} پوشه", "ServerRestartNeededAfterPluginInstall": "بعد از نصب یک افزونه ، Jellyfin باید دوباره راه اندازی شود.", "ServerUpdateNeeded": "این سرور باید به روز شود. برای بارگیری آخرین نسخه ، لطفاً به {0} مراجعه کنید", "Settings": "تنظیمات", @@ -1590,5 +1590,16 @@ "IgnoreDts": "نادیده‌گرفتن DTS (decoding timestamp)", "HomeVideosPhotos": "ویدیو ها و تصاویر خانگی", "Experimental": "آزمایشی", - "DownloadAll": "دانلود همه" + "DownloadAll": "دانلود همه", + "Bold": "درشت", + "LabelDummyChapterDuration": "وقفه", + "LabelChapterImageResolution": "وضوح تصویر", + "LabelTextWeight": "وزن متن", + "MessageSent": "پیام ارسال شد.", + "MessageNoItemsAvailable": "هیچ آیتمی در حال حاضر در دسترس نیست.", + "MessageNoFavoritesAvailable": "هیچ مورد علاقه ای در حال حاضر در دسترس نیست.", + "HeaderPerformance": "کارایی", + "IgnoreDtsHelp": "غیر فعال کردن این گزینه ممکن است برخی اشکالات را رفع کند، مثل نبودن صدا بر روی کانال هایی که جریان صدا و تصویر جداگانه دارند.", + "LabelDummyChapterDurationHelp": "وقفه استخراج تصاویر فصل به ثانیه.", + "HeaderDummyChapter": "تصاویر فصل" } From 18cd64ca0b7b00cac7dc2a1d39bb28cc4146035c Mon Sep 17 00:00:00 2001 From: stanol Date: Mon, 24 Apr 2023 20:36:54 +0000 Subject: [PATCH 017/112] Translated using Weblate (Ukrainian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/ --- src/strings/uk.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/strings/uk.json b/src/strings/uk.json index 0c8a450847..2e155e2a81 100644 --- a/src/strings/uk.json +++ b/src/strings/uk.json @@ -1718,5 +1718,6 @@ "LabelParallelImageEncodingLimit": "Обмеження на паралельне кодування зображень", "LabelParallelImageEncodingLimitHelp": "Максимальна кількість кодувань зображень, які дозволено запускати паралельно. Якщо встановити значення 0, буде обрано обмеження на основі характеристик вашої системи.", "LabelEnableAudioVbrHelp": "Змінний бітрейт забезпечує краще співвідношення якості до середнього бітрейту, але в деяких рідкісних випадках може спричинити проблеми з буферизацією та сумісністю.", - "LabelEnableAudioVbr": "Увімкнути VBR" + "LabelEnableAudioVbr": "Увімкнути VBR", + "Select": "Вибрати" } From eb15f97955fb2a9ee860d9dba46bb49e348b37de Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Tue, 14 Mar 2023 20:37:20 +0800 Subject: [PATCH 018/112] Drop progressive transcoding in web client Signed-off-by: nyanmisaka --- src/scripts/browserDeviceProfile.js | 46 ----------------------------- 1 file changed, 46 deletions(-) diff --git a/src/scripts/browserDeviceProfile.js b/src/scripts/browserDeviceProfile.js index c603d475d4..f99e0ab343 100644 --- a/src/scripts/browserDeviceProfile.js +++ b/src/scripts/browserDeviceProfile.js @@ -686,30 +686,6 @@ export default function (options) { }); }); - if (canPlayMkv && !browser.tizen && options.enableMkvProgressive !== false) { - profile.TranscodingProfiles.push({ - Container: 'mkv', - Type: 'Video', - AudioCodec: videoAudioCodecs.join(','), - VideoCodec: mp4VideoCodecs.join(','), - Context: 'Streaming', - MaxAudioChannels: physicalAudioChannels.toString(), - CopyTimestamps: true - }); - } - - if (canPlayMkv) { - profile.TranscodingProfiles.push({ - Container: 'mkv', - Type: 'Video', - AudioCodec: videoAudioCodecs.join(','), - VideoCodec: mp4VideoCodecs.join(','), - Context: 'Static', - MaxAudioChannels: physicalAudioChannels.toString(), - CopyTimestamps: true - }); - } - if (canPlayHls() && options.enableHls !== false) { if (hlsInFmp4VideoCodecs.length && hlsInFmp4VideoAudioCodecs.length && userSettings.preferFmp4HlsContainer() && (browser.safari || browser.tizen || browser.web0s)) { profile.TranscodingProfiles.push({ @@ -740,28 +716,6 @@ export default function (options) { } } - // Progressive mp4 transcoding - if (mp4VideoCodecs.length && videoAudioCodecs.length) { - profile.TranscodingProfiles.push({ - Container: 'mp4', - Type: 'Video', - AudioCodec: videoAudioCodecs.join(','), - VideoCodec: mp4VideoCodecs.join(','), - Context: 'Streaming', - Protocol: 'http', - MaxAudioChannels: physicalAudioChannels.toString() - }); - } - - profile.TranscodingProfiles.push({ - Container: 'mp4', - Type: 'Video', - AudioCodec: videoAudioCodecs.join(','), - VideoCodec: 'h264', - Context: 'Static', - Protocol: 'http' - }); - profile.ContainerProfiles = []; profile.CodecProfiles = []; From f93bfdec4208c1fd3586ccb9b9030822197bc04e Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Fri, 14 Apr 2023 18:50:24 +0800 Subject: [PATCH 019/112] Add tonemap mode options Signed-off-by: nyanmisaka --- src/controllers/dashboard/encodingsettings.html | 12 ++++++++---- src/controllers/dashboard/encodingsettings.js | 4 ++-- src/strings/en-us.json | 4 +++- src/strings/zh-cn.json | 4 +++- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/controllers/dashboard/encodingsettings.html b/src/controllers/dashboard/encodingsettings.html index 759c19d7d4..3d4ed0b99b 100644 --- a/src/controllers/dashboard/encodingsettings.html +++ b/src/controllers/dashboard/encodingsettings.html @@ -167,6 +167,14 @@ ${TonemappingAlgorithmHelp} +
+ +
${TonemappingModeHelp}
+
${LabelTonemappingDesatHelp}
-
- -
${LabelTonemappingThresholdHelp}
-
${LabelTonemappingPeakHelp}
diff --git a/src/controllers/dashboard/encodingsettings.js b/src/controllers/dashboard/encodingsettings.js index 38ca954d0e..2ae00b3dec 100644 --- a/src/controllers/dashboard/encodingsettings.js +++ b/src/controllers/dashboard/encodingsettings.js @@ -32,9 +32,9 @@ function loadPage(page, config, systemInfo) { page.querySelector('#chkTonemapping').checked = config.EnableTonemapping; page.querySelector('#chkVppTonemapping').checked = config.EnableVppTonemapping; page.querySelector('#selectTonemappingAlgorithm').value = config.TonemappingAlgorithm; + page.querySelector('#selectTonemappingMode').value = config.TonemappingMode; page.querySelector('#selectTonemappingRange').value = config.TonemappingRange; page.querySelector('#txtTonemappingDesat').value = config.TonemappingDesat; - page.querySelector('#txtTonemappingThreshold').value = config.TonemappingThreshold; page.querySelector('#txtTonemappingPeak').value = config.TonemappingPeak; page.querySelector('#txtTonemappingParam').value = config.TonemappingParam || ''; page.querySelector('#txtVppTonemappingBrightness').value = config.VppTonemappingBrightness; @@ -90,9 +90,9 @@ function onSubmit() { config.EnableTonemapping = form.querySelector('#chkTonemapping').checked; config.EnableVppTonemapping = form.querySelector('#chkVppTonemapping').checked; config.TonemappingAlgorithm = form.querySelector('#selectTonemappingAlgorithm').value; + config.TonemappingMode = form.querySelector('#selectTonemappingMode').value; config.TonemappingRange = form.querySelector('#selectTonemappingRange').value; config.TonemappingDesat = form.querySelector('#txtTonemappingDesat').value; - config.TonemappingThreshold = form.querySelector('#txtTonemappingThreshold').value; config.TonemappingPeak = form.querySelector('#txtTonemappingPeak').value; config.TonemappingParam = form.querySelector('#txtTonemappingParam').value || '0'; config.VppTonemappingBrightness = form.querySelector('#txtVppTonemappingBrightness').value; diff --git a/src/strings/en-us.json b/src/strings/en-us.json index e2b39af691..7a8ce9d8ee 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1706,5 +1706,7 @@ "MediaInfoElPresentFlag": "DV el preset flag", "MediaInfoBlPresentFlag": "DV bl preset flag", "MediaInfoDvBlSignalCompatibilityId": "DV bl signal compatibility id", - "Unreleased": "Not yet released" + "Unreleased": "Not yet released", + "LabelTonemappingMode": "Tone mapping mode:", + "TonemappingModeHelp": "Select the tone mapping mode. If you experience blown out highlights try switching to the RGB mode." } diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index d0ce56c4f8..9a047ed0be 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -1721,5 +1721,7 @@ "HeaderPerformance": "性能", "LabelParallelImageEncodingLimit": "并行图像编码限制", "LabelEnableAudioVbr": "启用 VBR 音频编码", - "LabelEnableAudioVbrHelp": "可变比特率(VBR)相比平均比特率(ABR)可以提供更好的质量,但在少见情况中可能造成缓冲和兼容性问题。" + "LabelEnableAudioVbrHelp": "可变比特率(VBR)相比平均比特率(ABR)可以提供更好的质量,但在少见情况中可能造成缓冲和兼容性问题。", + "LabelTonemappingMode": "色调映射模式:", + "TonemappingModeHelp": "如果您遇到高光过曝问题,请尝试切换到 RGB 模式。" } From 89158b66531a9f71a9f4fe25a1808bec6ed69ee3 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Fri, 14 Apr 2023 18:55:08 +0800 Subject: [PATCH 020/112] Update translations for tonemapping Signed-off-by: nyanmisaka --- src/strings/en-us.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 7a8ce9d8ee..be9ee91bab 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -32,7 +32,7 @@ "AllowOnTheFlySubtitleExtractionHelp": "Embedded subtitles can be extracted from videos and delivered to clients in plain text, in order to help prevent video transcoding. On some systems this can take a long time and cause video playback to stall during the extraction process. Disable this to have embedded subtitles burned in with video transcoding when they are not natively supported by the client device.", "AllowRemoteAccess": "Allow remote connections to this server", "AllowRemoteAccessHelp": "If unchecked, all remote connections will be blocked.", - "AllowTonemappingHelp": "Tone-mapping can transform the dynamic range of a video from HDR to SDR while maintaining image details and colors, which are very important information for representing the original scene. Currently works only with HDR10 or HLG videos. This requires the corresponding OpenCL or CUDA runtime.", + "AllowTonemappingHelp": "Tone-mapping can transform the dynamic range of a video from HDR to SDR while maintaining image details and colors, which are very important information for representing the original scene. Currently works only with 10bit HDR10,HLG and DoVi videos. This requires the corresponding OpenCL or CUDA runtime.", "AlwaysPlaySubtitles": "Always Play", "AlwaysPlaySubtitlesHelp": "Subtitles matching the language preference will be loaded regardless of the audio language.", "AnyLanguage": "Any Language", @@ -1691,9 +1691,9 @@ "EnableEnhancedNvdecDecoderHelp": "Experimental NVDEC implementation, do not enable this option unless you encounter decoding errors.", "EnableSplashScreen": "Enable the splash screen", "LabelVppTonemappingBrightness": "VPP Tone mapping brightness gain", - "LabelVppTonemappingBrightnessHelp": "Apply brightness gain in VPP tone mapping. Both recommended and default values are 0.", + "LabelVppTonemappingBrightnessHelp": "Apply brightness gain in VPP tone mapping. The recommended and default values are 16 and 0.", "LabelVppTonemappingContrast": "VPP Tone mapping contrast gain", - "LabelVppTonemappingContrastHelp": "Apply contrast gain in VPP tone mapping. The recommended and default values are 1.2 and 1.", + "LabelVppTonemappingContrastHelp": "Apply contrast gain in VPP tone mapping. Both recommended and default values are 1.", "VideoRangeTypeNotSupported": "The video's range type is not supported", "LabelVideoRangeType": "Video range type", "MediaInfoVideoRangeType": "Video range type", From 24126b15740ee6b340dfd9807d8ce321e7d3bade Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 25 Apr 2023 01:54:03 -0400 Subject: [PATCH 021/112] Remove colons from label translations --- src/strings/en-us.json | 2 +- src/strings/zh-cn.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/strings/en-us.json b/src/strings/en-us.json index be9ee91bab..9c4d2c8764 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1707,6 +1707,6 @@ "MediaInfoBlPresentFlag": "DV bl preset flag", "MediaInfoDvBlSignalCompatibilityId": "DV bl signal compatibility id", "Unreleased": "Not yet released", - "LabelTonemappingMode": "Tone mapping mode:", + "LabelTonemappingMode": "Tone mapping mode", "TonemappingModeHelp": "Select the tone mapping mode. If you experience blown out highlights try switching to the RGB mode." } diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index 9a047ed0be..8818053189 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -1722,6 +1722,6 @@ "LabelParallelImageEncodingLimit": "并行图像编码限制", "LabelEnableAudioVbr": "启用 VBR 音频编码", "LabelEnableAudioVbrHelp": "可变比特率(VBR)相比平均比特率(ABR)可以提供更好的质量,但在少见情况中可能造成缓冲和兼容性问题。", - "LabelTonemappingMode": "色调映射模式:", + "LabelTonemappingMode": "色调映射模式", "TonemappingModeHelp": "如果您遇到高光过曝问题,请尝试切换到 RGB 模式。" } From 99262d6edd0d2f5db616424111f6c09d1d4f6dba Mon Sep 17 00:00:00 2001 From: Oskari Lavinto Date: Tue, 25 Apr 2023 06:47:43 +0000 Subject: [PATCH 022/112] Translated using Weblate (Finnish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fi/ --- src/strings/fi.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/strings/fi.json b/src/strings/fi.json index 76b86d8016..f67a1dcaef 100644 --- a/src/strings/fi.json +++ b/src/strings/fi.json @@ -1719,5 +1719,6 @@ "HeaderPerformance": "Suorituskyky", "LabelParallelImageEncodingLimit": "Rinnakkaisten kuvaenkoodauksien rajoitus", "LabelEnableAudioVbr": "Käytä äänen VBR-enkoodausta", - "LabelEnableAudioVbrHelp": "Muuttuva bittinopeus (variable bitrate, VBR) tuottaa keskitasoista paremman laadun, mutta saattaa joissakin harvoissa tapauksissa aiheuttaa puskurointi ja yhteensopivuusongelmia." + "LabelEnableAudioVbrHelp": "Muuttuva bittinopeus (variable bitrate, VBR) tuottaa keskitasoista paremman laadun, mutta saattaa joissakin harvoissa tapauksissa aiheuttaa puskurointi ja yhteensopivuusongelmia.", + "Select": "Valitse" } From eeddd5dc2fcbb33cb05f25b3bae2f433323b0c5a Mon Sep 17 00:00:00 2001 From: Bas Date: Tue, 25 Apr 2023 14:59:45 +0000 Subject: [PATCH 023/112] Translated using Weblate (Dutch) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/ --- src/strings/nl.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/strings/nl.json b/src/strings/nl.json index 3c73edc564..0ef61eb21b 100644 --- a/src/strings/nl.json +++ b/src/strings/nl.json @@ -1720,5 +1720,6 @@ "LabelParallelImageEncodingLimitHelp": "Maximum aantal afbeeldingscoderingen dat tegelijkertijd mag lopen. Bij een instelling van 0 wordt een limiet gekozen gebaseerd op je systeemspecificaties.", "LabelParallelImageEncodingLimit": "Limiet gelijktijdige afbeeldingscoderingen", "LabelEnableAudioVbr": "VBR-audiocodering inschakelen", - "LabelEnableAudioVbrHelp": "Een variabele bitsnelheid biedt betere kwaliteit bij een vergelijkbare gemiddelde bitsnelheid, maar kan in zeldzame gevallen tot bufferen of compatibiliteitsproblemen leiden." + "LabelEnableAudioVbrHelp": "Een variabele bitsnelheid biedt betere kwaliteit bij een vergelijkbare gemiddelde bitsnelheid, maar kan in zeldzame gevallen tot bufferen of compatibiliteitsproblemen leiden.", + "Select": "Selecteren" } From 66937e696ff28c73c8f738cb5c8c17d712bcb49f Mon Sep 17 00:00:00 2001 From: blob03 Date: Tue, 25 Apr 2023 22:09:49 +0000 Subject: [PATCH 024/112] Translated using Weblate (French) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/ --- src/strings/fr.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/strings/fr.json b/src/strings/fr.json index 259f435d12..a2df89fe28 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -1384,7 +1384,7 @@ "LabelTonemappingRange": "Gamme de mappage tonal", "TonemappingAlgorithmHelp": "Le mappage tonal peut être affiné. Si vous n'êtes pas familier avec ces réglages, il est conseillé de choisir les valeurs recommandées. L'algorithme de mappage recommandé est 'BT.2390'.", "LabelTonemappingAlgorithm": "Sélectionner l'algorithme de mappage tonal à utiliser", - "AllowTonemappingHelp": "Le mappage tonal est capable de convertir une gamme dynamique HDR en SDR tout en maintenant les détails et les couleurs d'image si importants au rendu de la scène originale. Pour le moment, ne fonctionne qu'avec les vidéos HDR10 ou HLG et requiert les environnements d'exécution OpenCL et CUDA correspondant.", + "AllowTonemappingHelp": "Le mappage tonal est capable de convertir une gamme dynamique HDR en SDR tout en maintenant les détails et les couleurs d'image si importants au rendu de la scène originale. Pour le moment, ne fonctionne qu'avec les vidéos 10bits HDR10, HLG, DoVi et requiert les environnements d'exécution OpenCL et CUDA correspondant.", "EnableTonemapping": "Activer le mappage tonal", "LabelOpenclDeviceHelp": "Ce dispositif OpenCL est utilisé pour le mappage tonal. La partie à gauche du point est le numéro de plate-forme et la partie à droite est le numéro du dispositif sur la plate-forme. La valeur par défaut est 0,0. Le fichier de l'application FFmpeg contenant l'accélération matérielle OpenCL est nécessaire.", "LabelOpenclDevice": "Dispositif OpenCL", @@ -1667,9 +1667,9 @@ "MediaInfoVideoRangeType": "Type de plage vidéo", "LabelVideoRangeType": "Type de plage vidéo", "VideoRangeTypeNotSupported": "Le type de plage de la vidéo n'est pas pris en charge", - "LabelVppTonemappingContrastHelp": "Appliquer le gain de contraste dans le mappage de tonalité VPP. La valeur recommandée est 1,2 ; la valeur par défaut est 1.", + "LabelVppTonemappingContrastHelp": "Appliquer le gain de contraste dans le mappage tonal VPP. La valeur recommandée et par défaut est 1.", "LabelVppTonemappingContrast": "Gain de contraste du mappage VPP", - "LabelVppTonemappingBrightnessHelp": "Appliquer le gain de luminosité dans le mappage de tonalité VPP. La valeur recommandée et par défaut est 0.", + "LabelVppTonemappingBrightnessHelp": "Appliquer le gain de luminosité dans le mappage tonal VPP. La valeur recommandée et celle par défaut sont respectivement 16 et 0.", "LabelVppTonemappingBrightness": "Gain de luminosité du mappage VPP", "ScreenResolution": "Résolution d'écran", "RememberSubtitleSelectionsHelp": "Choisir la piste de sous-titres la plus proche de la dernière vidéo.", @@ -1721,5 +1721,8 @@ "LabelParallelImageEncodingLimit": "Limite de parallélisation de l'encodage d'image", "LabelParallelImageEncodingLimitHelp": "Nombre maximal d’encodages d’image autorisés à s’exécuter en parallèle. Si vous définissez cette valeur sur 0, vous choisirez une limite en fonction des spécifications de votre système.", "LabelEnableAudioVbr": "Activer l’encodage audio VBR", - "LabelEnableAudioVbrHelp": "Le débit binaire variable offre une qualité supérieure à la moyenne mais peut, dans de rares cas, causer des problèmes de mise en mémoire tampon et de compatibilité." + "LabelEnableAudioVbrHelp": "Le débit binaire variable offre une qualité supérieure à la moyenne mais peut, dans de rares cas, causer des problèmes de mise en mémoire tampon et de compatibilité.", + "LabelTonemappingMode": "Mode de mappage tonal", + "TonemappingModeHelp": "Sélectionnez le mode de mappage tonal. Si vous rencontrez des reflets soufflés, essayez le mode RVB.", + "Select": "Sélectionner" } From dbf4e8e3cfe16bcaa8c456241a794db282cc66d2 Mon Sep 17 00:00:00 2001 From: stanol Date: Tue, 25 Apr 2023 22:39:43 +0000 Subject: [PATCH 025/112] Translated using Weblate (Ukrainian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/ --- src/strings/uk.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/strings/uk.json b/src/strings/uk.json index 2e155e2a81..5183ac4fc0 100644 --- a/src/strings/uk.json +++ b/src/strings/uk.json @@ -302,7 +302,7 @@ "DirectStreamHelp1": "Відеопотік сумісний із пристроєм, але має несумісний аудіоформат (DTS, Dolby True HD тощо) або кількість аудіоканалів. Перед відправленням на пристрій, відеопотік буде перепаковуватись без втрат \"на льоту\". Буде перекодовано лише аудіопотік.", "DefaultSubtitlesHelp": "Завантаження субтитрів визначається опціями \"За замовчуванням\" і \"Форсовані\" у вбудованих метаданих. Мовні уподобання враховуються за наявності кількох опцій.", "DefaultMetadataLangaugeDescription": "Це значення за замовчуванням. Вони можуть бути налаштовані індивідуально для кожної медіатеки.", - "AllowTonemappingHelp": "Відображення тонів може перетворити динамічний діапазон відео з HDR до SDR, зберігаючи деталі зображення та кольори, які є дуже важливою інформацією для представлення оригінальної сцени. Наразі працює лише з відео HDR10 або HLG. Для цього потрібне відповідне середовище виконання OpenCL або CUDA.", + "AllowTonemappingHelp": "Відображення тонів може перетворити динамічний діапазон відео з HDR до SDR, зберігаючи деталі зображення та кольори, які є дуже важливою інформацією для представлення оригінальної сцени. Наразі працює лише з відео 10bit HDR10, HLG або DoVi. Для цього потрібне відповідне середовище виконання OpenCL або CUDA.", "HeaderCastAndCrew": "Актори і знімальна команда", "HeaderCancelSeries": "Скасувати серіал", "HeaderCancelRecording": "Скасувати запис", @@ -1669,9 +1669,9 @@ "MediaInfoVideoRangeType": "Тип діапазону відео", "LabelVideoRangeType": "Тип діапазону відео", "VideoRangeTypeNotSupported": "Тип диапазону відео не підтримується", - "LabelVppTonemappingContrastHelp": "Застосувати чутливість яскравості для VPP tone mapping. Значення за замовчуванням (1.2 та 1) є рекомендованими.", + "LabelVppTonemappingContrastHelp": "Застосувати чутливість яскравості для VPP tone mapping. Значення за замовчуванням (1) є рекомендованими.", "LabelVppTonemappingContrast": "Чутливість контрасту для VPP Tone mapping", - "LabelVppTonemappingBrightnessHelp": "Застосувати чутливість яскравості для VPP tone mapping. Значення за замовчуванням (0) є рекомендованим.", + "LabelVppTonemappingBrightnessHelp": "Застосувати чутливість яскравості для VPP tone mapping. Рекомендоване значення 16, значення за замовчуванням 0.", "LabelVppTonemappingBrightness": "Чутливість яскравості для VPP Tone mapping", "IgnoreDts": "Ігнорувати DTS (мітка часу декодування)", "IgnoreDtsHelp": "Вимкнення цієї опції може вирішити деякі проблеми, напр. відсутність аудіо на каналах з окремими аудіо- та відеопотоками.", From 60d3859a2f11b5f18f183ad5ae715c5cb41bd759 Mon Sep 17 00:00:00 2001 From: Ian Walton Date: Sat, 22 Apr 2023 10:12:58 -0400 Subject: [PATCH 026/112] Escape device id in raw HTML. --- src/controllers/dashboard/devices/devices.js | 7 ++++--- src/scripts/imagehelper.js | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/controllers/dashboard/devices/devices.js b/src/controllers/dashboard/devices/devices.js index 8413c42dee..f28064e09a 100644 --- a/src/controllers/dashboard/devices/devices.js +++ b/src/controllers/dashboard/devices/devices.js @@ -90,11 +90,12 @@ function load(page, devices) { let html = ''; html += devices.map(function (device) { let deviceHtml = ''; - deviceHtml += "
"; + deviceHtml += "
"; deviceHtml += '
'; deviceHtml += '
'; deviceHtml += '
'; - deviceHtml += ``; + deviceHtml += ``; + // audit note: getDeviceIcon returns static text const iconUrl = imageHelper.getDeviceIcon(device); if (iconUrl) { @@ -113,7 +114,7 @@ function load(page, devices) { deviceHtml += '
'; else deviceHtml += '
'; - deviceHtml += ''; + deviceHtml += ''; deviceHtml += '
'; } diff --git a/src/scripts/imagehelper.js b/src/scripts/imagehelper.js index 49fe204b33..052c68111e 100644 --- a/src/scripts/imagehelper.js +++ b/src/scripts/imagehelper.js @@ -1,5 +1,6 @@ const BASE_DEVICE_IMAGE_URL = 'assets/img/devices/'; +// audit note: this module is expected to return safe text for use in HTML function getWebDeviceIcon(browser) { switch (browser) { case 'Opera': From 097471863e35c4fc2967efdfc0856f0dfad2e255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Kucharczyk?= Date: Wed, 26 Apr 2023 07:22:30 +0000 Subject: [PATCH 027/112] Translated using Weblate (Czech) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/cs/ --- src/strings/cs.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/strings/cs.json b/src/strings/cs.json index 9a186bda61..ae924414cb 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -1386,7 +1386,7 @@ "LabelTonemappingRange": "Rozsah mapování tónů", "TonemappingAlgorithmHelp": "Mapování tonů je možné dále ladit. Pokud možnostem zde nerozumíte, je možné ponechat vše ve výchozím nastavení. Doporučená hodnota je 'BT.2390'.", "LabelTonemappingAlgorithm": "Algoritmus mapování tónů", - "AllowTonemappingHelp": "Mapování tónů umožňuje změnit dynamický rozsah videa z HDR na SDR bez ztráty detailů a barev, tj. důležitých informací původního obrazu. Tato funkce momentálně funguje pouze u videí, které obsahují HDR10 nebo HLG, a vyžaduje buď OpenCL nebo CUDA.", + "AllowTonemappingHelp": "Mapování tónů umožňuje změnit dynamický rozsah videa z HDR na SDR bez ztráty detailů a barev, tj. důležitých informací původního obrazu. Tato funkce momentálně funguje pouze u videí, které obsahují 10bitové HDR10, HLG nebo Dolby Vision. Funkce rovněž vyžaduje OpenCL nebo CUDA.", "EnableTonemapping": "Zapnout mapování tónů", "LabelOpenclDeviceHelp": "Zařízení OpenCL použité pro mapování tónů. Nalevo od tečky je číslo platformy, napravo pak číslo zařízení na této platformě. Výchozí hodnota je 0.0. Soubor aplikace FFmpeg, který obsahuje metodu pro hardwarovou akceleraci OpenCL, je povinný.", "LabelOpenclDevice": "Zařízení OpenCL", @@ -1666,9 +1666,9 @@ "MediaInfoVideoRangeType": "Typ rozsahu videa", "LabelVideoRangeType": "Typ rozsahu videa", "VideoRangeTypeNotSupported": "Typ rozsahu videa není podporován", - "LabelVppTonemappingContrastHelp": "Zvýší kontrast při mapování tonů VPP. Doporučená hodnota je 1.2, výchozí hodnota je 1.", + "LabelVppTonemappingContrastHelp": "Zvýší kontrast při mapování tonů VPP. Doporučená i výchozí hodnota je 1.", "LabelVppTonemappingContrast": "Zvýšení kontrastu mapování tónů VPP", - "LabelVppTonemappingBrightnessHelp": "Zvýší jas při mapování tonů VPP. Doporučená i výchozí hodnota je 0.", + "LabelVppTonemappingBrightnessHelp": "Zvýší jas při mapování tonů VPP. Doporučená hodnota je 16, výchozí hodnota je 0.", "LabelVppTonemappingBrightness": "Zvýšení jasu mapování tónů VPP", "ScreenResolution": "Rozlišení obrazovky", "RememberSubtitleSelectionsHelp": "Pokusí se nastavit titulkovou stopu co nejpodobněji předchozímu videu.", @@ -1722,5 +1722,7 @@ "LabelParallelImageEncodingLimitHelp": "Maximální počet kódování obrázků, které mohou běžet zároveň. Nastavením na 0 bude limit nastaven dle parametrů systému.", "LabelEnableAudioVbr": "Povolit kódování zvuku VBR", "LabelEnableAudioVbrHelp": "Proměnlivý bitový tok (VBR) nabízí lepší poměr mezi kvalitou a průměrným bitovým tokem, ale někdy může způsobit dodatečné načítání či problémy s kompatibilitou.", - "Select": "Vybrat" + "Select": "Vybrat", + "LabelTonemappingMode": "Režim mapování tónů", + "TonemappingModeHelp": "Určute režim mapování tónů. Pokud narazíte na přeexponovaná světlá místa, zkuste přepnout do režimu RGB." } From 829f476ce3ac9a431f36d1d28560b74f4d10cb84 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 26 Apr 2023 09:50:48 -0400 Subject: [PATCH 028/112] Refactor backdrop and header to separate components --- src/App.tsx | 23 +++++------------------ src/components/AppHeader.tsx | 20 ++++++++++++++++++++ src/components/Backdrop.tsx | 17 +++++++++++++++++ 3 files changed, 42 insertions(+), 18 deletions(-) create mode 100644 src/components/AppHeader.tsx create mode 100644 src/components/Backdrop.tsx diff --git a/src/App.tsx b/src/App.tsx index 1a544723a1..d72fd3831e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,8 @@ import { History } from '@remix-run/router'; -import React, { useEffect } from 'react'; +import React from 'react'; +import AppHeader from './components/AppHeader'; +import Backdrop from './components/Backdrop'; import { HistoryRouter } from './components/HistoryRouter'; import { ApiProvider } from './hooks/useApi'; import { AppRoutes, ExperimentalAppRoutes } from './routes'; @@ -8,31 +10,16 @@ import { AppRoutes, ExperimentalAppRoutes } from './routes'; const App = ({ history }: { history: History }) => { const layoutMode = localStorage.getItem('layout'); - useEffect(() => { - Promise.all([ - // Initialize the UI components after first render - import('./scripts/libraryMenu'), - import('./scripts/autoBackdrops') - ]); - }, []); - return ( -
-
- -
-
-
-
+ +
{layoutMode === 'experimental' ? : }
- -
); diff --git a/src/components/AppHeader.tsx b/src/components/AppHeader.tsx new file mode 100644 index 0000000000..941d36a940 --- /dev/null +++ b/src/components/AppHeader.tsx @@ -0,0 +1,20 @@ +import React, { useEffect } from 'react'; + +const AppHeader = () => { + useEffect(() => { + // Initialize the UI components after first render + import('../scripts/libraryMenu'); + }, []); + + return ( + <> +
+
+
+
+
+ + ); +}; + +export default AppHeader; diff --git a/src/components/Backdrop.tsx b/src/components/Backdrop.tsx new file mode 100644 index 0000000000..1283be0aa9 --- /dev/null +++ b/src/components/Backdrop.tsx @@ -0,0 +1,17 @@ +import React, { useEffect } from 'react'; + +const Backdrop = () => { + useEffect(() => { + // Initialize the UI components after first render + import('../scripts/autoBackdrops'); + }, []); + + return ( + <> +
+
+ + ); +}; + +export default Backdrop; From 8f730b82706253ffa63f4b4e8e7d1d65e16c3be4 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 26 Apr 2023 11:30:57 -0400 Subject: [PATCH 029/112] Fix eslint warnings in ts files --- src/components/ServerContentPage.tsx | 3 ++- src/components/viewManager/ViewManagerPage.tsx | 3 ++- src/elements/emby-scroller/Scroller.tsx | 2 +- src/types/viewManager.ts | 3 +++ src/utils/jellyfin-apiclient/getItems.ts | 11 ++++++----- 5 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 src/types/viewManager.ts diff --git a/src/components/ServerContentPage.tsx b/src/components/ServerContentPage.tsx index 7473c856e8..e5428269bc 100644 --- a/src/components/ServerContentPage.tsx +++ b/src/components/ServerContentPage.tsx @@ -4,6 +4,7 @@ import { useLocation } from 'react-router-dom'; import ServerConnections from './ServerConnections'; import viewManager from './viewManager/viewManager'; import globalize from '../scripts/globalize'; +import type { RestoreViewFailResponse } from '../types/viewManager'; interface ServerContentPageProps { view: string @@ -29,7 +30,7 @@ const ServerContentPage: FunctionComponent = ({ view }) }; viewManager.tryRestoreView(viewOptions) - .catch(async (result?: any) => { + .catch(async (result?: RestoreViewFailResponse) => { if (!result || !result.cancelled) { const apiClient = ServerConnections.currentApiClient(); diff --git a/src/components/viewManager/ViewManagerPage.tsx b/src/components/viewManager/ViewManagerPage.tsx index 563603e531..511338d1e2 100644 --- a/src/components/viewManager/ViewManagerPage.tsx +++ b/src/components/viewManager/ViewManagerPage.tsx @@ -2,6 +2,7 @@ import React, { FunctionComponent, useEffect } from 'react'; import { useLocation } from 'react-router-dom'; import globalize from '../../scripts/globalize'; +import type { RestoreViewFailResponse } from '../../types/viewManager'; import viewManager from './viewManager'; export interface ViewManagerPageProps { @@ -45,7 +46,7 @@ const ViewManagerPage: FunctionComponent = ({ }; viewManager.tryRestoreView(viewOptions) - .catch(async (result?: any) => { + .catch(async (result?: RestoreViewFailResponse) => { if (!result || !result.cancelled) { const [ controllerFactory, viewHtml ] = await Promise.all([ import(/* webpackChunkName: "[request]" */ `../../controllers/${controller}`), diff --git a/src/elements/emby-scroller/Scroller.tsx b/src/elements/emby-scroller/Scroller.tsx index 36b38cc1fb..773d184c59 100644 --- a/src/elements/emby-scroller/Scroller.tsx +++ b/src/elements/emby-scroller/Scroller.tsx @@ -126,7 +126,7 @@ const Scroller: FC = ({ }, [getScrollPosition, getScrollSize, getScrollWidth]); const initCenterFocus = useCallback((elem: EventTarget, scrollerInstance: scrollerFactory) => { - dom.addEventListener(elem, 'focus', function (e: { target: any; }) { + dom.addEventListener(elem, 'focus', function (e: FocusEvent) { const focused = focusManager.focusableParent(e.target); if (focused) { scrollerInstance.toCenter(focused, false); diff --git a/src/types/viewManager.ts b/src/types/viewManager.ts new file mode 100644 index 0000000000..541bbdbc75 --- /dev/null +++ b/src/types/viewManager.ts @@ -0,0 +1,3 @@ +export interface RestoreViewFailResponse { + cancelled?: boolean +} diff --git a/src/utils/jellyfin-apiclient/getItems.ts b/src/utils/jellyfin-apiclient/getItems.ts index dee681a5d5..4bbe711f81 100644 --- a/src/utils/jellyfin-apiclient/getItems.ts +++ b/src/utils/jellyfin-apiclient/getItems.ts @@ -31,25 +31,26 @@ function getItemsSplit(apiClient: ApiClient, userId: string, options: GetItemsRe function mergeResults(results: BaseItemDtoQueryResult[]) { const merged: BaseItemDtoQueryResult = { Items: [], - TotalRecordCount: 0, StartIndex: 0 }; + // set TotalRecordCount separately so TS knows it is defined + merged.TotalRecordCount = 0; for (const result of results) { - if (result.Items == null) { + if (!result.Items) { console.log('[getItems] Retrieved Items array is invalid', result.Items); continue; } - if (result.TotalRecordCount == null) { + if (!result.TotalRecordCount) { console.log('[getItems] Retrieved TotalRecordCount is invalid', result.TotalRecordCount); continue; } - if (result.StartIndex == null) { + if (typeof result.StartIndex === 'undefined') { console.log('[getItems] Retrieved StartIndex is invalid', result.StartIndex); continue; } merged.Items = merged.Items?.concat(result.Items); - merged.TotalRecordCount! += result.TotalRecordCount; + merged.TotalRecordCount += result.TotalRecordCount; merged.StartIndex = Math.min(merged.StartIndex || 0, result.StartIndex); } return merged; From 9c128b8c106abdb76d23e0d31986f5c33ddb6422 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 26 Apr 2023 12:32:15 -0400 Subject: [PATCH 030/112] Fix complexity warnings in user routes --- src/routes/user/useredit.tsx | 58 +++++++++++-------------- src/routes/user/usernew.tsx | 8 +--- src/routes/user/userparentalcontrol.tsx | 8 +--- src/routes/user/userprofile.tsx | 8 +--- 4 files changed, 31 insertions(+), 51 deletions(-) diff --git a/src/routes/user/useredit.tsx b/src/routes/user/useredit.tsx index 67fe055632..64e70f32f6 100644 --- a/src/routes/user/useredit.tsx +++ b/src/routes/user/useredit.tsx @@ -25,6 +25,17 @@ type AuthProvider = { Id?: string; } +const getCheckedElementDataIds = (elements: NodeListOf) => ( + Array.prototype.filter.call(elements, e => e.checked) + .map(e => e.getAttribute('data-id')) +); + +function onSaveComplete() { + Dashboard.navigate('userprofiles.html'); + loading.hide(); + toast(globalize.translate('SettingsSaved')); +} + const UserEdit: FunctionComponent = () => { const [ userName, setUserName ] = useState(''); const [ deleteFoldersAccess, setDeleteFoldersAccess ] = useState([]); @@ -56,7 +67,7 @@ const UserEdit: FunctionComponent = () => { } const fldSelectLoginProvider = page.querySelector('.fldSelectLoginProvider') as HTMLDivElement; - providers.length > 1 ? fldSelectLoginProvider.classList.remove('hide') : fldSelectLoginProvider.classList.add('hide'); + fldSelectLoginProvider.classList.toggle('hide', providers.length <= 1); setAuthProviders(providers); @@ -73,7 +84,7 @@ const UserEdit: FunctionComponent = () => { } const fldSelectPasswordResetProvider = page.querySelector('.fldSelectPasswordResetProvider') as HTMLDivElement; - providers.length > 1 ? fldSelectPasswordResetProvider.classList.remove('hide') : fldSelectPasswordResetProvider.classList.add('hide'); + fldSelectPasswordResetProvider.classList.toggle('hide', providers.length <= 1); setPasswordResetProviders(providers); @@ -145,7 +156,7 @@ const UserEdit: FunctionComponent = () => { }); const disabledUserBanner = page.querySelector('.disabledUserBanner') as HTMLDivElement; - user.Policy.IsDisabled ? disabledUserBanner.classList.remove('hide') : disabledUserBanner.classList.add('hide'); + disabledUserBanner.classList.toggle('hide', !user.Policy.IsDisabled); const txtUserName = page.querySelector('#txtUserName') as HTMLInputElement; txtUserName.disabled = false; @@ -198,19 +209,9 @@ const UserEdit: FunctionComponent = () => { loadData(); - function onSaveComplete() { - Dashboard.navigate('userprofiles.html'); - loading.hide(); - toast(globalize.translate('SettingsSaved')); - } - const saveUser = (user: UserDto) => { - if (!user.Id) { - throw new Error('Unexpected null user.Id'); - } - - if (!user.Policy) { - throw new Error('Unexpected null user.Policy'); + if (!user.Id || !user.Policy) { + throw new Error('Unexpected null user id or policy'); } user.Name = (page.querySelector('#txtUserName') as HTMLInputElement).value; @@ -235,19 +236,15 @@ const UserEdit: FunctionComponent = () => { user.Policy.AuthenticationProviderId = (page.querySelector('#selectLoginProvider') as HTMLSelectElement).value; user.Policy.PasswordResetProviderId = (page.querySelector('#selectPasswordResetProvider') as HTMLSelectElement).value; user.Policy.EnableContentDeletion = (page.querySelector('.chkEnableDeleteAllFolders') as HTMLInputElement).checked; - user.Policy.EnableContentDeletionFromFolders = user.Policy.EnableContentDeletion ? [] : Array.prototype.filter.call(page.querySelectorAll('.chkFolder'), function (c) { - return c.checked; - }).map(function (c) { - return c.getAttribute('data-id'); - }); - if (window.ApiClient.isMinServerVersion('10.6.0')) { - user.Policy.SyncPlayAccess = (page.querySelector('#selectSyncPlayAccess') as HTMLSelectElement).value as SyncPlayUserAccessType; - } - window.ApiClient.updateUser(user).then(function () { - window.ApiClient.updateUserPolicy(user.Id || '', user.Policy || {}).then(function () { + user.Policy.EnableContentDeletionFromFolders = user.Policy.EnableContentDeletion ? [] : getCheckedElementDataIds(page.querySelectorAll('.chkFolder')); + user.Policy.SyncPlayAccess = (page.querySelector('#selectSyncPlayAccess') as HTMLSelectElement).value as SyncPlayUserAccessType; + + window.ApiClient.updateUser(user) + .then(() => ( + window.ApiClient.updateUserPolicy(user.Id || '', user.Policy || {}) + )).then(() => { onSaveComplete(); }); - }); }; const onSubmit = (e: Event) => { @@ -261,16 +258,11 @@ const UserEdit: FunctionComponent = () => { }; (page.querySelector('.chkEnableDeleteAllFolders') as HTMLInputElement).addEventListener('change', function (this: HTMLInputElement) { - if (this.checked) { - (page.querySelector('.deleteAccess') as HTMLDivElement).classList.add('hide'); - } else { - (page.querySelector('.deleteAccess') as HTMLDivElement).classList.remove('hide'); - } + (page.querySelector('.deleteAccess') as HTMLDivElement).classList.toggle('hide', this.checked); }); window.ApiClient.getNamedConfiguration('network').then(function (config) { - const fldRemoteAccess = page.querySelector('.fldRemoteAccess') as HTMLDivElement; - config.EnableRemoteAccess ? fldRemoteAccess.classList.remove('hide') : fldRemoteAccess.classList.add('hide'); + (page.querySelector('.fldRemoteAccess') as HTMLDivElement).classList.toggle('hide', !config.EnableRemoteAccess); }); (page.querySelector('.editUserProfileForm') as HTMLFormElement).addEventListener('submit', onSubmit); diff --git a/src/routes/user/usernew.tsx b/src/routes/user/usernew.tsx index e3610b07f5..25d1a13140 100644 --- a/src/routes/user/usernew.tsx +++ b/src/routes/user/usernew.tsx @@ -111,12 +111,8 @@ const UserNew: FunctionComponent = () => { userInput.Name = (page.querySelector('#txtUsername') as HTMLInputElement).value; userInput.Password = (page.querySelector('#txtPassword') as HTMLInputElement).value; window.ApiClient.createUser(userInput).then(function (user) { - if (!user.Id) { - throw new Error('Unexpected null user.Id'); - } - - if (!user.Policy) { - throw new Error('Unexpected null user.Policy'); + if (!user.Id || !user.Policy) { + throw new Error('Unexpected null user id or policy'); } user.Policy.EnableAllFolders = (page.querySelector('.chkEnableAllFolders') as HTMLInputElement).checked; diff --git a/src/routes/user/userparentalcontrol.tsx b/src/routes/user/userparentalcontrol.tsx index dcf465a773..be28cf5089 100644 --- a/src/routes/user/userparentalcontrol.tsx +++ b/src/routes/user/userparentalcontrol.tsx @@ -215,12 +215,8 @@ const UserParentalControl: FunctionComponent = () => { }; const saveUser = (user: UserDto) => { - if (!user.Id) { - throw new Error('Unexpected null user.Id'); - } - - if (!user.Policy) { - throw new Error('Unexpected null user.Policy'); + if (!user.Id || !user.Policy) { + throw new Error('Unexpected null user id or policy'); } const parentalRating = parseInt((page.querySelector('#selectMaxParentalRating') as HTMLSelectElement).value, 10); diff --git a/src/routes/user/userprofile.tsx b/src/routes/user/userprofile.tsx index fb1b5d08f3..0b35d50943 100644 --- a/src/routes/user/userprofile.tsx +++ b/src/routes/user/userprofile.tsx @@ -30,12 +30,8 @@ const UserProfile: FunctionComponent = () => { loading.show(); window.ApiClient.getUser(userId).then(function (user) { - if (!user.Name) { - throw new Error('Unexpected null user.Name'); - } - - if (!user.Id) { - throw new Error('Unexpected null user.Id'); + if (!user.Name || !user.Id) { + throw new Error('Unexpected null user name or id'); } setUserName(user.Name); From 0e0a30a0679b12a766fc698542b5276b207ff71c Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 26 Apr 2023 13:13:37 -0400 Subject: [PATCH 031/112] Fix complexity warnings in search results --- src/components/search/SearchResults.tsx | 219 +++++++++++++----------- 1 file changed, 116 insertions(+), 103 deletions(-) diff --git a/src/components/search/SearchResults.tsx b/src/components/search/SearchResults.tsx index bc3528261d..720cee0e3c 100644 --- a/src/components/search/SearchResults.tsx +++ b/src/components/search/SearchResults.tsx @@ -1,7 +1,7 @@ -import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'; +import type { BaseItemDto, BaseItemDtoQueryResult } from '@jellyfin/sdk/lib/generated-client'; import type { ApiClient } from 'jellyfin-apiclient'; import classNames from 'classnames'; -import React, { FunctionComponent, useEffect, useState } from 'react'; +import React, { FunctionComponent, useCallback, useEffect, useState } from 'react'; import globalize from '../../scripts/globalize'; import ServerConnections from '../ServerConnections'; @@ -14,6 +14,17 @@ type SearchResultsProps = { query?: string; } +const ensureNonNullItems = (result: BaseItemDtoQueryResult) => ({ + ...result, + Items: result.Items || [] +}); + +const isMovies = (collectionType: string) => collectionType === 'movies'; + +const isMusic = (collectionType: string) => collectionType === 'music'; + +const isTVShows = (collectionType: string) => collectionType === 'tvshows' || collectionType === 'tv'; + /* * React component to display search result rows for global search and non-live tv library search */ @@ -35,55 +46,55 @@ const SearchResults: FunctionComponent = ({ serverId = windo const [ people, setPeople ] = useState([]); const [ collections, setCollections ] = useState([]); - useEffect(() => { - const getDefaultParameters = () => ({ - ParentId: parentId, - searchTerm: query, - Limit: 24, - Fields: 'PrimaryImageAspectRatio,CanDelete,BasicSyncInfo,MediaSourceCount', - Recursive: true, - EnableTotalRecordCount: false, - ImageTypeLimit: 1, - IncludePeople: false, - IncludeMedia: false, - IncludeGenres: false, - IncludeStudios: false, - IncludeArtists: false - }); + const getDefaultParameters = useCallback(() => ({ + ParentId: parentId, + searchTerm: query, + Limit: 24, + Fields: 'PrimaryImageAspectRatio,CanDelete,BasicSyncInfo,MediaSourceCount', + Recursive: true, + EnableTotalRecordCount: false, + ImageTypeLimit: 1, + IncludePeople: false, + IncludeMedia: false, + IncludeGenres: false, + IncludeStudios: false, + IncludeArtists: false + }), [parentId, query]); - const fetchArtists = (apiClient: ApiClient, params = {}) => apiClient?.getArtists( - apiClient?.getCurrentUserId(), + const fetchArtists = useCallback((apiClient: ApiClient, params = {}) => ( + apiClient?.getArtists( + apiClient.getCurrentUserId(), { ...getDefaultParameters(), IncludeArtists: true, ...params } - ); + ).then(ensureNonNullItems) + ), [getDefaultParameters]); - const fetchItems = (apiClient: ApiClient, params = {}) => apiClient?.getItems( - apiClient?.getCurrentUserId(), + const fetchItems = useCallback((apiClient: ApiClient, params = {}) => ( + apiClient?.getItems( + apiClient.getCurrentUserId(), { ...getDefaultParameters(), IncludeMedia: true, ...params } - ); + ).then(ensureNonNullItems) + ), [getDefaultParameters]); - const fetchPeople = (apiClient: ApiClient, params = {}) => apiClient?.getPeople( - apiClient?.getCurrentUserId(), + const fetchPeople = useCallback((apiClient: ApiClient, params = {}) => ( + apiClient?.getPeople( + apiClient.getCurrentUserId(), { ...getDefaultParameters(), IncludePeople: true, ...params } - ); - - const isMovies = () => collectionType === 'movies'; - - const isMusic = () => collectionType === 'music'; - - const isTVShows = () => collectionType === 'tvshows' || collectionType === 'tv'; + ).then(ensureNonNullItems) + ), [getDefaultParameters]); + useEffect(() => { // Reset state setMovies([]); setShows([]); @@ -102,78 +113,80 @@ const SearchResults: FunctionComponent = ({ serverId = windo setPeople([]); setCollections([]); - if (query) { - const apiClient = ServerConnections.getApiClient(serverId); - - // Movie libraries - if (!collectionType || isMovies()) { - // Movies row - fetchItems(apiClient, { IncludeItemTypes: 'Movie' }) - .then(result => setMovies(result.Items || [])); - } - - // TV Show libraries - if (!collectionType || isTVShows()) { - // Shows row - fetchItems(apiClient, { IncludeItemTypes: 'Series' }) - .then(result => setShows(result.Items || [])); - // Episodes row - fetchItems(apiClient, { IncludeItemTypes: 'Episode' }) - .then(result => setEpisodes(result.Items || [])); - } - - // People are included for Movies and TV Shows - if (!collectionType || isMovies() || isTVShows()) { - // People row - fetchPeople(apiClient).then(result => setPeople(result.Items || [])); - } - - // Music libraries - if (!collectionType || isMusic()) { - // Playlists row - fetchItems(apiClient, { IncludeItemTypes: 'Playlist' }) - .then(results => setPlaylists(results.Items || [])); - // Artists row - fetchArtists(apiClient).then(result => setArtists(result.Items || [])); - // Albums row - fetchItems(apiClient, { IncludeItemTypes: 'MusicAlbum' }) - .then(result => setAlbums(result.Items || [])); - // Songs row - fetchItems(apiClient, { IncludeItemTypes: 'Audio' }) - .then(result => setSongs(result.Items || [])); - } - - // Other libraries do not support in-library search currently - if (!collectionType) { - // Videos row - fetchItems(apiClient, { - MediaTypes: 'Video', - ExcludeItemTypes: 'Movie,Episode,TvChannel' - }).then(result => setVideos(result.Items || [])); - // Programs row - fetchItems(apiClient, { IncludeItemTypes: 'LiveTvProgram' }) - .then(result => setPrograms(result.Items || [])); - // Channels row - fetchItems(apiClient, { IncludeItemTypes: 'TvChannel' }) - .then(result => setChannels(result.Items || [])); - // Photo Albums row - fetchItems(apiClient, { IncludeItemTypes: 'PhotoAlbum' }) - .then(results => setPhotoAlbums(results.Items || [])); - // Photos row - fetchItems(apiClient, { IncludeItemTypes: 'Photo' }) - .then(results => setPhotos(results.Items || [])); - // Audio Books row - fetchItems(apiClient, { IncludeItemTypes: 'AudioBook' }) - .then(results => setAudioBooks(results.Items || [])); - // Books row - fetchItems(apiClient, { IncludeItemTypes: 'Book' }) - .then(results => setBooks(results.Items || [])); - // Collections row - fetchItems(apiClient, { IncludeItemTypes: 'BoxSet' }) - .then(result => setCollections(result.Items || [])); - } + if (!query) { + return; } - }, [collectionType, parentId, query, serverId]); + + const apiClient = ServerConnections.getApiClient(serverId); + + // Movie libraries + if (!collectionType || isMovies(collectionType)) { + // Movies row + fetchItems(apiClient, { IncludeItemTypes: 'Movie' }) + .then(result => setMovies(result.Items)); + } + + // TV Show libraries + if (!collectionType || isTVShows(collectionType)) { + // Shows row + fetchItems(apiClient, { IncludeItemTypes: 'Series' }) + .then(result => setShows(result.Items)); + // Episodes row + fetchItems(apiClient, { IncludeItemTypes: 'Episode' }) + .then(result => setEpisodes(result.Items)); + } + + // People are included for Movies and TV Shows + if (!collectionType || isMovies(collectionType) || isTVShows(collectionType)) { + // People row + fetchPeople(apiClient).then(result => setPeople(result.Items)); + } + + // Music libraries + if (!collectionType || isMusic(collectionType)) { + // Playlists row + fetchItems(apiClient, { IncludeItemTypes: 'Playlist' }) + .then(results => setPlaylists(results.Items)); + // Artists row + fetchArtists(apiClient).then(result => setArtists(result.Items)); + // Albums row + fetchItems(apiClient, { IncludeItemTypes: 'MusicAlbum' }) + .then(result => setAlbums(result.Items)); + // Songs row + fetchItems(apiClient, { IncludeItemTypes: 'Audio' }) + .then(result => setSongs(result.Items)); + } + + // Other libraries do not support in-library search currently + if (!collectionType) { + // Videos row + fetchItems(apiClient, { + MediaTypes: 'Video', + ExcludeItemTypes: 'Movie,Episode,TvChannel' + }).then(result => setVideos(result.Items)); + // Programs row + fetchItems(apiClient, { IncludeItemTypes: 'LiveTvProgram' }) + .then(result => setPrograms(result.Items)); + // Channels row + fetchItems(apiClient, { IncludeItemTypes: 'TvChannel' }) + .then(result => setChannels(result.Items)); + // Photo Albums row + fetchItems(apiClient, { IncludeItemTypes: 'PhotoAlbum' }) + .then(result => setPhotoAlbums(result.Items)); + // Photos row + fetchItems(apiClient, { IncludeItemTypes: 'Photo' }) + .then(result => setPhotos(result.Items)); + // Audio Books row + fetchItems(apiClient, { IncludeItemTypes: 'AudioBook' }) + .then(result => setAudioBooks(result.Items)); + // Books row + fetchItems(apiClient, { IncludeItemTypes: 'Book' }) + .then(result => setBooks(result.Items)); + // Collections row + fetchItems(apiClient, { IncludeItemTypes: 'BoxSet' }) + .then(result => setCollections(result.Items)); + } + }, [collectionType, fetchArtists, fetchItems, fetchPeople, query, serverId]); return (
Date: Wed, 26 Apr 2023 15:13:51 -0400 Subject: [PATCH 032/112] Fix complexity warnings in ViewItemsContainer --- src/components/common/ViewItemsContainer.tsx | 90 +++++++++----------- 1 file changed, 39 insertions(+), 51 deletions(-) diff --git a/src/components/common/ViewItemsContainer.tsx b/src/components/common/ViewItemsContainer.tsx index 086d160137..d4f2937513 100644 --- a/src/components/common/ViewItemsContainer.tsx +++ b/src/components/common/ViewItemsContainer.tsx @@ -1,4 +1,4 @@ -import type { BaseItemDtoQueryResult } from '@jellyfin/sdk/lib/generated-client'; +import { type BaseItemDtoQueryResult, ItemFields, ItemFilter } from '@jellyfin/sdk/lib/generated-client'; import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; import loading from '../loading/loading'; @@ -33,6 +33,41 @@ const getDefaultSortBy = () => { return 'SortName'; }; +const getFields = (viewQuerySettings: ViewQuerySettings) => { + const fields: ItemFields[] = [ + ItemFields.BasicSyncInfo, + ItemFields.MediaSourceCount + ]; + + if (viewQuerySettings.imageType === 'primary') { + fields.push(ItemFields.PrimaryImageAspectRatio); + } + + return fields.join(','); +}; + +const getFilters = (viewQuerySettings: ViewQuerySettings) => { + const filters: ItemFilter[] = []; + + if (viewQuerySettings.IsPlayed) { + filters.push(ItemFilter.IsPlayed); + } + + if (viewQuerySettings.IsUnplayed) { + filters.push(ItemFilter.IsUnplayed); + } + + if (viewQuerySettings.IsFavorite) { + filters.push(ItemFilter.IsFavorite); + } + + if (viewQuerySettings.IsResumable) { + filters.push(ItemFilter.IsResumable); + } + + return filters; +}; + const getVisibleViewSettings = () => { return [ 'showTitle', @@ -228,33 +263,7 @@ const ViewItemsContainer: FC = ({ }, [getCardOptions, getContext, itemsResult.Items, getNoItemsMessage, viewQuerySettings.imageType]); const getQuery = useCallback(() => { - let fields = 'BasicSyncInfo,MediaSourceCount'; - - if (viewQuerySettings.imageType === 'primary') { - fields += ',PrimaryImageAspectRatio'; - } - - if (viewQuerySettings.showYear) { - fields += ',ProductionYear'; - } - - const queryFilters: string[] = []; - - if (viewQuerySettings.IsPlayed) { - queryFilters.push('IsPlayed'); - } - - if (viewQuerySettings.IsUnplayed) { - queryFilters.push('IsUnplayed'); - } - - if (viewQuerySettings.IsFavorite) { - queryFilters.push('IsFavorite'); - } - - if (viewQuerySettings.IsResumable) { - queryFilters.push('IsResumable'); - } + const queryFilters = getFilters(viewQuerySettings); let queryIsHD; @@ -271,7 +280,7 @@ const ViewItemsContainer: FC = ({ SortOrder: viewQuerySettings.SortOrder, IncludeItemTypes: getItemTypes().join(','), Recursive: true, - Fields: fields, + Fields: getFields(viewQuerySettings), ImageTypeLimit: 1, EnableImageTypes: 'Primary,Backdrop,Banner,Thumb,Disc,Logo', Limit: userSettings.libraryPageSize(undefined) || undefined, @@ -293,28 +302,7 @@ const ViewItemsContainer: FC = ({ ParentId: topParentId }; }, [ - viewQuerySettings.imageType, - viewQuerySettings.showYear, - viewQuerySettings.IsPlayed, - viewQuerySettings.IsUnplayed, - viewQuerySettings.IsFavorite, - viewQuerySettings.IsResumable, - viewQuerySettings.IsHD, - viewQuerySettings.IsSD, - viewQuerySettings.SortBy, - viewQuerySettings.SortOrder, - viewQuerySettings.VideoTypes, - viewQuerySettings.GenreIds, - viewQuerySettings.Is4K, - viewQuerySettings.Is3D, - viewQuerySettings.HasSubtitles, - viewQuerySettings.HasTrailer, - viewQuerySettings.HasSpecialFeature, - viewQuerySettings.HasThemeSong, - viewQuerySettings.HasThemeVideo, - viewQuerySettings.StartIndex, - viewQuerySettings.NameLessThan, - viewQuerySettings.NameStartsWith, + viewQuerySettings, getItemTypes, getBasekey, topParentId From a6c8c63d2ed51be03858a280a3838cc5767e3142 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 26 Apr 2023 15:47:21 -0400 Subject: [PATCH 033/112] Fix complexity warnings in UserPasswordForm --- .../dashboard/users/UserPasswordForm.tsx | 80 ++++++++----------- 1 file changed, 33 insertions(+), 47 deletions(-) diff --git a/src/components/dashboard/users/UserPasswordForm.tsx b/src/components/dashboard/users/UserPasswordForm.tsx index 3d3daa2993..8cfb47b5b1 100644 --- a/src/components/dashboard/users/UserPasswordForm.tsx +++ b/src/components/dashboard/users/UserPasswordForm.tsx @@ -1,4 +1,3 @@ -import type { UserDto } from '@jellyfin/sdk/lib/generated-client'; import React, { FunctionComponent, useCallback, useEffect, useRef } from 'react'; import Dashboard from '../../../utils/dashboard'; import globalize from '../../../scripts/globalize'; @@ -17,7 +16,7 @@ type IProps = { const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { const element = useRef(null); - const loadUser = useCallback(() => { + const loadUser = useCallback(async () => { const page = element.current; if (!page) { @@ -25,61 +24,48 @@ const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { return; } - window.ApiClient.getUser(userId).then(function (user) { - Dashboard.getCurrentUser().then(function (loggedInUser: UserDto) { - if (!user.Policy) { - throw new Error('Unexpected null user.Policy'); - } + const user = await window.ApiClient.getUser(userId); + const loggedInUser = await Dashboard.getCurrentUser(); - if (!user.Configuration) { - throw new Error('Unexpected null user.Configuration'); - } + if (!user.Policy || !user.Configuration) { + throw new Error('Unexpected null user policy or configuration'); + } - LibraryMenu.setTitle(user.Name); + LibraryMenu.setTitle(user.Name); - let showLocalAccessSection = false; + let showLocalAccessSection = false; - if (user.HasConfiguredPassword) { - (page.querySelector('#btnResetPassword') as HTMLDivElement).classList.remove('hide'); - (page.querySelector('#fldCurrentPassword') as HTMLDivElement).classList.remove('hide'); - showLocalAccessSection = true; - } else { - (page.querySelector('#btnResetPassword') as HTMLDivElement).classList.add('hide'); - (page.querySelector('#fldCurrentPassword') as HTMLDivElement).classList.add('hide'); - } + if (user.HasConfiguredPassword) { + (page.querySelector('#btnResetPassword') as HTMLDivElement).classList.remove('hide'); + (page.querySelector('#fldCurrentPassword') as HTMLDivElement).classList.remove('hide'); + showLocalAccessSection = true; + } else { + (page.querySelector('#btnResetPassword') as HTMLDivElement).classList.add('hide'); + (page.querySelector('#fldCurrentPassword') as HTMLDivElement).classList.add('hide'); + } - if (loggedInUser?.Policy?.IsAdministrator || user.Policy.EnableUserPreferenceAccess) { - (page.querySelector('.passwordSection') as HTMLDivElement).classList.remove('hide'); - } else { - (page.querySelector('.passwordSection') as HTMLDivElement).classList.add('hide'); - } + const canChangePassword = loggedInUser?.Policy?.IsAdministrator || user.Policy.EnableUserPreferenceAccess; + (page.querySelector('.passwordSection') as HTMLDivElement).classList.toggle('hide', !canChangePassword); + (page.querySelector('.localAccessSection') as HTMLDivElement).classList.toggle('hide', !(showLocalAccessSection && canChangePassword)); - if (showLocalAccessSection && (loggedInUser?.Policy?.IsAdministrator || user.Policy.EnableUserPreferenceAccess)) { - (page.querySelector('.localAccessSection') as HTMLDivElement).classList.remove('hide'); - } else { - (page.querySelector('.localAccessSection') as HTMLDivElement).classList.add('hide'); - } + const txtEasyPassword = page.querySelector('#txtEasyPassword') as HTMLInputElement; + txtEasyPassword.value = ''; - const txtEasyPassword = page.querySelector('#txtEasyPassword') as HTMLInputElement; - txtEasyPassword.value = ''; + if (user.HasConfiguredEasyPassword) { + txtEasyPassword.placeholder = '******'; + (page.querySelector('#btnResetEasyPassword') as HTMLDivElement).classList.remove('hide'); + } else { + txtEasyPassword.removeAttribute('placeholder'); + txtEasyPassword.placeholder = ''; + (page.querySelector('#btnResetEasyPassword') as HTMLDivElement).classList.add('hide'); + } - if (user.HasConfiguredEasyPassword) { - txtEasyPassword.placeholder = '******'; - (page.querySelector('#btnResetEasyPassword') as HTMLDivElement).classList.remove('hide'); - } else { - txtEasyPassword.removeAttribute('placeholder'); - txtEasyPassword.placeholder = ''; - (page.querySelector('#btnResetEasyPassword') as HTMLDivElement).classList.add('hide'); - } + const chkEnableLocalEasyPassword = page.querySelector('.chkEnableLocalEasyPassword') as HTMLInputElement; - const chkEnableLocalEasyPassword = page.querySelector('.chkEnableLocalEasyPassword') as HTMLInputElement; + chkEnableLocalEasyPassword.checked = user.Configuration.EnableLocalPassword || false; - chkEnableLocalEasyPassword.checked = user.Configuration.EnableLocalPassword || false; - - import('../../autoFocuser').then(({ default: autoFocuser }) => { - autoFocuser.autoFocus(page); - }); - }); + import('../../autoFocuser').then(({ default: autoFocuser }) => { + autoFocuser.autoFocus(page); }); (page.querySelector('#txtCurrentPassword') as HTMLInputElement).value = ''; From 6fc90c174050f9d3d593623e3908246b0bac01db Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 26 Apr 2023 16:44:46 -0400 Subject: [PATCH 034/112] Fix complexity warnings in ConnectionRequired --- src/components/ConnectionRequired.tsx | 199 +++++++++++++------------- 1 file changed, 101 insertions(+), 98 deletions(-) diff --git a/src/components/ConnectionRequired.tsx b/src/components/ConnectionRequired.tsx index 9c5f402b0a..59e680e219 100644 --- a/src/components/ConnectionRequired.tsx +++ b/src/components/ConnectionRequired.tsx @@ -1,4 +1,4 @@ -import React, { FunctionComponent, useEffect, useState } from 'react'; +import React, { FunctionComponent, useCallback, useEffect, useState } from 'react'; import { Outlet, useLocation, useNavigate } from 'react-router-dom'; import type { ConnectResponse } from 'jellyfin-apiclient'; @@ -35,116 +35,119 @@ const ConnectionRequired: FunctionComponent = ({ const [ isLoading, setIsLoading ] = useState(true); - useEffect(() => { - const bounce = async (connectionResponse: ConnectResponse) => { - switch (connectionResponse.State) { - case ConnectionState.SignedIn: - // Already logged in, bounce to the home page - console.debug('[ConnectionRequired] already logged in, redirecting to home'); - navigate(BounceRoutes.Home); - return; - case ConnectionState.ServerSignIn: - // Bounce to the login page - if (location.pathname === BounceRoutes.Login) { - setIsLoading(false); - } else { - console.debug('[ConnectionRequired] not logged in, redirecting to login page'); - navigate(`${BounceRoutes.Login}?serverid=${connectionResponse.ApiClient.serverId()}`); - } - return; - case ConnectionState.ServerSelection: - // Bounce to select server page - console.debug('[ConnectionRequired] redirecting to select server page'); - navigate(BounceRoutes.SelectServer); - return; - case ConnectionState.ServerUpdateNeeded: - // Show update needed message and bounce to select server page - try { - await alert({ - text: globalize.translate('ServerUpdateNeeded', 'https://github.com/jellyfin/jellyfin'), - html: globalize.translate('ServerUpdateNeeded', 'https://github.com/jellyfin/jellyfin') - }); - } catch (ex) { - console.warn('[ConnectionRequired] failed to show alert', ex); - } - console.debug('[ConnectionRequired] server update required, redirecting to select server page'); - navigate(BounceRoutes.SelectServer); - return; - } - - console.warn('[ConnectionRequired] unhandled connection state', connectionResponse.State); - }; - - const validateConnection = async () => { - // Check connection status on initial page load - const firstConnection = appRouter.firstConnectionResult; - appRouter.firstConnectionResult = null; - - if (firstConnection && firstConnection.State !== ConnectionState.SignedIn) { - if (firstConnection.State === ConnectionState.ServerSignIn) { - // Verify the wizard is complete - try { - const infoResponse = await fetch(`${firstConnection.ApiClient.serverAddress()}/System/Info/Public`); - if (!infoResponse.ok) { - throw new Error('Public system info request failed'); - } - const systemInfo = await infoResponse.json(); - if (!systemInfo?.StartupWizardCompleted) { - // Update the current ApiClient - // TODO: Is there a better place to handle this? - ServerConnections.setLocalApiClient(firstConnection.ApiClient); - // Bounce to the wizard - console.info('[ConnectionRequired] startup wizard is not complete, redirecting there'); - navigate(BounceRoutes.StartWizard); - return; - } - } catch (ex) { - console.error('[ConnectionRequired] checking wizard status failed', ex); - return; - } + const bounce = useCallback(async (connectionResponse: ConnectResponse) => { + switch (connectionResponse.State) { + case ConnectionState.SignedIn: + // Already logged in, bounce to the home page + console.debug('[ConnectionRequired] already logged in, redirecting to home'); + navigate(BounceRoutes.Home); + return; + case ConnectionState.ServerSignIn: + // Bounce to the login page + if (location.pathname === BounceRoutes.Login) { + setIsLoading(false); + } else { + console.debug('[ConnectionRequired] not logged in, redirecting to login page'); + navigate(`${BounceRoutes.Login}?serverid=${connectionResponse.ApiClient.serverId()}`); } + return; + case ConnectionState.ServerSelection: + // Bounce to select server page + console.debug('[ConnectionRequired] redirecting to select server page'); + navigate(BounceRoutes.SelectServer); + return; + case ConnectionState.ServerUpdateNeeded: + // Show update needed message and bounce to select server page + try { + await alert({ + text: globalize.translate('ServerUpdateNeeded', 'https://github.com/jellyfin/jellyfin'), + html: globalize.translate('ServerUpdateNeeded', 'https://github.com/jellyfin/jellyfin') + }); + } catch (ex) { + console.warn('[ConnectionRequired] failed to show alert', ex); + } + console.debug('[ConnectionRequired] server update required, redirecting to select server page'); + navigate(BounceRoutes.SelectServer); + return; + } - // Bounce to the correct page in the login flow - bounce(firstConnection); + console.warn('[ConnectionRequired] unhandled connection state', connectionResponse.State); + }, [location.pathname, navigate]); + + const handleIncompleteWizard = useCallback(async (firstConnection: ConnectResponse) => { + if (firstConnection.State === ConnectionState.ServerSignIn) { + // Verify the wizard is complete + try { + const infoResponse = await fetch(`${firstConnection.ApiClient.serverAddress()}/System/Info/Public`); + if (!infoResponse.ok) { + throw new Error('Public system info request failed'); + } + const systemInfo = await infoResponse.json(); + if (!systemInfo?.StartupWizardCompleted) { + // Update the current ApiClient + // TODO: Is there a better place to handle this? + ServerConnections.setLocalApiClient(firstConnection.ApiClient); + // Bounce to the wizard + console.info('[ConnectionRequired] startup wizard is not complete, redirecting there'); + navigate(BounceRoutes.StartWizard); + return; + } + } catch (ex) { + console.error('[ConnectionRequired] checking wizard status failed', ex); return; } + } - // TODO: appRouter will call appHost.exit() if navigating back when you are already at the default route. - // This case will need to be handled elsewhere before appRouter can be killed. + // Bounce to the correct page in the login flow + bounce(firstConnection); + }, [bounce, navigate]); - const client = ServerConnections.currentApiClient(); + const validateUserAccess = useCallback(async () => { + const client = ServerConnections.currentApiClient(); - // If this is a user route, ensure a user is logged in - if ((isAdminRequired || isUserRequired) && !client?.isLoggedIn()) { - try { - console.warn('[ConnectionRequired] unauthenticated user attempted to access user route'); + // If this is a user route, ensure a user is logged in + if ((isAdminRequired || isUserRequired) && !client?.isLoggedIn()) { + try { + console.warn('[ConnectionRequired] unauthenticated user attempted to access user route'); + bounce(await ServerConnections.connect()); + } catch (ex) { + console.warn('[ConnectionRequired] error bouncing from user route', ex); + } + return; + } + + // If this is an admin route, ensure the user has access + if (isAdminRequired) { + try { + const user = await client?.getCurrentUser(); + if (!user?.Policy?.IsAdministrator) { + console.warn('[ConnectionRequired] normal user attempted to access admin route'); bounce(await ServerConnections.connect()); - } catch (ex) { - console.warn('[ConnectionRequired] error bouncing from user route', ex); - } - return; - } - - // If this is an admin route, ensure the user has access - if (isAdminRequired) { - try { - const user = await client?.getCurrentUser(); - if (!user?.Policy?.IsAdministrator) { - console.warn('[ConnectionRequired] normal user attempted to access admin route'); - bounce(await ServerConnections.connect()); - return; - } - } catch (ex) { - console.warn('[ConnectionRequired] error bouncing from admin route', ex); return; } + } catch (ex) { + console.warn('[ConnectionRequired] error bouncing from admin route', ex); + return; } + } - setIsLoading(false); - }; + setIsLoading(false); + }, [bounce, isAdminRequired, isUserRequired]); - validateConnection(); - }, [ isAdminRequired, isUserRequired, location.pathname, navigate ]); + useEffect(() => { + // TODO: appRouter will call appHost.exit() if navigating back when you are already at the default route. + // This case will need to be handled elsewhere before appRouter can be killed. + + // Check connection status on initial page load + const firstConnection = appRouter.firstConnectionResult; + appRouter.firstConnectionResult = null; + + if (firstConnection && firstConnection.State !== ConnectionState.SignedIn) { + handleIncompleteWizard(firstConnection); + } else { + validateUserAccess(); + } + }, [handleIncompleteWizard, validateUserAccess]); if (isLoading) { return ; From 6c6b841f41451fe80382fc5ed206e579da79e567 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 26 Apr 2023 16:53:31 -0400 Subject: [PATCH 035/112] Disable exhaustive dependency warnings where required --- src/components/ServerContentPage.tsx | 7 ++++--- src/components/viewManager/ViewManagerPage.tsx | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/ServerContentPage.tsx b/src/components/ServerContentPage.tsx index e5428269bc..5b86d66072 100644 --- a/src/components/ServerContentPage.tsx +++ b/src/components/ServerContentPage.tsx @@ -47,12 +47,13 @@ const ServerContentPage: FunctionComponent = ({ view }) }; loadPage(); - }, [ + }, + // location.state is NOT included as a dependency here since dialogs will update state while the current view stays the same + // eslint-disable-next-line react-hooks/exhaustive-deps + [ view, location.pathname, location.search - // location.state is NOT included as a dependency here since dialogs will update state while the current view - // stays the same ]); return <>; diff --git a/src/components/viewManager/ViewManagerPage.tsx b/src/components/viewManager/ViewManagerPage.tsx index 511338d1e2..98cf0dcb01 100644 --- a/src/components/viewManager/ViewManagerPage.tsx +++ b/src/components/viewManager/ViewManagerPage.tsx @@ -64,7 +64,10 @@ const ViewManagerPage: FunctionComponent = ({ }; loadPage(); - }, [ + }, + // location.state is NOT included as a dependency here since dialogs will update state while the current view stays the same + // eslint-disable-next-line react-hooks/exhaustive-deps + [ controller, view, type, @@ -74,8 +77,6 @@ const ViewManagerPage: FunctionComponent = ({ transition, location.pathname, location.search - // location.state is NOT included as a dependency here since dialogs will update state while the current view - // stays the same ]); return <>; From 675135d3a3848a432c3f20b1662b80dbb9a3db48 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Apr 2023 00:01:39 +0000 Subject: [PATCH 036/112] Update github/codeql-action action to v2.3.1 --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 76f544d9fd..dd5d5fb523 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -21,11 +21,11 @@ jobs: - name: Checkout repository uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Initialize CodeQL - uses: github/codeql-action/init@b2c19fb9a2a485599ccf4ed5d65527d94bc57226 # v2.3.0 + uses: github/codeql-action/init@8662eabe0e9f338a07350b7fd050732745f93848 # v2.3.1 with: languages: ${{ matrix.language }} queries: +security-extended - name: Autobuild - uses: github/codeql-action/autobuild@b2c19fb9a2a485599ccf4ed5d65527d94bc57226 # v2.3.0 + uses: github/codeql-action/autobuild@8662eabe0e9f338a07350b7fd050732745f93848 # v2.3.1 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b2c19fb9a2a485599ccf4ed5d65527d94bc57226 # v2.3.0 + uses: github/codeql-action/analyze@8662eabe0e9f338a07350b7fd050732745f93848 # v2.3.1 From 372e57027322a63882fa30bcfe590719f543c201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9A=87=E7=94=AB=E6=9C=9D=E4=BA=91?= Date: Thu, 27 Apr 2023 02:19:19 +0000 Subject: [PATCH 037/112] Translated using Weblate (Chinese (Simplified)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/ --- src/strings/zh-cn.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index 8818053189..ed2ca9457d 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -1353,7 +1353,7 @@ "LabelOpenclDevice": "OpenCL 设备", "LabelOpenclDeviceHelp": "这是用于色调映射的 OpenCL 设备。 点左边是平台号,右边是平台上的设备号。 默认值为 0.0。 需要支持OpenCL 硬件加速的 FFmpeg 应用程序。", "EnableTonemapping": "启用色调映射", - "AllowTonemappingHelp": "色调映射可以将视频的动态范围从 HDR 变换成 SDR,同时保持图像细节与颜色等对于表现原始场景非常重要的信息。目前仅对 HDR10 或 HLG 视频生效。此项需要对应的 OpenCL 或 CUDA 运行库。", + "AllowTonemappingHelp": "色调映射可以将视频的动态范围从 HDR 变换成 SDR,同时保持图像细节与颜色等对于表现原始场景非常重要的信息。目前仅对 HDR10 、HLG10bit HDR10、HLG和DoVi视频生效。此项需要对应的 OpenCL 或 CUDA 运行库。", "LabelTonemappingAlgorithm": "选择要使用的色调映射算法", "TonemappingAlgorithmHelp": "色调映射可以微调。如果你不是很熟悉这些选项,保持默认即可。建议值为 'BT.2390'。", "LabelTonemappingRange": "色调映射范围", @@ -1666,10 +1666,10 @@ "MediaInfoVideoRangeType": "动态范围类型", "LabelVideoRangeType": "动态范围类型", "VideoRangeTypeNotSupported": "视频动态范围不支持", - "LabelVppTonemappingContrastHelp": "在 VPP 色调映射中应用对比度增益。推荐值和默认值分别为 1.2 和 1。", + "LabelVppTonemappingContrastHelp": "在 VPP 色调映射中应用对比度增益。推荐值和默认值均为 1。", "LabelVppTonemappingBrightness": "VPP 色调映射亮度增益", "LabelVppTonemappingContrast": "VPP 色调映射对比度增益", - "LabelVppTonemappingBrightnessHelp": "在 VPP 色调映射中应用亮度增益。推荐值和默认值均为 0。", + "LabelVppTonemappingBrightnessHelp": "在 VPP 色调映射中应用亮度增益。推荐值和默认值为16和 0。", "ScreenResolution": "屏幕分辨率", "LabelMaxVideoResolution": "允许的最大视频转码分辨率", "RememberSubtitleSelectionsHelp": "尝试将字幕轨道设置为与最后一个视频最接近的匹配。", @@ -1723,5 +1723,6 @@ "LabelEnableAudioVbr": "启用 VBR 音频编码", "LabelEnableAudioVbrHelp": "可变比特率(VBR)相比平均比特率(ABR)可以提供更好的质量,但在少见情况中可能造成缓冲和兼容性问题。", "LabelTonemappingMode": "色调映射模式", - "TonemappingModeHelp": "如果您遇到高光过曝问题,请尝试切换到 RGB 模式。" + "TonemappingModeHelp": "如果您遇到高光过曝问题,请尝试切换到 RGB 模式。", + "Select": "选择" } From d8fe05fb4a9a615102788a35fb5334176357b07f Mon Sep 17 00:00:00 2001 From: stanol Date: Thu, 27 Apr 2023 09:08:02 +0000 Subject: [PATCH 038/112] Translated using Weblate (Ukrainian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/ --- src/strings/uk.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/strings/uk.json b/src/strings/uk.json index 5183ac4fc0..dec608a738 100644 --- a/src/strings/uk.json +++ b/src/strings/uk.json @@ -1719,5 +1719,7 @@ "LabelParallelImageEncodingLimitHelp": "Максимальна кількість кодувань зображень, які дозволено запускати паралельно. Якщо встановити значення 0, буде обрано обмеження на основі характеристик вашої системи.", "LabelEnableAudioVbrHelp": "Змінний бітрейт забезпечує краще співвідношення якості до середнього бітрейту, але в деяких рідкісних випадках може спричинити проблеми з буферизацією та сумісністю.", "LabelEnableAudioVbr": "Увімкнути VBR", - "Select": "Вибрати" + "Select": "Вибрати", + "LabelTonemappingMode": "Режим тонального відображення", + "TonemappingModeHelp": "Виберіть режим тонального відображення. Якщо ви спостерігаєте вигоряння яскравих ділянок, спробуйте переключитися в режим RGB." } From cfe016ad7ac1963b75988d5a1d6b664b07ef50cc Mon Sep 17 00:00:00 2001 From: stanol Date: Thu, 27 Apr 2023 19:28:45 +0000 Subject: [PATCH 039/112] Translated using Weblate (Ukrainian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/ --- src/strings/uk.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/uk.json b/src/strings/uk.json index dec608a738..52c426fde7 100644 --- a/src/strings/uk.json +++ b/src/strings/uk.json @@ -370,7 +370,7 @@ "LabelAutomaticallyRefreshInternetMetadataEvery": "Автоматично оновлювати метадані з інтернету", "LabelAuthProvider": "Провайдер аутентіфікаціі", "LabelAudioLanguagePreference": "Бажана мова аудіо", - "LabelAudioCodec": "Кодек аудіо", + "LabelAudioCodec": "Аудіокодек", "LabelAudioChannels": "Аудіоканали", "LabelAudioBitrate": "Бітрейт аудіо", "LabelArtists": "Виконавці", From c17c23fd8eb42981fddcf7e88c55166a9417b75a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Apr 2023 21:29:57 +0000 Subject: [PATCH 040/112] Update github/codeql-action action to v2.3.2 --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index dd5d5fb523..240f558cfb 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -21,11 +21,11 @@ jobs: - name: Checkout repository uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Initialize CodeQL - uses: github/codeql-action/init@8662eabe0e9f338a07350b7fd050732745f93848 # v2.3.1 + uses: github/codeql-action/init@f3feb00acb00f31a6f60280e6ace9ca31d91c76a # v2.3.2 with: languages: ${{ matrix.language }} queries: +security-extended - name: Autobuild - uses: github/codeql-action/autobuild@8662eabe0e9f338a07350b7fd050732745f93848 # v2.3.1 + uses: github/codeql-action/autobuild@f3feb00acb00f31a6f60280e6ace9ca31d91c76a # v2.3.2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8662eabe0e9f338a07350b7fd050732745f93848 # v2.3.1 + uses: github/codeql-action/analyze@f3feb00acb00f31a6f60280e6ace9ca31d91c76a # v2.3.2 From d748372a286ca736e603f3ec92546dc9f6b9f253 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 27 Apr 2023 17:04:33 -0400 Subject: [PATCH 041/112] Refactor app structure --- README.md | 33 ++++++++++--------- src/{App.tsx => RootApp.tsx} | 15 ++++++--- src/apps/experimental/App.tsx | 19 +++++++++++ .../experimental/routes/AppRoutes.tsx} | 8 ++--- .../experimental/routes}/asyncRoutes/admin.ts | 2 +- .../experimental/routes}/asyncRoutes/index.ts | 0 .../experimental/routes}/asyncRoutes/user.ts | 2 +- .../routes}/legacyRoutes/admin.ts | 2 +- .../routes}/legacyRoutes/index.ts | 0 .../routes}/legacyRoutes/public.ts | 2 +- .../experimental/routes}/legacyRoutes/user.ts | 2 +- src/apps/stable/App.tsx | 19 +++++++++++ .../stable/routes/AppRoutes.tsx} | 8 ++--- .../stable/routes}/asyncRoutes/index.ts | 0 .../stable/routes}/asyncRoutes/user.ts | 2 +- .../stable/routes}/legacyRoutes/admin.ts | 2 +- .../stable/routes}/legacyRoutes/index.ts | 0 .../stable/routes}/legacyRoutes/public.ts | 2 +- .../stable/routes}/legacyRoutes/user.ts | 2 +- .../router}/AsyncRoute.tsx | 2 +- .../router}/LegacyRoute.tsx | 2 +- src/index.jsx | 4 +-- src/routes/index.tsx | 2 -- 23 files changed, 88 insertions(+), 42 deletions(-) rename src/{App.tsx => RootApp.tsx} (60%) create mode 100644 src/apps/experimental/App.tsx rename src/{routes/experimentalAppRoutes/index.tsx => apps/experimental/routes/AppRoutes.tsx} (82%) rename src/{routes/experimentalAppRoutes => apps/experimental/routes}/asyncRoutes/admin.ts (85%) rename src/{routes/experimentalAppRoutes => apps/experimental/routes}/asyncRoutes/index.ts (100%) rename src/{routes/experimentalAppRoutes => apps/experimental/routes}/asyncRoutes/user.ts (77%) rename src/{routes/experimentalAppRoutes => apps/experimental/routes}/legacyRoutes/admin.ts (98%) rename src/{routes/appRoutes => apps/experimental/routes}/legacyRoutes/index.ts (100%) rename src/{routes/appRoutes => apps/experimental/routes}/legacyRoutes/public.ts (96%) rename src/{routes/experimentalAppRoutes => apps/experimental/routes}/legacyRoutes/user.ts (97%) create mode 100644 src/apps/stable/App.tsx rename src/{routes/appRoutes/index.tsx => apps/stable/routes/AppRoutes.tsx} (81%) rename src/{routes/appRoutes => apps/stable/routes}/asyncRoutes/index.ts (100%) rename src/{routes/appRoutes => apps/stable/routes}/asyncRoutes/user.ts (57%) rename src/{routes/appRoutes => apps/stable/routes}/legacyRoutes/admin.ts (98%) rename src/{routes/experimentalAppRoutes => apps/stable/routes}/legacyRoutes/index.ts (100%) rename src/{routes/experimentalAppRoutes => apps/stable/routes}/legacyRoutes/public.ts (96%) rename src/{routes/appRoutes => apps/stable/routes}/legacyRoutes/user.ts (97%) rename src/{routes => components/router}/AsyncRoute.tsx (89%) rename src/{routes => components/router}/LegacyRoute.tsx (80%) delete mode 100644 src/routes/index.tsx diff --git a/README.md b/README.md index 99637125ae..bcb0c53311 100644 --- a/README.md +++ b/README.md @@ -76,21 +76,24 @@ Jellyfin Web is the frontend used for most of the clients available for end user ``` . └── src - ├── assets # Static assets - ├── components # Higher order visual components and React components - ├── controllers # Legacy page views and controllers 🧹 - ├── elements # Basic webcomponents and React wrappers 🧹 - ├── hooks # Custom React hooks - ├── legacy # Polyfills for legacy browsers - ├── libraries # Third party libraries 🧹 - ├── plugins # Client plugins - ├── routes # React routes/pages - ├── scripts # Random assortment of visual components and utilities 🐉 - ├── strings # Translation files - ├── styles # Common app Sass stylesheets - ├── themes # CSS themes - ├── types # Common TypeScript interfaces/types - └── utils # Utility functions + ├── apps + │   ├── experimental # New experimental app layout + │   └── stable # Classic (stable) app layout + ├── assets # Static assets + ├── components # Higher order visual components and React components + ├── controllers # Legacy page views and controllers 🧹 + ├── elements # Basic webcomponents and React wrappers 🧹 + ├── hooks # Custom React hooks + ├── legacy # Polyfills for legacy browsers + ├── libraries # Third party libraries 🧹 + ├── plugins # Client plugins + ├── routes # React routes/pages + ├── scripts # Random assortment of visual components and utilities 🐉 + ├── strings # Translation files + ├── styles # Common app Sass stylesheets + ├── themes # CSS themes + ├── types # Common TypeScript interfaces/types + └── utils # Utility functions ``` - 🧹 — Needs cleanup diff --git a/src/App.tsx b/src/RootApp.tsx similarity index 60% rename from src/App.tsx rename to src/RootApp.tsx index d72fd3831e..dddf31b5b1 100644 --- a/src/App.tsx +++ b/src/RootApp.tsx @@ -1,13 +1,16 @@ +import loadable from '@loadable/component'; import { History } from '@remix-run/router'; import React from 'react'; +import StableApp from './apps/stable/App'; import AppHeader from './components/AppHeader'; import Backdrop from './components/Backdrop'; import { HistoryRouter } from './components/HistoryRouter'; import { ApiProvider } from './hooks/useApi'; -import { AppRoutes, ExperimentalAppRoutes } from './routes'; -const App = ({ history }: { history: History }) => { +const ExperimentalApp = loadable(() => import('./apps/experimental/App')); + +const RootApp = ({ history }: { history: History }) => { const layoutMode = localStorage.getItem('layout'); return ( @@ -18,11 +21,15 @@ const App = ({ history }: { history: History }) => {
- {layoutMode === 'experimental' ? : } + { + layoutMode === 'experimental' ? + : + + }
); }; -export default App; +export default RootApp; diff --git a/src/apps/experimental/App.tsx b/src/apps/experimental/App.tsx new file mode 100644 index 0000000000..842cdaf38a --- /dev/null +++ b/src/apps/experimental/App.tsx @@ -0,0 +1,19 @@ +import React from 'react'; + +import AppHeader from '../../components/AppHeader'; +import Backdrop from '../../components/Backdrop'; +import { ExperimentalAppRoutes } from './routes/AppRoutes'; + +const ExperimentalApp = () => ( + <> + + + +
+
+ +
+ +); + +export default ExperimentalApp; diff --git a/src/routes/experimentalAppRoutes/index.tsx b/src/apps/experimental/routes/AppRoutes.tsx similarity index 82% rename from src/routes/experimentalAppRoutes/index.tsx rename to src/apps/experimental/routes/AppRoutes.tsx index bd4cf8a19f..e87476c554 100644 --- a/src/routes/experimentalAppRoutes/index.tsx +++ b/src/apps/experimental/routes/AppRoutes.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { Navigate, Route, Routes } from 'react-router-dom'; -import ConnectionRequired from '../../components/ConnectionRequired'; -import ServerContentPage from '../../components/ServerContentPage'; -import { toAsyncPageRoute } from '../AsyncRoute'; -import { toViewManagerPageRoute } from '../LegacyRoute'; +import ConnectionRequired from '../../../components/ConnectionRequired'; +import ServerContentPage from '../../../components/ServerContentPage'; +import { toAsyncPageRoute } from '../../../components/router/AsyncRoute'; +import { toViewManagerPageRoute } from '../../../components/router/LegacyRoute'; import { ASYNC_ADMIN_ROUTES, ASYNC_USER_ROUTES } from './asyncRoutes'; import { LEGACY_ADMIN_ROUTES, LEGACY_PUBLIC_ROUTES, LEGACY_USER_ROUTES } from './legacyRoutes'; diff --git a/src/routes/experimentalAppRoutes/asyncRoutes/admin.ts b/src/apps/experimental/routes/asyncRoutes/admin.ts similarity index 85% rename from src/routes/experimentalAppRoutes/asyncRoutes/admin.ts rename to src/apps/experimental/routes/asyncRoutes/admin.ts index 3c75058288..0f2ec6b9cf 100644 --- a/src/routes/experimentalAppRoutes/asyncRoutes/admin.ts +++ b/src/apps/experimental/routes/asyncRoutes/admin.ts @@ -1,4 +1,4 @@ -import { AsyncRoute } from '../../AsyncRoute'; +import { AsyncRoute } from '../../../../components/router/AsyncRoute'; export const ASYNC_ADMIN_ROUTES: AsyncRoute[] = [ { path: 'usernew.html', page: 'user/usernew' }, diff --git a/src/routes/experimentalAppRoutes/asyncRoutes/index.ts b/src/apps/experimental/routes/asyncRoutes/index.ts similarity index 100% rename from src/routes/experimentalAppRoutes/asyncRoutes/index.ts rename to src/apps/experimental/routes/asyncRoutes/index.ts diff --git a/src/routes/experimentalAppRoutes/asyncRoutes/user.ts b/src/apps/experimental/routes/asyncRoutes/user.ts similarity index 77% rename from src/routes/experimentalAppRoutes/asyncRoutes/user.ts rename to src/apps/experimental/routes/asyncRoutes/user.ts index 7126b0f2ad..44674e888c 100644 --- a/src/routes/experimentalAppRoutes/asyncRoutes/user.ts +++ b/src/apps/experimental/routes/asyncRoutes/user.ts @@ -1,4 +1,4 @@ -import { AsyncRoute } from '../../AsyncRoute'; +import { AsyncRoute } from '../../../../components/router/AsyncRoute'; export const ASYNC_USER_ROUTES: AsyncRoute[] = [ { path: 'search.html', page: 'search' }, diff --git a/src/routes/experimentalAppRoutes/legacyRoutes/admin.ts b/src/apps/experimental/routes/legacyRoutes/admin.ts similarity index 98% rename from src/routes/experimentalAppRoutes/legacyRoutes/admin.ts rename to src/apps/experimental/routes/legacyRoutes/admin.ts index 16365e4fc8..dd1f95f6e5 100644 --- a/src/routes/experimentalAppRoutes/legacyRoutes/admin.ts +++ b/src/apps/experimental/routes/legacyRoutes/admin.ts @@ -1,4 +1,4 @@ -import { LegacyRoute } from '../../LegacyRoute'; +import { LegacyRoute } from '../../../../components/router/LegacyRoute'; export const LEGACY_ADMIN_ROUTES: LegacyRoute[] = [ { diff --git a/src/routes/appRoutes/legacyRoutes/index.ts b/src/apps/experimental/routes/legacyRoutes/index.ts similarity index 100% rename from src/routes/appRoutes/legacyRoutes/index.ts rename to src/apps/experimental/routes/legacyRoutes/index.ts diff --git a/src/routes/appRoutes/legacyRoutes/public.ts b/src/apps/experimental/routes/legacyRoutes/public.ts similarity index 96% rename from src/routes/appRoutes/legacyRoutes/public.ts rename to src/apps/experimental/routes/legacyRoutes/public.ts index 15f8f0e8a9..4fdb6a9395 100644 --- a/src/routes/appRoutes/legacyRoutes/public.ts +++ b/src/apps/experimental/routes/legacyRoutes/public.ts @@ -1,4 +1,4 @@ -import { LegacyRoute } from '../../LegacyRoute'; +import { LegacyRoute } from '../../../../components/router/LegacyRoute'; export const LEGACY_PUBLIC_ROUTES: LegacyRoute[] = [ { diff --git a/src/routes/experimentalAppRoutes/legacyRoutes/user.ts b/src/apps/experimental/routes/legacyRoutes/user.ts similarity index 97% rename from src/routes/experimentalAppRoutes/legacyRoutes/user.ts rename to src/apps/experimental/routes/legacyRoutes/user.ts index cc41c99957..49afc715f1 100644 --- a/src/routes/experimentalAppRoutes/legacyRoutes/user.ts +++ b/src/apps/experimental/routes/legacyRoutes/user.ts @@ -1,4 +1,4 @@ -import { LegacyRoute } from '../../LegacyRoute'; +import { LegacyRoute } from '../../../../components/router/LegacyRoute'; export const LEGACY_USER_ROUTES: LegacyRoute[] = [ { diff --git a/src/apps/stable/App.tsx b/src/apps/stable/App.tsx new file mode 100644 index 0000000000..7d619f6230 --- /dev/null +++ b/src/apps/stable/App.tsx @@ -0,0 +1,19 @@ +import React from 'react'; + +import AppHeader from '../../components/AppHeader'; +import Backdrop from '../../components/Backdrop'; +import { AppRoutes } from './routes/AppRoutes'; + +const StableApp = () => ( + <> + + + +
+
+ +
+ +); + +export default StableApp; diff --git a/src/routes/appRoutes/index.tsx b/src/apps/stable/routes/AppRoutes.tsx similarity index 81% rename from src/routes/appRoutes/index.tsx rename to src/apps/stable/routes/AppRoutes.tsx index 0136dc5531..cdeaedfe54 100644 --- a/src/routes/appRoutes/index.tsx +++ b/src/apps/stable/routes/AppRoutes.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { Navigate, Route, Routes } from 'react-router-dom'; -import ConnectionRequired from '../../components/ConnectionRequired'; -import ServerContentPage from '../../components/ServerContentPage'; -import { toAsyncPageRoute } from '../AsyncRoute'; -import { toViewManagerPageRoute } from '../LegacyRoute'; +import ConnectionRequired from '../../../components/ConnectionRequired'; +import ServerContentPage from '../../../components/ServerContentPage'; +import { toAsyncPageRoute } from '../../../components/router/AsyncRoute'; +import { toViewManagerPageRoute } from '../../../components/router/LegacyRoute'; import { ASYNC_USER_ROUTES } from './asyncRoutes'; import { LEGACY_ADMIN_ROUTES, LEGACY_PUBLIC_ROUTES, LEGACY_USER_ROUTES } from './legacyRoutes'; diff --git a/src/routes/appRoutes/asyncRoutes/index.ts b/src/apps/stable/routes/asyncRoutes/index.ts similarity index 100% rename from src/routes/appRoutes/asyncRoutes/index.ts rename to src/apps/stable/routes/asyncRoutes/index.ts diff --git a/src/routes/appRoutes/asyncRoutes/user.ts b/src/apps/stable/routes/asyncRoutes/user.ts similarity index 57% rename from src/routes/appRoutes/asyncRoutes/user.ts rename to src/apps/stable/routes/asyncRoutes/user.ts index 23621101be..7b86c9c7c0 100644 --- a/src/routes/appRoutes/asyncRoutes/user.ts +++ b/src/apps/stable/routes/asyncRoutes/user.ts @@ -1,4 +1,4 @@ -import { AsyncRoute } from '../../AsyncRoute'; +import { AsyncRoute } from '../../../../components/router/AsyncRoute'; export const ASYNC_USER_ROUTES: AsyncRoute[] = [ { path: 'search.html', page: 'search' } diff --git a/src/routes/appRoutes/legacyRoutes/admin.ts b/src/apps/stable/routes/legacyRoutes/admin.ts similarity index 98% rename from src/routes/appRoutes/legacyRoutes/admin.ts rename to src/apps/stable/routes/legacyRoutes/admin.ts index 055f97c57f..0f358a5d65 100644 --- a/src/routes/appRoutes/legacyRoutes/admin.ts +++ b/src/apps/stable/routes/legacyRoutes/admin.ts @@ -1,4 +1,4 @@ -import { LegacyRoute } from '../../LegacyRoute'; +import { LegacyRoute } from '../../../../components/router/LegacyRoute'; export const LEGACY_ADMIN_ROUTES: LegacyRoute[] = [ { diff --git a/src/routes/experimentalAppRoutes/legacyRoutes/index.ts b/src/apps/stable/routes/legacyRoutes/index.ts similarity index 100% rename from src/routes/experimentalAppRoutes/legacyRoutes/index.ts rename to src/apps/stable/routes/legacyRoutes/index.ts diff --git a/src/routes/experimentalAppRoutes/legacyRoutes/public.ts b/src/apps/stable/routes/legacyRoutes/public.ts similarity index 96% rename from src/routes/experimentalAppRoutes/legacyRoutes/public.ts rename to src/apps/stable/routes/legacyRoutes/public.ts index 15f8f0e8a9..4fdb6a9395 100644 --- a/src/routes/experimentalAppRoutes/legacyRoutes/public.ts +++ b/src/apps/stable/routes/legacyRoutes/public.ts @@ -1,4 +1,4 @@ -import { LegacyRoute } from '../../LegacyRoute'; +import { LegacyRoute } from '../../../../components/router/LegacyRoute'; export const LEGACY_PUBLIC_ROUTES: LegacyRoute[] = [ { diff --git a/src/routes/appRoutes/legacyRoutes/user.ts b/src/apps/stable/routes/legacyRoutes/user.ts similarity index 97% rename from src/routes/appRoutes/legacyRoutes/user.ts rename to src/apps/stable/routes/legacyRoutes/user.ts index 4179907cb4..8f460dcbc2 100644 --- a/src/routes/appRoutes/legacyRoutes/user.ts +++ b/src/apps/stable/routes/legacyRoutes/user.ts @@ -1,4 +1,4 @@ -import { LegacyRoute } from '../../LegacyRoute'; +import { LegacyRoute } from '../../../../components/router/LegacyRoute'; export const LEGACY_USER_ROUTES: LegacyRoute[] = [ { diff --git a/src/routes/AsyncRoute.tsx b/src/components/router/AsyncRoute.tsx similarity index 89% rename from src/routes/AsyncRoute.tsx rename to src/components/router/AsyncRoute.tsx index ba5bc90c42..6fb189e8bf 100644 --- a/src/routes/AsyncRoute.tsx +++ b/src/components/router/AsyncRoute.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Route } from 'react-router-dom'; -import AsyncPage from '../components/AsyncPage'; +import AsyncPage from '../AsyncPage'; export interface AsyncRoute { /** The URL path for this route. */ diff --git a/src/routes/LegacyRoute.tsx b/src/components/router/LegacyRoute.tsx similarity index 80% rename from src/routes/LegacyRoute.tsx rename to src/components/router/LegacyRoute.tsx index f548a122cc..bba780a513 100644 --- a/src/routes/LegacyRoute.tsx +++ b/src/components/router/LegacyRoute.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Route } from 'react-router-dom'; -import ViewManagerPage, { ViewManagerPageProps } from '../components/viewManager/ViewManagerPage'; +import ViewManagerPage, { ViewManagerPageProps } from '../viewManager/ViewManagerPage'; export interface LegacyRoute { path: string, diff --git a/src/index.jsx b/src/index.jsx index 87e4fde803..2b9aafbd5d 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -34,7 +34,7 @@ import './legacy/htmlMediaElement'; import './legacy/vendorStyles'; import { currentSettings } from './scripts/settings/userSettings'; import taskButton from './scripts/taskbutton'; -import App from './App.tsx'; +import RootApp from './RootApp.tsx'; import './styles/livetv.scss'; import './styles/dashboard.scss'; @@ -151,7 +151,7 @@ async function onAppReady() { ReactDOM.render( - + , root ); diff --git a/src/routes/index.tsx b/src/routes/index.tsx deleted file mode 100644 index d06d48a747..0000000000 --- a/src/routes/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from './appRoutes'; -export * from './experimentalAppRoutes'; From ffed8c6a6509e5aa6df70131b8ad32e7a0c3dce6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 16:14:54 +0000 Subject: [PATCH 042/112] Update dependency swiper to v9.2.4 --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0ee9c9b56e..b53fed83c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,7 @@ "resize-observer-polyfill": "1.5.1", "screenfull": "6.0.2", "sortablejs": "1.15.0", - "swiper": "9.2.3", + "swiper": "9.2.4", "webcomponents.js": "0.7.24", "whatwg-fetch": "3.6.2", "workbox-core": "6.5.4", @@ -18149,9 +18149,9 @@ } }, "node_modules/swiper": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.2.3.tgz", - "integrity": "sha512-hxqcjIsYPP1fv+KIXPqGywl6ik8RBp0y0i9+TOIh55ca6SpZ5FrgNJ4QXPhsl6mlSBMEYPmh5zOKtZpI8zpWeQ==", + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.2.4.tgz", + "integrity": "sha512-L7y3K/iiMXNYQ94FbfcJn7jex4QPnS4+voXGupTdC+UHW4XrR40QDdm4c9hXJ+Br0Il7PP0vP1W3goM9/Ly6Sg==", "funding": [ { "type": "patreon", @@ -33433,9 +33433,9 @@ } }, "swiper": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.2.3.tgz", - "integrity": "sha512-hxqcjIsYPP1fv+KIXPqGywl6ik8RBp0y0i9+TOIh55ca6SpZ5FrgNJ4QXPhsl6mlSBMEYPmh5zOKtZpI8zpWeQ==", + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.2.4.tgz", + "integrity": "sha512-L7y3K/iiMXNYQ94FbfcJn7jex4QPnS4+voXGupTdC+UHW4XrR40QDdm4c9hXJ+Br0Il7PP0vP1W3goM9/Ly6Sg==", "requires": { "ssr-window": "^4.0.2" } diff --git a/package.json b/package.json index f6d1d59d3b..cbcf24fa10 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "resize-observer-polyfill": "1.5.1", "screenfull": "6.0.2", "sortablejs": "1.15.0", - "swiper": "9.2.3", + "swiper": "9.2.4", "webcomponents.js": "0.7.24", "whatwg-fetch": "3.6.2", "workbox-core": "6.5.4", From 4967c0efcf0447719fffc0601cc54f417695a8f9 Mon Sep 17 00:00:00 2001 From: Kotsasmin Date: Fri, 28 Apr 2023 14:50:24 +0000 Subject: [PATCH 043/112] Translated using Weblate (Greek) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/el/ --- src/strings/el.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/el.json b/src/strings/el.json index 49d512e462..5584a0fca2 100644 --- a/src/strings/el.json +++ b/src/strings/el.json @@ -1087,7 +1087,7 @@ "MusicVideos": "Μουσικά Βίντεο", "Bwdif": "BWDIF", "Arranger": "Ταξιθέτηση", - "AllowTonemappingHelp": "Η αντιστοίχηση απόχρωσης μπορεί να αλλάξει το δυναμικό εύρος ενός βίντεο από HDR σε SDR διατηρώντας την ευκρίνεια και τα χρώματα της εικόνας, τα οποία είναι σημαντικές πληροφορίες για την απόδοση της αρχικής σκηνής. Προς το παρόν δουλεύει μόνο όταν μετακωδικοποιούνται βίντεο με ενσωματωμένα μεταδεδομένα HDR10 ή HLG. Αυτή η επιλογή απαιτεί OpenCL ή CUDA.", + "AllowTonemappingHelp": "Η αντιστοίχηση απόχρωσης μπορεί να αλλάξει το δυναμικό εύρος ενός βίντεο από HDR σε SDR διατηρώντας την ευκρίνεια και τα χρώματα της εικόνας, τα οποία είναι σημαντικές πληροφορίες για την απόδοση της αρχικής σκηνής. Προς το παρόν δουλεύει μόνο όταν μετακωδικοποιούνται βίντεο με ενσωματωμένα μεταδεδομένα 10bit HDR10, HLG και DoVi. Αυτή η επιλογή απαιτεί OpenCL ή CUDA.", "AgeValue": "({0} έτη)", "OptionBluray": "BD", "MediaInfoTimestamp": "Xρονική σφραγίδα", From d7500ba6c908308359b7be354986e51882ff32c6 Mon Sep 17 00:00:00 2001 From: sleepycatcoding Date: Fri, 28 Apr 2023 15:58:51 +0000 Subject: [PATCH 044/112] Translated using Weblate (Estonian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/et/ --- src/strings/et.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/strings/et.json b/src/strings/et.json index 62442bdd45..e4e4f61bff 100644 --- a/src/strings/et.json +++ b/src/strings/et.json @@ -285,7 +285,7 @@ "CustomDlnaProfilesHelp": "Loo kohandatud profiil uue seadme jaoks või tühista süsteemi profiil.", "ConfigureDateAdded": "Seadista, kuidas lisamise kuupäev kuvatakse juhtpaneeli meediakogu seadetes", "Banner": "Bänner", - "AllowTonemappingHelp": "Värvikaardistus võib muuta video dünaamilise ulatuse HDR -st SDR -ks, säilitades samal ajal pildi üksikasjad ja värvid, mis on algse stseeni kujutamisel väga oluline teave. Praegu töötab ainult HDR10 või HLG videotega. See vajab vastavat OpenGL või CUDA käitusaega.", + "AllowTonemappingHelp": "Värvikaardistus võib muuta video dünaamilise ulatuse HDR -st SDR -ks, säilitades samal ajal pildi üksikasjad ja värvid, mis on algse stseeni kujutamisel väga oluline teave. Praegu töötab ainult 10-bitise HDR10, HLG või DoVi videotega. See vajab vastavat OpenGL või CUDA käitusaega.", "HeaderDirectPlayProfile": "Otse-esituse profiil", "HeaderContainerProfileHelp": "Konteineri profiilid näitavad seadme piiranguid teatud vormingute esitamisel. Kui kehtib piirang, meedium transkooditakse, isegi kui vorming on seadistatud otse-esituseks.", "HeaderCodecProfileHelp": "Koodeki profiilid näitavad seadme piiranguid konkreetsete koodekite esitamisel. Kui kehtivad piirangud, transkooditakse meedia, isegi kui koodek on seadistatud otse-esituseks.", @@ -1652,5 +1652,8 @@ "Experimental": "Eksperimentaalne", "HeaderRecordingMetadataSaving": "Salvestise metaandmed", "HeaderPerformance": "Jõudlus", - "IgnoreDts": "Ignoreeri DTS-i (dekodeerimise ajatempel)" + "IgnoreDts": "Ignoreeri DTS-i (dekodeerimise ajatempel)", + "Select": "Vali", + "EnableIntelLowPowerH264HwEncoder": "Luba Intel Low-Power H.264 riistvara kodeerija", + "HeaderDummyChapter": "Peatükipildid" } From 5360df52c08e7bb83d57a371c2ca3f0b0ae41409 Mon Sep 17 00:00:00 2001 From: Nyanmisaka <799610810@qq.com> Date: Sat, 29 Apr 2023 19:17:19 +0000 Subject: [PATCH 045/112] Translated using Weblate (Chinese (Simplified)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/ --- src/strings/zh-cn.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index ed2ca9457d..0b94f633dd 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -1353,7 +1353,7 @@ "LabelOpenclDevice": "OpenCL 设备", "LabelOpenclDeviceHelp": "这是用于色调映射的 OpenCL 设备。 点左边是平台号,右边是平台上的设备号。 默认值为 0.0。 需要支持OpenCL 硬件加速的 FFmpeg 应用程序。", "EnableTonemapping": "启用色调映射", - "AllowTonemappingHelp": "色调映射可以将视频的动态范围从 HDR 变换成 SDR,同时保持图像细节与颜色等对于表现原始场景非常重要的信息。目前仅对 HDR10 、HLG10bit HDR10、HLG和DoVi视频生效。此项需要对应的 OpenCL 或 CUDA 运行库。", + "AllowTonemappingHelp": "色调映射可以将视频的动态范围从 HDR 变换成 SDR,同时保持图像细节与颜色等对于表现原始场景非常重要的信息。目前仅对 10bit HDR10,HLG 和 DoVi 视频生效。此项需要对应的 OpenCL 或 CUDA 运行库。", "LabelTonemappingAlgorithm": "选择要使用的色调映射算法", "TonemappingAlgorithmHelp": "色调映射可以微调。如果你不是很熟悉这些选项,保持默认即可。建议值为 'BT.2390'。", "LabelTonemappingRange": "色调映射范围", @@ -1669,7 +1669,7 @@ "LabelVppTonemappingContrastHelp": "在 VPP 色调映射中应用对比度增益。推荐值和默认值均为 1。", "LabelVppTonemappingBrightness": "VPP 色调映射亮度增益", "LabelVppTonemappingContrast": "VPP 色调映射对比度增益", - "LabelVppTonemappingBrightnessHelp": "在 VPP 色调映射中应用亮度增益。推荐值和默认值为16和 0。", + "LabelVppTonemappingBrightnessHelp": "在 VPP 色调映射中应用亮度增益。推荐值和默认值为 16 和 0。", "ScreenResolution": "屏幕分辨率", "LabelMaxVideoResolution": "允许的最大视频转码分辨率", "RememberSubtitleSelectionsHelp": "尝试将字幕轨道设置为与最后一个视频最接近的匹配。", From 5161fe0f501f9ea53237600b69ec67abf92f0ad8 Mon Sep 17 00:00:00 2001 From: kyaroslav83 Date: Sat, 29 Apr 2023 21:50:49 +0000 Subject: [PATCH 046/112] Translated using Weblate (Russian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ru/ --- src/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/ru.json b/src/strings/ru.json index eb37854aae..610becf14c 100644 --- a/src/strings/ru.json +++ b/src/strings/ru.json @@ -760,7 +760,7 @@ "MediaInfoAnamorphic": "Анаморфность", "MediaInfoAspectRatio": "Соотношение сторон", "MediaInfoBitDepth": "Разрядность", - "MediaInfoBitrate": "Потоковая скорость", + "MediaInfoBitrate": "Битрейт", "MediaInfoChannels": "Каналы", "MediaInfoCodec": "Кодек", "MediaInfoCodecTag": "Тег кодека", From 134764f38b2db1d10f940ae60fb558343cb0d6f4 Mon Sep 17 00:00:00 2001 From: NenoRMa1eN Date: Sun, 30 Apr 2023 08:22:39 +0000 Subject: [PATCH 047/112] Translated using Weblate (Bulgarian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/bg/ --- src/strings/bg-bg.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/bg-bg.json b/src/strings/bg-bg.json index 12999583fa..e200e520d9 100644 --- a/src/strings/bg-bg.json +++ b/src/strings/bg-bg.json @@ -1453,7 +1453,7 @@ "KnownProxiesHelp": "Списък от IP ареси или хост имена на известни прокси сървъри, разделени със запетая, използвани при свързване с Jellyfin сървър. Това е задължително за да се използва правилнен \"X-Forwarded-For\" хедър. Изисква рестартиране след прилагане.", "HomeVideosPhotos": "Домашни видеа и снимки", "DirectPlayHelp": "Основният файл е напълно съвместим с този клиент, което значи че го получавате без модификации.", - "AllowTonemappingHelp": "Тоналното-картографиране може да помогне при преработка от HDR към SDR, запазвайки детайлите и цветовете на картината възможно най-близо до оригиналната сцена. В момента се поддържа само HDR10 или HGL видео потоци. Нужно е да имате поддръжка от OpenCL или CUDA от процесора и/или графичната ви карта.", + "AllowTonemappingHelp": "Тоналното картографиране може да трансформира динамичния обхват на видеото от HDR към SDR, като същевременно запазва детайлите и цветовете на изображението, които са много важна информация за представяне на оригиналната сцена. В момента работи само с 10-битови HDR10,HLG и DoVi видеоклипове. Това изисква съответното време за изпълнение от OpenCL или CUDA.", "LabelMaxAudiobookResumeHelp": "Приема се ,че файловете се възпроизведени до края , ако се спре след като оставащото време е по-малко от тази стойност.", "Experimental": "Експериментални", "IgnoreDtsHelp": "Изключването на опцията може да теши някои проблеми, напр. липсващ звук на канали с отделни звукови и видео потоци.", From b11445ffe06fbed7f5a5ba739d66ec44681977a3 Mon Sep 17 00:00:00 2001 From: Oskari Lavinto Date: Sun, 30 Apr 2023 08:50:17 +0000 Subject: [PATCH 048/112] Translated using Weblate (Finnish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fi/ --- src/strings/fi.json | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/strings/fi.json b/src/strings/fi.json index f67a1dcaef..0bb1eebfc5 100644 --- a/src/strings/fi.json +++ b/src/strings/fi.json @@ -120,7 +120,7 @@ "ButtonResetEasyPassword": "Poista Helppo PIN -koodi", "ButtonResume": "Jatka", "ButtonRevoke": "Peruuta", - "ButtonScanAllLibraries": "Skannaa kaikki kirjastot", + "ButtonScanAllLibraries": "Päivitä kaikki kirjastot", "ButtonSelectDirectory": "Valitse hakemisto", "ButtonSelectView": "Valitse näkymä", "ButtonSend": "Lähetä", @@ -596,7 +596,7 @@ "Screenshots": "Kuvakaappaukset", "Screenshot": "Kuvakaappaus", "Schedule": "Ajoita", - "ScanLibrary": "Skannaa kirjasto", + "ScanLibrary": "Päivitä kirjasto", "SaveSubtitlesIntoMediaFolders": "Tallenna tekstitykset mediakansioihin", "Saturday": "Lauantai", "ResumeAt": "Jatka kohdasta {0}", @@ -824,7 +824,7 @@ "LabelDeviceDescription": "Laitteen kuvaus", "LabelDefaultScreen": "Oletusnäyttö", "LabelDefaultUser": "Oletuskäyttäjä", - "LabelDashboardTheme": "Palvelimen hallintapaneelin teema", + "LabelDashboardTheme": "Palvelimen Hallintapaneelin teema", "LabelCustomCertificatePathHelp": "Varmenteen ja yksityisen avaimen sisältävän PKCS #12 -tiedoston sijainti oman verkkotunnuksen TLS-tuen käyttöönottamiseksi.", "LabelCustomCertificatePath": "Oman SSL-varmenteen sijainti", "LabelContentType": "Sisältötyyppi", @@ -841,7 +841,7 @@ "ButtonTogglePlaylist": "Soittolista", "Artist": "Esittäjä", "RefreshQueued": "Päivitys odottamassa.", - "SeriesCancelled": "Sarja peruttu.", + "SeriesCancelled": "Sarja on peruttu.", "MediaInfoRefFrames": "Viitekehykset", "LabelXDlnaDoc": "Laitteen luokitustunnus", "LabelXDlnaCap": "Laitteen ominaisuustunnus", @@ -887,7 +887,7 @@ "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Seuraavat mediasijainnit tullaan poistamaan kirjastostasi", "MessageItemsAdded": "Kohteet lisätty.", "MessageItemSaved": "Kohde tallennettu.", - "MessageEnablingOptionLongerScans": "Asetuksen käyttö saattaa pidentää kirjaston skannausaikaa merkittävästi.", + "MessageEnablingOptionLongerScans": "Asetuksen käyttö saattaa pidentää kirjastopäivityksiä merkittävästi.", "MessageDownloadQueued": "Lataus asetettu jonoon.", "MessageConfirmRevokeApiKey": "Haluatko varmasti poistaa API-avaimen? Sovelluksen yhteys palvelimeen katkeaa välittömästi.", "MessageConfirmRemoveMediaLocation": "Haluatko varmasti poistaa tämän sijainnin?", @@ -1053,7 +1053,7 @@ "LabelFriendlyName": "Käyttäjäystävällinen nimi", "LabelFileOrUrl": "Tiedosto tai URL", "LabelFailed": "Epäonnistui", - "LabelExtractChaptersDuringLibraryScan": "Pura kappalekuvat kirjastojen skannauksen yhteydessä", + "LabelExtractChaptersDuringLibraryScan": "Pura kappalekuvat kirjastopäivityksen yhteydessä", "LabelBaseUrl": "Perus-URL", "LabelEvent": "Tapahtuma", "LabelEnableSingleImageInDidlLimit": "Rajoita yhteen upotettuun kuvaan", @@ -1069,7 +1069,7 @@ "LabelAirDays": "Lähetyspäivät", "LabelAccessStart": "Aloitusaika", "LabelAccessEnd": "Lopetusaika", - "InstantMix": "Välitön miksaus", + "InstantMix": "Pikasekoitus", "Image": "Kuva", "HttpsRequiresCert": "Ottaaksesi suojatut yhteydet käyttöösi tulee sinun toimittaa luotettu SSL-varmenne (esim. Let's Encrypt). Ole hyvä ja toimita varmenne tai ota suojattu yhteys pois käytöstä.", "HeaderSyncPlayEnabled": "Ryhmäkatselu päällä", @@ -1080,7 +1080,7 @@ "HeaderLibraryAccess": "Kirjastojen käyttöoikeudet", "HeaderKeepSeries": "Pidä sarja", "HeaderKeepRecording": "Jatka tallennusta", - "HeaderInstantMix": "Välitön miksaus", + "HeaderInstantMix": "Pikasekoitus", "HeaderImageSettings": "Kuva-asetukset", "HeaderImageOptions": "Kuva-asetukset", "HeaderIdentificationHeader": "Tunnistusotsake", @@ -1232,7 +1232,7 @@ "EnableTonemapping": "Käytä sävykartoitusta", "EnableBlurHashHelp": "Kuvat, joita ladataan vielä, näytetään yksilöllisellä paikkamerkillä.", "EnableBlurHash": "Ota sumennetut paikkamerkit käyttöön kuville", - "AllowTonemappingHelp": "Sävykartoitus voi muuttaa videon dynaamisen alueen HDR:stä SDR:ksi säilyttäen samalla kuvan yksityiskohdat ja värit, jotka ovat kohtauksen alkuperäisen ilmeen kannalta erittäin tärkeitä. Toimii tällä hetkellä vain HDR10- ja HLG-videoiden kanssa ja edellyttää soveltuvaa OpenCL- tai CUDA-suoritusalustaa.", + "AllowTonemappingHelp": "Sävykartoitus voi muuttaa videon dynaamisen alueen HDR:stä SDR:ksi säilyttäen samalla kuvan yksityiskohdat ja värit, jotka ovat kohtauksen alkuperäisen ilmeen kannalta erittäin tärkeitä. Toimii tällä hetkellä vain 10bit HDR10, HLG ja Dovi -videoiden kanssa ja edellyttää soveltuvaa OpenCL- tai CUDA-suoritusalustaa.", "LabelffmpegPathHelp": "FFmpeg-sovellustiedoston tai -kansion tiedostosijainti.", "LabelKodiMetadataEnablePathSubstitutionHelp": "Mahdollistaa kuvien tiedostosijaintien korvauksen palvelimen korvausasetuksien perusteella.", "ThumbCard": "Pienoiskortti", @@ -1244,7 +1244,7 @@ "LabelTVHomeScreen": "Televisiotilan aloitusnäyttö", "LabelHomeScreenSectionValue": "Aloitusnäyttö-osio {0}", "LabelHDHomerunPortRangeHelp": "Rajoittaa HD Homerun -laitteiden UDP-porttialueen tähän arvoon (oletus on 1024 - 65535).", - "LabelExtractChaptersDuringLibraryScanHelp": "Pura kappalekuvat, kun videoita tuodaan kirjastojen skannauksen aikana. Muutoin ne puretaan kappalekuvien ajoitetun tehtävän aikana, jolloin kirjaston säännöllinen skannaus voidaan suorittaa nopeammin.", + "LabelExtractChaptersDuringLibraryScanHelp": "Pura kirjastopäivityksen yhteydessä tuotavien videoiden kappalekuvat. Muutoin tämä tapahtuu kappalekuvien purun ajoitetun tehtävän aikana, jolloin kirjaston perustarkastus nopeutuu.", "LabelHDHomerunPortRange": "HDHomeRun -portin alue", "LabelH265Crf": "H.265-koodauksen CRF", "LabelGroupMoviesIntoCollectionsHelp": "Kokoelmiin kuuluvat elokuvat näytetään elokuvalistauksissa kokoelmiin ryhmiteltyinä.", @@ -1267,7 +1267,7 @@ "LatestFromLibrary": "Viimeksi lisätty: {0}", "LabelVideoRange": "Videon alue", "LabelVaapiDeviceHelp": "Tämä on renderöintinoodi, jota käytetään laitteistokiihdytykseen.", - "LabelUserRemoteClientBitrateLimitHelp": "Korvaa globaali arvo asetusten kohdasta Ohjauspaneeli > Toisto > Suoratoisto.", + "LabelUserRemoteClientBitrateLimitHelp": "Korvaa globaali arvo asetusten kohdasta Hallintapaneeli > Toisto > Suoratoisto.", "LabelUserMaxActiveSessions": "Yhtäaikaisten käyttäjäistuntojen enimmäismäärä", "LabelUserLibraryHelp": "Valitse käyttäjäkirjasto joka näytetään laitteella. Jätä tyhjäksi käyttääksesi oletusasetusta.", "LabelUserAgent": "Käyttäjäagentti", @@ -1422,7 +1422,7 @@ "Casual": "Rento", "ErrorPlayerNotFound": "Pyydetylle medialle sopivaa soitinta ei löytynyt.", "Cursive": "Kursivointi", - "WizardCompleted": "Siinä kaikki tällä erää tarvittava. Jellyfin on aloittanut kirjastosi tietojen keräyksen. Tutustu sovelluksiimme ja paina lopuksi Valmis avataksesi hallintapaneelin.", + "WizardCompleted": "Siinä kaikki tällä erää tarvittava. Jellyfin on aloittanut kirjastosi tietojen keräyksen. Tutustu sovelluksiimme ja paina lopuksi Valmis avataksesi Hallintapaneelin.", "HeaderSyncPlayTimeSyncSettings": "Ajan synkronointi", "LabelMaxDaysForNextUpHelp": "Määritä enimmäisaika päivinä, jonka katsomaton sarja pysyy 'Seuraavaksi'-osiossa.", "LabelMaxDaysForNextUp": "'Seuraavaksi'-osion päivien enimmäismäärä", @@ -1585,7 +1585,7 @@ "SettingsWarning": "Näiden arvojen muutos voi aiheuttaa epävakautta tai yhteysongelmia. Jos havaitset ongelmia, kannattaa palauttaa ne takaisin oletusarvoihin.", "SeriesRecordingScheduled": "Sarjan tallennus on ajoitettu.", "SeriesDisplayOrderHelp": "Järjestä jaksot esitysajan, DVD-levyn tai absoluuttisen numeroinnin mukaan.", - "ScanForNewAndUpdatedFiles": "Etsi uusia ja päivitettyjä tiedostoja", + "ScanForNewAndUpdatedFiles": "Etsi uusia ja muuttuneita tiedostoja", "ReleaseGroup": "Julkaisuryhmä", "RecommendationStarring": "Pääosissa {0}", "RecommendationDirectedBy": "Ohjannut {0}", @@ -1664,8 +1664,8 @@ "MediaInfoVideoRangeType": "Videon aluetyyppi", "LabelVideoRangeType": "Videon aluetyyppi", "VideoRangeTypeNotSupported": "Videon aluetyyppiä ei tueta", - "LabelVppTonemappingContrastHelp": "Käytä kontrastin vahvistusta VPP-sävykartoituksen kanssa. Molemmat ovat suositeltavia ja oletusarvot ovat 0.", - "LabelVppTonemappingBrightnessHelp": "Käytä kirkkauden vahvistusta VPP-sävykartoituksen kanssa. Molemmat ovat suositeltavia ja oletusarvot ovat 0.", + "LabelVppTonemappingContrastHelp": "Käytä kontrastin vahvistusta VPP-sävykartoituksen kanssa. Suositus- ja oletusarvo on 1.", + "LabelVppTonemappingBrightnessHelp": "Käytä kirkkauden vahvistusta VPP-sävykartoituksen kanssa. Suositus- ja oletusarvot ovat 10 ja 0.", "LabelVppTonemappingContrast": "VPP-sävykartoituksen kontrastin vahvistus", "LabelVppTonemappingBrightness": "VPP-sävykartoituksen kirkkauden vahvistus", "IgnoreDtsHelp": "Valinnan käytöstä poisto voi korjata joitakin onhelmia, kuten puuttuvan äänen kanavilla, joilla on erilliset ääni- ja videokanavat.", @@ -1720,5 +1720,7 @@ "LabelParallelImageEncodingLimit": "Rinnakkaisten kuvaenkoodauksien rajoitus", "LabelEnableAudioVbr": "Käytä äänen VBR-enkoodausta", "LabelEnableAudioVbrHelp": "Muuttuva bittinopeus (variable bitrate, VBR) tuottaa keskitasoista paremman laadun, mutta saattaa joissakin harvoissa tapauksissa aiheuttaa puskurointi ja yhteensopivuusongelmia.", - "Select": "Valitse" + "Select": "Valitse", + "LabelTonemappingMode": "Sävykartoituksen tila", + "TonemappingModeHelp": "Valitse sävykartoituksen tila. Jos esiintyy ylikorostuneita värejä, kokeile RGB>-tilaa." } From 5977a336869431fef523c8bebf1c9c429c4c1810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20PONTON?= Date: Sun, 30 Apr 2023 07:52:12 +0000 Subject: [PATCH 049/112] Translated using Weblate (French) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/ --- src/strings/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/fr.json b/src/strings/fr.json index a2df89fe28..bd5f8ed005 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -1715,7 +1715,7 @@ "SubtitleRed": "Rouge", "SubtitleWhite": "Blanc", "SubtitleYellow": "Jaune", - "Featurette": "Featurette", + "Featurette": "Moyen-Métrage", "Short": "Court-métrage", "HeaderPerformance": "Performance", "LabelParallelImageEncodingLimit": "Limite de parallélisation de l'encodage d'image", From 2b9141f4cde9a5dc5be109b5de65dc9df3b2eb57 Mon Sep 17 00:00:00 2001 From: Rares Tamasanu Date: Sun, 30 Apr 2023 19:15:14 +0100 Subject: [PATCH 050/112] fix code smell: 'for loop should be for-of' --- src/components/cardbuilder/cardBuilder.js | 13 +++++-------- src/components/homesections/homesections.js | 12 ++++++------ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index d4f3aafa49..0367648d3a 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -679,9 +679,8 @@ function getCardTextLines(lines, cssClass, forceLines, isOuterFooter, cardLayout let valid = 0; - for (let i = 0; i < lines.length; i++) { + for (const text of lines) { let currentCssClass = cssClass; - const text = lines[i]; if (valid > 0 && isOuterFooter) { currentCssClass += ' cardText-secondary'; @@ -862,8 +861,8 @@ function getCardFooterText(item, apiClient, options, footerClass, progressHtml, if (options.textLines) { const additionalLines = options.textLines(item); - for (let i = 0; i < additionalLines.length; i++) { - lines.push(additionalLines[i]); + for (const additionalLine of additionalLines) { + lines.push(additionalLine); } } @@ -1724,8 +1723,7 @@ export function onTimerCreated(programId, newTimerId, itemsContainer) { export function onTimerCancelled(timerId, itemsContainer) { const cells = itemsContainer.querySelectorAll('.card[data-timerid="' + timerId + '"]'); - for (let i = 0; i < cells.length; i++) { - const cell = cells[i]; + for (const cell of cells) { const icon = cell.querySelector('.timerIndicator'); if (icon) { icon.parentNode.removeChild(icon); @@ -1742,8 +1740,7 @@ export function onTimerCancelled(timerId, itemsContainer) { export function onSeriesTimerCancelled(cancelledTimerId, itemsContainer) { const cells = itemsContainer.querySelectorAll('.card[data-seriestimerid="' + cancelledTimerId + '"]'); - for (let i = 0; i < cells.length; i++) { - const cell = cells[i]; + for (const cell of cells) { const icon = cell.querySelector('.timerIndicator'); if (icon) { icon.parentNode.removeChild(icon); diff --git a/src/components/homesections/homesections.js b/src/components/homesections/homesections.js index 5cf83ced94..32ad3bed6d 100644 --- a/src/components/homesections/homesections.js +++ b/src/components/homesections/homesections.js @@ -100,10 +100,10 @@ export function loadSections(elem, apiClient, user, userSettings) { export function destroySections(elem) { const elems = elem.querySelectorAll('.itemsContainer'); - for (let i = 0; i < elems.length; i++) { - elems[i].fetchData = null; - elems[i].parentContainer = null; - elems[i].getItemsHtml = null; + for (const e of elems) { + e.fetchData = null; + e.parentContainer = null; + e.getItemsHtml = null; } elem.innerHTML = ''; @@ -111,8 +111,8 @@ export function destroySections(elem) { export function pause(elem) { const elems = elem.querySelectorAll('.itemsContainer'); - for (let i = 0; i < elems.length; i++) { - elems[i].pause(); + for (const e of elems) { + e.pause(); } } From 35bdbdf8a4633eed5f3efacceae150a39e917337 Mon Sep 17 00:00:00 2001 From: Andi Chandler Date: Sun, 30 Apr 2023 22:35:06 +0000 Subject: [PATCH 051/112] Translated using Weblate (English (United Kingdom)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/en_GB/ --- src/strings/en-gb.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/strings/en-gb.json b/src/strings/en-gb.json index fb83bb6717..066375ae27 100644 --- a/src/strings/en-gb.json +++ b/src/strings/en-gb.json @@ -1392,7 +1392,7 @@ "LabelTonemappingRange": "Tone mapping range", "TonemappingAlgorithmHelp": "Tone mapping can be fine-tuned. If you are not familiar with these options, just keep the default. The recommended value is 'BT.2390'.", "LabelTonemappingAlgorithm": "Select the Tone mapping algorithm to use", - "AllowTonemappingHelp": "Tone-mapping can transform the dynamic range of a video from HDR to SDR while maintaining image details and colors, which are very important information for representing the original scene. Currently works only with HDR10 or HLG videos. This requires the corresponding OpenCL or CUDA runtime.", + "AllowTonemappingHelp": "Tone mapping can transform the dynamic range of a video from HDR to SDR while maintaining image details and colours, which are very important information for representing the original scene. Currently works only with 10bit HDR10,HLG and DoVi videos. This requires the corresponding OpenCL or CUDA runtime.", "EnableTonemapping": "Enable Tone mapping", "LabelOpenclDeviceHelp": "This is the OpenCL device that is used for tone mapping. The left side of the dot is the platform number, and the right side is the device number on the platform. The default value is 0.0. The FFmpeg application file containing the OpenCL hardware acceleration method is required.", "LabelOpenclDevice": "OpenCL Device", @@ -1666,9 +1666,9 @@ "MediaInfoVideoRangeType": "Video range type", "LabelVideoRangeType": "Video range type", "VideoRangeTypeNotSupported": "The video's range type is not supported", - "LabelVppTonemappingContrastHelp": "Apply contrast gain in VPP tone mapping. The recommended and default values are 1.2 and 1.", + "LabelVppTonemappingContrastHelp": "Apply contrast gain in VPP tone mapping. Both recommended and default values are 1.", "LabelVppTonemappingContrast": "VPP Tone mapping contrast gain", - "LabelVppTonemappingBrightnessHelp": "Apply brightness gain in VPP tone mapping. Both recommended and default values are 0.", + "LabelVppTonemappingBrightnessHelp": "Apply brightness gain in VPP tone mapping. The recommended and default values are 16 and 0.", "LabelVppTonemappingBrightness": "VPP Tone mapping brightness gain", "ScreenResolution": "Screen Resolution", "RememberSubtitleSelectionsHelp": "Try to set the subtitle track to the closest match to the last video.", @@ -1721,5 +1721,8 @@ "LabelParallelImageEncodingLimit": "Parallel image encoding limit", "LabelParallelImageEncodingLimitHelp": "Maximum amount of image encodings that are allowed to run in parallel. Setting this to 0 will choose a limit based on your system specs.", "LabelEnableAudioVbr": "Enable VBR audio encoding", - "LabelEnableAudioVbrHelp": "Variable bitrate offers better quality to average bitrate ratio, but in some rare cases may cause buffering and compatibility issues." + "LabelEnableAudioVbrHelp": "Variable bitrate offers better quality to average bitrate ratio, but in some rare cases may cause buffering and compatibility issues.", + "LabelTonemappingMode": "Tone mapping mode", + "Select": "Select", + "TonemappingModeHelp": "Select the tone mapping mode. If you experience blown out highlights try switching to the RGB mode." } From 8439fd343bfbaf0a756c0293e1ad02cfb24a8c72 Mon Sep 17 00:00:00 2001 From: sleepycatcoding Date: Mon, 1 May 2023 00:08:55 +0000 Subject: [PATCH 052/112] Translated using Weblate (Estonian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/et/ --- src/strings/et.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/et.json b/src/strings/et.json index e4e4f61bff..c3e153e2f3 100644 --- a/src/strings/et.json +++ b/src/strings/et.json @@ -285,7 +285,7 @@ "CustomDlnaProfilesHelp": "Loo kohandatud profiil uue seadme jaoks või tühista süsteemi profiil.", "ConfigureDateAdded": "Seadista, kuidas lisamise kuupäev kuvatakse juhtpaneeli meediakogu seadetes", "Banner": "Bänner", - "AllowTonemappingHelp": "Värvikaardistus võib muuta video dünaamilise ulatuse HDR -st SDR -ks, säilitades samal ajal pildi üksikasjad ja värvid, mis on algse stseeni kujutamisel väga oluline teave. Praegu töötab ainult 10-bitise HDR10, HLG või DoVi videotega. See vajab vastavat OpenGL või CUDA käitusaega.", + "AllowTonemappingHelp": "Värvikaardistus võib muuta video dünaamilise ulatuse HDR -st SDR -ks, säilitades samal ajal pildi üksikasjad ja värvid, mis on algse stseeni kujutamisel väga oluline teave. Praegu töötab ainult 10-bitise HDR10, HLG ja DoVi videotega. See vajab vastavat OpenGL või CUDA käitusaega.", "HeaderDirectPlayProfile": "Otse-esituse profiil", "HeaderContainerProfileHelp": "Konteineri profiilid näitavad seadme piiranguid teatud vormingute esitamisel. Kui kehtib piirang, meedium transkooditakse, isegi kui vorming on seadistatud otse-esituseks.", "HeaderCodecProfileHelp": "Koodeki profiilid näitavad seadme piiranguid konkreetsete koodekite esitamisel. Kui kehtivad piirangud, transkooditakse meedia, isegi kui koodek on seadistatud otse-esituseks.", From 575afa2e98aa70c6e3bda2821872e3198f6b4471 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 1 May 2023 13:08:16 +0000 Subject: [PATCH 053/112] Translated using Weblate (German) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/ --- src/strings/de.json | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/strings/de.json b/src/strings/de.json index 0ce6b1bd0e..49cfa0fa21 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -879,7 +879,7 @@ "OptionReportByteRangeSeekingWhenTranscodingHelp": "Dies wird für manche Abspielgeräte benötigt, auf denen die Zeitsuche nicht gut funktioniert.", "OptionRequirePerfectSubtitleMatch": "Nur Untertitel mit einem perfekten Ergebnis zu meinen Videos herunterladen", "OptionRequirePerfectSubtitleMatchHelp": "Perfektes Ergebnis wählt beim Filtern nur Untertitel, welche getestet und für deine exakte Videodatei verifiziert wurden. Die Abwahl dieser Option erhöht die Chance, dass Untertitel heruntergeladen werden, die Möglichkeit falscher Untertitel oder dass Text an falschen Positionen angezeigt wird ist aber ebenfalls größer.", - "OptionResElement": "'res' element", + "OptionResElement": "'res'-Element", "OptionResumable": "Fortsetzbar", "OptionSaveMetadataAsHidden": "Speichere Metadaten und Bilder als versteckte Dateien", "OptionSaveMetadataAsHiddenHelp": "Diese Änderung betrifft nur neu gespeicherte Metadaten. Schon gespeicherte Metadaten werden erst aktualisiert, wenn der Server diese erneut speichert.", @@ -1377,7 +1377,7 @@ "LabelColorSpace": "Farbraum", "MediaInfoColorSpace": "Farbraum", "VideoAudio": "Videoton", - "AllowTonemappingHelp": "Tone-Mapping kann die Dynamic Range eines Videos von HDR zu SDR umwandeln und dabei Bilddetails und Farben beibehalten. Dies funktioniert zurzeit nur bei HDR10- oder HLG-Videos. Entsprechend der gewählten Hardwarebeschleunigung wird die passende OpenCL- oder CUDA-Laufzeitumgebung benötigt.", + "AllowTonemappingHelp": "Dynamikkompression kann den Dynamikumfang eines Videos von HDR nach SDR wandeln und dabei die für die Darstellung der Originalszene sehr wichtigen Bilddetails und Farben beibehalten. Dies funktioniert zurzeit nur bei 10-Bit-HDR10, HLG und DoVi-V und benötigt die entsprechende OpenCL- oder CUDA-Laufzeitumgebung.", "TonemappingRangeHelp": "Wähle den Ausgabefarbraum aus. Auto ist derselbe wie der Eingabefarbraum.", "TonemappingAlgorithmHelp": "Das Tone-Mapping kann fein abgestimmt werden. Wenn du mit diesen Optionen nicht vertraut bist, behalte einfach den Standardwert bei. Der empfohlene Wert ist \"BT.2390\".", "LabelTonemappingAlgorithm": "Wähle den zu verwendenden Tone-Mapping-Algorithmus aus", @@ -1411,7 +1411,7 @@ "QuickConnectAuthorizeCode": "Login Code {0} eingeben", "QuickConnectActivationSuccessful": "Erfolgreich aktiviert", "EnableQuickConnect": "Quick Connect auf diesem Server aktivieren", - "QuickConnect": "Quick Connect", + "QuickConnect": "Schnellverbindung", "PosterCard": "Posterkarte", "LabelQuickConnectCode": "Quick Connect-Code", "LabelCurrentStatus": "Aktueller Status", @@ -1462,7 +1462,7 @@ "HeaderAddUser": "Benutzer hinzufügen", "HeaderAddUpdateSubtitle": "Untertitel hinzufügen/aktualisieren", "LabelSSDPTracingFilterHelp": "Optionale IP-Adresse zum Filtern des protokollierten SSDP-Verkehrs.", - "LabelSSDPTracingFilter": "SSDP Filter", + "LabelSSDPTracingFilter": "SSDP-Filter", "LabelPublishedServerUriHelp": "Überschreibt die von Jellyfin genutzte URI auf Basis des Interfaces oder der IP-Adresse des Clients.", "LabelPublishedServerUri": "Veröffentlichte Server-URIs", "LabelEnableSSDPTracingHelp": "Aktiviere detailreiche SSDP Netzwerkverfolgung-Logs.
WARNUNG: Dies wird erhebliche Einbüßungen in der Leistung hervorrufen.", @@ -1660,9 +1660,9 @@ "MediaInfoDvVersionMinor": "DV Nebenversion", "MediaInfoDvVersionMajor": "DV Hauptversion", "MediaInfoDoViTitle": "DV Titel", - "LabelVppTonemappingContrastHelp": "VPP Tonemapping Kontrast anwenden. Empfohlene und Standartwerte sind 1,2 und 1.", + "LabelVppTonemappingContrastHelp": "Kontrast der VPP-Dynamikkompression erhöhen. Der empfohlene und voreingestellte Wert sind beide 1.", "LabelVppTonemappingContrast": "VPP Tonemapping Kontrast", - "LabelVppTonemappingBrightnessHelp": "VPP Tonemapping Helligkeit anwenden. Empfohlener und Standartwert sind 0.", + "LabelVppTonemappingBrightnessHelp": "Helligkeit der VPP-Dynamikkompression erhöhen. Der empfohlene Wert ist 16, der voreingestellte 0.", "LabelVppTonemappingBrightness": "VPP Tonemapping Helligkeit", "ScreenResolution": "Bildschirmauflösung", "RememberSubtitleSelectionsHelp": "Versuche den zum letzten Video ähnlichsten Untertitel zu setzen.", @@ -1721,5 +1721,8 @@ "LabelParallelImageEncodingLimitHelp": "Maximale Anzahl von Bildkodierungen, die parallel ausgeführt werden können. Wenn Sie diesen Wert auf 0 setzen, wird eine Grenze auf der Grundlage Ihrer Systemspezifikationen gewählt.", "HeaderPerformance": "Leistung", "LabelEnableAudioVbr": "Aktiviere Audio-Konvertierung mit variabler Bitrate (VBR)", - "LabelEnableAudioVbrHelp": "Eine variable Bitrate bietet bessere Qualität im Vergleich zu einer konstanten, kann jedoch in manchen Fällen zu Problemen beim Buffering und der Kompatibilität führen." + "LabelEnableAudioVbrHelp": "Eine variable Bitrate bietet bessere Qualität im Vergleich zu einer konstanten, kann jedoch in manchen Fällen zu Problemen beim Buffering und der Kompatibilität führen.", + "Select": "Auswählen", + "LabelTonemappingMode": "Dynamikkompressionsmodus", + "TonemappingModeHelp": "Dynamikkompressionsmodus auswählen. Falls etwas überbelichtet ist, versuche in den RGB-Modus zu wechseln." } From 1676b0c990a26a63cc9fbd886a17e398217eea7f Mon Sep 17 00:00:00 2001 From: "Chen-Tai,Peng" Date: Mon, 1 May 2023 16:22:09 +0000 Subject: [PATCH 054/112] Translated using Weblate (Chinese (Traditional)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hant/ --- src/strings/zh-tw.json | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/strings/zh-tw.json b/src/strings/zh-tw.json index ec084cfd71..169a7d7974 100644 --- a/src/strings/zh-tw.json +++ b/src/strings/zh-tw.json @@ -1611,7 +1611,7 @@ "AudioIsExternal": "外部音訊串流", "LabelVppTonemappingBrightness": "VPP 色調映射亮度增益", "EnableSplashScreen": "啟用啟動畫面", - "LabelVppTonemappingContrastHelp": "在 VPP 色調映射中使用對比度增益。 推薦值和預設值是 1.2 和 1。", + "LabelVppTonemappingContrastHelp": "在 VPP 色調映射中使用對比度增益。 推薦值和預設值是 1。", "Clip": "花絮", "Larger": "較大的", "Sample": "樣本", @@ -1664,7 +1664,7 @@ "ThemeSong": "主題曲", "ThemeVideo": "主題影片", "EnableEnhancedNvdecDecoderHelp": "實驗性 NVDEC 實現,除非遇到解碼錯誤,否則不要啟用此選項。", - "LabelVppTonemappingBrightnessHelp": "在 VPP 色調映射中使用亮度增益。 推薦值和預設值均為 0。", + "LabelVppTonemappingBrightnessHelp": "在 VPP 色調映射中使用亮度增益。 推薦值和預設值均為 16 和 0。", "LabelVppTonemappingContrast": "VPP 色調映射對比度增益", "VideoRangeTypeNotSupported": "不支援影片的範圍類型", "LabelVideoRangeType": "影片範圍類型", @@ -1688,5 +1688,16 @@ "StereoDownmixAlgorithmHelp": "會將多聲道的音訊混縮為雙聲道的演算法。", "DownloadAll": "下載全部", "Experimental": "實驗性", - "HeaderDummyChapter": "章節影像" + "HeaderDummyChapter": "章節影像", + "LabelEnableAudioVbr": "啟用 VBR 音訊編碼", + "LabelParallelImageEncodingLimit": "並行圖片編碼限制", + "LabelParallelImageEncodingLimitHelp": "允許並行運行的圖像編碼最大數量。將其設置為 0 將根據您的系統規格限制。", + "HeaderPerformance": "效能", + "LabelDummyChapterDuration": "頻率", + "LabelDummyChapterDurationHelp": "章節圖片擷取頻率為幾秒。", + "LabelDummyChapterCount": "限制", + "LabelDummyChapterCountHelp": "每個媒體檔案的最大的章節擷取圖片數量。", + "LabelChapterImageResolution": "解析度", + "LabelChapterImageResolutionHelp": "章節擷取圖片解析度。", + "HeaderRecordingMetadataSaving": "錄製中繼資料" } From d7c72080e97edafd811c4dcc896c20beedf648be Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Mon, 1 May 2023 14:19:50 -0400 Subject: [PATCH 055/112] Remove duplicated app elements --- src/RootApp.tsx | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/RootApp.tsx b/src/RootApp.tsx index dddf31b5b1..018ac7c10a 100644 --- a/src/RootApp.tsx +++ b/src/RootApp.tsx @@ -3,8 +3,6 @@ import { History } from '@remix-run/router'; import React from 'react'; import StableApp from './apps/stable/App'; -import AppHeader from './components/AppHeader'; -import Backdrop from './components/Backdrop'; import { HistoryRouter } from './components/HistoryRouter'; import { ApiProvider } from './hooks/useApi'; @@ -16,17 +14,11 @@ const RootApp = ({ history }: { history: History }) => { return ( - - - -
-
- { - layoutMode === 'experimental' ? - : - - } -
+ { + layoutMode === 'experimental' ? + : + + } ); From 621355b53b1adc8fa1cca9f4dc08dc4fc9a9c151 Mon Sep 17 00:00:00 2001 From: Brian Bentancour Date: Mon, 1 May 2023 18:47:18 +0000 Subject: [PATCH 056/112] Translated using Weblate (Spanish (Argentina)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es_AR/ --- src/strings/es-ar.json | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/strings/es-ar.json b/src/strings/es-ar.json index 36a100d7da..775a45a41a 100644 --- a/src/strings/es-ar.json +++ b/src/strings/es-ar.json @@ -1400,7 +1400,7 @@ "LabelTonemappingDesat": "Desaturación del mapa de tonos", "TonemappingRangeHelp": "Seleccione la gama de colores de salida. Auto es el mismo que el rango de entrada.", "TonemappingAlgorithmHelp": "El mapeo de tonos se puede ajustar con precisión. Si no está familiarizado con estas opciones, mantenga las predeterminadas. El valor recomendado es Hable.", - "AllowTonemappingHelp": "El mapeo de tonos puede transformar el rango dinámico de un video de HDR a SDR mientras mantiene los detalles y colores de la imagen, que son información muy importante para representar la escena original. Actualmente solo funciona con videos HDR10 o HLG. Esto requiere el OpenCL o CUDA runtime correspondiente.", + "AllowTonemappingHelp": "El mapeo de tonos puede transformar el rango dinámico de un video de HDR a SDR mientras mantiene los detalles y colores de la imagen, que son información muy importante para representar la escena original. Actualmente solo funciona con videos HDR10 de 10 bits, HLG y DoVi. Esto requiere el runtime correspondiente, CUDA u OpenCL.", "QuickConnectNotActive": "La conexión rápida no está activa en este servidor", "QuickConnectNotAvailable": "Pida al administrador del servidor que habilite la conexión rápida", "QuickConnectInvalidCode": "Código de conexión rápida no válido", @@ -1704,5 +1704,22 @@ "LabelEnableAudioVbrHelp": "La tasa de bits variable ofrece una mejor relación entre calidad y tasa de bits promedio, pero en algunos casos raros puede causar problemas de almacenamiento en búfer y compatibilidad.", "LabelParallelImageEncodingLimit": "Límite de codificación de imágenes en paralelo", "ResolutionMatchSource": "Fuente de coincidencia", - "HeaderPerformance": "Rendimiento" + "HeaderPerformance": "Rendimiento", + "Featurette": "Mediometraje", + "SubtitleBlack": "Negro", + "SaveRecordingNFOHelp": "Guardar los metadatos del proveedor de listados EPG junto a los archivos multimedia.", + "SaveRecordingImages": "Guardar grabación de imágenes EPG", + "SecondarySubtitles": "Subtítulos secundarios", + "SubtitleBlue": "Azul", + "SubtitleCyan": "Cian", + "SubtitleGray": "Gris", + "SubtitleGreen": "Verde", + "SubtitleMagenta": "Magenta", + "SubtitleWhite": "Blanco", + "Select": "Seleccionar", + "SaveRecordingImagesHelp": "Guardar las imágenes del proveedor de listados EPG junto a los archivos multimedia.", + "SubtitleLightGray": "Gris claro", + "SubtitleRed": "Rojo", + "SubtitleYellow": "Amarillo", + "Short": "Cortometraje" } From 15fc04ea4a2461db47aaf4af65be63844d32aa4f Mon Sep 17 00:00:00 2001 From: Brian Bentancour Date: Mon, 1 May 2023 18:54:02 +0000 Subject: [PATCH 057/112] Translated using Weblate (Spanish (Argentina)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es_AR/ --- src/strings/es-ar.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/es-ar.json b/src/strings/es-ar.json index 775a45a41a..67fbbe8597 100644 --- a/src/strings/es-ar.json +++ b/src/strings/es-ar.json @@ -1671,7 +1671,7 @@ "ShowParentImages": "Mostrar imágenes de la serie", "StoryArc": "Arco narrativo", "Clip": "Ficha técnica", - "LabelVppTonemappingBrightnessHelp": "Aplicar ganancia de brillo en el mapeo de tonos VPP. Tanto los valores recomendados como los predeterminados son 0.", + "LabelVppTonemappingBrightnessHelp": "Aplicar ganancia de brillo en el mapeo de tonos VPP. El valor predeterminado es 0 y el recomendado es 16.", "LabelVppTonemappingContrastHelp": "Aplicar ganancia de contraste en el mapeo de tonos VPP. Los valores recomendados y predeterminados son 1.2 y 1.", "VideoRangeTypeNotSupported": "El tipo de rango del video no es compatible", "MediaInfoRpuPresentFlag": "Bandera preestablecida de DV rpu", From 31293e4cd89c44ee47ed6d6038a26eeaf3e3a53e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 May 2023 21:04:37 +0000 Subject: [PATCH 058/112] Update Linters --- package-lock.json | 228 +++++++++++++++++++++++----------------------- package.json | 8 +- 2 files changed, 118 insertions(+), 118 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0ee9c9b56e..c313ac3389 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,8 +68,8 @@ "@types/lodash-es": "4.17.7", "@types/react": "17.0.58", "@types/react-dom": "17.0.19", - "@typescript-eslint/eslint-plugin": "5.59.0", - "@typescript-eslint/parser": "5.59.0", + "@typescript-eslint/eslint-plugin": "5.59.1", + "@typescript-eslint/parser": "5.59.1", "@uupaa/dynamic-import-polyfill": "1.0.2", "autoprefixer": "10.4.14", "babel-loader": "9.1.2", @@ -81,7 +81,7 @@ "css-loader": "6.7.3", "cssnano": "6.0.0", "es-check": "7.1.1", - "eslint": "8.38.0", + "eslint": "8.39.0", "eslint-plugin-compat": "4.1.4", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-import": "2.27.5", @@ -102,7 +102,7 @@ "sass-loader": "13.2.2", "source-map-loader": "4.0.1", "style-loader": "3.3.2", - "stylelint": "15.5.0", + "stylelint": "15.6.0", "stylelint-config-rational-order": "0.1.2", "stylelint-no-browser-hacks": "1.2.1", "stylelint-order": "6.0.3", @@ -2667,9 +2667,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz", - "integrity": "sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", + "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3410,15 +3410,15 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.0.tgz", - "integrity": "sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.1.tgz", + "integrity": "sha512-AVi0uazY5quFB9hlp2Xv+ogpfpk77xzsgsIEWyVS7uK/c7MZ5tw7ZPbapa0SbfkqE0fsAMkz5UwtgMLVk2BQAg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.0", - "@typescript-eslint/type-utils": "5.59.0", - "@typescript-eslint/utils": "5.59.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/type-utils": "5.59.1", + "@typescript-eslint/utils": "5.59.1", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -3459,14 +3459,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.0.tgz", - "integrity": "sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.1.tgz", + "integrity": "sha512-nzjFAN8WEu6yPRDizIFyzAfgK7nybPodMNFGNH0M9tei2gYnYszRDqVA0xlnRjkl7Hkx2vYrEdb6fP2a21cG1g==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.59.0", - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/typescript-estree": "5.59.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/typescript-estree": "5.59.1", "debug": "^4.3.4" }, "engines": { @@ -3486,13 +3486,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.0.tgz", - "integrity": "sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz", + "integrity": "sha512-mau0waO5frJctPuAzcxiNWqJR5Z8V0190FTSqRw1Q4Euop6+zTwHAf8YIXNwDOT29tyUDrQ65jSg9aTU/H0omA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/visitor-keys": "5.59.0" + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/visitor-keys": "5.59.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3503,13 +3503,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.0.tgz", - "integrity": "sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.1.tgz", + "integrity": "sha512-ZMWQ+Oh82jWqWzvM3xU+9y5U7MEMVv6GLioM3R5NJk6uvP47kZ7YvlgSHJ7ERD6bOY7Q4uxWm25c76HKEwIjZw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.0", - "@typescript-eslint/utils": "5.59.0", + "@typescript-eslint/typescript-estree": "5.59.1", + "@typescript-eslint/utils": "5.59.1", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -3530,9 +3530,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.0.tgz", - "integrity": "sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.1.tgz", + "integrity": "sha512-dg0ICB+RZwHlysIy/Dh1SP+gnXNzwd/KS0JprD3Lmgmdq+dJAJnUPe1gNG34p0U19HvRlGX733d/KqscrGC1Pg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3543,13 +3543,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.0.tgz", - "integrity": "sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.1.tgz", + "integrity": "sha512-lYLBBOCsFltFy7XVqzX0Ju+Lh3WPIAWxYpmH/Q7ZoqzbscLiCW00LeYCdsUnnfnj29/s1WovXKh2gwCoinHNGA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/visitor-keys": "5.59.0", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/visitor-keys": "5.59.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3614,17 +3614,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.0.tgz", - "integrity": "sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.1.tgz", + "integrity": "sha512-MkTe7FE+K1/GxZkP5gRj3rCztg45bEhsd8HYjczBuYm+qFHP5vtZmjx3B0yUCDotceQ4sHgTyz60Ycl225njmA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.0", - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/typescript-estree": "5.59.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/typescript-estree": "5.59.1", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -3655,12 +3655,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.0.tgz", - "integrity": "sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz", + "integrity": "sha512-6waEYwBTCWryx0VJmP7JaM4FpipLsFl9CvYf2foAE8Qh/Y0s+bxWysciwOs0LTBED4JCaNxTZ5rGadB14M6dwA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.0", + "@typescript-eslint/types": "5.59.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -6790,15 +6790,15 @@ } }, "node_modules/eslint": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.38.0.tgz", - "integrity": "sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", + "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.38.0", + "@eslint/js": "8.39.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -6808,7 +6808,7 @@ "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", + "eslint-scope": "^7.2.0", "eslint-visitor-keys": "^3.4.0", "espree": "^9.5.1", "esquery": "^1.4.2", @@ -15458,14 +15458,14 @@ } }, "node_modules/stylelint": { - "version": "15.5.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.5.0.tgz", - "integrity": "sha512-jyMO3R1QtE5mUS4v40+Gg+sIQBqe7CF1xPslxycDzNVkIBCUD4O+5F1vLPq16VmunUTv4qG9o2rUKLnU5KkVeQ==", + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.6.0.tgz", + "integrity": "sha512-Cqzpc8tvJm77KaM8qUbhpJ/UYK55Ia0whQXj4b9IId9dlPICO7J8Lyo15SZWiHxKjlvy3p5FQor/3n6i8ignXg==", "dev": true, "dependencies": { - "@csstools/css-parser-algorithms": "^2.1.0", - "@csstools/css-tokenizer": "^2.1.0", - "@csstools/media-query-list-parser": "^2.0.2", + "@csstools/css-parser-algorithms": "^2.1.1", + "@csstools/css-tokenizer": "^2.1.1", + "@csstools/media-query-list-parser": "^2.0.4", "@csstools/selector-specificity": "^2.2.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", @@ -15490,7 +15490,7 @@ "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.21", + "postcss": "^8.4.22", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", @@ -21754,9 +21754,9 @@ } }, "@eslint/js": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz", - "integrity": "sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", + "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", "dev": true }, "@fontsource/noto-sans": { @@ -22403,15 +22403,15 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.0.tgz", - "integrity": "sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.1.tgz", + "integrity": "sha512-AVi0uazY5quFB9hlp2Xv+ogpfpk77xzsgsIEWyVS7uK/c7MZ5tw7ZPbapa0SbfkqE0fsAMkz5UwtgMLVk2BQAg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.0", - "@typescript-eslint/type-utils": "5.59.0", - "@typescript-eslint/utils": "5.59.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/type-utils": "5.59.1", + "@typescript-eslint/utils": "5.59.1", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -22432,53 +22432,53 @@ } }, "@typescript-eslint/parser": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.0.tgz", - "integrity": "sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.1.tgz", + "integrity": "sha512-nzjFAN8WEu6yPRDizIFyzAfgK7nybPodMNFGNH0M9tei2gYnYszRDqVA0xlnRjkl7Hkx2vYrEdb6fP2a21cG1g==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.0", - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/typescript-estree": "5.59.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/typescript-estree": "5.59.1", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.0.tgz", - "integrity": "sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz", + "integrity": "sha512-mau0waO5frJctPuAzcxiNWqJR5Z8V0190FTSqRw1Q4Euop6+zTwHAf8YIXNwDOT29tyUDrQ65jSg9aTU/H0omA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/visitor-keys": "5.59.0" + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/visitor-keys": "5.59.1" } }, "@typescript-eslint/type-utils": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.0.tgz", - "integrity": "sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.1.tgz", + "integrity": "sha512-ZMWQ+Oh82jWqWzvM3xU+9y5U7MEMVv6GLioM3R5NJk6uvP47kZ7YvlgSHJ7ERD6bOY7Q4uxWm25c76HKEwIjZw==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.0", - "@typescript-eslint/utils": "5.59.0", + "@typescript-eslint/typescript-estree": "5.59.1", + "@typescript-eslint/utils": "5.59.1", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.0.tgz", - "integrity": "sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.1.tgz", + "integrity": "sha512-dg0ICB+RZwHlysIy/Dh1SP+gnXNzwd/KS0JprD3Lmgmdq+dJAJnUPe1gNG34p0U19HvRlGX733d/KqscrGC1Pg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.0.tgz", - "integrity": "sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.1.tgz", + "integrity": "sha512-lYLBBOCsFltFy7XVqzX0Ju+Lh3WPIAWxYpmH/Q7ZoqzbscLiCW00LeYCdsUnnfnj29/s1WovXKh2gwCoinHNGA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/visitor-keys": "5.59.0", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/visitor-keys": "5.59.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -22518,17 +22518,17 @@ } }, "@typescript-eslint/utils": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.0.tgz", - "integrity": "sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.1.tgz", + "integrity": "sha512-MkTe7FE+K1/GxZkP5gRj3rCztg45bEhsd8HYjczBuYm+qFHP5vtZmjx3B0yUCDotceQ4sHgTyz60Ycl225njmA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.0", - "@typescript-eslint/types": "5.59.0", - "@typescript-eslint/typescript-estree": "5.59.0", + "@typescript-eslint/scope-manager": "5.59.1", + "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/typescript-estree": "5.59.1", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -22545,12 +22545,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.0.tgz", - "integrity": "sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA==", + "version": "5.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz", + "integrity": "sha512-6waEYwBTCWryx0VJmP7JaM4FpipLsFl9CvYf2foAE8Qh/Y0s+bxWysciwOs0LTBED4JCaNxTZ5rGadB14M6dwA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.0", + "@typescript-eslint/types": "5.59.1", "eslint-visitor-keys": "^3.3.0" }, "dependencies": { @@ -24931,15 +24931,15 @@ "dev": true }, "eslint": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.38.0.tgz", - "integrity": "sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", + "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.38.0", + "@eslint/js": "8.39.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -24949,7 +24949,7 @@ "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", + "eslint-scope": "^7.2.0", "eslint-visitor-keys": "^3.4.0", "espree": "^9.5.1", "esquery": "^1.4.2", @@ -31323,14 +31323,14 @@ } }, "stylelint": { - "version": "15.5.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.5.0.tgz", - "integrity": "sha512-jyMO3R1QtE5mUS4v40+Gg+sIQBqe7CF1xPslxycDzNVkIBCUD4O+5F1vLPq16VmunUTv4qG9o2rUKLnU5KkVeQ==", + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.6.0.tgz", + "integrity": "sha512-Cqzpc8tvJm77KaM8qUbhpJ/UYK55Ia0whQXj4b9IId9dlPICO7J8Lyo15SZWiHxKjlvy3p5FQor/3n6i8ignXg==", "dev": true, "requires": { - "@csstools/css-parser-algorithms": "^2.1.0", - "@csstools/css-tokenizer": "^2.1.0", - "@csstools/media-query-list-parser": "^2.0.2", + "@csstools/css-parser-algorithms": "^2.1.1", + "@csstools/css-tokenizer": "^2.1.1", + "@csstools/media-query-list-parser": "^2.0.4", "@csstools/selector-specificity": "^2.2.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", @@ -31355,7 +31355,7 @@ "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.21", + "postcss": "^8.4.22", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", diff --git a/package.json b/package.json index f6d1d59d3b..3c0010923f 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "@types/lodash-es": "4.17.7", "@types/react": "17.0.58", "@types/react-dom": "17.0.19", - "@typescript-eslint/eslint-plugin": "5.59.0", - "@typescript-eslint/parser": "5.59.0", + "@typescript-eslint/eslint-plugin": "5.59.1", + "@typescript-eslint/parser": "5.59.1", "@uupaa/dynamic-import-polyfill": "1.0.2", "autoprefixer": "10.4.14", "babel-loader": "9.1.2", @@ -31,7 +31,7 @@ "css-loader": "6.7.3", "cssnano": "6.0.0", "es-check": "7.1.1", - "eslint": "8.38.0", + "eslint": "8.39.0", "eslint-plugin-compat": "4.1.4", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-import": "2.27.5", @@ -52,7 +52,7 @@ "sass-loader": "13.2.2", "source-map-loader": "4.0.1", "style-loader": "3.3.2", - "stylelint": "15.5.0", + "stylelint": "15.6.0", "stylelint-config-rational-order": "0.1.2", "stylelint-no-browser-hacks": "1.2.1", "stylelint-order": "6.0.3", From 747f647b5dadfffd621c639db1fbafd0f97cb4b9 Mon Sep 17 00:00:00 2001 From: Brian Bentancour Date: Mon, 1 May 2023 18:55:36 +0000 Subject: [PATCH 059/112] Translated using Weblate (Spanish (Argentina)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es_AR/ --- src/strings/es-ar.json | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/strings/es-ar.json b/src/strings/es-ar.json index 67fbbe8597..b8eae118bb 100644 --- a/src/strings/es-ar.json +++ b/src/strings/es-ar.json @@ -182,7 +182,7 @@ "DisplayInOtherHomeScreenSections": "Mostrar en las secciones de la pantalla principal, como \"Últimos Medios\" y \"Continuar viendo\"", "DisplayMissingEpisodesWithinSeasons": "Mostrar capítulos faltantes entre temporadas", "DisplayMissingEpisodesWithinSeasonsHelp": "Esto también debe estar habilitado para las bibliotecas de TV en la configuración del servidor.", - "DisplayModeHelp": "Seleccione el estilo de diseño que desea en la Interfaz.", + "DisplayModeHelp": "Seleccionar el estilo de diseño que desea en la Interfaz.", "DoNotRecord": "No grabar", "Down": "Abajo", "Download": "Descargar", @@ -278,7 +278,7 @@ "HeaderActiveDevices": "Dispositivos activos", "HeaderAccessScheduleHelp": "Cree un horario de acceso para limitar el acceso a ciertas horas.", "HeaderAccessSchedule": "Horario de acceso", - "HardwareAccelerationWarning": "Habilitar la aceleración de hardware puede causar inestabilidad en algunos entornos. Asegúrese de que su sistema operativo y los controladores de vídeo estén completamente actualizados. Si tiene dificultades para reproducir el vídeo después de habilitarlo, deberá volver a cambiar la configuración a \"Nada\".", + "HardwareAccelerationWarning": "Habilitar la aceleración de hardware puede causar inestabilidad en algunos entornos. Asegúrese de que su sistema operativo y los controladores de video estén completamente actualizados. Si tiene dificultades para reproducir el video después de habilitarlo, deberá volver a cambiar la configuración a Ninguno.", "HDPrograms": "Programas en HD", "EncoderPresetHelp": "Elegí un valor más rápido para mejorar el rendimiento, o un valor más lento para mejorar la calidad.", "FetchingData": "Obteniendo información adicional", @@ -1015,7 +1015,7 @@ "OptionCustomUsers": "Personalizado", "OptionCriticRating": "Valoración crítica", "OptionCommunityRating": "Calificación de la comunidad", - "OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)", + "OptionCaptionInfoExSamsung": "Información sobre subtítulos Ex (Samsung)", "OptionBluray": "Blu-ray", "MusicLibraryHelp": "Revise la {0}guía de nomenclatura musical{1}.", "MovieLibraryHelp": "Revise la {0}guía de nombres de películas{1}.", @@ -1120,13 +1120,13 @@ "OptionSaveMetadataAsHiddenHelp": "Cambiar esto se aplicará a los nuevos metadatos guardados en el futuro. Los archivos de metadatos existentes se actualizarán la próxima vez que el servidor los guarde.", "OptionSaveMetadataAsHidden": "Guardar metadatos e imágenes como archivos ocultos", "OptionResumable": "Reanudable", - "OptionResElement": "'res' element", + "OptionResElement": "Elemento 'res'", "OptionRequirePerfectSubtitleMatchHelp": "Requerir una combinación perfecta filtrará los subtítulos para incluir solo aquellos que han sido probados y verificados con su archivo de video exacto. Desmarcar esto aumentará la probabilidad de que se descarguen los subtítulos, pero aumentará las posibilidades de texto de subtítulos incorrecto o incorrecto.", "OptionRequirePerfectSubtitleMatch": "Descargar solo subtítulos que coincidan perfectamente con mis archivos de video", "OptionReportByteRangeSeekingWhenTranscodingHelp": "Esto es necesario para algunos dispositivos que no buscan el tiempo muy bien.", "OptionReportByteRangeSeekingWhenTranscoding": "Informe que el servidor admite la búsqueda de bytes al transcodificar", "OptionReleaseDate": "Fecha de lanzamiento", - "OptionRegex": "Regex", + "OptionRegex": "RegEx (Expresión regular)", "OptionRandom": "Aleatorio", "OptionProtocolHttp": "HTTP", "OptionProtocolHls": "Transmisión en vivo HTTP (HLS)", @@ -1170,7 +1170,7 @@ "RemoveFromCollection": "Eliminar de la colección", "RememberMe": "Recuérdame", "ButtonCast": "Transmitir a Dispositivo", - "ButtonSyncPlay": "SyncPlay", + "ButtonSyncPlay": "SyncPlay (Reproducción sincronizada)", "EnableBlurHashHelp": "Las imágenes que aún se están cargando se mostrarán con un marcador de posición único.", "EnableBlurHash": "Habilitar marcadores de posición borrosos para imágenes", "OnApplicationStartup": "En el inicio de la aplicación", @@ -1255,7 +1255,7 @@ "TabParentalControl": "Control parental", "TabOther": "Otro", "TabNotifications": "Notificaciones", - "TabNfoSettings": "Configuraciones de NFO", + "TabNfoSettings": "Configuración de NFO", "TabNetworking": "Redes", "TabNetworks": "TV Redes", "TabMyPlugins": "Mis complementos", @@ -1510,7 +1510,7 @@ "Framerate": "Tasa de Cuadros", "DirectPlayHelp": "El Archivo fuente es enteramente compatible con este cliente y la sesión esta recibiendo el archivo sin modificaciones.", "HeaderContinueReading": "Continuar leyendo", - "EnableGamepadHelp": "Esperando por entradas desde cualquier controlador conectado.", + "EnableGamepadHelp": "Esperando por entradas desde cualquier controlador conectado. (Requiere: modo de visualización 'TV')", "LabelEnableGamepad": "Habilitar Gamepad", "Controls": "Controles", "TextSent": "Texto enviado.", @@ -1672,7 +1672,7 @@ "StoryArc": "Arco narrativo", "Clip": "Ficha técnica", "LabelVppTonemappingBrightnessHelp": "Aplicar ganancia de brillo en el mapeo de tonos VPP. El valor predeterminado es 0 y el recomendado es 16.", - "LabelVppTonemappingContrastHelp": "Aplicar ganancia de contraste en el mapeo de tonos VPP. Los valores recomendados y predeterminados son 1.2 y 1.", + "LabelVppTonemappingContrastHelp": "Aplicar ganancia de contraste en el mapeo de tonos VPP. Ambos valores, tanto recomendados como predeterminados, son 1.", "VideoRangeTypeNotSupported": "El tipo de rango del video no es compatible", "MediaInfoRpuPresentFlag": "Bandera preestablecida de DV rpu", "MediaInfoElPresentFlag": "Indicador preestablecido DV el", @@ -1721,5 +1721,7 @@ "SubtitleLightGray": "Gris claro", "SubtitleRed": "Rojo", "SubtitleYellow": "Amarillo", - "Short": "Cortometraje" + "Short": "Cortometraje", + "LabelTonemappingMode": "Modo de mapeo de tono", + "TonemappingModeHelp": "Seleccionar el modo de mapeo de tono. Si experimenta sobreexposición intente cambiar al modo RGB." } From c93d362b3605d22a7a134eb61aae3e1370be9258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20V=C3=A9lez=20Schrod?= Date: Mon, 1 May 2023 21:21:52 +0000 Subject: [PATCH 060/112] Translated using Weblate (Spanish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es/ --- src/strings/es.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/strings/es.json b/src/strings/es.json index f42116c959..f1267a4a34 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1414,7 +1414,7 @@ "PosterCard": "Tarjeta de presentación", "EnableAutoCast": "Marcar como predeterminado", "LabelTonemappingDesatHelp": "Aplicar desaturación a realces que excedan este nivel de brillo. Mientras más alto el parámetro, se preservará más información de color. Este ajuste ayuda a prevenir la aparición de colores innecesariamente apagados en realces altos, cambiándolos gradualmente a blanco. Esto hace que las imágenes se vean más naturales, a cambio de reducir información relativa a los colores que estén fuera del rango. Se recomiendan los valores predeterminados 0 y 0.5.", - "AllowTonemappingHelp": "El mapeo de tonos puede transformar el rango dinámico de un video HDR a SDR mientras se mantienen los detalles y colores en la imagen, por lo tanto es importante para representar la escena original. Actualmente solo funciona con vídeos HDR10 o HLG. Esto requiere la librería OpenCL o Cuda, según corresponda.", + "AllowTonemappingHelp": "El mapeo de tonos puede transformar el rango dinámico de un video HDR a SDR mientras se mantienen los detalles y colores en la imagen, por lo tanto es importante para representar la escena original. Actualmente solo funciona con vídeos 10bit HDR10, HLG o DoVi. Esto requiere la librería OpenCL o Cuda, según corresponda.", "LabelOpenclDeviceHelp": "Este es el dispositivo OpenCL que se usará para el mapeo de tonos. La parte izquierda del punto es el número de plataforma, la derecha es el número de dispositivo en la plataforma. El valor predeterminado es 0.0. Se requiere especificar el archivo ejecutable FFmpeg con el método de aceleración por Hardware para OpenCL.", "LabelMaxMuxingQueueSizeHelp": "El número máximo de paquetes que se pueden almacenar en buffer mientras se espera a que se inicialicen todos los flujos. Intenta aumentar este valor si aún encuentras el mensaje de error \"Demasiados paquetes en buffer para transmitir\" en los registros de FFmpeg. El valor recomendado es 2048.", "LabelTonemappingPeakHelp": "Se omitirán los picos de referencia con este valor. Util cuando la información de pico incrustada en los metadatos de imagen no es confiable o cuando se hace un mapeo de tonos de un rango bajo a uno más alto. Se recomiendan los valores predeterminados 100 y 0.", @@ -1677,9 +1677,9 @@ "LabelStereoDownmixAlgorithm": "Algoritmo de mezcla estéreo", "StereoDownmixAlgorithmHelp": "Algoritmo utilizado para mezclar audio multicanal a estéreo.", "LabelVppTonemappingBrightness": "Ganancia de brillo de mapeo de tonos VPP", - "LabelVppTonemappingBrightnessHelp": "Aplicar gananca de brillo en mapeo de tonos VPP. El valor recomendado y por defecto es 0.", + "LabelVppTonemappingBrightnessHelp": "Aplicar ganancia de brillo en mapeo de tonos VPP. Los valores recomendados y por defecto son 16 y 0.", "Unreleased": "No publicado todavía", - "LabelVppTonemappingContrastHelp": "Aplicar ganancia de contraste en el mapeado de tonos VPP. Los valores recomendados y por defecto son 1.2 y 1 respectivamente.", + "LabelVppTonemappingContrastHelp": "Aplicar ganancia de contraste en el mapeado de tonos VPP. Los valores recomendados y seleccionados por defecto son 1.", "VideoRangeTypeNotSupported": "El tipo de rango del video no es compatible", "MediaInfoDvLevel": "Nivel de DV", "MediaInfoRpuPresentFlag": "Bandera preestablecida de DV rpu", @@ -1721,5 +1721,8 @@ "SubtitleRed": "Rojo", "SubtitleYellow": "Amarillo", "Short": "Cortometraje", - "HeaderPerformance": "Rendimiento" + "HeaderPerformance": "Rendimiento", + "LabelTonemappingMode": "Modo de mapeo de tono", + "TonemappingModeHelp": "Seleccione el modo de mapeado de tono. Si experimenta sobreiluminación intente cambiar al modo RGB.", + "Select": "Seleccionar" } From 848e9a738cdeb905314cd19aec72680d47d2f460 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 May 2023 01:31:32 +0000 Subject: [PATCH 061/112] Update peter-evans/create-or-update-comment action to v3.0.1 --- .github/workflows/commands.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/commands.yml b/.github/workflows/commands.yml index 20ec075c5b..27bf335e19 100644 --- a/.github/workflows/commands.yml +++ b/.github/workflows/commands.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Notify as seen - uses: peter-evans/create-or-update-comment@3383acd359705b10cb1eeef05c0e88c056ea4666 # v3.0.0 + uses: peter-evans/create-or-update-comment@ca08ebd5dc95aa0cd97021e9708fcd6b87138c9b # v3.0.1 with: token: ${{ secrets.JF_BOT_TOKEN }} comment-id: ${{ github.event.comment.id }} @@ -28,7 +28,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }} - name: Comment on failure if: failure() - uses: peter-evans/create-or-update-comment@3383acd359705b10cb1eeef05c0e88c056ea4666 # v3.0.0 + uses: peter-evans/create-or-update-comment@ca08ebd5dc95aa0cd97021e9708fcd6b87138c9b # v3.0.1 with: token: ${{ secrets.JF_BOT_TOKEN }} issue-number: ${{ github.event.issue.number }} From 5cfdb1647f9f96e92fb7b177d9dc15788dfe8423 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 2 May 2023 12:53:20 -0400 Subject: [PATCH 062/112] Fix getter return value bugs --- src/components/scrollManager.js | 2 +- src/legacy/focusPreventScroll.js | 2 +- src/scripts/dom.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/scrollManager.js b/src/components/scrollManager.js index 7417c7643e..52c46bcaf7 100644 --- a/src/components/scrollManager.js +++ b/src/components/scrollManager.js @@ -39,9 +39,9 @@ try { const elem = document.createElement('div'); const opts = Object.defineProperty({}, 'behavior', { - // eslint-disable-next-line getter-return get: function () { supportsScrollToOptions = true; + return null; } }); diff --git a/src/legacy/focusPreventScroll.js b/src/legacy/focusPreventScroll.js index 8f912207b5..6ed7d6d017 100644 --- a/src/legacy/focusPreventScroll.js +++ b/src/legacy/focusPreventScroll.js @@ -12,9 +12,9 @@ if (HTMLElement.prototype.nativeFocus === undefined) { }, true); const opts = Object.defineProperty({}, 'preventScroll', { - // eslint-disable-next-line getter-return get: function () { supportsPreventScrollOption = true; + return null; } }); diff --git a/src/scripts/dom.js b/src/scripts/dom.js index 75bf68cc1f..35ff2078a6 100644 --- a/src/scripts/dom.js +++ b/src/scripts/dom.js @@ -87,9 +87,9 @@ export function parentWithClass(elem, classNames) { let supportsCaptureOption = false; try { const opts = Object.defineProperty({}, 'capture', { - // eslint-disable-next-line getter-return get: function () { supportsCaptureOption = true; + return null; } }); window.addEventListener('test', null, opts); From 45450324a895b92b141625f6ff73112f78d55edc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 May 2023 18:36:54 +0000 Subject: [PATCH 063/112] Update dependency jassub to v1.5.13 --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6026fe142e..dd5ffbb5b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "history": "5.3.0", "hls.js": "1.4.0", "intersection-observer": "0.12.2", - "jassub": "1.5.12", + "jassub": "1.5.13", "jellyfin-apiclient": "1.10.0", "jquery": "3.6.4", "jstree": "3.3.15", @@ -10093,9 +10093,9 @@ } }, "node_modules/jassub": { - "version": "1.5.12", - "resolved": "https://registry.npmjs.org/jassub/-/jassub-1.5.12.tgz", - "integrity": "sha512-CJiuNCXMMGqfmVVlaDyxqaKfOy3RIHW4HBwVWvbq8pl/d1/y1fgTarfR31whUUupHZCe7Tfq8XB7WDgdu6IHaA==", + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/jassub/-/jassub-1.5.13.tgz", + "integrity": "sha512-mQM88BcYgppvpPG6VE+DPQm7r6QS65EBedbm13RE4lRIhdrnQ+ihWhBOZXYZe3SlGhg+ROIDRK8uY4dm9ER2XQ==", "dependencies": { "rvfc-polyfill": "^1.0.4" } @@ -27375,9 +27375,9 @@ "dev": true }, "jassub": { - "version": "1.5.12", - "resolved": "https://registry.npmjs.org/jassub/-/jassub-1.5.12.tgz", - "integrity": "sha512-CJiuNCXMMGqfmVVlaDyxqaKfOy3RIHW4HBwVWvbq8pl/d1/y1fgTarfR31whUUupHZCe7Tfq8XB7WDgdu6IHaA==", + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/jassub/-/jassub-1.5.13.tgz", + "integrity": "sha512-mQM88BcYgppvpPG6VE+DPQm7r6QS65EBedbm13RE4lRIhdrnQ+ihWhBOZXYZe3SlGhg+ROIDRK8uY4dm9ER2XQ==", "requires": { "rvfc-polyfill": "^1.0.4" } diff --git a/package.json b/package.json index 4e7e73d04c..7d831bc995 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "history": "5.3.0", "hls.js": "1.4.0", "intersection-observer": "0.12.2", - "jassub": "1.5.12", + "jassub": "1.5.13", "jellyfin-apiclient": "1.10.0", "jquery": "3.6.4", "jstree": "3.3.15", From 2badabb661e030a5be4d2ae9213938831aa98691 Mon Sep 17 00:00:00 2001 From: Bas Date: Tue, 2 May 2023 17:38:32 +0000 Subject: [PATCH 064/112] Translated using Weblate (Dutch) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/ --- src/strings/nl.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/strings/nl.json b/src/strings/nl.json index 0ef61eb21b..474c87ab18 100644 --- a/src/strings/nl.json +++ b/src/strings/nl.json @@ -1404,7 +1404,7 @@ "LabelTonemappingRange": "Tonemapping-bereik", "TonemappingAlgorithmHelp": "Tonemapping kan worden verfijnd. Als je niet bekend bent met deze opties, behoud je gewoon de standaardwaarde. De aanbevolen waarde is 'BT.2390'.", "LabelTonemappingAlgorithm": "Selecteer het te gebruiken tonemapping-algoritme", - "AllowTonemappingHelp": "Tone-mapping kan het dynamische bereik van een video transformeren van HDR naar SDR met behoud van beelddetails en kleuren, wat zeer belangrijke informatie is voor het weergeven van de originele scène. Werkt momenteel alleen met HDR10 of HLG videos. Dit vereist de bijbehorende OpenCL- of CUDA-runtime.", + "AllowTonemappingHelp": "Tone-mapping kan het dynamische bereik van een video transformeren van HDR naar SDR met behoud van beelddetails en kleuren, wat zeer belangrijke informatie is voor het weergeven van de originele scène. Werkt momenteel alleen met 10bit HDR10-, HLG- en DoVi-videos. Dit vereist de bijbehorende OpenCL- of CUDA-runtime.", "EnableTonemapping": "Tonemapping inschakelen", "LabelOpenclDeviceHelp": "Dit is het OpenCL-apparaat dat wordt gebruikt voor tonemapping. De linkerkant van het punt is het platformnummer en de rechterkant is het apparaatnummer op het platform. De standaardwaarde is 0,0. Het FFmpeg-toepassingsbestand met de OpenCL-hardwareversnellingsmethode is vereist.", "LabelOpenclDevice": "OpenCL-apparaat", @@ -1662,7 +1662,7 @@ "VideoRangeTypeNotSupported": "Het bereiktype van de video wordt niet ondersteund", "LabelVppTonemappingContrastHelp": "Pas contrastversterking toe in VPP-tonemapping. De aanbevolen en standaardwaarden zijn 1.2 en 1.", "LabelVppTonemappingContrast": "Contrastversterking VPP-tonemapping", - "LabelVppTonemappingBrightnessHelp": "Pas helderheidsversterking toe bij VPP-tonemapping. Zowel de aanbevolen als de standaardwaarden zijn 0.", + "LabelVppTonemappingBrightnessHelp": "Pas helderheidsversterking toe bij VPP-tonemapping. De aanbevolen en standaardwaarden zijn 0.", "LabelVppTonemappingBrightness": "Helderheidsversterking VPP-tonemapping", "EnableSplashScreen": "Opstartscherm inschakelen", "EnableEnhancedNvdecDecoderHelp": "Experimentele NVDEC-implementatie; deze instelling niet inschakelen tenzij u decoderingsfouten tegenkomt.", @@ -1721,5 +1721,7 @@ "LabelParallelImageEncodingLimit": "Limiet gelijktijdige afbeeldingscoderingen", "LabelEnableAudioVbr": "VBR-audiocodering inschakelen", "LabelEnableAudioVbrHelp": "Een variabele bitsnelheid biedt betere kwaliteit bij een vergelijkbare gemiddelde bitsnelheid, maar kan in zeldzame gevallen tot bufferen of compatibiliteitsproblemen leiden.", - "Select": "Selecteren" + "Select": "Selecteren", + "LabelTonemappingMode": "Tonemapping-modus", + "TonemappingModeHelp": "Selecteer de tonemapping-modus. Indien je overbelichtingsfouten ervaart, probeer dan de RGB-modus." } From 80411674737fc838810164e18f9626fffbf73c96 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 2 May 2023 15:51:46 -0400 Subject: [PATCH 065/112] Use typescript eslint parser for all files --- .eslintrc.js | 38 +++----- package-lock.json | 104 ---------------------- package.json | 2 - src/components/cardbuilder/cardBuilder.js | 3 - src/scripts/editorsidebar.js | 1 - src/scripts/keyboardNavigation.js | 1 - 6 files changed, 13 insertions(+), 136 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 01714c04c4..03e06eb499 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2,8 +2,9 @@ const restrictedGlobals = require('confusing-browser-globals'); module.exports = { root: true, + parser: '@typescript-eslint/parser', plugins: [ - '@babel', + '@typescript-eslint', 'react', 'promise', 'import', @@ -16,14 +17,6 @@ module.exports = { es2017: true, es2020: true }, - parserOptions: { - ecmaVersion: 2020, - sourceType: 'module', - ecmaFeatures: { - impliedStrict: true, - jsx: true - } - }, extends: [ 'eslint:recommended', 'plugin:react/recommended', @@ -53,14 +46,19 @@ module.exports = { 'no-multi-spaces': ['error'], 'no-multiple-empty-lines': ['error', { 'max': 1 }], 'no-nested-ternary': ['error'], + 'no-redeclare': ['off'], + '@typescript-eslint/no-redeclare': ['error', { builtinGlobals: false }], 'no-restricted-globals': ['error'].concat(restrictedGlobals), 'no-return-assign': ['error'], 'no-return-await': ['error'], 'no-sequences': ['error', { 'allowInParentheses': false }], - 'no-shadow': ['error'], + 'no-shadow': ['off'], + '@typescript-eslint/no-shadow': ['error'], 'no-trailing-spaces': ['error'], - '@babel/no-unused-expressions': ['error', { 'allowShortCircuit': true, 'allowTernary': true, 'allowTaggedTemplates': true }], - 'no-useless-constructor': ['error'], + 'no-unused-expressions': ['off'], + '@typescript-eslint/no-unused-expressions': ['error', { 'allowShortCircuit': true, 'allowTernary': true, 'allowTaggedTemplates': true }], + 'no-useless-constructor': ['off'], + '@typescript-eslint/no-useless-constructor': ['error'], 'no-var': ['error'], 'no-void': ['error', { 'allowAsStatement': true }], 'no-warning-comments': ['warn', { 'terms': ['fixme', 'hack', 'xxx'] }], @@ -71,7 +69,7 @@ module.exports = { 'prefer-const': ['error', { 'destructuring': 'all' }], 'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }], 'radix': ['error'], - '@babel/semi': ['error'], + '@typescript-eslint/semi': ['error'], 'space-before-blocks': ['error'], 'space-infix-ops': 'error', 'yoda': 'error', @@ -201,9 +199,9 @@ module.exports = { files: [ './src/**/*.js', './src/**/*.jsx', - './src/**/*.ts' + './src/**/*.ts', + './src/**/*.tsx' ], - parser: '@babel/eslint-parser', env: { node: false, amd: true, @@ -241,8 +239,6 @@ module.exports = { 'TaskButton': 'writable', 'UserParentalControlPage': 'writable', 'Windows': 'readonly' - }, - rules: { } }, // TypeScript source files @@ -251,8 +247,6 @@ module.exports = { './src/**/*.ts', './src/**/*.tsx' ], - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], extends: [ 'eslint:recommended', 'plugin:import/typescript', @@ -263,12 +257,6 @@ module.exports = { 'plugin:jsx-a11y/recommended' ], rules: { - // Use TypeScript equivalent rules when required - 'no-shadow': ['off'], - '@typescript-eslint/no-shadow': ['error'], - 'no-useless-constructor': ['off'], - '@typescript-eslint/no-useless-constructor': ['error'], - 'sonarjs/cognitive-complexity': ['warn'] } } diff --git a/package-lock.json b/package-lock.json index 6026fe142e..20807c8044 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,8 +56,6 @@ }, "devDependencies": { "@babel/core": "7.21.4", - "@babel/eslint-parser": "7.21.3", - "@babel/eslint-plugin": "7.19.1", "@babel/plugin-proposal-class-properties": "7.18.6", "@babel/plugin-proposal-private-methods": "7.18.6", "@babel/plugin-transform-modules-umd": "7.18.6", @@ -225,40 +223,6 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/eslint-parser": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.3.tgz", - "integrity": "sha512-kfhmPimwo6k4P8zxNs8+T7yR44q1LdpsZdE1NkCsVlfiuTPRfnGgjaF8Qgug9q9Pou17u6wneYF0lDCZJATMFg==", - "dev": true, - "dependencies": { - "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || >=14.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.11.0", - "eslint": "^7.5.0 || ^8.0.0" - } - }, - "node_modules/@babel/eslint-plugin": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-plugin/-/eslint-plugin-7.19.1.tgz", - "integrity": "sha512-ElGPkQPapKMa3zVqXHkZYzuL7I5LbRw9UWBUArgWsdWDDb9XcACqOpBib5tRPA9XvbVZYrFUkoQPbiJ4BFvu4w==", - "dev": true, - "dependencies": { - "eslint-rule-composer": "^0.3.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || >=14.0.0" - }, - "peerDependencies": { - "@babel/eslint-parser": ">=7.11.0", - "eslint": ">=7.5.0" - } - }, "node_modules/@babel/generator": { "version": "7.21.4", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", @@ -2902,15 +2866,6 @@ "node": ">=4" } }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", - "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", - "dev": true, - "dependencies": { - "eslint-scope": "5.1.1" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7232,15 +7187,6 @@ "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/eslint-rule-composer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", - "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -7254,15 +7200,6 @@ "node": ">=8.0.0" } }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint/node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -20171,26 +20108,6 @@ "semver": "^6.3.0" } }, - "@babel/eslint-parser": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.3.tgz", - "integrity": "sha512-kfhmPimwo6k4P8zxNs8+T7yR44q1LdpsZdE1NkCsVlfiuTPRfnGgjaF8Qgug9q9Pou17u6wneYF0lDCZJATMFg==", - "dev": true, - "requires": { - "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" - } - }, - "@babel/eslint-plugin": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-plugin/-/eslint-plugin-7.19.1.tgz", - "integrity": "sha512-ElGPkQPapKMa3zVqXHkZYzuL7I5LbRw9UWBUArgWsdWDDb9XcACqOpBib5tRPA9XvbVZYrFUkoQPbiJ4BFvu4w==", - "dev": true, - "requires": { - "eslint-rule-composer": "^0.3.0" - } - }, "@babel/generator": { "version": "7.21.4", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", @@ -21938,15 +21855,6 @@ "glob-to-regexp": "^0.3.0" } }, - "@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", - "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", - "dev": true, - "requires": { - "eslint-scope": "5.1.1" - } - }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -25452,12 +25360,6 @@ "dev": true, "requires": {} }, - "eslint-rule-composer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", - "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", - "dev": true - }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -25468,12 +25370,6 @@ "estraverse": "^4.1.1" } }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, "espree": { "version": "9.5.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", diff --git a/package.json b/package.json index 4e7e73d04c..5aca9baac6 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,6 @@ "license": "GPL-2.0-or-later", "devDependencies": { "@babel/core": "7.21.4", - "@babel/eslint-parser": "7.21.3", - "@babel/eslint-plugin": "7.19.1", "@babel/plugin-proposal-class-properties": "7.18.6", "@babel/plugin-proposal-private-methods": "7.18.6", "@babel/plugin-transform-modules-umd": "7.18.6", diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index d4f3aafa49..0271a5084b 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -1118,7 +1118,6 @@ let refreshIndicatorLoaded; function importRefreshIndicator() { if (!refreshIndicatorLoaded) { refreshIndicatorLoaded = true; - /* eslint-disable-next-line @babel/no-unused-expressions */ import('../../elements/emby-itemrefreshindicator/emby-itemrefreshindicator'); } } @@ -1469,7 +1468,6 @@ function getHoverMenuHtml(item, action) { const userData = item.UserData || {}; if (itemHelper.canMarkPlayed(item)) { - /* eslint-disable-next-line @babel/no-unused-expressions */ import('../../elements/emby-playstatebutton/emby-playstatebutton'); html += ''; } @@ -1477,7 +1475,6 @@ function getHoverMenuHtml(item, action) { if (itemHelper.canRate(item)) { const likes = userData.Likes == null ? '' : userData.Likes; - /* eslint-disable-next-line @babel/no-unused-expressions */ import('../../elements/emby-ratingbutton/emby-ratingbutton'); html += ''; } diff --git a/src/scripts/editorsidebar.js b/src/scripts/editorsidebar.js index e3a1f58ab8..8f6cd24c98 100644 --- a/src/scripts/editorsidebar.js +++ b/src/scripts/editorsidebar.js @@ -300,7 +300,6 @@ let selectedNodeId; $(document).on('itemsaved', '.metadataEditorPage', function (e, item) { updateEditorNode(this, item); }).on('pagebeforeshow', '.metadataEditorPage', function () { - /* eslint-disable-next-line @babel/no-unused-expressions */ import('../styles/metadataeditor.scss'); }).on('pagebeforeshow', '.metadataEditorPage', function () { const page = this; diff --git a/src/scripts/keyboardNavigation.js b/src/scripts/keyboardNavigation.js index 39c187479d..6e8e477d7a 100644 --- a/src/scripts/keyboardNavigation.js +++ b/src/scripts/keyboardNavigation.js @@ -202,7 +202,6 @@ export function enable() { function attachGamepadScript() { console.log('Gamepad connected! Attaching gamepadtokey.js script'); window.removeEventListener('gamepadconnected', attachGamepadScript); - /* eslint-disable-next-line @babel/no-unused-expressions */ import('./gamepadtokey'); } From 45623fe586859550cce6441bfabcab46b571b96f Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 2 May 2023 15:54:53 -0400 Subject: [PATCH 066/112] Fix missing semicolons in ts files --- src/apiclient.d.ts | 2 +- src/components/dashboard/users/AccessContainer.tsx | 2 +- src/components/dashboard/users/AccessScheduleList.tsx | 2 +- src/components/dashboard/users/BlockedTagList.tsx | 2 +- src/components/dashboard/users/LinkEditUserPreferences.tsx | 2 +- src/components/dashboard/users/SectionTabs.tsx | 2 +- src/components/dashboard/users/UserCardBox.tsx | 2 +- src/components/dashboard/users/UserPasswordForm.tsx | 2 +- src/components/search/LiveTVSearchResults.tsx | 2 +- src/components/search/SearchResults.tsx | 2 +- src/components/search/SearchResultsRow.tsx | 4 ++-- src/components/search/SearchSuggestions.tsx | 2 +- src/elements/ButtonElement.tsx | 2 +- src/elements/CheckBoxElement.tsx | 2 +- src/elements/IconButtonElement.tsx | 2 +- src/elements/InputElement.tsx | 2 +- src/elements/SectionTitleContainer.tsx | 2 +- src/elements/SectionTitleLinkElement.tsx | 2 +- src/elements/SelectElement.tsx | 2 +- src/routes/home.tsx | 4 ++-- src/routes/user/useredit.tsx | 4 ++-- src/routes/user/userlibraryaccess.tsx | 2 +- src/routes/user/usernew.tsx | 4 ++-- src/routes/user/userparentalcontrol.tsx | 2 +- src/routes/user/userprofiles.tsx | 2 +- 25 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/apiclient.d.ts b/src/apiclient.d.ts index 33f3752ca7..a9f7f61ccd 100644 --- a/src/apiclient.d.ts +++ b/src/apiclient.d.ts @@ -268,7 +268,7 @@ declare module 'jellyfin-apiclient' { sendWebSocketMessage(name: string, data: any): void; serverAddress(val?: string): string; serverId(): string; - serverVersion(): string + serverVersion(): string; setAuthenticationInfo(accessKey?: string, userId?: string): void; setRequestHeaders(headers: any): void; setSystemInfo(info: SystemInfo): void; diff --git a/src/components/dashboard/users/AccessContainer.tsx b/src/components/dashboard/users/AccessContainer.tsx index 32fe9c213d..88727f396a 100644 --- a/src/components/dashboard/users/AccessContainer.tsx +++ b/src/components/dashboard/users/AccessContainer.tsx @@ -12,7 +12,7 @@ type IProps = { listTitle?: string; description?: string; children?: React.ReactNode -} +}; const AccessContainer: FunctionComponent = ({ containerClassName, headerTitle, checkBoxClassName, checkBoxTitle, listContainerClassName, accessClassName, listTitle, description, children }: IProps) => { return ( diff --git a/src/components/dashboard/users/AccessScheduleList.tsx b/src/components/dashboard/users/AccessScheduleList.tsx index 41c55c3621..f1e5affb8c 100644 --- a/src/components/dashboard/users/AccessScheduleList.tsx +++ b/src/components/dashboard/users/AccessScheduleList.tsx @@ -9,7 +9,7 @@ type AccessScheduleListProps = { DayOfWeek?: string; StartHour?: number ; EndHour?: number; -} +}; function getDisplayTime(hours = 0) { let minutes = 0; diff --git a/src/components/dashboard/users/BlockedTagList.tsx b/src/components/dashboard/users/BlockedTagList.tsx index 20e7f88ef2..5158a63e97 100644 --- a/src/components/dashboard/users/BlockedTagList.tsx +++ b/src/components/dashboard/users/BlockedTagList.tsx @@ -3,7 +3,7 @@ import IconButtonElement from '../../../elements/IconButtonElement'; type IProps = { tag?: string; -} +}; const BlockedTagList: FunctionComponent = ({ tag }: IProps) => { return ( diff --git a/src/components/dashboard/users/LinkEditUserPreferences.tsx b/src/components/dashboard/users/LinkEditUserPreferences.tsx index fde63ba514..fd272fd770 100644 --- a/src/components/dashboard/users/LinkEditUserPreferences.tsx +++ b/src/components/dashboard/users/LinkEditUserPreferences.tsx @@ -4,7 +4,7 @@ import globalize from '../../../scripts/globalize'; type IProps = { title?: string; className?: string; -} +}; const createLinkElement = ({ className, title }: IProps) => ({ __html: ` ({ __html: ` { if (lastActivityDate) { diff --git a/src/components/dashboard/users/UserPasswordForm.tsx b/src/components/dashboard/users/UserPasswordForm.tsx index 8cfb47b5b1..0337c06510 100644 --- a/src/components/dashboard/users/UserPasswordForm.tsx +++ b/src/components/dashboard/users/UserPasswordForm.tsx @@ -11,7 +11,7 @@ import InputElement from '../../../elements/InputElement'; type IProps = { userId: string; -} +}; const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { const element = useRef(null); diff --git a/src/components/search/LiveTVSearchResults.tsx b/src/components/search/LiveTVSearchResults.tsx index 5b4c097c5c..a087dc23cc 100644 --- a/src/components/search/LiveTVSearchResults.tsx +++ b/src/components/search/LiveTVSearchResults.tsx @@ -24,7 +24,7 @@ type LiveTVSearchResultsProps = { parentId?: string | null; collectionType?: string | null; query?: string; -} +}; /* * React component to display search result rows for live tv library search diff --git a/src/components/search/SearchResults.tsx b/src/components/search/SearchResults.tsx index 720cee0e3c..731cc6ec35 100644 --- a/src/components/search/SearchResults.tsx +++ b/src/components/search/SearchResults.tsx @@ -12,7 +12,7 @@ type SearchResultsProps = { parentId?: string | null; collectionType?: string | null; query?: string; -} +}; const ensureNonNullItems = (result: BaseItemDtoQueryResult) => ({ ...result, diff --git a/src/components/search/SearchResultsRow.tsx b/src/components/search/SearchResultsRow.tsx index 9dbb330578..0e5c1a50a4 100644 --- a/src/components/search/SearchResultsRow.tsx +++ b/src/components/search/SearchResultsRow.tsx @@ -35,13 +35,13 @@ type CardOptions = { showChannelName?: boolean, showTitle?: boolean, showYear?: boolean -} +}; type SearchResultsRowProps = { title?: string; items?: BaseItemDto[]; cardOptions?: CardOptions; -} +}; const SearchResultsRow: FunctionComponent = ({ title, items = [], cardOptions = {} }: SearchResultsRowProps) => { const element = useRef(null); diff --git a/src/components/search/SearchSuggestions.tsx b/src/components/search/SearchSuggestions.tsx index d16cdca8e6..7e70d19ee5 100644 --- a/src/components/search/SearchSuggestions.tsx +++ b/src/components/search/SearchSuggestions.tsx @@ -25,7 +25,7 @@ const createSuggestionLink = ({ name, href }: { name: string, href: string }) => type SearchSuggestionsProps = { parentId?: string | null; -} +}; const SearchSuggestions: FunctionComponent = ({ parentId }: SearchSuggestionsProps) => { const [ suggestions, setSuggestions ] = useState([]); diff --git a/src/elements/ButtonElement.tsx b/src/elements/ButtonElement.tsx index 3de90f0c11..f9ed58954b 100644 --- a/src/elements/ButtonElement.tsx +++ b/src/elements/ButtonElement.tsx @@ -21,7 +21,7 @@ type IProps = { title?: string; leftIcon?: string; rightIcon?: string; -} +}; const ButtonElement: FunctionComponent = ({ type, id, className, title, leftIcon, rightIcon }: IProps) => { return ( diff --git a/src/elements/CheckBoxElement.tsx b/src/elements/CheckBoxElement.tsx index fade823891..c8d861a0bb 100644 --- a/src/elements/CheckBoxElement.tsx +++ b/src/elements/CheckBoxElement.tsx @@ -29,7 +29,7 @@ type IProps = { itemCheckedAttribute?: string; itemName?: string title?: string -} +}; const CheckBoxElement: FunctionComponent = ({ labelClassName, className, elementId, dataFilter, itemType, itemId, itemAppName, itemCheckedAttribute, itemName, title }: IProps) => { const appName = itemAppName ? `- ${itemAppName}` : ''; diff --git a/src/elements/IconButtonElement.tsx b/src/elements/IconButtonElement.tsx index b39847403b..50b4d76f6e 100644 --- a/src/elements/IconButtonElement.tsx +++ b/src/elements/IconButtonElement.tsx @@ -10,7 +10,7 @@ type IProps = { dataIndex?: string | number; dataTag?: string | number; dataProfileid?: string | number; -} +}; const createIconButtonElement = ({ is, id, className, title, icon, dataIndex, dataTag, dataProfileid }: IProps) => ({ __html: ` - - -
- -
-
-
diff --git a/src/controllers/dashboard/users/useredit.js b/src/controllers/dashboard/users/useredit.js deleted file mode 100644 index 98aa0dd40e..0000000000 --- a/src/controllers/dashboard/users/useredit.js +++ /dev/null @@ -1,196 +0,0 @@ -import 'jquery'; -import loading from '../../../components/loading/loading'; -import libraryMenu from '../../../scripts/libraryMenu'; -import globalize from '../../../scripts/globalize'; -import Dashboard from '../../../utils/dashboard'; -import toast from '../../../components/toast/toast'; -import { getParameterByName } from '../../../utils/url.ts'; - -function loadDeleteFolders(page, user, mediaFolders) { - ApiClient.getJSON(ApiClient.getUrl('Channels', { - SupportsMediaDeletion: true - })).then(function (channelsResult) { - let isChecked; - let checkedAttribute; - let html = ''; - - for (const folder of mediaFolders) { - isChecked = user.Policy.EnableContentDeletion || user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id) != -1; - checkedAttribute = isChecked ? ' checked="checked"' : ''; - html += ''; - } - - for (const folder of channelsResult.Items) { - isChecked = user.Policy.EnableContentDeletion || user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id) != -1; - checkedAttribute = isChecked ? ' checked="checked"' : ''; - html += ''; - } - - $('.deleteAccess', page).html(html).trigger('create'); - $('#chkEnableDeleteAllFolders', page).prop('checked', user.Policy.EnableContentDeletion); - }); -} - -function loadAuthProviders(page, user, providers) { - if (providers.length > 1) { - page.querySelector('.fldSelectLoginProvider').classList.remove('hide'); - } else { - page.querySelector('.fldSelectLoginProvider').classList.add('hide'); - } - - const currentProviderId = user.Policy.AuthenticationProviderId; - page.querySelector('.selectLoginProvider').innerHTML = providers.map(function (provider) { - const selected = provider.Id === currentProviderId || providers.length < 2 ? ' selected' : ''; - return ''; - }); -} - -function loadPasswordResetProviders(page, user, providers) { - if (providers.length > 1) { - page.querySelector('.fldSelectPasswordResetProvider').classList.remove('hide'); - } else { - page.querySelector('.fldSelectPasswordResetProvider').classList.add('hide'); - } - - const currentProviderId = user.Policy.PasswordResetProviderId; - page.querySelector('.selectPasswordResetProvider').innerHTML = providers.map(function (provider) { - const selected = provider.Id === currentProviderId || providers.length < 2 ? ' selected' : ''; - return ''; - }); -} - -function loadUser(page, user) { - ApiClient.getJSON(ApiClient.getUrl('Auth/Providers')).then(function (providers) { - loadAuthProviders(page, user, providers); - }); - ApiClient.getJSON(ApiClient.getUrl('Auth/PasswordResetProviders')).then(function (providers) { - loadPasswordResetProviders(page, user, providers); - }); - ApiClient.getJSON(ApiClient.getUrl('Library/MediaFolders', { - IsHidden: false - })).then(function (folders) { - loadDeleteFolders(page, user, folders.Items); - }); - - if (user.Policy.IsDisabled) { - $('.disabledUserBanner', page).show(); - } else { - $('.disabledUserBanner', page).hide(); - } - - $('#txtUserName', page).prop('disabled', '').removeAttr('disabled'); - $('#fldConnectInfo', page).show(); - $('.lnkEditUserPreferences', page).attr('href', 'mypreferencesmenu.html?userId=' + user.Id); - libraryMenu.setTitle(user.Name); - page.querySelector('.username').innerHTML = user.Name; - $('#txtUserName', page).val(user.Name); - $('#chkIsAdmin', page).prop('checked', user.Policy.IsAdministrator); - $('#chkDisabled', page).prop('checked', user.Policy.IsDisabled); - $('#chkIsHidden', page).prop('checked', user.Policy.IsHidden); - $('#chkEnableCollectionManagement', page).prop('checked', user.Policy.chkEnableCollectionManagement); - $('#chkRemoteControlSharedDevices', page).prop('checked', user.Policy.EnableSharedDeviceControl); - $('#chkEnableRemoteControlOtherUsers', page).prop('checked', user.Policy.EnableRemoteControlOfOtherUsers); - $('#chkEnableDownloading', page).prop('checked', user.Policy.EnableContentDownloading); - $('#chkManageLiveTv', page).prop('checked', user.Policy.EnableLiveTvManagement); - $('#chkEnableLiveTvAccess', page).prop('checked', user.Policy.EnableLiveTvAccess); - $('#chkEnableMediaPlayback', page).prop('checked', user.Policy.EnableMediaPlayback); - $('#chkEnableAudioPlaybackTranscoding', page).prop('checked', user.Policy.EnableAudioPlaybackTranscoding); - $('#chkEnableVideoPlaybackTranscoding', page).prop('checked', user.Policy.EnableVideoPlaybackTranscoding); - $('#chkEnableVideoPlaybackRemuxing', page).prop('checked', user.Policy.EnablePlaybackRemuxing); - $('#chkForceRemoteSourceTranscoding', page).prop('checked', user.Policy.ForceRemoteSourceTranscoding); - $('#chkRemoteAccess', page).prop('checked', user.Policy.EnableRemoteAccess == null || user.Policy.EnableRemoteAccess); - $('#txtRemoteClientBitrateLimit', page).val(user.Policy.RemoteClientBitrateLimit / 1e6 || ''); - $('#txtLoginAttemptsBeforeLockout', page).val(user.Policy.LoginAttemptsBeforeLockout || '0'); - $('#txtMaxActiveSessions', page).val(user.Policy.MaxActiveSessions || '0'); - if (ApiClient.isMinServerVersion('10.6.0')) { - $('#selectSyncPlayAccess').val(user.Policy.SyncPlayAccess); - } - loading.hide(); -} - -function onSaveComplete() { - Dashboard.navigate('userprofiles.html'); - loading.hide(); - toast(globalize.translate('SettingsSaved')); -} - -function saveUser(user, page) { - user.Name = $('#txtUserName', page).val(); - user.Policy.IsAdministrator = $('#chkIsAdmin', page).is(':checked'); - user.Policy.IsHidden = $('#chkIsHidden', page).is(':checked'); - user.Policy.IsDisabled = $('#chkDisabled', page).is(':checked'); - user.Policy.EnableRemoteControlOfOtherUsers = $('#chkEnableRemoteControlOtherUsers', page).is(':checked'); - user.Policy.EnableLiveTvManagement = $('#chkManageLiveTv', page).is(':checked'); - user.Policy.EnableLiveTvAccess = $('#chkEnableLiveTvAccess', page).is(':checked'); - user.Policy.EnableSharedDeviceControl = $('#chkRemoteControlSharedDevices', page).is(':checked'); - user.Policy.EnableMediaPlayback = $('#chkEnableMediaPlayback', page).is(':checked'); - user.Policy.EnableAudioPlaybackTranscoding = $('#chkEnableAudioPlaybackTranscoding', page).is(':checked'); - user.Policy.EnableVideoPlaybackTranscoding = $('#chkEnableVideoPlaybackTranscoding', page).is(':checked'); - user.Policy.EnablePlaybackRemuxing = $('#chkEnableVideoPlaybackRemuxing', page).is(':checked'); - user.Policy.EnableCollectionManagement = $('#chkEnableCollectionManagement', page).is(':checked'); - user.Policy.ForceRemoteSourceTranscoding = $('#chkForceRemoteSourceTranscoding', page).is(':checked'); - user.Policy.EnableContentDownloading = $('#chkEnableDownloading', page).is(':checked'); - user.Policy.EnableRemoteAccess = $('#chkRemoteAccess', page).is(':checked'); - user.Policy.RemoteClientBitrateLimit = parseInt(1e6 * parseFloat($('#txtRemoteClientBitrateLimit', page).val() || '0'), 10); - user.Policy.LoginAttemptsBeforeLockout = parseInt($('#txtLoginAttemptsBeforeLockout', page).val() || '0', 10); - user.Policy.MaxActiveSessions = parseInt($('#txtMaxActiveSessions', page).val() || '0', 10); - user.Policy.AuthenticationProviderId = page.querySelector('.selectLoginProvider').value; - user.Policy.PasswordResetProviderId = page.querySelector('.selectPasswordResetProvider').value; - user.Policy.EnableContentDeletion = $('#chkEnableDeleteAllFolders', page).is(':checked'); - user.Policy.EnableContentDeletionFromFolders = user.Policy.EnableContentDeletion ? [] : $('.chkFolder', page).get().filter(function (c) { - return c.checked; - }).map(function (c) { - return c.getAttribute('data-id'); - }); - if (ApiClient.isMinServerVersion('10.6.0')) { - user.Policy.SyncPlayAccess = page.querySelector('#selectSyncPlayAccess').value; - } - ApiClient.updateUser(user).then(function () { - ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { - onSaveComplete(); - }); - }); -} - -function onSubmit() { - const page = $(this).parents('.page')[0]; - loading.show(); - getUser().then(function (result) { - saveUser(result, page); - }); - return false; -} - -function getUser() { - const userId = getParameterByName('userId'); - return ApiClient.getUser(userId); -} - -function loadData(page) { - loading.show(); - getUser().then(function (user) { - loadUser(page, user); - }); -} - -$(document).on('pageinit', '#editUserPage', function () { - $('.editUserProfileForm').off('submit', onSubmit).on('submit', onSubmit); - const page = this; - $('#chkEnableDeleteAllFolders', this).on('change', function () { - if (this.checked) { - $('.deleteAccess', page).hide(); - } else { - $('.deleteAccess', page).show(); - } - }); - ApiClient.getServerConfiguration().then(function (config) { - if (config.EnableRemoteAccess) { - page.querySelector('.fldRemoteAccess').classList.remove('hide'); - } else { - page.querySelector('.fldRemoteAccess').classList.add('hide'); - } - }); -}).on('pagebeforeshow', '#editUserPage', function () { - loadData(this); -}); - diff --git a/src/controllers/dashboard/users/userlibraryaccess.html b/src/controllers/dashboard/users/userlibraryaccess.html deleted file mode 100644 index bf6ba93408..0000000000 --- a/src/controllers/dashboard/users/userlibraryaccess.html +++ /dev/null @@ -1,68 +0,0 @@ -
- -
-
- -
-
-

- ${Help} -
-
- - -
- -
-

${HeaderLibraryAccess}

- -
-
-
-
${LibraryAccessHelp}
-
-
- -
-
-

${HeaderDeviceAccess}

- -
-
-
-
${DeviceAccessHelp}
-
-
-
-
-
- -
-
-
-
-
diff --git a/src/controllers/dashboard/users/userlibraryaccess.js b/src/controllers/dashboard/users/userlibraryaccess.js deleted file mode 100644 index e84638e8e0..0000000000 --- a/src/controllers/dashboard/users/userlibraryaccess.js +++ /dev/null @@ -1,184 +0,0 @@ -import 'jquery'; -import loading from '../../../components/loading/loading'; -import libraryMenu from '../../../scripts/libraryMenu'; -import globalize from '../../../scripts/globalize'; -import Dashboard from '../../../utils/dashboard'; -import toast from '../../../components/toast/toast'; -import { getParameterByName } from '../../../utils/url.ts'; - -function triggerChange(select) { - const evt = document.createEvent('HTMLEvents'); - evt.initEvent('change', false, true); - select.dispatchEvent(evt); -} - -function loadMediaFolders(page, user, mediaFolders) { - let html = ''; - html += '

' + globalize.translate('HeaderLibraries') + '

'; - html += '
'; - - for (let i = 0, length = mediaFolders.length; i < length; i++) { - const folder = mediaFolders[i]; - const isChecked = user.Policy.EnableAllFolders || user.Policy.EnabledFolders.indexOf(folder.Id) != -1; - const checkedAttribute = isChecked ? ' checked="checked"' : ''; - html += ''; - } - - html += '
'; - page.querySelector('.folderAccess').innerHTML = html; - const chkEnableAllFolders = page.querySelector('#chkEnableAllFolders'); - chkEnableAllFolders.checked = user.Policy.EnableAllFolders; - triggerChange(chkEnableAllFolders); -} - -function loadChannels(page, user, channels) { - let html = ''; - html += '

' + globalize.translate('Channels') + '

'; - html += '
'; - - for (let i = 0, length = channels.length; i < length; i++) { - const folder = channels[i]; - const isChecked = user.Policy.EnableAllChannels || user.Policy.EnabledChannels.indexOf(folder.Id) != -1; - const checkedAttribute = isChecked ? ' checked="checked"' : ''; - html += ''; - } - - html += '
'; - $('.channelAccess', page).show().html(html); - - if (channels.length) { - $('.channelAccessContainer', page).show(); - } else { - $('.channelAccessContainer', page).hide(); - } - - const chkEnableAllChannels = page.querySelector('#chkEnableAllChannels'); - chkEnableAllChannels.checked = user.Policy.EnableAllChannels; - triggerChange(chkEnableAllChannels); -} - -function loadDevices(page, user, devices) { - let html = ''; - html += '

' + globalize.translate('HeaderDevices') + '

'; - html += '
'; - - for (let i = 0, length = devices.length; i < length; i++) { - const device = devices[i]; - const checkedAttribute = user.Policy.EnableAllDevices || user.Policy.EnabledDevices.indexOf(device.Id) != -1 ? ' checked="checked"' : ''; - html += ''; - } - - html += '
'; - $('.deviceAccess', page).show().html(html); - const chkEnableAllDevices = page.querySelector('#chkEnableAllDevices'); - chkEnableAllDevices.checked = user.Policy.EnableAllDevices; - triggerChange(chkEnableAllDevices); - - if (user.Policy.IsAdministrator) { - page.querySelector('.deviceAccessContainer').classList.add('hide'); - } else { - page.querySelector('.deviceAccessContainer').classList.remove('hide'); - } -} - -function loadUser(page, user, loggedInUser, mediaFolders, channels, devices) { - page.querySelector('.username').innerHTML = user.Name; - libraryMenu.setTitle(user.Name); - loadChannels(page, user, channels); - loadMediaFolders(page, user, mediaFolders); - loadDevices(page, user, devices); - loading.hide(); -} - -function onSaveComplete() { - loading.hide(); - toast(globalize.translate('SettingsSaved')); -} - -function saveUser(user, page) { - user.Policy.EnableAllFolders = $('#chkEnableAllFolders', page).is(':checked'); - user.Policy.EnabledFolders = user.Policy.EnableAllFolders ? [] : $('.chkFolder', page).get().filter(function (c) { - return c.checked; - }).map(function (c) { - return c.getAttribute('data-id'); - }); - user.Policy.EnableAllChannels = $('#chkEnableAllChannels', page).is(':checked'); - user.Policy.EnabledChannels = user.Policy.EnableAllChannels ? [] : $('.chkChannel', page).get().filter(function (c) { - return c.checked; - }).map(function (c) { - return c.getAttribute('data-id'); - }); - user.Policy.EnableAllDevices = $('#chkEnableAllDevices', page).is(':checked'); - user.Policy.EnabledDevices = user.Policy.EnableAllDevices ? [] : $('.chkDevice', page).get().filter(function (c) { - return c.checked; - }).map(function (c) { - return c.getAttribute('data-id'); - }); - user.Policy.BlockedChannels = null; - user.Policy.BlockedMediaFolders = null; - ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { - onSaveComplete(); - }); -} - -function onSubmit() { - const page = $(this).parents('.page'); - loading.show(); - const userId = getParameterByName('userId'); - ApiClient.getUser(userId).then(function (result) { - saveUser(result, page); - }); - return false; -} - -$(document).on('pageinit', '#userLibraryAccessPage', function () { - const page = this; - $('#chkEnableAllDevices', page).on('change', function () { - if (this.checked) { - $('.deviceAccessListContainer', page).hide(); - } else { - $('.deviceAccessListContainer', page).show(); - } - }); - $('#chkEnableAllChannels', page).on('change', function () { - if (this.checked) { - $('.channelAccessListContainer', page).hide(); - } else { - $('.channelAccessListContainer', page).show(); - } - }); - page.querySelector('#chkEnableAllFolders').addEventListener('change', function () { - if (this.checked) { - page.querySelector('.folderAccessListContainer').classList.add('hide'); - } else { - page.querySelector('.folderAccessListContainer').classList.remove('hide'); - } - }); - $('.userLibraryAccessForm').off('submit', onSubmit).on('submit', onSubmit); -}).on('pageshow', '#userLibraryAccessPage', function () { - const page = this; - loading.show(); - let promise1; - const userId = getParameterByName('userId'); - - if (userId) { - promise1 = ApiClient.getUser(userId); - } else { - const deferred = $.Deferred(); - deferred.resolveWith(null, [{ - Configuration: {} - }]); - promise1 = deferred.promise(); - } - - const promise2 = Dashboard.getCurrentUser(); - const promise4 = ApiClient.getJSON(ApiClient.getUrl('Library/MediaFolders', { - IsHidden: false - })); - const promise5 = ApiClient.getJSON(ApiClient.getUrl('Channels')); - const promise6 = ApiClient.getJSON(ApiClient.getUrl('Devices')); - Promise.all([promise1, promise2, promise4, promise5, promise6]).then(function (responses) { - loadUser(page, responses[0], responses[1], responses[2].Items, responses[3].Items, responses[4].Items); - }); -}); - diff --git a/src/controllers/dashboard/users/usernew.html b/src/controllers/dashboard/users/usernew.html deleted file mode 100644 index 5d50ede80a..0000000000 --- a/src/controllers/dashboard/users/usernew.html +++ /dev/null @@ -1,62 +0,0 @@ -
-
-
-
-
-
-

${ButtonAddUser}

- ${Help} -
- -
- -
- -
- -
-
- -
-

${HeaderLibraryAccess}

-
- -
${LibraryAccessHelp}
-
-
-
-
-
-
- - - -
- - - -
-
-
-
-
diff --git a/src/controllers/dashboard/users/usernew.js b/src/controllers/dashboard/users/usernew.js deleted file mode 100644 index 9477506aca..0000000000 --- a/src/controllers/dashboard/users/usernew.js +++ /dev/null @@ -1,128 +0,0 @@ -import 'jquery'; -import loading from '../../../components/loading/loading'; -import globalize from '../../../scripts/globalize'; -import '../../../elements/emby-checkbox/emby-checkbox'; -import Dashboard from '../../../utils/dashboard'; -import toast from '../../../components/toast/toast'; - -function loadMediaFolders(page, mediaFolders) { - let html = ''; - html += '

' + globalize.translate('HeaderLibraries') + '

'; - html += '
'; - - for (let i = 0; i < mediaFolders.length; i++) { - const folder = mediaFolders[i]; - html += ''; - } - - html += '
'; - $('.folderAccess', page).html(html).trigger('create'); - $('#chkEnableAllFolders', page).prop('checked', false); -} - -function loadChannels(page, channels) { - let html = ''; - html += '

' + globalize.translate('Channels') + '

'; - html += '
'; - - for (let i = 0; i < channels.length; i++) { - const folder = channels[i]; - html += ''; - } - - html += '
'; - $('.channelAccess', page).show().html(html).trigger('create'); - - if (channels.length) { - $('.channelAccessContainer', page).show(); - } else { - $('.channelAccessContainer', page).hide(); - } - - $('#chkEnableAllChannels', page).prop('checked', false); -} - -function loadUser(page) { - $('#txtUsername', page).val(''); - $('#txtPassword', page).val(''); - loading.show(); - const promiseFolders = ApiClient.getJSON(ApiClient.getUrl('Library/MediaFolders', { - IsHidden: false - })); - const promiseChannels = ApiClient.getJSON(ApiClient.getUrl('Channels')); - Promise.all([promiseFolders, promiseChannels]).then(function (responses) { - loadMediaFolders(page, responses[0].Items); - loadChannels(page, responses[1].Items); - loading.hide(); - }); -} - -function saveUser(page) { - const _user = { - Name: $('#txtUsername', page).val(), - Password: $('#txtPassword', page).val() - }; - ApiClient.createUser(_user).then(function (user) { - user.Policy.EnableAllFolders = $('#chkEnableAllFolders', page).is(':checked'); - user.Policy.EnabledFolders = []; - - if (!user.Policy.EnableAllFolders) { - user.Policy.EnabledFolders = $('.chkFolder', page).get().filter(function (i) { - return i.checked; - }).map(function (i) { - return i.getAttribute('data-id'); - }); - } - - user.Policy.EnableAllChannels = $('#chkEnableAllChannels', page).is(':checked'); - user.Policy.EnabledChannels = []; - - if (!user.Policy.EnableAllChannels) { - user.Policy.EnabledChannels = $('.chkChannel', page).get().filter(function (i) { - return i.checked; - }).map(function (i) { - return i.getAttribute('data-id'); - }); - } - - ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { - Dashboard.navigate('useredit.html?userId=' + user.Id); - }); - }, function () { - toast(globalize.translate('ErrorDefault')); - loading.hide(); - }); -} - -function onSubmit() { - const page = $(this).parents('.page')[0]; - loading.show(); - saveUser(page); - return false; -} - -function loadData(page) { - loadUser(page); -} - -$(document).on('pageinit', '#newUserPage', function () { - const page = this; - $('#chkEnableAllChannels', page).on('change', function () { - if (this.checked) { - $('.channelAccessListContainer', page).hide(); - } else { - $('.channelAccessListContainer', page).show(); - } - }); - $('#chkEnableAllFolders', page).on('change', function () { - if (this.checked) { - $('.folderAccessListContainer', page).hide(); - } else { - $('.folderAccessListContainer', page).show(); - } - }); - $('.newUserProfileForm').off('submit', onSubmit).on('submit', onSubmit); -}).on('pageshow', '#newUserPage', function () { - loadData(this); -}); - diff --git a/src/controllers/dashboard/users/userparentalcontrol.html b/src/controllers/dashboard/users/userparentalcontrol.html deleted file mode 100644 index 5b58047c60..0000000000 --- a/src/controllers/dashboard/users/userparentalcontrol.html +++ /dev/null @@ -1,60 +0,0 @@ -
-
-
-
-
-

- ${Help} -
-
- - - -
-
- -
${MaxParentalRatingHelp}
-
- -
-
-
- -
- -
-
-

${LabelBlockContentWithTags}

- -
-
-
- -
-
-

${HeaderAccessSchedule}

- -
- -

${HeaderAccessScheduleHelp}

-
-
- -
- -
-
-
-
-
diff --git a/src/controllers/dashboard/users/userparentalcontrol.js b/src/controllers/dashboard/users/userparentalcontrol.js deleted file mode 100644 index 0b527e09ef..0000000000 --- a/src/controllers/dashboard/users/userparentalcontrol.js +++ /dev/null @@ -1,278 +0,0 @@ -import 'jquery'; -import datetime from '../../../scripts/datetime'; -import loading from '../../../components/loading/loading'; -import libraryMenu from '../../../scripts/libraryMenu'; -import globalize from '../../../scripts/globalize'; -import '../../../components/listview/listview.scss'; -import '../../../elements/emby-button/paper-icon-button-light'; -import toast from '../../../components/toast/toast'; -import { getParameterByName } from '../../../utils/url.ts'; - -function populateRatings(allParentalRatings, page) { - let html = ''; - html += ""; - let rating; - const ratings = []; - - for (let i = 0, length = allParentalRatings.length; i < length; i++) { - rating = allParentalRatings[i]; - if (ratings.length) { - const lastRating = ratings[ratings.length - 1]; - - if (lastRating.Value === rating.Value) { - lastRating.Name += '/' + rating.Name; - continue; - } - } - - ratings.push({ - Name: rating.Name, - Value: rating.Value - }); - } - - for (let i = 0, length = ratings.length; i < length; i++) { - rating = ratings[i]; - html += "'; - } - - $('#selectMaxParentalRating', page).html(html); -} - -function loadUnratedItems(page, user) { - const items = [{ - name: globalize.translate('Books'), - value: 'Book' - }, { - name: globalize.translate('Channels'), - value: 'ChannelContent' - }, { - name: globalize.translate('LiveTV'), - value: 'LiveTvChannel' - }, { - name: globalize.translate('Movies'), - value: 'Movie' - }, { - name: globalize.translate('Music'), - value: 'Music' - }, { - name: globalize.translate('Trailers'), - value: 'Trailer' - }, { - name: globalize.translate('Shows'), - value: 'Series' - }]; - let html = ''; - html += '

' + globalize.translate('HeaderBlockItemsWithNoRating') + '

'; - html += '
'; - - for (let i = 0, length = items.length; i < length; i++) { - const item = items[i]; - const checkedAttribute = user.Policy.BlockUnratedItems.indexOf(item.value) != -1 ? ' checked="checked"' : ''; - html += ''; - } - - html += '
'; - $('.blockUnratedItems', page).html(html).trigger('create'); -} - -function loadUser(page, user, allParentalRatings) { - page.querySelector('.username').innerHTML = user.Name; - libraryMenu.setTitle(user.Name); - loadUnratedItems(page, user); - loadBlockedTags(page, user.Policy.BlockedTags); - populateRatings(allParentalRatings, page); - let ratingValue = ''; - - if (user.Policy.MaxParentalRating) { - for (let i = 0, length = allParentalRatings.length; i < length; i++) { - const rating = allParentalRatings[i]; - - if (user.Policy.MaxParentalRating >= rating.Value) { - ratingValue = rating.Value; - } - } - } - - $('#selectMaxParentalRating', page).val(ratingValue); - - if (user.Policy.IsAdministrator) { - $('.accessScheduleSection', page).hide(); - } else { - $('.accessScheduleSection', page).show(); - } - - renderAccessSchedule(page, user.Policy.AccessSchedules || []); - loading.hide(); -} - -function loadBlockedTags(page, tags) { - let html = tags.map(function (h) { - let li = '
'; - li += '
'; - li += '

'; - li += h; - li += '

'; - li += '
'; - li += ''; - li += '
'; - return li; - }).join(''); - - if (html) { - html = '
' + html + '
'; - } - - const blockedTags = page.querySelector('.blockedTags'); - blockedTags.innerHTML = html; - - for (const btnDeleteTag of blockedTags.querySelectorAll('.btnDeleteTag')) { - btnDeleteTag.addEventListener('click', function () { - const tag = this.getAttribute('data-tag'); - const newTags = tags.filter(function (t) { - return t != tag; - }); - loadBlockedTags(page, newTags); - }); - } -} - -function deleteAccessSchedule(page, schedules, index) { - schedules.splice(index, 1); - renderAccessSchedule(page, schedules); -} - -function renderAccessSchedule(page, schedules) { - let html = ''; - let index = 0; - html += schedules.map(function (a) { - let itemHtml = ''; - itemHtml += '
'; - itemHtml += '
'; - itemHtml += '

'; - itemHtml += globalize.translate('Option' + a.DayOfWeek); - itemHtml += '

'; - itemHtml += '
' + getDisplayTime(a.StartHour) + ' - ' + getDisplayTime(a.EndHour) + '
'; - itemHtml += '
'; - itemHtml += ''; - itemHtml += '
'; - index++; - return itemHtml; - }).join(''); - const accessScheduleList = page.querySelector('.accessScheduleList'); - accessScheduleList.innerHTML = html; - $('.btnDelete', accessScheduleList).on('click', function () { - deleteAccessSchedule(page, schedules, parseInt(this.getAttribute('data-index'), 10)); - }); -} - -function onSaveComplete() { - loading.hide(); - toast(globalize.translate('SettingsSaved')); -} - -function saveUser(user, page) { - user.Policy.MaxParentalRating = $('#selectMaxParentalRating', page).val() || null; - user.Policy.BlockUnratedItems = $('.chkUnratedItem', page).get().filter(function (i) { - return i.checked; - }).map(function (i) { - return i.getAttribute('data-itemtype'); - }); - user.Policy.AccessSchedules = getSchedulesFromPage(page); - user.Policy.BlockedTags = getBlockedTagsFromPage(page); - ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { - onSaveComplete(); - }); -} - -function getDisplayTime(hours) { - let minutes = 0; - const pct = hours % 1; - - if (pct) { - minutes = parseInt(60 * pct, 10); - } - - return datetime.getDisplayTime(new Date(2000, 1, 1, hours, minutes, 0, 0)); -} - -function showSchedulePopup(page, schedule, index) { - schedule = schedule || {}; - import('../../../components/accessSchedule/accessSchedule').then(({ default: accessschedule }) => { - accessschedule.show({ - schedule: schedule - }).then(function (updatedSchedule) { - const schedules = getSchedulesFromPage(page); - - if (index == -1) { - index = schedules.length; - } - - schedules[index] = updatedSchedule; - renderAccessSchedule(page, schedules); - }); - }); -} - -function getSchedulesFromPage(page) { - return $('.liSchedule', page).map(function () { - return { - DayOfWeek: this.getAttribute('data-day'), - StartHour: this.getAttribute('data-start'), - EndHour: this.getAttribute('data-end') - }; - }).get(); -} - -function getBlockedTagsFromPage(page) { - return $('.blockedTag', page).map(function () { - return this.getAttribute('data-tag'); - }).get(); -} - -function showBlockedTagPopup(page) { - import('../../../components/prompt/prompt').then(({ default: prompt }) => { - prompt({ - label: globalize.translate('LabelTag') - }).then(function (value) { - const tags = getBlockedTagsFromPage(page); - - if (tags.indexOf(value) == -1) { - tags.push(value); - loadBlockedTags(page, tags); - } - }); - }); -} - -window.UserParentalControlPage = { - onSubmit: function () { - const page = $(this).parents('.page'); - loading.show(); - const userId = getParameterByName('userId'); - ApiClient.getUser(userId).then(function (result) { - saveUser(result, page); - }); - return false; - } -}; -$(document).on('pageinit', '#userParentalControlPage', function () { - const page = this; - $('.btnAddSchedule', page).on('click', function () { - showSchedulePopup(page, {}, -1); - }); - $('.btnAddBlockedTag', page).on('click', function () { - showBlockedTagPopup(page); - }); - $('.userParentalControlForm').off('submit', UserParentalControlPage.onSubmit).on('submit', UserParentalControlPage.onSubmit); -}).on('pageshow', '#userParentalControlPage', function () { - const page = this; - loading.show(); - const userId = getParameterByName('userId'); - const promise1 = ApiClient.getUser(userId); - const promise2 = ApiClient.getParentalRatings(); - Promise.all([promise1, promise2]).then(function (responses) { - loadUser(page, responses[0], responses[1]); - }); -}); - diff --git a/src/controllers/dashboard/users/userpassword.html b/src/controllers/dashboard/users/userpassword.html deleted file mode 100644 index 897f0e7bd5..0000000000 --- a/src/controllers/dashboard/users/userpassword.html +++ /dev/null @@ -1,72 +0,0 @@ -
-
-
-
-
-

- ${Help} -
-
- - - -
-
-
-
- -
-
- -
-
- -
-
-
- - -
-
-
-
-
-
-
- ${HeaderEasyPinCode} -
-
-
${EasyPasswordHelp}
-
-
- -
-
-
- -
${LabelInNetworkSignInWithEasyPasswordHelp}
-
-
- - -
-
-
-
-
-
-
diff --git a/src/controllers/dashboard/users/userpasswordpage.js b/src/controllers/dashboard/users/userpasswordpage.js deleted file mode 100644 index 4171c55d6e..0000000000 --- a/src/controllers/dashboard/users/userpasswordpage.js +++ /dev/null @@ -1,179 +0,0 @@ -import loading from '../../../components/loading/loading'; -import libraryMenu from '../../../scripts/libraryMenu'; -import globalize from '../../../scripts/globalize'; -import '../../../elements/emby-button/emby-button'; -import Dashboard from '../../../utils/dashboard'; -import toast from '../../../components/toast/toast'; -import confirm from '../../../components/confirm/confirm'; - -function loadUser(page, params) { - const userid = params.userId; - ApiClient.getUser(userid).then(function (user) { - Dashboard.getCurrentUser().then(function (loggedInUser) { - libraryMenu.setTitle(user.Name); - page.querySelector('.username').innerText = user.Name; - let showPasswordSection = true; - let showLocalAccessSection = false; - - if (user.ConnectLinkType == 'Guest') { - page.querySelector('.localAccessSection').classList.add('hide'); - showPasswordSection = false; - } else if (user.HasConfiguredPassword) { - page.querySelector('#btnResetPassword').classList.remove('hide'); - page.querySelector('#fldCurrentPassword').classList.remove('hide'); - showLocalAccessSection = true; - } else { - page.querySelector('#btnResetPassword').classList.add('hide'); - page.querySelector('#fldCurrentPassword').classList.add('hide'); - } - - if (showPasswordSection && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess)) { - page.querySelector('.passwordSection').classList.remove('hide'); - } else { - page.querySelector('.passwordSection').classList.add('hide'); - } - - if (showLocalAccessSection && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess)) { - page.querySelector('.localAccessSection').classList.remove('hide'); - } else { - page.querySelector('.localAccessSection').classList.add('hide'); - } - - const txtEasyPassword = page.querySelector('#txtEasyPassword'); - txtEasyPassword.value = ''; - - if (user.HasConfiguredEasyPassword) { - txtEasyPassword.placeholder = '******'; - page.querySelector('#btnResetEasyPassword').classList.remove('hide'); - } else { - txtEasyPassword.removeAttribute('placeholder'); - txtEasyPassword.placeholder = ''; - page.querySelector('#btnResetEasyPassword').classList.add('hide'); - } - - page.querySelector('.chkEnableLocalEasyPassword').checked = user.Configuration.EnableLocalPassword; - - import('../../../components/autoFocuser').then(({ default: autoFocuser }) => { - autoFocuser.autoFocus(page); - }); - }); - }); - page.querySelector('#txtCurrentPassword').value = ''; - page.querySelector('#txtNewPassword').value = ''; - page.querySelector('#txtNewPasswordConfirm').value = ''; -} - -export default function (view, params) { - function saveEasyPassword() { - const userId = params.userId; - const easyPassword = view.querySelector('#txtEasyPassword').value; - - if (easyPassword) { - ApiClient.updateEasyPassword(userId, easyPassword).then(function () { - onEasyPasswordSaved(userId); - }); - } else { - onEasyPasswordSaved(userId); - } - } - - function onEasyPasswordSaved(userId) { - ApiClient.getUser(userId).then(function (user) { - user.Configuration.EnableLocalPassword = view.querySelector('.chkEnableLocalEasyPassword').checked; - ApiClient.updateUserConfiguration(user.Id, user.Configuration).then(function () { - loading.hide(); - toast(globalize.translate('SettingsSaved')); - - loadUser(view, params); - }); - }); - } - - function savePassword() { - const userId = params.userId; - let currentPassword = view.querySelector('#txtCurrentPassword').value; - const newPassword = view.querySelector('#txtNewPassword').value; - - if (view.querySelector('#fldCurrentPassword').classList.contains('hide')) { - // Firefox does not respect autocomplete=off, so clear it if the field is supposed to be hidden (and blank) - // This should only happen when user.HasConfiguredPassword is false, but this information is not passed on - currentPassword = ''; - } - - ApiClient.updateUserPassword(userId, currentPassword, newPassword).then(function () { - loading.hide(); - toast(globalize.translate('PasswordSaved')); - - loadUser(view, params); - }, function () { - loading.hide(); - Dashboard.alert({ - title: globalize.translate('HeaderLoginFailure'), - message: globalize.translate('MessageInvalidUser') - }); - }); - } - - function onSubmit(e) { - const form = this; - - if (form.querySelector('#txtNewPassword').value != form.querySelector('#txtNewPasswordConfirm').value) { - toast(globalize.translate('PasswordMatchError')); - } else { - loading.show(); - savePassword(); - } - - e.preventDefault(); - return false; - } - - function onLocalAccessSubmit(e) { - loading.show(); - saveEasyPassword(); - e.preventDefault(); - return false; - } - - function resetPassword() { - const msg = globalize.translate('PasswordResetConfirmation'); - confirm(msg, globalize.translate('ResetPassword')).then(function () { - const userId = params.userId; - loading.show(); - ApiClient.resetUserPassword(userId).then(function () { - loading.hide(); - Dashboard.alert({ - message: globalize.translate('PasswordResetComplete'), - title: globalize.translate('ResetPassword') - }); - loadUser(view, params); - }); - }); - } - - function resetEasyPassword() { - const msg = globalize.translate('PinCodeResetConfirmation'); - - confirm(msg, globalize.translate('HeaderPinCodeReset')).then(function () { - const userId = params.userId; - loading.show(); - ApiClient.resetEasyPassword(userId).then(function () { - loading.hide(); - Dashboard.alert({ - message: globalize.translate('PinCodeResetComplete'), - title: globalize.translate('HeaderPinCodeReset') - }); - loadUser(view, params); - }); - }); - } - - view.querySelector('.updatePasswordForm').addEventListener('submit', onSubmit); - view.querySelector('.localAccessForm').addEventListener('submit', onLocalAccessSubmit); - view.querySelector('#btnResetEasyPassword').addEventListener('click', resetEasyPassword); - view.querySelector('#btnResetPassword').addEventListener('click', resetPassword); - view.addEventListener('viewshow', function () { - loadUser(view, params); - }); -} - diff --git a/src/controllers/dashboard/users/userprofiles.html b/src/controllers/dashboard/users/userprofiles.html deleted file mode 100644 index 9e2908266b..0000000000 --- a/src/controllers/dashboard/users/userprofiles.html +++ /dev/null @@ -1,16 +0,0 @@ -
-
-
-
-
-

${HeaderUsers}

- - ${Help} -
-
-
-
-
-
diff --git a/src/controllers/dashboard/users/userprofilespage.js b/src/controllers/dashboard/users/userprofilespage.js deleted file mode 100644 index 59d61a443f..0000000000 --- a/src/controllers/dashboard/users/userprofilespage.js +++ /dev/null @@ -1,184 +0,0 @@ -import loading from '../../../components/loading/loading'; -import dom from '../../../scripts/dom'; -import globalize from '../../../scripts/globalize'; -import { formatDistanceToNow } from 'date-fns'; -import { getLocaleWithSuffix } from '../../../utils/dateFnsLocale.ts'; -import '../../../elements/emby-button/paper-icon-button-light'; -import '../../../components/cardbuilder/card.scss'; -import '../../../elements/emby-button/emby-button'; -import '../../../components/indicators/indicators.scss'; -import '../../../styles/flexstyles.scss'; -import Dashboard, { pageIdOn } from '../../../utils/dashboard'; -import confirm from '../../../components/confirm/confirm'; -import cardBuilder from '../../../components/cardbuilder/cardBuilder'; - -function deleteUser(page, id) { - const msg = globalize.translate('DeleteUserConfirmation'); - - confirm({ - title: globalize.translate('DeleteUser'), - text: msg, - confirmText: globalize.translate('Delete'), - primary: 'delete' - }).then(function () { - loading.show(); - ApiClient.deleteUser(id).then(function () { - loadData(page); - }); - }); -} - -function showUserMenu(elem) { - const card = dom.parentWithClass(elem, 'card'); - const page = dom.parentWithClass(card, 'page'); - const userId = card.getAttribute('data-userid'); - const menuItems = []; - menuItems.push({ - name: globalize.translate('ButtonOpen'), - id: 'open', - icon: 'mode_edit' - }); - menuItems.push({ - name: globalize.translate('ButtonLibraryAccess'), - id: 'access', - icon: 'lock' - }); - menuItems.push({ - name: globalize.translate('ButtonParentalControl'), - id: 'parentalcontrol', - icon: 'person' - }); - menuItems.push({ - name: globalize.translate('Delete'), - id: 'delete', - icon: 'delete' - }); - - import('../../../components/actionSheet/actionSheet').then(({ default: actionsheet }) => { - actionsheet.show({ - items: menuItems, - positionTo: card, - callback: function (id) { - switch (id) { - case 'open': - Dashboard.navigate('useredit.html?userId=' + userId); - break; - - case 'access': - Dashboard.navigate('userlibraryaccess.html?userId=' + userId); - break; - - case 'parentalcontrol': - Dashboard.navigate('userparentalcontrol.html?userId=' + userId); - break; - - case 'delete': - deleteUser(page, userId); - } - } - }); - }); -} - -function getUserHtml(user) { - let html = ''; - let cssClass = 'card squareCard scalableCard squareCard-scalable'; - - if (user.Policy.IsDisabled) { - cssClass += ' grayscale'; - } - - html += "
"; - html += '
'; - html += '
'; - html += '
'; - html += ``; - let imgUrl; - - if (user.PrimaryImageTag) { - imgUrl = ApiClient.getUserImageUrl(user.Id, { - width: 300, - tag: user.PrimaryImageTag, - type: 'Primary' - }); - } - - let imageClass = 'cardImage'; - - if (user.Policy.IsDisabled) { - imageClass += ' disabledUser'; - } - - if (imgUrl) { - html += ''; - html += '
'; - html += '
'; - html += '
'; - html += user.Name; - html += '
'; - html += ''; - html += '
'; - html += '
'; - const lastSeen = getLastSeenText(user.LastActivityDate); - html += lastSeen != '' ? lastSeen : ' '; - html += '
'; - html += '
'; - html += '
'; - return html + '
'; -} -// FIXME: It seems that, sometimes, server sends date in the future, so date-fns displays messages like 'in less than a minute'. We should fix -// how dates are returned by the server when the session is active and show something like 'Active now', instead of past/future sentences -function getLastSeenText(lastActivityDate) { - const localeWithSuffix = getLocaleWithSuffix(); - - if (lastActivityDate) { - return globalize.translate('LastSeen', formatDistanceToNow(Date.parse(lastActivityDate), localeWithSuffix)); - } - - return ''; -} - -function getUserSectionHtml(users) { - return users.map(function (u__q) { - return getUserHtml(u__q); - }).join(''); -} - -function renderUsers(page, users) { - page.querySelector('.localUsers').innerHTML = getUserSectionHtml(users); -} - -function loadData(page) { - loading.show(); - ApiClient.getUsers().then(function (users) { - renderUsers(page, users); - loading.hide(); - }); -} - -pageIdOn('pageinit', 'userProfilesPage', function () { - const page = this; - page.querySelector('.btnAddUser').addEventListener('click', function() { - Dashboard.navigate('usernew.html'); - }); - page.querySelector('.localUsers').addEventListener('click', function (e__e) { - const btnUserMenu = dom.parentWithClass(e__e.target, 'btnUserMenu'); - - if (btnUserMenu) { - showUserMenu(btnUserMenu); - } - }); -}); - -pageIdOn('pagebeforeshow', 'userProfilesPage', function () { - loadData(this); -}); - diff --git a/src/controllers/user/profile/index.html b/src/controllers/user/profile/index.html deleted file mode 100644 index 3eaa2f7299..0000000000 --- a/src/controllers/user/profile/index.html +++ /dev/null @@ -1,69 +0,0 @@ -
-
-
-
- -
-
-
-

-
- - -
-
-
-
-

- ${HeaderPassword} -

-
- -
-
- -
-
- -
-
- - -
-
-
-
-
-

${HeaderEasyPinCode}

-
${EasyPasswordHelp}
-
-
- -
-
- -
${LabelInNetworkSignInWithEasyPasswordHelp}
-
-
- - -
-
-
-
-
diff --git a/src/controllers/user/profile/index.js b/src/controllers/user/profile/index.js deleted file mode 100644 index 07bab611c3..0000000000 --- a/src/controllers/user/profile/index.js +++ /dev/null @@ -1,105 +0,0 @@ -import UserPasswordPage from '../../dashboard/users/userpasswordpage'; -import loading from '../../../components/loading/loading'; -import libraryMenu from '../../../scripts/libraryMenu'; -import { appHost } from '../../../components/apphost'; -import globalize from '../../../scripts/globalize'; -import '../../../elements/emby-button/emby-button'; -import Dashboard from '../../../utils/dashboard'; -import toast from '../../../components/toast/toast'; -import confirm from '../../../components/confirm/confirm'; -import { getParameterByName } from '../../../utils/url.ts'; - -function reloadUser(page) { - const userId = getParameterByName('userId'); - loading.show(); - ApiClient.getUser(userId).then(function (user) { - page.querySelector('.username').innerText = user.Name; - libraryMenu.setTitle(user.Name); - - let imageUrl = 'assets/img/avatar.png'; - if (user.PrimaryImageTag) { - imageUrl = ApiClient.getUserImageUrl(user.Id, { - tag: user.PrimaryImageTag, - type: 'Primary' - }); - } - - const userImage = page.querySelector('#image'); - userImage.style.backgroundImage = 'url(' + imageUrl + ')'; - - Dashboard.getCurrentUser().then(function (loggedInUser) { - if (user.PrimaryImageTag) { - page.querySelector('#btnAddImage').classList.add('hide'); - page.querySelector('#btnDeleteImage').classList.remove('hide'); - } else if (appHost.supports('fileinput') && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess)) { - page.querySelector('#btnDeleteImage').classList.add('hide'); - page.querySelector('#btnAddImage').classList.remove('hide'); - } - }); - loading.hide(); - }); -} - -function onFileReaderError(evt) { - loading.hide(); - switch (evt.target.error.code) { - case evt.target.error.NOT_FOUND_ERR: - toast(globalize.translate('FileNotFound')); - break; - case evt.target.error.ABORT_ERR: - onFileReaderAbort(); - break; - case evt.target.error.NOT_READABLE_ERR: - default: - toast(globalize.translate('FileReadError')); - } -} - -function onFileReaderAbort() { - loading.hide(); - toast(globalize.translate('FileReadCancelled')); -} - -function setFiles(page, files) { - const userImage = page.querySelector('#image'); - const file = files[0]; - - if (!file || !file.type.match('image.*')) { - return false; - } - - const reader = new FileReader(); - reader.onerror = onFileReaderError; - reader.onabort = onFileReaderAbort; - reader.onload = function (evt) { - userImage.style.backgroundImage = 'url(' + evt.target.result + ')'; - const userId = getParameterByName('userId'); - ApiClient.uploadUserImage(userId, 'Primary', file).then(function () { - loading.hide(); - reloadUser(page); - }); - }; - - reader.readAsDataURL(file); -} - -export default function (view, params) { - reloadUser(view); - new UserPasswordPage(view, params); - view.querySelector('#btnDeleteImage').addEventListener('click', function () { - confirm(globalize.translate('DeleteImageConfirmation'), globalize.translate('DeleteImage')).then(function () { - loading.show(); - const userId = getParameterByName('userId'); - ApiClient.deleteUserImage(userId, 'primary').then(function () { - loading.hide(); - reloadUser(view); - }); - }); - }); - view.querySelector('#btnAddImage').addEventListener('click', function () { - view.querySelector('#uploadImage').click(); - }); - view.querySelector('#uploadImage').addEventListener('change', function (evt) { - setFiles(view, evt.target.files); - }); -} From 81a2d878ca9f156f221747b1ad1904c628e6fbc4 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Tue, 2 May 2023 18:43:53 +0300 Subject: [PATCH 071/112] Fix query selector target Cherry-picked from: https://github.com/jellyfin/jellyfin-web/commit/1fb5c4d95d4607ed33b00be2d8cee1ae35d5631b --- src/controllers/playback/video/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controllers/playback/video/index.js b/src/controllers/playback/video/index.js index 745170f5fc..93da237ec0 100644 --- a/src/controllers/playback/video/index.js +++ b/src/controllers/playback/video/index.js @@ -539,11 +539,11 @@ export default function (view) { } function onBeginFetch() { - document.querySelector('.osdMediaStatus').classList.remove('hide'); + view.querySelector('.osdMediaStatus').classList.remove('hide'); } function onEndFetch() { - document.querySelector('.osdMediaStatus').classList.add('hide'); + view.querySelector('.osdMediaStatus').classList.add('hide'); } function bindToPlayer(player) { @@ -1437,7 +1437,7 @@ export default function (view) { const btnFastForward = view.querySelector('.btnFastForward'); const transitionEndEventName = dom.whichTransitionEvent(); const headerElement = document.querySelector('.skinHeader'); - const osdBottomElement = document.querySelector('.videoOsdBottom-maincontrols'); + const osdBottomElement = view.querySelector('.videoOsdBottom-maincontrols'); nowPlayingPositionSlider.enableKeyboardDragging(); nowPlayingVolumeSlider.enableKeyboardDragging(); From df5798700231e9c13047f94ad2e4014ece411649 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 May 2023 22:33:34 +0000 Subject: [PATCH 072/112] Update dependency @types/react-dom to v17.0.20 --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 20807c8044..c17e7bdba8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,7 +65,7 @@ "@types/loadable__component": "5.13.4", "@types/lodash-es": "4.17.7", "@types/react": "17.0.58", - "@types/react-dom": "17.0.19", + "@types/react-dom": "17.0.20", "@typescript-eslint/eslint-plugin": "5.59.1", "@typescript-eslint/parser": "5.59.1", "@uupaa/dynamic-import-polyfill": "1.0.2", @@ -3259,9 +3259,9 @@ } }, "node_modules/@types/react-dom": { - "version": "17.0.19", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.19.tgz", - "integrity": "sha512-PiYG40pnQRdPHnlf7tZnp0aQ6q9tspYr72vD61saO6zFCybLfMqwUCN0va1/P+86DXn18ZWeW30Bk7xlC5eEAQ==", + "version": "17.0.20", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.20.tgz", + "integrity": "sha512-4pzIjSxDueZZ90F52mU3aPoogkHIoSIDG+oQ+wQK7Cy2B9S+MvOqY0uEA/qawKz381qrEDkvpwyt8Bm31I8sbA==", "dev": true, "dependencies": { "@types/react": "^17" @@ -22206,9 +22206,9 @@ } }, "@types/react-dom": { - "version": "17.0.19", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.19.tgz", - "integrity": "sha512-PiYG40pnQRdPHnlf7tZnp0aQ6q9tspYr72vD61saO6zFCybLfMqwUCN0va1/P+86DXn18ZWeW30Bk7xlC5eEAQ==", + "version": "17.0.20", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.20.tgz", + "integrity": "sha512-4pzIjSxDueZZ90F52mU3aPoogkHIoSIDG+oQ+wQK7Cy2B9S+MvOqY0uEA/qawKz381qrEDkvpwyt8Bm31I8sbA==", "dev": true, "requires": { "@types/react": "^17" diff --git a/package.json b/package.json index 5aca9baac6..8ed1ac292b 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "@types/loadable__component": "5.13.4", "@types/lodash-es": "4.17.7", "@types/react": "17.0.58", - "@types/react-dom": "17.0.19", + "@types/react-dom": "17.0.20", "@typescript-eslint/eslint-plugin": "5.59.1", "@typescript-eslint/parser": "5.59.1", "@uupaa/dynamic-import-polyfill": "1.0.2", From f6f6c3fb9604be36b549322467a56e649bc6cea6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 May 2023 01:56:57 +0000 Subject: [PATCH 073/112] Update dependency sass to v1.62.1 --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 20807c8044..ab04200018 100644 --- a/package-lock.json +++ b/package-lock.json @@ -96,7 +96,7 @@ "postcss-loader": "7.2.4", "postcss-preset-env": "8.3.2", "postcss-scss": "4.0.6", - "sass": "1.62.0", + "sass": "1.62.1", "sass-loader": "13.2.2", "source-map-loader": "4.0.1", "style-loader": "3.3.2", @@ -14270,9 +14270,9 @@ "dev": true }, "node_modules/sass": { - "version": "1.62.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.0.tgz", - "integrity": "sha512-Q4USplo4pLYgCi+XlipZCWUQz5pkg/ruSSgJ0WRDSb/+3z9tXUOkQ7QPYn4XrhZKYAK4HlpaQecRwKLJX6+DBg==", + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz", + "integrity": "sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -30331,9 +30331,9 @@ "dev": true }, "sass": { - "version": "1.62.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.0.tgz", - "integrity": "sha512-Q4USplo4pLYgCi+XlipZCWUQz5pkg/ruSSgJ0WRDSb/+3z9tXUOkQ7QPYn4XrhZKYAK4HlpaQecRwKLJX6+DBg==", + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz", + "integrity": "sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==", "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", diff --git a/package.json b/package.json index 5aca9baac6..6c3e6e18ad 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "postcss-loader": "7.2.4", "postcss-preset-env": "8.3.2", "postcss-scss": "4.0.6", - "sass": "1.62.0", + "sass": "1.62.1", "sass-loader": "13.2.2", "source-map-loader": "4.0.1", "style-loader": "3.3.2", From daddde7acd08860692871d0f46127d2adc77a8f1 Mon Sep 17 00:00:00 2001 From: shape93 Date: Wed, 3 May 2023 08:14:04 +0000 Subject: [PATCH 074/112] Translated using Weblate (Italian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/it/ --- src/strings/it.json | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/strings/it.json b/src/strings/it.json index 6ee3510585..d3aec5a30d 100644 --- a/src/strings/it.json +++ b/src/strings/it.json @@ -1407,7 +1407,7 @@ "TonemappingRangeHelp": "Seleziona l'intervallo di colore in uscita. Auto imposta lo stesso del valore di entrata.", "LabelTonemappingRange": "Intervallo mappatura dei toni", "TonemappingAlgorithmHelp": "La mappatura dei toni può essere messa a punto. Se non sei abbastanza familiare con queste opzioni, lascia quelle predefinite. Il valore raccomandato è 'BT.2390'.", - "AllowTonemappingHelp": "La mappatura dei toni può trasformare l'intervallo dinamico di un video da HDR a SDR mantenendo il dettaglio e i colori dell'immagine, che sono informazioni molto importanti per rappresentare la scena originale. Attualmente funziona solo con video HDR10 o HLG. Richiede le corrispondenti librerie OpenCL o CUDA.", + "AllowTonemappingHelp": "La mappatura dei toni può trasformare l'intervallo dinamico di un video da HDR a SDR mantenendo il dettaglio e i colori dell'immagine, che sono informazioni molto importanti per rappresentare la scena originale. Attualmente funziona solo con video HDR10, HLG e DoVi. Richiede le corrispondenti librerie OpenCL o CUDA.", "LabelOpenclDeviceHelp": "Questo è il dispositivo OpenCL utilizzato per la mappatura dei toni. Il lato sinistro del punto è il numero di piattaforma, mentre la parte destra è il numero del dispositivo sulla piattaforma. Il valore base è 0.0. Il file di applicazione FFmpeg contenente il metodo di accelerazione hardware OpenCL è richiesto.", "LabelColorPrimaries": "Primari colore", "LabelColorTransfer": "Trasferimento colore", @@ -1666,8 +1666,8 @@ "MediaInfoVideoRangeType": "Tipo range del video", "LabelVideoRangeType": "Tipo range del video", "VideoRangeTypeNotSupported": "Tipo range del video non supportato", - "LabelVppTonemappingBrightnessHelp": "Applica un guadagno luminosità nella mappatura toni VPP. Il valore consigliato e predefinito è 0.", - "LabelVppTonemappingContrastHelp": "Applica un guadagno al contrasto nella mappatura toni VPP. Il valore consigliato è 1.2 e quello predefinito è 1.", + "LabelVppTonemappingBrightnessHelp": "Applica un guadagno luminosità nella mappatura toni VPP. I valori consigliati e predefiniti sono 16 e 0.", + "LabelVppTonemappingContrastHelp": "Applica un guadagno al contrasto nella mappatura toni VPP. Il valore consigliato e predefinito è 1.", "LabelVppTonemappingContrast": "Guadagno contrasto della mappatura toni VPP", "LabelVppTonemappingBrightness": "Guadagno luminosità della mappatura toni VPP", "ScreenResolution": "Risoluzione schermo", @@ -1706,5 +1706,23 @@ "LabelDummyChapterDurationHelp": "Intervallo in secondi tra le estrazioni delle immagini in capitoli.", "LabelDummyChapterCountHelp": "Numero massimo di capitoli da estrarre per ciascun file.", "LabelChapterImageResolutionHelp": "Risoluzione delle immagini per l'estrazione", - "HeaderDummyChapter": "Immagini Capitolo" + "HeaderDummyChapter": "Immagini Capitolo", + "SaveRecordingNFO": "Salva i metadati EPG in NFO", + "HeaderRecordingMetadataSaving": "Registrazione Metadati", + "SaveRecordingNFOHelp": "Salva i metadati dal fornitore di elenchi EPG insieme ai media.", + "SaveRecordingImages": "Salva le immagini EPG delle registrazioni", + "SecondarySubtitles": "Sottotitoli Secondari", + "Featurette": "Featurette", + "Select": "Seleziona", + "Short": "Corto", + "TonemappingModeHelp": "Seleziona la modalità di mappatura dei toni. Se riscontri colori poco fedeli, prova a passare alla modalità RGB.", + "LabelTonemappingMode": "Modalità di mappatura dei toni", + "ResolutionMatchSource": "Abbina alla sorgente", + "LabelEnableAudioVbr": "Abilita codifica audio VBR", + "LabelEnableAudioVbrHelp": "Il bitrate variabile offre una migliore qualità rispetto al rapporto bitrate medio, ma in alcuni rari casi può causare problemi di buffering e compatibilità.", + "LabelParallelImageEncodingLimit": "Limite codifica parallela delle immagini", + "LabelParallelImageEncodingLimitHelp": "Numero massimo di codifiche di immagini che possono essere eseguite in parallelo. Impostandolo su 0 sceglierai un limite basato sulle specifiche del tuo sistema.", + "PreferEmbeddedExtrasTitlesOverFileNames": "Preferisci i titoli incorporati ai nomi dei file per gli extra", + "PreferEmbeddedExtrasTitlesOverFileNamesHelp": "Gli extra hanno spesso lo stesso nome incorporato del parent, controlla questo per usare comunque titoli incorporati per loro.", + "SaveRecordingImagesHelp": "Salva le immagini dal fornitore di elenchi EPG insieme ai media." } From 7dff81ef68e7153d518f290b4d8d04d00ad1ac3f Mon Sep 17 00:00:00 2001 From: Marcinbar Date: Thu, 4 May 2023 08:11:15 +0000 Subject: [PATCH 075/112] Translated using Weblate (Polish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pl/ --- src/strings/pl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/pl.json b/src/strings/pl.json index 83f2375699..f02ab5eefd 100644 --- a/src/strings/pl.json +++ b/src/strings/pl.json @@ -1396,7 +1396,7 @@ "HeaderAddUser": "Dodaj użytkownika", "HeaderAddUpdateSubtitle": "Dodaj/Zaktualizuj napisy", "EnableTonemapping": "Włącz Tone mapping", - "AllowTonemappingHelp": "Mapowanie tonalne może przekształcić zakres dynamiczny wideo z HDR na SDR, zachowując jednocześnie szczegóły obrazu i kolory, które są bardzo ważnymi informacjami dla odwzorowania oryginalnej sceny. Obecnie działa tylko z filmami HDR10 lub HLG. Wymaga to odpowiedniego środowiska uruchomieniowego OpenCL lub CUDA.", + "AllowTonemappingHelp": "Mapowanie tonalne może przekształcić zakres dynamiczny wideo z HDR na SDR, zachowując jednocześnie szczegóły obrazu i kolory, które są bardzo ważnymi informacjami dla odwzorowania oryginalnej sceny. Obecnie działa tylko z filmami 10bit HDR10, HLG i DoVi. Wymaga to odpowiedniego środowiska uruchomieniowego OpenCL lub CUDA.", "TonemappingAlgorithmHelp": "Mapowanie tonów może zostać dostrojone. Jeśli nie znasz tych opcji, pozostaw domyślne wartości. Domyślna wartość to 'BT.2390'.", "PreferFmp4HlsContainerHelp": "Preferuj fMP4 jako domyślny format dla HLS, pozwalając na bezpośrednie odtwarzanie zawartości HEVC na wspieranych urządzeniach.", "PreferFmp4HlsContainer": "Preferuj format fMP4-HLS", From 2584de5efae6e6db28182293ef02b91978d7efbe Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 4 May 2023 10:58:11 -0400 Subject: [PATCH 076/112] Make cognitive complexity an error for ts files --- .eslintrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index 03e06eb499..6ccaca73f0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -257,7 +257,7 @@ module.exports = { 'plugin:jsx-a11y/recommended' ], rules: { - 'sonarjs/cognitive-complexity': ['warn'] + 'sonarjs/cognitive-complexity': ['error'] } } ] From ef719c45f44220b42031b6f5f2606dbc3ce0e0af Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 4 May 2023 11:00:48 -0400 Subject: [PATCH 077/112] Add prefer for-of eslint rule --- .eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc.js b/.eslintrc.js index 6ccaca73f0..36e895e510 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -67,6 +67,7 @@ module.exports = { 'operator-linebreak': ['error', 'before', { overrides: { '?': 'after', ':': 'after', '=': 'after' } }], 'padded-blocks': ['error', 'never'], 'prefer-const': ['error', { 'destructuring': 'all' }], + '@typescript-eslint/prefer-for-of': ['error'], 'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }], 'radix': ['error'], '@typescript-eslint/semi': ['error'], From 1b03cd79eb78507f790646028601255af619bbdc Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 4 May 2023 11:27:15 -0400 Subject: [PATCH 078/112] Fix prefer for-of errors --- .../libraryoptionseditor.js | 30 +++++++------------ .../metadataEditor/metadataEditor.js | 3 +- src/components/playback/playbackmanager.js | 8 ++--- .../dashboard/plugins/add/index.js | 3 +- .../dashboard/plugins/available/index.js | 3 +- .../scheduledtasks/scheduledtasks.js | 3 +- src/controllers/session/login/index.js | 4 +-- src/elements/emby-textarea/emby-textarea.js | 4 +-- src/scripts/autocast.js | 6 ++-- src/scripts/browser.js | 4 +-- src/scripts/libraryMenu.js | 5 +--- 11 files changed, 26 insertions(+), 47 deletions(-) diff --git a/src/components/libraryoptionseditor/libraryoptionseditor.js b/src/components/libraryoptionseditor/libraryoptionseditor.js index 0b0f66b61e..6785dafe1f 100644 --- a/src/components/libraryoptionseditor/libraryoptionseditor.js +++ b/src/components/libraryoptionseditor/libraryoptionseditor.js @@ -23,8 +23,7 @@ function populateLanguages(parent) { function populateLanguagesIntoSelect(select, languages) { let html = ''; html += ""; - for (let i = 0; i < languages.length; i++) { - const culture = languages[i]; + for (const culture of languages) { html += ``; } select.innerHTML = html; @@ -32,8 +31,7 @@ function populateLanguagesIntoSelect(select, languages) { function populateLanguagesIntoList(element, languages) { let html = ''; - for (let i = 0; i < languages.length; i++) { - const culture = languages[i]; + for (const culture of languages) { html += ``; } element.innerHTML = html; @@ -43,8 +41,7 @@ function populateCountries(select) { return ApiClient.getCountries().then(allCountries => { let html = ''; html += ""; - for (let i = 0; i < allCountries.length; i++) { - const culture = allCountries[i]; + for (const culture of allCountries) { html += ``; } select.innerHTML = html; @@ -109,8 +106,7 @@ function renderMetadataSavers(page, metadataSavers) { } html += `

${globalize.translate('LabelMetadataSavers')}

`; html += '
'; - for (let i = 0; i < metadataSavers.length; i++) { - const plugin = metadataSavers[i]; + for (const plugin of metadataSavers) { html += ``; } html += '
'; @@ -157,8 +153,7 @@ function getMetadataFetchersForTypeHtml(availableTypeOptions, libraryOptionsForT function getTypeOptions(allOptions, type) { const allTypeOptions = allOptions.TypeOptions || []; - for (let i = 0; i < allTypeOptions.length; i++) { - const typeOptions = allTypeOptions[i]; + for (const typeOptions of allTypeOptions) { if (typeOptions.Type === type) return typeOptions; } return null; @@ -167,8 +162,7 @@ function getTypeOptions(allOptions, type) { function renderMetadataFetchers(page, availableOptions, libraryOptions) { let html = ''; const elem = page.querySelector('.metadataFetchers'); - for (let i = 0; i < availableOptions.TypeOptions.length; i++) { - const availableTypeOptions = availableOptions.TypeOptions[i]; + for (const availableTypeOptions of availableOptions.TypeOptions) { html += getMetadataFetchersForTypeHtml(availableTypeOptions, getTypeOptions(libraryOptions, availableTypeOptions.Type) || {}); } elem.innerHTML = html; @@ -262,8 +256,7 @@ function getImageFetchersForTypeHtml(availableTypeOptions, libraryOptionsForType function renderImageFetchers(page, availableOptions, libraryOptions) { let html = ''; const elem = page.querySelector('.imageFetchers'); - for (let i = 0; i < availableOptions.TypeOptions.length; i++) { - const availableTypeOptions = availableOptions.TypeOptions[i]; + for (const availableTypeOptions of availableOptions.TypeOptions) { html += getImageFetchersForTypeHtml(availableTypeOptions, getTypeOptions(libraryOptions, availableTypeOptions.Type) || {}); } elem.innerHTML = html; @@ -454,8 +447,7 @@ function setSubtitleFetchersIntoOptions(parent, options) { function setMetadataFetchersIntoOptions(parent, options) { const sections = parent.querySelectorAll('.metadataFetcher'); - for (let i = 0; i < sections.length; i++) { - const section = sections[i]; + for (const section of sections) { const type = section.getAttribute('data-type'); let typeOptions = getTypeOptions(options, type); if (!typeOptions) { @@ -478,8 +470,7 @@ function setMetadataFetchersIntoOptions(parent, options) { function setImageFetchersIntoOptions(parent, options) { const sections = parent.querySelectorAll('.imageFetcher'); - for (let i = 0; i < sections.length; i++) { - const section = sections[i]; + for (const section of sections) { const type = section.getAttribute('data-type'); let typeOptions = getTypeOptions(options, type); if (!typeOptions) { @@ -503,8 +494,7 @@ function setImageFetchersIntoOptions(parent, options) { function setImageOptionsIntoOptions(options) { const originalTypeOptions = (currentLibraryOptions || {}).TypeOptions || []; - for (let i = 0; i < originalTypeOptions.length; i++) { - const originalTypeOption = originalTypeOptions[i]; + for (const originalTypeOption of originalTypeOptions) { let typeOptions = getTypeOptions(options, originalTypeOption.Type); if (!typeOptions) { diff --git a/src/components/metadataEditor/metadataEditor.js b/src/components/metadataEditor/metadataEditor.js index 422f3c964d..dfe7a99237 100644 --- a/src/components/metadataEditor/metadataEditor.js +++ b/src/components/metadataEditor/metadataEditor.js @@ -955,8 +955,7 @@ function populatePeople(context, people) { function getLockedFieldsHtml(fields, currentFields) { let html = ''; - for (let i = 0; i < fields.length; i++) { - const field = fields[i]; + for (const field of fields) { const name = field.name; const value = field.value || field.name; const checkedHtml = currentFields.indexOf(value) === -1 ? ' checked' : ''; diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 392c6ceafb..879b5fe36f 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -853,11 +853,9 @@ class PlaybackManager { user: user }); - for (let i = 0; i < responses.length; i++) { - const subTargets = responses[i]; - - for (let j = 0; j < subTargets.length; j++) { - targets.push(subTargets[j]); + for (const subTargets of responses) { + for (const subTarget of subTargets) { + targets.push(subTarget); } } diff --git a/src/controllers/dashboard/plugins/add/index.js b/src/controllers/dashboard/plugins/add/index.js index 150fe3e1fd..62ae70ab4f 100644 --- a/src/controllers/dashboard/plugins/add/index.js +++ b/src/controllers/dashboard/plugins/add/index.js @@ -28,8 +28,7 @@ function populateVersions(packageInfo, page, installedPlugin) { return b.timestamp < a.timestamp ? -1 : 1; }); - for (let i = 0; i < packageInfo.versions.length; i++) { - const version = packageInfo.versions[i]; + for (const version of packageInfo.versions) { html += ''; } diff --git a/src/controllers/dashboard/plugins/available/index.js b/src/controllers/dashboard/plugins/available/index.js index 4dc172450f..78368b2c14 100644 --- a/src/controllers/dashboard/plugins/available/index.js +++ b/src/controllers/dashboard/plugins/available/index.js @@ -66,8 +66,7 @@ function populateList(options) { let currentCategory = null; let html = ''; - for (let i = 0; i < availablePlugins.length; i++) { - const plugin = availablePlugins[i]; + for (const plugin of availablePlugins) { const category = plugin.categoryDisplayName; if (category != currentCategory) { if (currentCategory) { diff --git a/src/controllers/dashboard/scheduledtasks/scheduledtasks.js b/src/controllers/dashboard/scheduledtasks/scheduledtasks.js index c074331aa1..8ae447aabc 100644 --- a/src/controllers/dashboard/scheduledtasks/scheduledtasks.js +++ b/src/controllers/dashboard/scheduledtasks/scheduledtasks.js @@ -133,8 +133,7 @@ function updateTaskButton(elem, state) { export default function(view) { function updateTasks(tasks) { - for (let i = 0; i < tasks.length; i++) { - const task = tasks[i]; + for (const task of tasks) { view.querySelector('#taskProgress' + task.Id).innerHTML = getTaskProgressHtml(task); updateTaskButton(view.querySelector('#btnTask' + task.Id), task.State); } diff --git a/src/controllers/session/login/index.js b/src/controllers/session/login/index.js index 0f2d18580c..6e75af6f08 100644 --- a/src/controllers/session/login/index.js +++ b/src/controllers/session/login/index.js @@ -135,9 +135,7 @@ function showManualForm(context, showCancel, focusPassword) { function loadUserList(context, apiClient, users) { let html = ''; - for (let i = 0; i < users.length; i++) { - const user = users[i]; - + for (const user of users) { // TODO move card creation code to Card component let cssClass = 'card squareCard scalableCard squareCard-scalable'; diff --git a/src/elements/emby-textarea/emby-textarea.js b/src/elements/emby-textarea/emby-textarea.js index 4acf38b594..04ce1a42d9 100644 --- a/src/elements/emby-textarea/emby-textarea.js +++ b/src/elements/emby-textarea/emby-textarea.js @@ -13,8 +13,8 @@ function calculateOffset(textarea) { const props = ['paddingTop', 'paddingBottom']; let offset = 0; - for (let i = 0; i < props.length; i++) { - offset += parseInt(style[props[i]], 10); + for (const prop of props) { + offset += parseInt(style[prop], 10); } return offset; } diff --git a/src/scripts/autocast.js b/src/scripts/autocast.js index a118022513..854403b4da 100644 --- a/src/scripts/autocast.js +++ b/src/scripts/autocast.js @@ -33,9 +33,9 @@ function onOpen() { const playerId = localStorage.getItem('autocastPlayerId'); playbackManager.getTargets().then(function (targets) { - for (let i = 0; i < targets.length; i++) { - if (targets[i].id == playerId) { - playbackManager.trySetActivePlayer(targets[i].playerName, targets[i]); + for (const target of targets) { + if (target.id == playerId) { + playbackManager.trySetActivePlayer(target.playerName, target); break; } } diff --git a/src/scripts/browser.js b/src/scripts/browser.js index 7540d0c684..47b0635d52 100644 --- a/src/scripts/browser.js +++ b/src/scripts/browser.js @@ -167,8 +167,8 @@ function supportsCssAnimation(allowPrefix) { } if (animation === false && allowPrefix) { - for (let i = 0; i < domPrefixes.length; i++) { - if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) { + for (const domPrefix of domPrefixes) { + if (elm.style[domPrefix + 'AnimationName'] !== undefined) { animation = true; break; } diff --git a/src/scripts/libraryMenu.js b/src/scripts/libraryMenu.js index 0a8ba07831..ec7f26a0b2 100644 --- a/src/scripts/libraryMenu.js +++ b/src/scripts/libraryMenu.js @@ -591,13 +591,10 @@ function getToolsLinkHtml(item) { function getToolsMenuHtml(apiClient) { return getToolsMenuLinks(apiClient).then(function (items) { - let item; let menuHtml = ''; menuHtml += '
'; - for (let i = 0; i < items.length; i++) { - item = items[i]; - + for (const item of items) { if (item.href) { menuHtml += getToolsLinkHtml(item); } else if (item.name) { From c981b47468709a923da96c5a946d989a6c903bb6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 May 2023 18:56:04 +0000 Subject: [PATCH 079/112] Update github/codeql-action action to v2.3.3 --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 240f558cfb..696c591aa5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -21,11 +21,11 @@ jobs: - name: Checkout repository uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Initialize CodeQL - uses: github/codeql-action/init@f3feb00acb00f31a6f60280e6ace9ca31d91c76a # v2.3.2 + uses: github/codeql-action/init@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 with: languages: ${{ matrix.language }} queries: +security-extended - name: Autobuild - uses: github/codeql-action/autobuild@f3feb00acb00f31a6f60280e6ace9ca31d91c76a # v2.3.2 + uses: github/codeql-action/autobuild@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f3feb00acb00f31a6f60280e6ace9ca31d91c76a # v2.3.2 + uses: github/codeql-action/analyze@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 From aaac4883e38b2f200c78ba0aedbfa63a6b13f523 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 2 May 2023 11:24:36 -0400 Subject: [PATCH 080/112] Add floating promises eslint rule --- .eslintrc.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index 36e895e510..aad915afde 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -203,6 +203,9 @@ module.exports = { './src/**/*.ts', './src/**/*.tsx' ], + parserOptions: { + project: ['./tsconfig.json'] + }, env: { node: false, amd: true, @@ -240,6 +243,9 @@ module.exports = { 'TaskButton': 'writable', 'UserParentalControlPage': 'writable', 'Windows': 'readonly' + }, + rules: { + '@typescript-eslint/no-floating-promises': ['error'] } }, // TypeScript source files From eedd40159c754782eb50b5ce5d4d2a0e390af62e Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 2 May 2023 11:24:53 -0400 Subject: [PATCH 081/112] Fix floating promises in ts files --- src/apps/experimental/routes/home.tsx | 2 + .../experimental/routes/movies/GenresView.tsx | 2 + .../routes/movies/SuggestionsView.tsx | 8 +++ src/apps/experimental/routes/movies/index.tsx | 2 + src/apps/stable/routes/user/useredit.tsx | 32 +++++++++--- .../stable/routes/user/userlibraryaccess.tsx | 6 +++ src/apps/stable/routes/user/usernew.tsx | 9 +++- .../routes/user/userparentalcontrol.tsx | 14 +++++ src/apps/stable/routes/user/userpassword.tsx | 2 + src/apps/stable/routes/user/userprofile.tsx | 10 ++++ src/apps/stable/routes/user/userprofiles.tsx | 30 +++++++++-- src/components/ConnectionRequired.tsx | 25 +++++++-- src/components/common/Filter.tsx | 4 ++ .../common/GenresItemsContainer.tsx | 2 + src/components/common/NewCollection.tsx | 4 ++ src/components/common/SelectView.tsx | 4 ++ src/components/common/Shuffle.tsx | 2 + src/components/common/Sort.tsx | 4 ++ src/components/common/ViewItemsContainer.tsx | 4 ++ .../dashboard/users/UserPasswordForm.tsx | 36 +++++++++++-- src/components/search/LiveTVSearchResults.tsx | 27 +++++++--- src/components/search/SearchResults.tsx | 51 +++++++++++++------ src/components/search/SearchSuggestions.tsx | 6 ++- src/elements/emby-button/LinkButton.tsx | 5 +- src/utils/dashboard.js | 6 +++ 25 files changed, 250 insertions(+), 47 deletions(-) diff --git a/src/apps/experimental/routes/home.tsx b/src/apps/experimental/routes/home.tsx index 0b0e38f3b2..af14e252e1 100644 --- a/src/apps/experimental/routes/home.tsx +++ b/src/apps/experimental/routes/home.tsx @@ -101,6 +101,8 @@ const Home: FunctionComponent = () => { controller.refreshed = true; tabController.current = controller; + }).catch(err => { + console.error('[Home] failed to get tab controller', err); }); }, [ getTabController ]); diff --git a/src/apps/experimental/routes/movies/GenresView.tsx b/src/apps/experimental/routes/movies/GenresView.tsx index a2c1d7a476..dd1af9efc9 100644 --- a/src/apps/experimental/routes/movies/GenresView.tsx +++ b/src/apps/experimental/routes/movies/GenresView.tsx @@ -23,6 +23,8 @@ const GenresView: FC = ({ topParentId }) => { ).then((result) => { setItemsResult(result); loading.hide(); + }).catch(err => { + console.error('[GenresView] failed to fetch genres', err); }); }, [topParentId]); diff --git a/src/apps/experimental/routes/movies/SuggestionsView.tsx b/src/apps/experimental/routes/movies/SuggestionsView.tsx index 48b402efbc..1d468d009b 100644 --- a/src/apps/experimental/routes/movies/SuggestionsView.tsx +++ b/src/apps/experimental/routes/movies/SuggestionsView.tsx @@ -30,6 +30,8 @@ const SuggestionsView: FC = ({ topParentId }) => { const autoFocus = useCallback((page) => { import('../../../../components/autoFocuser').then(({ default: autoFocuser }) => { autoFocuser.autoFocus(page); + }).catch(err => { + console.error('[SuggestionsView] failed to load data', err); }); }, []); @@ -55,6 +57,8 @@ const SuggestionsView: FC = ({ topParentId }) => { loading.hide(); autoFocus(page); + }).catch(err => { + console.error('[SuggestionsView] failed to fetch items', err); }); }, [autoFocus]); @@ -72,6 +76,8 @@ const SuggestionsView: FC = ({ topParentId }) => { setLatestItems(items); autoFocus(page); + }).catch(err => { + console.error('[SuggestionsView] failed to fetch latest items', err); }); }, [autoFocus]); @@ -95,6 +101,8 @@ const SuggestionsView: FC = ({ topParentId }) => { setRecommendations(result); autoFocus(page); + }).catch(err => { + console.error('[SuggestionsView] failed to fetch recommendations', err); }); }, [autoFocus]); diff --git a/src/apps/experimental/routes/movies/index.tsx b/src/apps/experimental/routes/movies/index.tsx index e2e7bfa4de..64f66368c8 100644 --- a/src/apps/experimental/routes/movies/index.tsx +++ b/src/apps/experimental/routes/movies/index.tsx @@ -114,6 +114,8 @@ const Movies: FC = () => { window.ApiClient.getItem(window.ApiClient.getCurrentUserId(), parentId).then((item) => { page.setAttribute('data-title', item.Name as string); libraryMenu.setTitle(item.Name); + }).catch(err => { + console.error('[movies] failed to fetch library', err); }); } else { page.setAttribute('data-title', globalize.translate('Movies')); diff --git a/src/apps/stable/routes/user/useredit.tsx b/src/apps/stable/routes/user/useredit.tsx index f099ee6407..c4acdfaaee 100644 --- a/src/apps/stable/routes/user/useredit.tsx +++ b/src/apps/stable/routes/user/useredit.tsx @@ -32,7 +32,10 @@ const getCheckedElementDataIds = (elements: NodeListOf) => ( ); function onSaveComplete() { - Dashboard.navigate('userprofiles.html'); + Dashboard.navigate('userprofiles.html') + .catch(err => { + console.error('[useredit] failed to navigate to user profile', err); + }); loading.hide(); toast(globalize.translate('SettingsSaved')); } @@ -133,6 +136,8 @@ const UserEdit: FunctionComponent = () => { const chkEnableDeleteAllFolders = page.querySelector('.chkEnableDeleteAllFolders') as HTMLInputElement; chkEnableDeleteAllFolders.checked = user.Policy.EnableContentDeletion; triggerChange(chkEnableDeleteAllFolders); + }).catch(err => { + console.error('[useredit] failed to fetch channels', err); }); }, []); @@ -146,14 +151,20 @@ const UserEdit: FunctionComponent = () => { window.ApiClient.getJSON(window.ApiClient.getUrl('Auth/Providers')).then(function (providers) { loadAuthProviders(user, providers); + }).catch(err => { + console.error('[useredit] failed to fetch auth providers', err); }); window.ApiClient.getJSON(window.ApiClient.getUrl('Auth/PasswordResetProviders')).then(function (providers) { loadPasswordResetProviders(user, providers); + }).catch(err => { + console.error('[useredit] failed to fetch password reset providers', err); }); window.ApiClient.getJSON(window.ApiClient.getUrl('Library/MediaFolders', { IsHidden: false })).then(function (folders) { loadDeleteFolders(user, folders.Items); + }).catch(err => { + console.error('[useredit] failed to fetch media folders', err); }); const disabledUserBanner = page.querySelector('.disabledUserBanner') as HTMLDivElement; @@ -197,6 +208,8 @@ const UserEdit: FunctionComponent = () => { loading.show(); getUser().then(function (user) { loadUser(user); + }).catch(err => { + console.error('[useredit] failed to load data', err); }); }, [loadUser]); @@ -240,18 +253,21 @@ const UserEdit: FunctionComponent = () => { user.Policy.EnableContentDeletionFromFolders = user.Policy.EnableContentDeletion ? [] : getCheckedElementDataIds(page.querySelectorAll('.chkFolder')); user.Policy.SyncPlayAccess = (page.querySelector('#selectSyncPlayAccess') as HTMLSelectElement).value as SyncPlayUserAccessType; - window.ApiClient.updateUser(user) - .then(() => ( - window.ApiClient.updateUserPolicy(user.Id || '', user.Policy || {}) - )).then(() => { - onSaveComplete(); - }); + window.ApiClient.updateUser(user).then(() => ( + window.ApiClient.updateUserPolicy(user.Id || '', user.Policy || {}) + )).then(() => { + onSaveComplete(); + }).catch(err => { + console.error('[useredit] failed to update user', err); + }); }; const onSubmit = (e: Event) => { loading.show(); getUser().then(function (result) { saveUser(result); + }).catch(err => { + console.error('[useredit] failed to fetch user', err); }); e.preventDefault(); e.stopPropagation(); @@ -264,6 +280,8 @@ const UserEdit: FunctionComponent = () => { window.ApiClient.getNamedConfiguration('network').then(function (config) { (page.querySelector('.fldRemoteAccess') as HTMLDivElement).classList.toggle('hide', !config.EnableRemoteAccess); + }).catch(err => { + console.error('[useredit] failed to load network config', err); }); (page.querySelector('.editUserProfileForm') as HTMLFormElement).addEventListener('submit', onSubmit); diff --git a/src/apps/stable/routes/user/userlibraryaccess.tsx b/src/apps/stable/routes/user/userlibraryaccess.tsx index e255376104..e9af88cb1f 100644 --- a/src/apps/stable/routes/user/userlibraryaccess.tsx +++ b/src/apps/stable/routes/user/userlibraryaccess.tsx @@ -148,6 +148,8 @@ const UserLibraryAccess: FunctionComponent = () => { const promise4 = window.ApiClient.getJSON(window.ApiClient.getUrl('Devices')); Promise.all([promise1, promise2, promise3, promise4]).then(function (responses) { loadUser(responses[0], responses[1].Items, responses[2].Items, responses[3].Items); + }).catch(err => { + console.error('[userlibraryaccess] failed to load data', err); }); }, [loadUser]); @@ -166,6 +168,8 @@ const UserLibraryAccess: FunctionComponent = () => { const userId = getParameterByName('userId'); window.ApiClient.getUser(userId).then(function (result) { saveUser(result); + }).catch(err => { + console.error('[userlibraryaccess] failed to fetch user', err); }); e.preventDefault(); e.stopPropagation(); @@ -203,6 +207,8 @@ const UserLibraryAccess: FunctionComponent = () => { user.Policy.BlockedMediaFolders = null; window.ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { onSaveComplete(); + }).catch(err => { + console.error('[userlibraryaccess] failed to update user policy', err); }); }; diff --git a/src/apps/stable/routes/user/usernew.tsx b/src/apps/stable/routes/user/usernew.tsx index 051bbce9b7..22758500ea 100644 --- a/src/apps/stable/routes/user/usernew.tsx +++ b/src/apps/stable/routes/user/usernew.tsx @@ -93,6 +93,8 @@ const UserNew: FunctionComponent = () => { loadMediaFolders(responses[0].Items); loadChannels(responses[1].Items); loading.hide(); + }).catch(err => { + console.error('[usernew] failed to load data', err); }); }, [loadChannels, loadMediaFolders]); @@ -138,7 +140,12 @@ const UserNew: FunctionComponent = () => { } window.ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { - Dashboard.navigate('useredit.html?userId=' + user.Id); + Dashboard.navigate('useredit.html?userId=' + user.Id) + .catch(err => { + console.error('[usernew] failed to navigate to edit user page', err); + }); + }).catch(err => { + console.error('[usernew] failed to update user policy', err); }); }, function () { toast(globalize.translate('ErrorDefault')); diff --git a/src/apps/stable/routes/user/userparentalcontrol.tsx b/src/apps/stable/routes/user/userparentalcontrol.tsx index ce02ba0f33..bee0fde1c7 100644 --- a/src/apps/stable/routes/user/userparentalcontrol.tsx +++ b/src/apps/stable/routes/user/userparentalcontrol.tsx @@ -197,6 +197,8 @@ const UserParentalControl: FunctionComponent = () => { const promise2 = window.ApiClient.getParentalRatings(); Promise.all([promise1, promise2]).then(function (responses) { loadUser(responses[0], responses[1]); + }).catch(err => { + console.error('[userparentalcontrol] failed to load data', err); }); }, [loadUser]); @@ -231,6 +233,8 @@ const UserParentalControl: FunctionComponent = () => { user.Policy.BlockedTags = getBlockedTagsFromPage(); window.ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { onSaveComplete(); + }).catch(err => { + console.error('[userparentalcontrol] failed to update user policy', err); }); }; @@ -248,7 +252,11 @@ const UserParentalControl: FunctionComponent = () => { schedules[index] = updatedSchedule; renderAccessSchedule(schedules); + }).catch(() => { + // access schedule closed }); + }).catch(err => { + console.error('[userparentalcontrol] failed to load access schedule', err); }); }; @@ -279,7 +287,11 @@ const UserParentalControl: FunctionComponent = () => { tags.push(value); loadBlockedTags(tags); } + }).catch(() => { + // prompt closed }); + }).catch(err => { + console.error('[userparentalcontrol] failed to load prompt', err); }); }; @@ -288,6 +300,8 @@ const UserParentalControl: FunctionComponent = () => { const userId = getParameterByName('userId'); window.ApiClient.getUser(userId).then(function (result) { saveUser(result); + }).catch(err => { + console.error('[userparentalcontrol] failed to fetch user', err); }); e.preventDefault(); e.stopPropagation(); diff --git a/src/apps/stable/routes/user/userpassword.tsx b/src/apps/stable/routes/user/userpassword.tsx index 3a518d6379..544e8c6dec 100644 --- a/src/apps/stable/routes/user/userpassword.tsx +++ b/src/apps/stable/routes/user/userpassword.tsx @@ -19,6 +19,8 @@ const UserPassword: FunctionComponent = () => { } setUserName(user.Name); loading.hide(); + }).catch(err => { + console.error('[userpassword] failed to fetch user', err); }); }, [userId]); useEffect(() => { diff --git a/src/apps/stable/routes/user/userprofile.tsx b/src/apps/stable/routes/user/userprofile.tsx index 7b1575d2c1..0c038bc84a 100644 --- a/src/apps/stable/routes/user/userprofile.tsx +++ b/src/apps/stable/routes/user/userprofile.tsx @@ -59,8 +59,12 @@ const UserProfile: FunctionComponent = () => { (page.querySelector('#btnDeleteImage') as HTMLButtonElement).classList.add('hide'); (page.querySelector('#btnAddImage') as HTMLButtonElement).classList.remove('hide'); } + }).catch(err => { + console.error('[userprofile] failed to get current user', err); }); loading.hide(); + }).catch(err => { + console.error('[userprofile] failed to load data', err); }); }, [userId]); @@ -110,6 +114,8 @@ const UserProfile: FunctionComponent = () => { window.ApiClient.uploadUserImage(userId, ImageType.Primary, file).then(function () { loading.hide(); reloadUser(); + }).catch(err => { + console.error('[userprofile] failed to upload image', err); }); }; @@ -125,7 +131,11 @@ const UserProfile: FunctionComponent = () => { window.ApiClient.deleteUserImage(userId, ImageType.Primary).then(function () { loading.hide(); reloadUser(); + }).catch(err => { + console.error('[userprofile] failed to delete image', err); }); + }).catch(() => { + // confirm dialog closed }); }); diff --git a/src/apps/stable/routes/user/userprofiles.tsx b/src/apps/stable/routes/user/userprofiles.tsx index 1eb2c9ee2e..b386533f4b 100644 --- a/src/apps/stable/routes/user/userprofiles.tsx +++ b/src/apps/stable/routes/user/userprofiles.tsx @@ -31,6 +31,8 @@ const UserProfiles: FunctionComponent = () => { window.ApiClient.getUsers().then(function (result) { setUsers(result); loading.hide(); + }).catch(err => { + console.error('[userprofiles] failed to fetch users', err); }); }; @@ -83,22 +85,35 @@ const UserProfiles: FunctionComponent = () => { callback: function (id: string) { switch (id) { case 'open': - Dashboard.navigate('useredit.html?userId=' + userId); + Dashboard.navigate('useredit.html?userId=' + userId) + .catch(err => { + console.error('[userprofiles] failed to navigate to user edit page', err); + }); break; case 'access': - Dashboard.navigate('userlibraryaccess.html?userId=' + userId); + Dashboard.navigate('userlibraryaccess.html?userId=' + userId) + .catch(err => { + console.error('[userprofiles] failed to navigate to user library page', err); + }); break; case 'parentalcontrol': - Dashboard.navigate('userparentalcontrol.html?userId=' + userId); + Dashboard.navigate('userparentalcontrol.html?userId=' + userId) + .catch(err => { + console.error('[userprofiles] failed to navigate to parental control page', err); + }); break; case 'delete': deleteUser(userId); } } + }).catch(() => { + // action sheet closed }); + }).catch(err => { + console.error('[userprofiles] failed to load action sheet', err); }); }; @@ -114,7 +129,11 @@ const UserProfiles: FunctionComponent = () => { loading.show(); window.ApiClient.deleteUser(id).then(function () { loadData(); + }).catch(err => { + console.error('[userprofiles] failed to delete user', err); }); + }).catch(() => { + // confirm dialog closed }); }; @@ -127,7 +146,10 @@ const UserProfiles: FunctionComponent = () => { }); (page.querySelector('#btnAddUser') as HTMLButtonElement).addEventListener('click', function() { - Dashboard.navigate('usernew.html'); + Dashboard.navigate('usernew.html') + .catch(err => { + console.error('[userprofiles] failed to navigate to new user page', err); + }); }); }, []); diff --git a/src/components/ConnectionRequired.tsx b/src/components/ConnectionRequired.tsx index c61e7c52ba..ca6c26b091 100644 --- a/src/components/ConnectionRequired.tsx +++ b/src/components/ConnectionRequired.tsx @@ -99,7 +99,10 @@ const ConnectionRequired: FunctionComponent = ({ } // Bounce to the correct page in the login flow - bounce(firstConnection); + bounce(firstConnection) + .catch(err => { + console.error('[ConnectionRequired] failed to bounce', err); + }); }, [bounce, navigate]); const validateUserAccess = useCallback(async () => { @@ -109,7 +112,10 @@ const ConnectionRequired: FunctionComponent = ({ if ((isAdminRequired || isUserRequired) && !client?.isLoggedIn()) { try { console.warn('[ConnectionRequired] unauthenticated user attempted to access user route'); - bounce(await ServerConnections.connect()); + bounce(await ServerConnections.connect()) + .catch(err => { + console.error('[ConnectionRequired] failed to bounce', err); + }); } catch (ex) { console.warn('[ConnectionRequired] error bouncing from user route', ex); } @@ -122,7 +128,10 @@ const ConnectionRequired: FunctionComponent = ({ const user = await client?.getCurrentUser(); if (!user?.Policy?.IsAdministrator) { console.warn('[ConnectionRequired] normal user attempted to access admin route'); - bounce(await ServerConnections.connect()); + bounce(await ServerConnections.connect()) + .catch(err => { + console.error('[ConnectionRequired] failed to bounce', err); + }); return; } } catch (ex) { @@ -143,9 +152,15 @@ const ConnectionRequired: FunctionComponent = ({ appRouter.firstConnectionResult = null; if (firstConnection && firstConnection.State !== ConnectionState.SignedIn) { - handleIncompleteWizard(firstConnection); + handleIncompleteWizard(firstConnection) + .catch(err => { + console.error('[ConnectionRequired] failed to start wizard', err); + }); } else { - validateUserAccess(); + validateUserAccess() + .catch(err => { + console.error('[ConnectionRequired] failed to validate user access', err); + }); } }, [handleIncompleteWizard, validateUserAccess]); diff --git a/src/components/common/Filter.tsx b/src/components/common/Filter.tsx index c3316df1a2..c3ccdd62f3 100644 --- a/src/components/common/Filter.tsx +++ b/src/components/common/Filter.tsx @@ -32,7 +32,11 @@ const Filter: FC = ({ serverId: window.ApiClient.serverId(), filterMenuOptions: getFilterMenuOptions(), setfilters: setViewQuerySettings + }).catch(() => { + // filter menu closed }); + }).catch(err => { + console.error('[Filter] failed to load filter menu', err); }); }, [viewQuerySettings, getVisibleFilters, topParentId, getItemTypes, getFilterMenuOptions, setViewQuerySettings]); diff --git a/src/components/common/GenresItemsContainer.tsx b/src/components/common/GenresItemsContainer.tsx index 796b6fa119..09623e7e57 100644 --- a/src/components/common/GenresItemsContainer.tsx +++ b/src/components/common/GenresItemsContainer.tsx @@ -73,6 +73,8 @@ const GenresItemsContainer: FC = ({ centerText: true, showYear: true }); + }).catch(err => { + console.error('[GenresItemsContainer] failed to fetch items', err); }); }, [getPortraitShape, topParentId]); diff --git a/src/components/common/NewCollection.tsx b/src/components/common/NewCollection.tsx index 4eadda8e36..837fe85fd3 100644 --- a/src/components/common/NewCollection.tsx +++ b/src/components/common/NewCollection.tsx @@ -12,7 +12,11 @@ const NewCollection: FC = () => { collectionEditor.show({ items: [], serverId: serverId + }).catch(() => { + // closed collection editor }); + }).catch(err => { + console.error('[NewCollection] failed to load collection editor', err); }); }, []); diff --git a/src/components/common/SelectView.tsx b/src/components/common/SelectView.tsx index f718529857..bfb34555b8 100644 --- a/src/components/common/SelectView.tsx +++ b/src/components/common/SelectView.tsx @@ -22,7 +22,11 @@ const SelectView: FC = ({ settings: viewQuerySettings, visibleSettings: getVisibleViewSettings(), setviewsettings: setViewQuerySettings + }).catch(() => { + // view settings closed }); + }).catch(err => { + console.error('[SelectView] failed to load view settings', err); }); }, [getVisibleViewSettings, viewQuerySettings, setViewQuerySettings]); diff --git a/src/components/common/Shuffle.tsx b/src/components/common/Shuffle.tsx index 7d5b06be4b..093dc74874 100644 --- a/src/components/common/Shuffle.tsx +++ b/src/components/common/Shuffle.tsx @@ -18,6 +18,8 @@ const Shuffle: FC = ({ itemsResult = {}, topParentId }) => { topParentId as string ).then((item) => { playbackManager.shuffle(item); + }).catch(err => { + console.error('[Shuffle] failed to fetch items', err); }); }, [topParentId]); diff --git a/src/components/common/Sort.tsx b/src/components/common/Sort.tsx index 5c5d1b6193..db5cb89956 100644 --- a/src/components/common/Sort.tsx +++ b/src/components/common/Sort.tsx @@ -25,7 +25,11 @@ const Sort: FC = ({ settings: viewQuerySettings, sortOptions: getSortMenuOptions(), setSortValues: setViewQuerySettings + }).catch(() => { + // sort menu closed }); + }).catch(err => { + console.error('[Sort] failed to load sort menu', err); }); }, [getSortMenuOptions, viewQuerySettings, setViewQuerySettings]); diff --git a/src/components/common/ViewItemsContainer.tsx b/src/components/common/ViewItemsContainer.tsx index d4f2937513..5cbc7aace6 100644 --- a/src/components/common/ViewItemsContainer.tsx +++ b/src/components/common/ViewItemsContainer.tsx @@ -335,9 +335,13 @@ const ViewItemsContainer: FC = ({ import('../../components/autoFocuser').then(({ default: autoFocuser }) => { autoFocuser.autoFocus(page); + }).catch(err => { + console.error('[ViewItemsContainer] failed to load autofocuser', err); }); loading.hide(); setisLoading(true); + }).catch(err => { + console.error('[ViewItemsContainer] failed to fetch data', err); }); }, [fetchData]); diff --git a/src/components/dashboard/users/UserPasswordForm.tsx b/src/components/dashboard/users/UserPasswordForm.tsx index 0337c06510..d7801fdb42 100644 --- a/src/components/dashboard/users/UserPasswordForm.tsx +++ b/src/components/dashboard/users/UserPasswordForm.tsx @@ -66,6 +66,8 @@ const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { import('../../autoFocuser').then(({ default: autoFocuser }) => { autoFocuser.autoFocus(page); + }).catch(err => { + console.error('[UserPasswordForm] failed to load autofocuser', err); }); (page.querySelector('#txtCurrentPassword') as HTMLInputElement).value = ''; @@ -81,7 +83,9 @@ const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { return; } - loadUser(); + loadUser().catch(err => { + console.error('[UserPasswordForm] failed to load user', err); + }); const onSubmit = (e: Event) => { if ((page.querySelector('#txtNewPassword') as HTMLInputElement).value != (page.querySelector('#txtNewPasswordConfirm') as HTMLInputElement).value) { @@ -109,7 +113,9 @@ const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { loading.hide(); toast(globalize.translate('PasswordSaved')); - loadUser(); + loadUser().catch(err => { + console.error('[UserPasswordForm] failed to load user', err); + }); }, function () { loading.hide(); Dashboard.alert({ @@ -132,6 +138,8 @@ const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { if (easyPassword) { window.ApiClient.updateEasyPassword(userId, easyPassword).then(function () { onEasyPasswordSaved(); + }).catch(err => { + console.error('[UserPasswordForm] failed to update easy password', err); }); } else { onEasyPasswordSaved(); @@ -153,8 +161,14 @@ const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { loading.hide(); toast(globalize.translate('SettingsSaved')); - loadUser(); + loadUser().catch(err => { + console.error('[UserPasswordForm] failed to load user', err); + }); + }).catch(err => { + console.error('[UserPasswordForm] failed to update user configuration', err); }); + }).catch(err => { + console.error('[UserPasswordForm] failed to fetch user', err); }); }; @@ -169,8 +183,14 @@ const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { message: globalize.translate('PinCodeResetComplete'), title: globalize.translate('HeaderPinCodeReset') }); - loadUser(); + loadUser().catch(err => { + console.error('[UserPasswordForm] failed to load user', err); + }); + }).catch(err => { + console.error('[UserPasswordForm] failed to reset easy password', err); }); + }).catch(() => { + // confirm dialog was closed }); }; @@ -184,8 +204,14 @@ const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { message: globalize.translate('PasswordResetComplete'), title: globalize.translate('ResetPassword') }); - loadUser(); + loadUser().catch(err => { + console.error('[UserPasswordForm] failed to load user', err); + }); + }).catch(err => { + console.error('[UserPasswordForm] failed to reset user password', err); }); + }).catch(() => { + // confirm dialog was closed }); }; diff --git a/src/components/search/LiveTVSearchResults.tsx b/src/components/search/LiveTVSearchResults.tsx index a087dc23cc..12d862804d 100644 --- a/src/components/search/LiveTVSearchResults.tsx +++ b/src/components/search/LiveTVSearchResults.tsx @@ -79,7 +79,9 @@ const LiveTVSearchResults: FunctionComponent = ({ serv fetchItems(apiClient, { IncludeItemTypes: 'LiveTvProgram', IsMovie: true - }).then(result => setMovies(result.Items || [])); + }) + .then(result => setMovies(result.Items || [])) + .catch(() => setMovies([])); // Episodes row fetchItems(apiClient, { IncludeItemTypes: 'LiveTvProgram', @@ -88,22 +90,30 @@ const LiveTVSearchResults: FunctionComponent = ({ serv IsSports: false, IsKids: false, IsNews: false - }).then(result => setEpisodes(result.Items || [])); + }) + .then(result => setEpisodes(result.Items || [])) + .catch(() => setEpisodes([])); // Sports row fetchItems(apiClient, { IncludeItemTypes: 'LiveTvProgram', IsSports: true - }).then(result => setSports(result.Items || [])); + }) + .then(result => setSports(result.Items || [])) + .catch(() => setSports([])); // Kids row fetchItems(apiClient, { IncludeItemTypes: 'LiveTvProgram', IsKids: true - }).then(result => setKids(result.Items || [])); + }) + .then(result => setKids(result.Items || [])) + .catch(() => setKids([])); // News row fetchItems(apiClient, { IncludeItemTypes: 'LiveTvProgram', IsNews: true - }).then(result => setNews(result.Items || [])); + }) + .then(result => setNews(result.Items || [])) + .catch(() => setNews([])); // Programs row fetchItems(apiClient, { IncludeItemTypes: 'LiveTvProgram', @@ -112,10 +122,13 @@ const LiveTVSearchResults: FunctionComponent = ({ serv IsSports: false, IsKids: false, IsNews: false - }).then(result => setPrograms(result.Items || [])); + }) + .then(result => setPrograms(result.Items || [])) + .catch(() => setPrograms([])); // Channels row fetchItems(apiClient, { IncludeItemTypes: 'TvChannel' }) - .then(result => setChannels(result.Items || [])); + .then(result => setChannels(result.Items || [])) + .catch(() => setChannels([])); } }, [collectionType, parentId, query, serverId]); diff --git a/src/components/search/SearchResults.tsx b/src/components/search/SearchResults.tsx index 731cc6ec35..f8e5a12fbd 100644 --- a/src/components/search/SearchResults.tsx +++ b/src/components/search/SearchResults.tsx @@ -123,38 +123,48 @@ const SearchResults: FunctionComponent = ({ serverId = windo if (!collectionType || isMovies(collectionType)) { // Movies row fetchItems(apiClient, { IncludeItemTypes: 'Movie' }) - .then(result => setMovies(result.Items)); + .then(result => setMovies(result.Items)) + .catch(() => setMovies([])); } // TV Show libraries if (!collectionType || isTVShows(collectionType)) { // Shows row fetchItems(apiClient, { IncludeItemTypes: 'Series' }) - .then(result => setShows(result.Items)); + .then(result => setShows(result.Items)) + .catch(() => setShows([])); // Episodes row fetchItems(apiClient, { IncludeItemTypes: 'Episode' }) - .then(result => setEpisodes(result.Items)); + .then(result => setEpisodes(result.Items)) + .catch(() => setEpisodes([])); } // People are included for Movies and TV Shows if (!collectionType || isMovies(collectionType) || isTVShows(collectionType)) { // People row - fetchPeople(apiClient).then(result => setPeople(result.Items)); + fetchPeople(apiClient) + .then(result => setPeople(result.Items)) + .catch(() => setPeople([])); } // Music libraries if (!collectionType || isMusic(collectionType)) { // Playlists row fetchItems(apiClient, { IncludeItemTypes: 'Playlist' }) - .then(results => setPlaylists(results.Items)); + .then(results => setPlaylists(results.Items)) + .catch(() => setPlaylists([])); // Artists row - fetchArtists(apiClient).then(result => setArtists(result.Items)); + fetchArtists(apiClient) + .then(result => setArtists(result.Items)) + .catch(() => setArtists([])); // Albums row fetchItems(apiClient, { IncludeItemTypes: 'MusicAlbum' }) - .then(result => setAlbums(result.Items)); + .then(result => setAlbums(result.Items)) + .catch(() => setAlbums([])); // Songs row fetchItems(apiClient, { IncludeItemTypes: 'Audio' }) - .then(result => setSongs(result.Items)); + .then(result => setSongs(result.Items)) + .catch(() => setSongs([])); } // Other libraries do not support in-library search currently @@ -163,28 +173,37 @@ const SearchResults: FunctionComponent = ({ serverId = windo fetchItems(apiClient, { MediaTypes: 'Video', ExcludeItemTypes: 'Movie,Episode,TvChannel' - }).then(result => setVideos(result.Items)); + }) + .then(result => setVideos(result.Items)) + .catch(() => setVideos([])); // Programs row fetchItems(apiClient, { IncludeItemTypes: 'LiveTvProgram' }) - .then(result => setPrograms(result.Items)); + .then(result => setPrograms(result.Items)) + .catch(() => setPrograms([])); // Channels row fetchItems(apiClient, { IncludeItemTypes: 'TvChannel' }) - .then(result => setChannels(result.Items)); + .then(result => setChannels(result.Items)) + .catch(() => setChannels([])); // Photo Albums row fetchItems(apiClient, { IncludeItemTypes: 'PhotoAlbum' }) - .then(result => setPhotoAlbums(result.Items)); + .then(result => setPhotoAlbums(result.Items)) + .catch(() => setPhotoAlbums([])); // Photos row fetchItems(apiClient, { IncludeItemTypes: 'Photo' }) - .then(result => setPhotos(result.Items)); + .then(result => setPhotos(result.Items)) + .catch(() => setPhotos([])); // Audio Books row fetchItems(apiClient, { IncludeItemTypes: 'AudioBook' }) - .then(result => setAudioBooks(result.Items)); + .then(result => setAudioBooks(result.Items)) + .catch(() => setAudioBooks([])); // Books row fetchItems(apiClient, { IncludeItemTypes: 'Book' }) - .then(result => setBooks(result.Items)); + .then(result => setBooks(result.Items)) + .catch(() => setBooks([])); // Collections row fetchItems(apiClient, { IncludeItemTypes: 'BoxSet' }) - .then(result => setCollections(result.Items)); + .then(result => setCollections(result.Items)) + .catch(() => setCollections([])); } }, [collectionType, fetchArtists, fetchItems, fetchPeople, query, serverId]); diff --git a/src/components/search/SearchSuggestions.tsx b/src/components/search/SearchSuggestions.tsx index 8d07d95da8..aefb831fe0 100644 --- a/src/components/search/SearchSuggestions.tsx +++ b/src/components/search/SearchSuggestions.tsx @@ -45,7 +45,11 @@ const SearchSuggestions: FunctionComponent = ({ parentId parentId: parentId || undefined, enableTotalRecordCount: false }) - .then(result => setSuggestions(result.data.Items || [])); + .then(result => setSuggestions(result.data.Items || [])) + .catch(err => { + console.error('[SearchSuggestions] failed to fetch search suggestions', err); + setSuggestions([]); + }); } }, [ api, parentId, user ]); diff --git a/src/elements/emby-button/LinkButton.tsx b/src/elements/emby-button/LinkButton.tsx index dceeac7b99..af2e5aa1d3 100644 --- a/src/elements/emby-button/LinkButton.tsx +++ b/src/elements/emby-button/LinkButton.tsx @@ -33,7 +33,10 @@ const LinkButton: React.FC = ({ } } else { e.preventDefault(); - appRouter.show(url); + appRouter.show(url) + .catch(err => { + console.error('[LinkButton] failed to show url', url, err); + }); } } else { e.preventDefault(); diff --git a/src/utils/dashboard.js b/src/utils/dashboard.js index a126aa1a58..8ceb81229f 100644 --- a/src/utils/dashboard.js +++ b/src/utils/dashboard.js @@ -107,6 +107,12 @@ export function getConfigurationResourceUrl(name) { }); } +/** + * Navigate to a url. + * @param {string} url - The url to navigate to. + * @param {boolean} [preserveQueryString] - A flag to indicate the current query string should be appended to the new url. + * @returns {Promise} + */ export function navigate(url, preserveQueryString) { if (!url) { throw new Error('url cannot be null or empty'); From 4a72d84a46cc0398b033ba1399241b9cf00b14b4 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 4 May 2023 16:04:09 -0400 Subject: [PATCH 082/112] Change promise lint rules to error in ts and warn in js --- .eslintrc.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index aad915afde..c089d3ac0e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -245,7 +245,7 @@ module.exports = { 'Windows': 'readonly' }, rules: { - '@typescript-eslint/no-floating-promises': ['error'] + '@typescript-eslint/no-floating-promises': ['warn'] } }, // TypeScript source files @@ -264,6 +264,8 @@ module.exports = { 'plugin:jsx-a11y/recommended' ], rules: { + '@typescript-eslint/no-floating-promises': ['error'], + 'sonarjs/cognitive-complexity': ['error'] } } From bdf28b89fc9b1642cdbd30c7e7ecc1de65b76422 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 4 May 2023 16:05:02 -0400 Subject: [PATCH 083/112] Disable the ignored return error in support check --- src/scripts/datetime.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scripts/datetime.js b/src/scripts/datetime.js index a6c677e2f6..3903b58638 100644 --- a/src/scripts/datetime.js +++ b/src/scripts/datetime.js @@ -114,6 +114,7 @@ export function getDisplayRunningTime(ticks) { const toLocaleTimeStringSupportsLocales = function () { try { + // eslint-disable-next-line sonarjs/no-ignored-return new Date().toLocaleTimeString('i'); } catch (e) { return e.name === 'RangeError'; From 30797d60ea702b6992696b961a54fd2e90860ced Mon Sep 17 00:00:00 2001 From: kimpig Date: Fri, 5 May 2023 02:39:34 +0000 Subject: [PATCH 084/112] Translated using Weblate (Korean) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ko/ --- src/strings/ko.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/ko.json b/src/strings/ko.json index 9d4bef151d..0062f4f5aa 100644 --- a/src/strings/ko.json +++ b/src/strings/ko.json @@ -1371,7 +1371,7 @@ "EveryXMinutes": "매 {0} 분마다", "OnWakeFromSleep": "잠에서 깨어날 때", "DailyAt": "매일 {0}", - "LastSeen": "마지막으로 본 {0}", + "LastSeen": "마지막 접속 {0}", "ListPaging": "{0}-{1} 의 {2}", "WriteAccessRequired": "Jellyfin에 이 폴더에 대한 쓰기 권한이 필요합니다. 쓰기 권한을 확인하고 다시 시도하십시오.", "PathNotFound": "경로를 찾을 수 없습니다. 경로가 유효한지 확인하고 다시 시도하십시오.", From f8f2477e762398cb1b4bb86959fd296381c1e253 Mon Sep 17 00:00:00 2001 From: diahyc Date: Fri, 5 May 2023 03:41:21 +0000 Subject: [PATCH 085/112] Translated using Weblate (Chinese (Traditional, Hong Kong)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hant_HK/ --- src/strings/zh-hk.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/strings/zh-hk.json b/src/strings/zh-hk.json index 0de9722602..b9dc1f5348 100644 --- a/src/strings/zh-hk.json +++ b/src/strings/zh-hk.json @@ -1146,5 +1146,6 @@ "EnableCardLayout": "顯示 visual CardBox", "NewCollectionHelp": "「系列」功能讓你可以自訂電影、劇集和音樂組合,將不同的媒體加至同一個系列中。", "RemoveFromCollection": "從系列中移除", - "MessageNoCollectionsAvailable": "「系列」功能讓你可以自訂電影、劇集和音樂組合,將不同的媒體加至系列/集合中。點撃「+」以新增系列。" + "MessageNoCollectionsAvailable": "「系列」功能讓你可以自訂電影、劇集和音樂組合,將不同的媒體加至系列/集合中。點撃「+」以新增系列。", + "HeaderPerformance": "效能" } From bb40b80a0f0be881ff5185f87db04d319f781a13 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:10 +0000 Subject: [PATCH 086/112] Translated using Weblate (Greek) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/el/ --- src/strings/el.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/strings/el.json b/src/strings/el.json index 5584a0fca2..5c767fb938 100644 --- a/src/strings/el.json +++ b/src/strings/el.json @@ -378,7 +378,7 @@ "LabelBlockContentWithTags": "Αποκλεισμός στοιχείων με ετικέτες", "LabelBurnSubtitles": "Εγγραφή υπότιτλων", "LabelCache": "Προσωρινά αρχεία", - "LabelCachePath": "Διαδρομή προσωρ. αποθ.", + "LabelCachePath": "Διαδρομή προσωρ. αποθ", "LabelCachePathHelp": "Καθορίστε μια προσαρμοσμένη τοποθεσία για τα αρχεία προσωρινής μνήμης του σέρβερ, όπως πχ. εικόνες. Αφήστε το κενό για να χρησιμοποιήσετε την προεπιλογή του διακομιστή.", "LabelCertificatePassword": "Κωδικός πρόσβασης πιστοποιητικού", "LabelCertificatePasswordHelp": "Εάν το πιστοποιητικό σας απαιτεί κωδικό πρόσβασης, πληκτρολογήστε τον εδώ.", @@ -1479,7 +1479,7 @@ "YoutubeBadRequest": "Κακό αίτημα.", "EnableVppTonemapping": "Ενεργοποίηση αντιστοίχισης VPP Tone", "LabelEnableGamepad": "Ενεργοποίηση Gamepad", - "EnableGamepadHelp": "Ακούστε πληροφορίες από τυχόν συνδεδεμένους ελεγκτές.", + "EnableGamepadHelp": "Ακούστε πληροφορίες από τυχόν συνδεδεμένους ελεγκτές", "AudioCodecNotSupported": "Ο κωδικοποιητής ήχου δεν υποστηρίζεται", "AudioChannelsNotSupported": "Ο αριθμός των καναλιών ήχου δεν υποστηρίζεται", "AudioSampleRateNotSupported": "Ο ρυθμός δειγματοληψίας του ήχου δεν υποστηρίζεται", @@ -1687,7 +1687,7 @@ "MediaInfoDoViTitle": "Τίτλος DV", "LabelEnableAudioVbrHelp": "Το μεταβλητό bitrate προσφέρει καλύτερη ποιότητα από τη μέση αναλογία bitrate, αλλά σε μερικές περιστάσεις μπορεί να προκαλέσει προβλήματα φόρτωσης και συμβατότητας.", "LabelDummyChapterDuration": "Διάστημα", - "LabelEnableAudioVbr": "Ενεργοποίηση της VBR κωδικοποίησης ήχων.", + "LabelEnableAudioVbr": "Ενεργοποίηση της VBR κωδικοποίησης ήχων", "LabelParallelImageEncodingLimit": "Όριο παράλληλης κωδικοποίησης εικόνας", "HeaderRecordingMetadataSaving": "Καταγραφή Μεταδεδομένων", "HeaderPerformance": "Επίδοση", From 2518b1aaf413ac819d4c63553b6db30c58777dff Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:22 +0000 Subject: [PATCH 087/112] Translated using Weblate (Spanish (Mexico)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es_MX/ --- src/strings/es-mx.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/es-mx.json b/src/strings/es-mx.json index de4d4f9476..2854d6ec4e 100644 --- a/src/strings/es-mx.json +++ b/src/strings/es-mx.json @@ -1525,7 +1525,7 @@ "SubtitleCodecNotSupported": "El formato de subtitulo no está soportado", "ContainerNotSupported": "El contenedor no está soportado", "AudioCodecNotSupported": "El formato de audio no está soportado", - "EnableGamepadHelp": "Recibir entrada de cualquier control conectado.", + "EnableGamepadHelp": "Recibir entrada de cualquier control conectado", "LabelEnableGamepad": "Habilitar Gamepad", "Controls": "Controles", "UseEpisodeImagesInNextUpHelp": "Las secciones 'Siguiente' y 'Continuar viendo' usarán imágenes de episodios como miniaturas en lugar de la miniatura principal del programa.", From 06c6bc660f20de31acda0fc9cf25283d94abfd01 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:30 +0000 Subject: [PATCH 088/112] Translated using Weblate (Finnish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fi/ --- src/strings/fi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/fi.json b/src/strings/fi.json index 0bb1eebfc5..6f21ff3ff6 100644 --- a/src/strings/fi.json +++ b/src/strings/fi.json @@ -1306,7 +1306,7 @@ "LabelSlowResponseEnabled": "Kirjaa lokimerkintä, jos palvelin vastasi liian hitaasti", "LabelSkipIfGraphicalSubsPresentHelp": "Tekstitysten säilytys tekstimuodossa mahdollistaa sujuvamman mediatoiston ja vähentää transkoodauksen todennäköisyyttä.", "SimultaneousConnectionLimitHelp": "Samanaikaisten suoratoistojen enimmäismäärä. Arvo 0 poistaa rajoituksen käytöstä.", - "EnableGamepadHelp": "Seuraa kytkettyjen ohjainten syötteitä (edellytys: TV-näyttötila).", + "EnableGamepadHelp": "Seuraa kytkettyjen ohjainten syötteitä (edellytys: TV-näyttötila)", "LabelEnableGamepad": "Ota käyttöön peliohjain", "Controls": "Ohjaimet", "AllowVppTonemappingHelp": "Täysi Intel-ajuriin pohjautuva sävykartoitus. Toimii toistaiseksi vain teittyjen laitteiden ja HDR10-videoiden kanssa. Tämä on muihin OpenCL-toteutuksiin verrattuna ensisijainen.", From fd3397f3a79628a211306a748a23a1a961f2c838 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:30:39 +0000 Subject: [PATCH 089/112] Translated using Weblate (French (Canada)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr_CA/ --- src/strings/fr-ca.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/fr-ca.json b/src/strings/fr-ca.json index ee1eeb0147..a62cb9c76f 100644 --- a/src/strings/fr-ca.json +++ b/src/strings/fr-ca.json @@ -1002,7 +1002,7 @@ "LabelMatchType": "Type recherché", "LabelMaxDaysForNextUp": "Nombre de jours maximal dans « À suivre »", "LabelIsForced": "Forcé", - "LabelInNetworkSignInWithEasyPassword": "Activer l'authentification locale avec un code Easy PIN", + "LabelInNetworkSignInWithEasyPassword": "Activer l'authentification locale avec un code Easy PIN", "LabelInternetQuality": "Qualité d'Internet", "LabelKeepUpTo": "Garder jusqu'à", "LabelKidsCategories": "Catégories enfant", From 7777e9a540827e0e78b858b8925c15af6eee3190 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:37 +0000 Subject: [PATCH 090/112] Translated using Weblate (Croatian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/hr/ --- src/strings/hr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/hr.json b/src/strings/hr.json index c65fc1e60b..b2c7cf2e61 100644 --- a/src/strings/hr.json +++ b/src/strings/hr.json @@ -1319,7 +1319,7 @@ "AspectRatioFill": "Ispunite", "Controls": "Kontrole", "LabelEnableGamepad": "Omogući Gamepad", - "EnableGamepadHelp": "Osluškujte unos bilo kojeg povezanog kontrolera.", + "EnableGamepadHelp": "Osluškujte unos bilo kojeg povezanog kontrolera", "AudioCodecNotSupported": "Audio kodek nije podržan", "SecondaryAudioNotSupported": "Sekundarni zvučni zapisi nisu podržani", "RefFramesNotSupported": "Referentni okviri nisu podržani", From 132fb073f09267bc253b9962ced61ec31bb36cf3 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:40 +0000 Subject: [PATCH 091/112] Translated using Weblate (Indonesian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/id/ --- src/strings/id.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/id.json b/src/strings/id.json index fd715406ce..c86d8042bd 100644 --- a/src/strings/id.json +++ b/src/strings/id.json @@ -1157,7 +1157,7 @@ "SubtitleCodecNotSupported": "Kodek subjudul tidak didukung", "ContainerNotSupported": "Kontainer tidak didukung", "AudioCodecNotSupported": "Kodek audio tidak didukung", - "EnableGamepadHelp": "Dengarkan masukan dari pengontrol yang terhubung.", + "EnableGamepadHelp": "Dengarkan masukan dari pengontrol yang terhubung", "LabelEnableGamepad": "Aktifkan Gamepad", "Controls": "Kontrol", "AllowVppTonemappingHelp": "Pemetaan nada berbasis driver Intel penuh. Saat ini hanya berfungsi pada perangkat keras tertentu dengan video HDR10. Ini memiliki prioritas lebih tinggi dibandingkan dengan implementasi OpenCL lainnya.", From ac450ef4ec1842c09e50b1cb2ffe3257ac418ff3 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:44 +0000 Subject: [PATCH 092/112] Translated using Weblate (Italian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/it/ --- src/strings/it.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/it.json b/src/strings/it.json index d3aec5a30d..274a751ad6 100644 --- a/src/strings/it.json +++ b/src/strings/it.json @@ -1705,7 +1705,7 @@ "LabelDummyChapterDuration": "Intervallo", "LabelDummyChapterDurationHelp": "Intervallo in secondi tra le estrazioni delle immagini in capitoli.", "LabelDummyChapterCountHelp": "Numero massimo di capitoli da estrarre per ciascun file.", - "LabelChapterImageResolutionHelp": "Risoluzione delle immagini per l'estrazione", + "LabelChapterImageResolutionHelp": "Risoluzione delle immagini per l'estrazione.", "HeaderDummyChapter": "Immagini Capitolo", "SaveRecordingNFO": "Salva i metadati EPG in NFO", "HeaderRecordingMetadataSaving": "Registrazione Metadati", From 42704035e20e189c61c7d70b68a0394a58ef3c4b Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:52 +0000 Subject: [PATCH 093/112] Translated using Weblate (Kazakh) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/kk/ --- src/strings/kk.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/kk.json b/src/strings/kk.json index 41df607614..d29bf080a8 100644 --- a/src/strings/kk.json +++ b/src/strings/kk.json @@ -1511,7 +1511,7 @@ "Framerate": "Kadr jyld-ğy", "DirectPlayHelp": "Qainar fail osy tūtynğyşpen tolyğymen üilesımdı, al seans osy faildy özgertusız qabyldaidy.", "HeaderContinueReading": "Oqudy jalğastyru", - "EnableGamepadHelp": "Kezkelgen qosylğan kontrolerlerden kırıstı tyñdau.", + "EnableGamepadHelp": "Kezkelgen qosylğan kontrolerlerden kırıstı tyñdau", "LabelEnableGamepad": "Gamepad qosu", "Controls": "Basqaru qūraldar", "TextSent": "Mätın jıberıldı.", From 5913944651dc3cf0fd0605097cc4a9a1e1e4c3e2 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:29:30 +0000 Subject: [PATCH 094/112] Translated using Weblate (Romanian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ro/ --- src/strings/ro.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/strings/ro.json b/src/strings/ro.json index 4546cd5786..f8e70f175a 100644 --- a/src/strings/ro.json +++ b/src/strings/ro.json @@ -868,7 +868,7 @@ "MessageYouHaveVersionInstalled": "În prezent, aveți versiunea {0} instalată.", "MessageUnsetContentHelp": "Conținutul va fi afișat ca foldere simple. Pentru cele mai bune rezultate, utilizați managerul de metadate pentru a seta tipurile de conținut ale sub-foldererelor.", "MessageUnableToConnectToServer": "Nu putem să ne conectăm la serverul selectat în acest moment. Vă rugăm să vă asigurați că funcționează și încercați din nou.", - "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Următoarele locații media vor fi eliminate din biblioteca dvs.", + "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Următoarele locații media vor fi eliminate din biblioteca dvs", "MessageReenableUser": "Consultați mai jos pentru a reactiva", "MessagePluginInstallDisclaimer": "Pluginurile create de membrii comunității sunt o modalitate excelentă de a vă îmbunătăți experiența cu funcții și beneficii suplimentare. Înainte de instalare, vă rugăm să fiți conștienți de efectele pe care le pot avea asupra serverului dvs., cum ar fi scanările de bibliotecă mai îndelungate, procesare suplimentară în fundal și scăderea stabilității sistemului.", "MessagePluginConfigurationRequiresLocalAccess": "Pentru a configura acest plugin, vă rugăm să vă conectați direct la serverul dvs. local.", @@ -1645,7 +1645,7 @@ "SubtitleCodecNotSupported": "Codecul subtitrarii nu este suportat", "ContainerNotSupported": "Containerul nu este suportat", "AudioCodecNotSupported": "Codec audio nu este suportat", - "EnableGamepadHelp": "Ascultați intrarea de la orice controler conectat.", + "EnableGamepadHelp": "Ascultați intrarea de la orice controler conectat", "LabelEnableGamepad": "Activați Gamepad", "Controls": "Controale", "UseEpisodeImagesInNextUpHelp": "Secțiunile „Următorul” și „Continuați vizionarea” vor folosi imagini ale episoadelor ca miniaturi în loc de miniatura principală a emisiunii.", @@ -1682,7 +1682,7 @@ "HeaderDummyChapter": "Imaginile Capitolelor", "HeaderRecordingMetadataSaving": "Înregistrarea Metadatelor", "EnableSplashScreen": "Activează ecranul splash", - "StereoDownmixAlgorithmHelp": "Algoritm utilizat pentru downmix multi-canale audio la stereo", + "StereoDownmixAlgorithmHelp": "Algoritm utilizat pentru downmix multi-canale audio la stereo.", "Short": "Scurt", "MediaInfoDoViTitle": "Titlu DV", "ResolutionMatchSource": "Potrivire Sursa", From 845253ccaf29c9412e62ae5ea17d1b83a0f623a7 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:29:34 +0000 Subject: [PATCH 095/112] Translated using Weblate (Slovenian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sl/ --- src/strings/sl-si.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/strings/sl-si.json b/src/strings/sl-si.json index df5cbf3013..9f423efd23 100644 --- a/src/strings/sl-si.json +++ b/src/strings/sl-si.json @@ -1580,7 +1580,7 @@ "SubtitleCodecNotSupported": "Kodek podnapisa ni podprt", "ContainerNotSupported": "Kontejner ni podprt", "AudioCodecNotSupported": "Zvočni kodek ni podprt", - "EnableGamepadHelp": "Poslušaj vnose iz katerega koli priključenega igralnega ploščka.", + "EnableGamepadHelp": "Poslušaj vnose iz katerega koli priključenega igralnega ploščka", "LabelEnableGamepad": "Omogoči igralni plošček", "Controls": "Nadzor", "HeaderSelectFallbackFontPath": "Izberite pot mape nadomestnih pisav", @@ -1691,7 +1691,7 @@ "SaveRecordingNFO": "Shrani posnete EPG metapodatke v NFO", "SaveRecordingImagesHelp": "Shrani prenešene slike v mapo datoteke.", "PreferEmbeddedExtrasTitlesOverFileNames": "Raje uporabi vdelane naslove kot imena datotek", - "SaveRecordingNFOHelp": "Shrani metapodatke v isto mapo", + "SaveRecordingNFOHelp": "Shrani metapodatke v isto mapo.", "LabelDummyChapterDuration": "interval", "LabelDummyChapterDurationHelp": "Interval ekstrakcije slike poglavja v sekundah.", "LabelDummyChapterCount": "Limit", From f9e22b0d0610fdbe1e1afeb9c7790523ea9c2178 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:29:46 +0000 Subject: [PATCH 096/112] Translated using Weblate (Turkish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/tr/ --- src/strings/tr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/tr.json b/src/strings/tr.json index b390e48824..cf91a1e594 100644 --- a/src/strings/tr.json +++ b/src/strings/tr.json @@ -1510,7 +1510,7 @@ "MessageSyncPlayPlaybackPermissionRequired": "Oynatma izni gerekiyor.", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Aşağıdaki medya konumları kitaplığınızdan kaldırılacak", "MessageSyncPlayCreateGroupDenied": "Grup oluşturmak için izin gerekiyor.", - "EnableGamepadHelp": "Bağlı herhangi bir kontrolcüden gelen girişi dinleyin.", + "EnableGamepadHelp": "Bağlı herhangi bir kontrolcüden gelen girişi dinleyin", "MessagePluginInstalled": "Eklenti başarıyla kuruldu. Değişikliklerin etkili olması için sunucunun yeniden başlatılması gerekecek.", "MessagePluginConfigurationRequiresLocalAccess": "Bu eklentiyi kurmak için lütfen doğrudan yerel sunucunuzda oturum açın.", "MessageNoPluginsInstalled": "Yüklü hiçbir eklentiniz yok.", From 2935297ba6ddd13301b08a5f2dbb76d50a5f38f7 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:33:49 +0000 Subject: [PATCH 097/112] Translated using Weblate (Chinese (Traditional, Hong Kong)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hant_HK/ --- src/strings/zh-hk.json | 510 ++++++++++++++++++++--------------------- 1 file changed, 255 insertions(+), 255 deletions(-) diff --git a/src/strings/zh-hk.json b/src/strings/zh-hk.json index b9dc1f5348..a0324a65d4 100644 --- a/src/strings/zh-hk.json +++ b/src/strings/zh-hk.json @@ -52,21 +52,21 @@ "HeaderUsers": "使用者", "HeaderVideos": "影片", "Help": "幫助", - "LabelAirsAfterSeason": "已播放劇集季度:", - "LabelAirsBeforeSeason": "尚未播放劇集季度:", - "LabelArtists": "藝人:", + "LabelAirsAfterSeason": "已播放劇集季度", + "LabelAirsBeforeSeason": "尚未播放劇集季度", + "LabelArtists": "藝人", "LabelArtistsHelp": "將多位藝人以「;」分隔。", - "LabelAudioLanguagePreference": "首選音訊語言:", - "LabelCache": "緩存:", - "LabelCachePath": "緩存路徑:", + "LabelAudioLanguagePreference": "首選音訊語言", + "LabelCache": "緩存", + "LabelCachePath": "緩存路徑", "LabelCachePathHelp": "選擇指定所需的緩存文件路徑;如圖像。保留空白以使用默認設定。", - "LabelCommunityRating": "討論區評分:", - "LabelContentType": "內容類型:", - "LabelCountry": "國家/地區:", - "LabelCurrentPassword": "目前密碼:", - "LabelCustomCss": "自訂 CSS:", + "LabelCommunityRating": "討論區評分", + "LabelContentType": "內容類型", + "LabelCountry": "國家/地區", + "LabelCurrentPassword": "目前密碼", + "LabelCustomCss": "自訂 CSS", "LabelCustomCssHelp": "於網頁介面套用您的自訂 CSS。", - "LabelDay": "星期:", + "LabelDay": "星期", "LabelDisplaySpecialsWithinSeasons": "顯示劇集季度中的特集", "LabelEnableAutomaticPortMap": "啟用自動連接埠映射", "LabelEnableAutomaticPortMapHelp": "自動嘗試映射公共連接埠到 UPnP 本地連接埠。這可能不適用於某些路由器型號或網路設定。在伺服器重新啟動後才會進行更改。", @@ -78,61 +78,61 @@ "LabelEnableDlnaPlayToHelp": "在網絡內檢測裝置並遠程控制它們。", "LabelEnableRealtimeMonitor": "啟用實時監控", "LabelEnableRealtimeMonitorHelp": "檔案的更改將在支援的檔案系統上立即處理。", - "LabelEvent": "事件:", - "LabelEveryXMinutes": "每:", + "LabelEvent": "事件", + "LabelEveryXMinutes": "每", "LabelFailed": "失敗", "LabelFinish": "完成", "LabelServerNameHelp": "名稱將作為伺服器名稱,預設是伺服器的主機名稱。", - "LabelHttpsPort": "本地 HTTPS 連接埠號碼:", + "LabelHttpsPort": "本地 HTTPS 連接埠號碼", "LabelHttpsPortHelp": "HTTPS 伺服器的 TCP 埠。", "LabelImageFetchersHelp": "啟用媒體圖片獲取來源的優先次序。", - "LabelLanguage": "語言:", - "LabelLocalHttpServerPortNumber": "本地 HTTP 連接埠:", + "LabelLanguage": "語言", + "LabelLocalHttpServerPortNumber": "本地 HTTP 連接埠", "LabelLocalHttpServerPortNumberHelp": "HTTP 伺服器的 TCP 埠。", - "LabelLoginDisclaimer": "登入免責事項:", + "LabelLoginDisclaimer": "登入免責事項", "LabelLoginDisclaimerHelp": "顯示在登入頁面底部的訊息。", - "LabelLogs": "日誌:", - "LabelMaxBackdropsPerItem": "每個背景項目的最大數目:", - "LabelMaxParentalRating": "最大允許的家長評級:", - "LabelMaxResumePercentage": "最大恢復播放百分比:", + "LabelLogs": "日誌", + "LabelMaxBackdropsPerItem": "每個背景項目的最大數目", + "LabelMaxParentalRating": "最大允許的家長評級", + "LabelMaxResumePercentage": "最大恢復播放百分比", "LabelMaxResumePercentageHelp": "媒體如果在這個時間之後停止,會被認定為已播放。", "LabelMaxScreenshotsPerItem": "每件截圖物品的最大數量:", - "LabelMetadata": "資料屬性:", - "LabelMetadataDownloadLanguage": "偏好下載語言:", + "LabelMetadata": "資料屬性", + "LabelMetadataDownloadLanguage": "偏好下載語言", "LabelMetadataDownloadersHelp": "啟用媒體屬性下載器的優先次序,愈下次序只會用來填補缺少的信息。", - "LabelMetadataPath": "媒體資料屬性路徑:", + "LabelMetadataPath": "媒體資料屬性路徑", "LabelMetadataPathHelp": "選擇藝術作品和媒體資料屬性下載的自定位置。", - "LabelMetadataReaders": "資料屬性閱讀器:", + "LabelMetadataReaders": "資料屬性閱讀器", "LabelMetadataReadersHelp": "優先排序您的首選資料屬性來源。首個找到的文件將被讀取。", - "LabelMinBackdropDownloadWidth": "最小下載背景寬度:", - "LabelMinResumeDuration": "最少恢復播放時間:", + "LabelMinBackdropDownloadWidth": "最小下載背景寬度", + "LabelMinResumeDuration": "最少恢復播放時間", "LabelMinResumeDurationHelp": "以秒為單位的最短影片長度,它將保存播放位置並讓您繼續播放。", - "LabelMinResumePercentage": "最少恢復播放百分比:", + "LabelMinResumePercentage": "最少恢復播放百分比", "LabelMinResumePercentageHelp": "媒體如果在這個時間之前停止,會被認定為未播放。", "LabelMinScreenshotDownloadWidth": "最小下載截圖寬度:", - "LabelName": "名稱:", - "LabelNewPassword": "新密碼:", - "LabelNewPasswordConfirm": "新密碼確認:", - "LabelNumberOfGuideDays": "下載電視指南日數:", + "LabelName": "名稱", + "LabelNewPassword": "新密碼", + "LabelNewPasswordConfirm": "新密碼確認", + "LabelNumberOfGuideDays": "下載電視指南日數", "LabelNumberOfGuideDaysHelp": "下載更多電視指南資料會提供更詳細時間表,但將需要更長的下載時間。選擇自動將會基於頻道數目來設定。", - "LabelPassword": "密碼:", + "LabelPassword": "密碼", "LabelPath": "路徑", - "LabelPreferredDisplayLanguage": "首選語言:", - "LabelPublicHttpPort": "公開 HTTP 連接埠:", + "LabelPreferredDisplayLanguage": "首選語言", + "LabelPublicHttpPort": "公開 HTTP 連接埠", "LabelPublicHttpPortHelp": "公共連接埠應映射到本地 HTTP 連接埠。", - "LabelPublicHttpsPort": "公共 HTTPS 連接埠:", + "LabelPublicHttpsPort": "公共 HTTPS 連接埠", "LabelPublicHttpsPortHelp": "公共連接埠應映射到本地 HTTPS 連接埠。", "LabelSaveLocalMetadata": "儲存媒體圖片和資料屬性到媒體所屬的文件夾", "LabelSaveLocalMetadataHelp": "直接儲存媒體圖片和資料到媒體文件夾,讓編輯工作更容易。", - "LabelSelectUsers": "選擇使用者:", + "LabelSelectUsers": "選擇使用者", "LabelSkipIfAudioTrackPresentHelp": "取消此項,無論音訊語言是否一致,所有影片都會確保下載字幕。", "LabelSkipIfGraphicalSubsPresentHelp": "保留文字版本的字幕會更有效率傳遞,減低影片轉碼的機會。", - "LabelStatus": "狀態:", - "LabelTime": "時間:", - "LabelTimeLimitHours": "時間限制(小時):", + "LabelStatus": "狀態", + "LabelTime": "時間", + "LabelTimeLimitHours": "時間限制(小時)", "LabelTranscodingTempPathHelp": "指定轉檔後的儲存路徑,留空將使用預設值。", - "LabelTriggerType": "觸發類別:", - "LabelUser": "使用者:", + "LabelTriggerType": "觸發類別", + "LabelUser": "使用者", "LabelVersionInstalled": "已安裝 {0}", "LabelYoureDone": "大功告成!", "LibraryAccessHelp": "選擇與此用戶共享媒體庫。管理員將能夠使用媒體資料瀏覽器以編輯所有文件夾。", @@ -484,108 +484,108 @@ "LastSeen": "上次觀看 {0}", "Large": "大", "LanNetworksHelp": "在強制頻寬限制時,認作本地網路上的 IP 位址或 IP/子網域遮罩項目的逗號分隔清單。若設置此項,所有其它 IP 位址將被視作在外部網路上,並且將受到外部頻寬限制。如果保留為空,則只將伺服器的子網域遮罩作本地網路。", - "LabelZipCode": "郵遞編號:", - "LabelYear": "年:", + "LabelZipCode": "郵遞編號", + "LabelYear": "年", "LabelXDlnaDocHelp": "決定在 'urn:schemas-dlna-org:device-1-0' namespace 中 'X-Dlna doc' 的內容。", - "LabelXDlnaDoc": "裝置 Class ID:", + "LabelXDlnaDoc": "裝置 Class ID", "LabelXDlnaCapHelp": "決定在 'urn:schemas-dlna-org:device-1-0' namespace 中 'X_DLNACAP' 的內容。", - "LabelXDlnaCap": "X-DLNA Capability ID:", - "LabelWeb": "網站:", - "LabelVideoResolution": "影片解像度:", - "LabelVideoRange": "動態範圍:", - "LabelVideoCodec": "影片編碼:", - "LabelVideoBitrate": "影片位元率:", - "LabelVersion": "版本:", - "LabelValue": "數值:", + "LabelXDlnaCap": "", + "LabelWeb": "網站", + "LabelVideoResolution": "影片解像度", + "LabelVideoRange": "動態範圍", + "LabelVideoCodec": "影片編碼", + "LabelVideoBitrate": "影片位元率", + "LabelVersion": "版本", + "LabelValue": "數值", "LabelVaapiDeviceHelp": "此渲染節點用來硬體加速。", - "LabelVaapiDevice": "VA-API 裝置:", + "LabelVaapiDevice": "VA-API 裝置", "LabelUserRemoteClientBitrateLimitHelp": "覆蓋伺服器設置的預設數值(控制台>播放>串流)。", - "LabelUsername": "使用者名稱:", - "LabelUserMaxActiveSessions": "最多同時工作階段數:", - "LabelUserLoginAttemptsBeforeLockout": "用戶登入失敗次數上限:", + "LabelUsername": "使用者名稱", + "LabelUserMaxActiveSessions": "最多同時工作階段數", + "LabelUserLoginAttemptsBeforeLockout": "用戶登入失敗次數上限", "LabelUserLibraryHelp": "選擇在裝置上顯示的使用者媒體庫,留空則使用預設設定值。", - "LabelUserLibrary": "使用者程式庫:", - "LabelUserAgent": "使用者代理:", - "LabelUseNotificationServices": "使用以下服務:", + "LabelUserLibrary": "使用者程式庫", + "LabelUserAgent": "使用者代理", + "LabelUseNotificationServices": "使用以下服務", "LabelUnstable": "不穩定", "LabelUDPPortRangeHelp": "進行 UDP 連線時,限制 Jellyfin 可使用的端口範圍。(預設值為 1024 - 65535)。
注意:某些功能需要固定端口,而這些端口可能不在此範圍內。", - "LabelUDPPortRange": "UDP 通訊範圍:", + "LabelUDPPortRange": "UDP 通訊範圍", "LabelTypeText": "文字", - "LabelTypeMetadataDownloaders": "個媒體資料下載器 ({0}):", + "LabelTypeMetadataDownloaders": "個媒體資料下載器 ({0})", "LabelProtocolInfoHelp": "當響應來自裝置的 GetProtocolInfo(獲取協議訊息)請求時,該值將被使用。", - "LabelProtocolInfo": "協議資訊:", - "LabelProtocol": "協議:", - "LabelProfileVideoCodecs": "影片編碼:", + "LabelProtocolInfo": "協議資訊", + "LabelProtocol": "協議", + "LabelProfileVideoCodecs": "影片編碼", "LabelProfileContainersHelp": "以逗號分隔,留空則適用於所有影片容器。", "LabelProfileContainer": "影片容器", "LabelProfileCodecsHelp": "以逗號分隔。留空則適用於所有編解碼器。", - "LabelProfileCodecs": "編碼:", - "LabelProfileAudioCodecs": "音訊編碼:", - "LabelPreferredSubtitleLanguage": "字幕語言偏好:", + "LabelProfileCodecs": "編碼", + "LabelProfileAudioCodecs": "音訊編碼", + "LabelPreferredSubtitleLanguage": "字幕語言偏好", "LabelPostProcessorArgumentsHelp": "使用 {path} 作為錄製檔案的路徑。", "LabelPostProcessorArguments": "處理器後命令行參數", "LabelPostProcessor": "後處理應用程式", "LabelPleaseRestart": "改動將在手動重啟用戶端後生效。", - "LabelPlayMethod": "播放方式:", - "LabelPlaylist": "播放清單:", - "LabelPlayerDimensions": "播放器尺寸:", - "LabelPlayer": "播放器:", + "LabelPlayMethod": "播放方式", + "LabelPlaylist": "播放清單", + "LabelPlayerDimensions": "播放器尺寸", + "LabelPlayer": "播放器", "LabelPlayDefaultAudioTrack": "無論如何都播放預設音軌", - "LabelPlaceOfBirth": "出生地:", + "LabelPlaceOfBirth": "出生地", "LabelPersonRoleHelp": "例如:冰淇淋車司機", - "LabelPersonRole": "角色:", - "LabelPasswordResetProvider": "密碼重設提供者:", - "LabelPasswordRecoveryPinCode": "PIN 碼:", - "LabelPasswordConfirm": "確認密碼:", - "LabelParentNumber": "父編號:", - "LabelParentalRating": "家長分級:", - "LabelOverview": "內容概述:", - "LabelOriginalTitle": "原始標題:", - "LabelOriginalAspectRatio": "原始長寬比:", + "LabelPersonRole": "角色", + "LabelPasswordResetProvider": "密碼重設提供者", + "LabelPasswordRecoveryPinCode": "PIN 碼", + "LabelPasswordConfirm": "確認密碼", + "LabelParentNumber": "父編號", + "LabelParentalRating": "家長分級", + "LabelOverview": "內容概述", + "LabelOriginalTitle": "原始標題", + "LabelOriginalAspectRatio": "原始長寬比", "LabelOptionalNetworkPathHelp": "如果這個資料夾在網路上分享,提供網路分享路徑可以供其他應用程式直接存取媒體檔案,例如 {0} 或者 {1}。", - "LabelOptionalNetworkPath": "分享的網路資料夾:", + "LabelOptionalNetworkPath": "分享的網路資料夾", "LabelOpenclDeviceHelp": "此 OpenCL 設備是用於色調映射。點的左側為平台號碼,右側為此平台上的設備號碼。預設值為 0.0。FFmpeg 需要具有 OpenCL 硬體加速功能。", - "LabelOpenclDevice": "OpenCL 裝置:", - "LabelNumber": "編號:", + "LabelOpenclDevice": "OpenCL 裝置", + "LabelNumber": "編號", "LabelNotificationEnabled": "啟用這個通知", - "LabelNewsCategories": "新分類:", - "LabelNewName": "新名稱:", + "LabelNewsCategories": "新分類", + "LabelNewName": "新名稱", "LabelMusicStreamingTranscodingBitrateHelp": "指定音樂串流時的最大位元率。", - "LabelMusicStreamingTranscodingBitrate": "音樂轉檔位元率:", - "LabelMovieRecordingPath": "電影錄製路徑:", + "LabelMusicStreamingTranscodingBitrate": "音樂轉檔位元率", + "LabelMovieRecordingPath": "電影錄製路徑", "LabelMoviePrefixHelp": "若前綴套用到電影標題,請在此處輸入它來方便伺服器能夠正確處理。", - "LabelMoviePrefix": "電影前綴:", - "LabelMovieCategories": "電影分類:", - "LabelMonitorUsers": "監控活動:", - "LabelModelUrl": "型號網址:", - "LabelModelNumber": "型號:", - "LabelModelName": "型號名稱:", - "LabelModelDescription": "型號描述:", + "LabelMoviePrefix": "電影前綴", + "LabelMovieCategories": "電影分類", + "LabelMonitorUsers": "監控活動", + "LabelModelUrl": "型號網址", + "LabelModelNumber": "型號", + "LabelModelName": "型號名稱", + "LabelModelDescription": "型號描述", "LabelMinAudiobookResumeHelp": "將在此時間前停止播放的媒體當作尚未播放。", - "LabelMinAudiobookResume": "恢復播放有聲書的最短時間:", - "LabelMethod": "方法:", + "LabelMinAudiobookResume": "恢復播放有聲書的最短時間", + "LabelMethod": "方法", "LabelMetadataSaversHelp": "選取媒體的中繼資料檔案格式。", - "LabelMetadataSavers": "媒體資料儲存方式:", - "LabelMessageTitle": "訊息標題:", - "LabelMessageText": "訊息文字:", + "LabelMetadataSavers": "媒體資料儲存方式", + "LabelMessageTitle": "訊息標題", + "LabelMessageText": "訊息文字", "LabelMaxStreamingBitrateHelp": "指定最大串流位元率。", - "LabelMaxStreamingBitrate": "最大串流畫質:", + "LabelMaxStreamingBitrate": "最大串流畫質", "LabelMaxMuxingQueueSizeHelp": "等待所有數據初始化時,可用作緩衝的最大封包數量。如果在 FFmpeg 日誌中仍然遇到「Too many packets buffered for output stream」錯誤,請嘗試增加數量。建議值為 2048。", - "LabelMaxMuxingQueueSize": "最大混合器佇列大小:", - "LabelMaxChromecastBitrate": "Google Cast 串流質素:", + "LabelMaxMuxingQueueSize": "最大混合器佇列大小", + "LabelMaxChromecastBitrate": "Google Cast 串流質素", "LabelMaxAudiobookResumeHelp": "將剩下的部分小於此時長後停止播放的媒體當作已播畢。", - "LabelMaxAudiobookResume": "恢復播放有聲書的剩餘時間:", - "LabelMatchType": "匹配的類型:", - "LabelManufacturerUrl": "製造商網址:", - "LabelManufacturer": "製造商:", + "LabelMaxAudiobookResume": "恢復播放有聲書的剩餘時間", + "LabelMatchType": "匹配的類型", + "LabelManufacturerUrl": "製造商網址", + "LabelManufacturer": "製造商", "LabelLockItemToPreventChanges": "鎖定此項目來避免被更改", "LabelLocalCustomCss": "自訂 CSS 樣式僅套用於此客戶端。你或需要停用伺服器自訂 CSS。", - "LabelLineup": "排隊:", + "LabelLineup": "排隊", "LabelLibraryPageSizeHelp": "設置媒體庫頁面每頁要顯示的最多媒體個數。設置為 0 來停用分頁。", - "LabelLibraryPageSize": "媒體庫分頁大小:", - "LabelLanNetworks": "區域網路:", + "LabelLibraryPageSize": "媒體庫分頁大小", + "LabelLanNetworks": "區域網路", "LabelKodiMetadataUserHelp": "儲存觀看資料到 NFO 檔案中以便其他應用程式使用。", - "LabelKodiMetadataUser": "儲存這些使用者的觀看資料到 NFO 檔案中:", + "LabelKodiMetadataUser": "儲存這些使用者的觀看資料到 NFO 檔案中", "LabelKodiMetadataSaveImagePathsHelp": "若如果您的圖片檔案名稱不符合 Kodi 規範,建議啟用。", "LabelKodiMetadataSaveImagePaths": "在 NFO 檔案中儲存圖片路徑", "LabelKodiMetadataEnablePathSubstitutionHelp": "允許將圖片的路徑以伺服器路徑取代。", @@ -593,24 +593,24 @@ "LabelKodiMetadataEnableExtraThumbsHelp": "為了相容 Kodi 主題,下載的圖片將被同時儲存在 extrafanart 和 extrathumbs 資料夾中。", "LabelKodiMetadataEnableExtraThumbs": "複製 extrafanart 到 extrathumbs 欄位", "LabelKodiMetadataDateFormatHelp": "NFO 檔案中的所有日期都將使用此格式。", - "LabelKodiMetadataDateFormat": "釋出日期格式:", - "LabelKnownProxies": "已知 Proxy:", - "LabelKidsCategories": "兒童分類:", - "LabelKeepUpTo": "最新:", + "LabelKodiMetadataDateFormat": "釋出日期格式", + "LabelKnownProxies": "已知 Proxy", + "LabelKidsCategories": "兒童分類", + "LabelKeepUpTo": "最新", "LabelIsForced": "強制", - "LabelInternetQuality": "網路畫質:", + "LabelInternetQuality": "網路畫質", "LabelInNetworkSignInWithEasyPasswordHelp": "你可以在你的家庭網路中使用你的簡易 PIN 登錄 Jellyfin 應用程式,僅在你使用外部網路時才需要輸入密碼,如果 PIN 碼留空,那麼在你的區域網路中便不需輸入密碼。", "LabelInNetworkSignInWithEasyPassword": "啟用以簡易 PIN 進行區域網路登入", "LabelImportOnlyFavoriteChannels": "僅限收藏的頻道", - "LabelImageType": "圖片格式:", + "LabelImageType": "圖片格式", "LabelIdentificationFieldHelp": "不區分大小寫的子字串或正則表達式。", - "LabelIconMaxWidth": "Icon 最寬寬度:", + "LabelIconMaxWidth": "Icon 最寬寬度", "LabelIconMaxResHelp": "透過「upnp:icon」屬性使用的圖示最高解析度。", - "LabelIconMaxHeight": "圖示最高高度:", - "LabelHomeScreenSectionValue": "主畫面模組 {0}:", - "LabelHomeNetworkQuality": "區域網路畫質:", + "LabelIconMaxHeight": "圖示最高高度", + "LabelHomeScreenSectionValue": "主畫面模組 {0}", + "LabelHomeNetworkQuality": "區域網路畫質", "LabelHDHomerunPortRangeHelp": "將 HDHomeRun UDP 端口範圍限制至該值內。(預設值為 1024 - 65535)。", - "LabelHDHomerunPortRange": "HDHomeRun 端口範圍:", + "LabelHDHomerunPortRange": "HDHomeRun 端口範圍", "LabelHardwareEncoding": "硬體加速", "LabelHardwareAccelerationTypeHelp": "硬體加速需要額外的設定。", "LabelHardwareAccelerationType": "硬體加速", @@ -618,21 +618,21 @@ "LabelH264Crf": "H.264 編碼 CRF", "LabelGroupMoviesIntoCollectionsHelp": "顯示電影清單時,屬於相同系列的電影將合併為單一項目顯示。", "LabelGroupMoviesIntoCollections": "按系列將電影分組", - "LabelFriendlyName": "好聽的名字:", - "LabelFormat": "格式:", + "LabelFriendlyName": "好聽的名字", + "LabelFormat": "格式", "LabelForgotPasswordUsernameHelp": "假如您還記得的話,請輸入您的使用者名稱。", - "LabelFont": "字體:", - "LabelFolder": "資料夾:", - "LabelFileOrUrl": "檔案或路徑:", + "LabelFont": "字體", + "LabelFolder": "資料夾", + "LabelFileOrUrl": "檔案或路徑", "LabelffmpegPathHelp": "FFmpeg 的路徑,或是包含 FFmpeg 的資料夾。", - "LabelffmpegPath": "FFmpeg 路徑:", + "LabelffmpegPath": "FFmpeg 路徑", "LabelExtractChaptersDuringLibraryScanHelp": "當媒體庫匯入影片並掃描時,將擷取章節圖片。否則,章節圖片將在之後的計畫任務中擷取,而媒體庫會更快完成掃描。", "LabelExtractChaptersDuringLibraryScan": "於媒體庫掃描時擷取章節圖片", - "LabelEpisodeNumber": "集:", - "LabelEndDate": "結束日期:", - "LabelEncoderPreset": "預設編碼:", + "LabelEpisodeNumber": "集", + "LabelEndDate": "結束日期", + "LabelEncoderPreset": "預設編碼", "LabelEnableSSDPTracingHelp": "將 SSDP 追蹤詳細資料記錄至日誌。
警告:這將導致效能嚴重損失。", - "LabelEnableSSDPTracing": "啟用 SSDP 追蹤:", + "LabelEnableSSDPTracing": "啟用 SSDP 追蹤", "LabelEnableSingleImageInDidlLimitHelp": "若在 DIDL 中嵌入多個圖片,某些裝置可能無法正常顯示。", "LabelEnableSingleImageInDidlLimit": "限制單個嵌入式圖片", "LabelEnableIP6Help": "啟用IPv6功能。", @@ -641,87 +641,87 @@ "LabelEnableIP4": "啟用IPv4", "LabelEnableHttpsHelp": "監聽指定的 HTTPS 埠。須設定有效的證書使其生效。", "LabelEnableHttps": "啟用 HTTPS", - "LabelEnableHardwareDecodingFor": "為以下啟用硬體解碼:", + "LabelEnableHardwareDecodingFor": "為以下啟用硬體解碼", "LabelEnableDlnaServerHelp": "允許網路上的 UPnP 設備瀏覽和播放內容。", "LabelEnableDlnaServer": "啟用 DLNA 伺服器", "LabelEnableBlastAliveMessagesHelp": "若此伺服器無法被其他 UPnP 裝置偵測到,請啟用此選項。", "LabelEnableBlastAliveMessages": "活動訊息", "LabelEmbedAlbumArtDidlHelp": "有些裝置使用這個方式來取得專輯封面,啟用這個選項可能導致其他設備播放失敗。", "LabelEmbedAlbumArtDidl": "於 DIDL 中嵌入專輯封面", - "LabelEasyPinCode": "簡易PIN代碼:", + "LabelEasyPinCode": "簡易PIN代碼", "LabelDynamicExternalId": "{0} Id", "LabelDropSubtitleHere": "將字幕檔拖動到這裡,或點擊瀏覽。", - "LabelDropShadow": "陰影:", - "LabelDroppedFrames": "丟棄的幀:", + "LabelDropShadow": "陰影", + "LabelDroppedFrames": "丟棄的幀", "LabelDropImageHere": "拖移圖片到這裡,或是點擊來選取。", "LabelDownMixAudioScaleHelp": "縮混時增強音訊。其中一個音軌將保持原始音量。", - "LabelDownMixAudioScale": "縮混時的音訊增強:", - "LabelDownloadLanguages": "下載語言:", - "LabelDisplayOrder": "顯示順序:", - "LabelDisplayName": "顯示名稱:", + "LabelDownMixAudioScale": "縮混時的音訊增強", + "LabelDownloadLanguages": "下載語言", + "LabelDisplayOrder": "顯示順序", + "LabelDisplayName": "顯示名稱", "LabelDisplayMode": "顯示模式", "LabelDisplayLanguageHelp": "翻譯 Jellyfin 是個進行中的專案。", - "LabelDisplayLanguage": "顯示語言:", - "LabelDiscNumber": "光碟編號:", + "LabelDisplayLanguage": "顯示語言", + "LabelDiscNumber": "光碟編號", "LabelDisableCustomCss": "停用由伺服器提供的自訂 CSS 代碼。", - "LabelDidlMode": "DIDL 模式:", - "LabelDeviceDescription": "裝置說明:", - "LabelDeinterlaceMethod": "反交錯方法:", + "LabelDidlMode": "DIDL 模式", + "LabelDeviceDescription": "裝置說明", + "LabelDeinterlaceMethod": "反交錯方法", "LabelDefaultUserHelp": "決定哪些使用者媒體庫顯示在已連接裝置上。這可以為每個裝置提供不同的使用者設定檔。", - "LabelDefaultUser": "預設使用者:", - "LabelDefaultScreen": "預設分頁:", - "LabelDeathDate": "死亡日期:", - "LabelDateTimeLocale": "設定時區:", + "LabelDefaultUser": "預設使用者", + "LabelDefaultScreen": "預設分頁", + "LabelDeathDate": "死亡日期", + "LabelDateTimeLocale": "設定時區", "LabelDateAddedBehaviorHelp": "若原本就有中繼資料,將會優先使用。", - "LabelDateAddedBehavior": "新內容加入的日期應使用:", - "LabelDateAdded": "新增日期:", - "LabelDashboardTheme": "控制台佈景主題:", - "LabelCustomRating": "自訂分級:", + "LabelDateAddedBehavior": "新內容加入的日期應使用", + "LabelDateAdded": "新增日期", + "LabelDashboardTheme": "控制台佈景主題", + "LabelCustomRating": "自訂分級", "LabelCustomDeviceDisplayNameHelp": "指定自訂的顯示名稱,或者留空以使用裝置的名稱。", "LabelCustomCertificatePathHelp": "提供包含證書和金鑰的 PKCS #12 文件的路徑以在自訂域名上啟用 TLS。", - "LabelCustomCertificatePath": "自訂 SSL 證書路徑:", - "LabelCurrentStatus": "目前狀態:", - "LabelCriticRating": "評論家評分:", + "LabelCustomCertificatePath": "自訂 SSL 證書路徑", + "LabelCurrentStatus": "目前狀態", + "LabelCriticRating": "評論家評分", "LabelCreateHttpPortMapHelp": "允許自動端口映射,為 HTTP 及 HTTPS 流量建立規則。", "LabelCreateHttpPortMap": "為 HTTP 與 HTTPS 流量啟用自動端口映射。", - "LabelCorruptedFrames": "損壞的幀:", - "LabelColorTransfer": "色彩轉換:", - "LabelColorSpace": "色域:", - "LabelColorPrimaries": "三原色:", + "LabelCorruptedFrames": "損壞的幀", + "LabelColorTransfer": "色彩轉換", + "LabelColorSpace": "色域", + "LabelColorPrimaries": "三原色", "LabelCollection": "系列", "LabelChromecastVersion": "Google Cast 版本", - "LabelChannels": "頻道:", + "LabelChannels": "頻道", "LabelCertificatePasswordHelp": "如果你的證書需要密碼,請在此輸入它。", - "LabelCertificatePassword": "證書密碼:", + "LabelCertificatePassword": "證書密碼", "LabelCancelled": "已取消", - "LabelBurnSubtitles": "燒錄字幕:", - "LabelBlockContentWithTags": "通過標籤鎖定內容:", + "LabelBurnSubtitles": "燒錄字幕", + "LabelBlockContentWithTags": "通過標籤鎖定內容", "LabelBlastMessageIntervalHelp": "決定伺服器活動消息之間的持續時間(秒)。", "LabelBlastMessageInterval": "活動信號的時間間隔", - "LabelBitrate": "位元率:", - "LabelBirthYear": "出生年:", - "LabelBirthDate": "出生日期:", + "LabelBitrate": "位元率", + "LabelBirthYear": "出生年", + "LabelBirthDate": "出生日期", "LabelBindToLocalNetworkAddressHelp": "(選用)覆蓋 HTTP 伺服器綁定的本地 IP 位址。留空則將監聽所有可用的位址。更改此欄位需重啟伺服器。", - "LabelBindToLocalNetworkAddress": "綁定本地網路地址:", + "LabelBindToLocalNetworkAddress": "綁定本地網路地址", "LabelBaseUrlHelp": "您可以在此處自訂伺服器 URL 路徑的子目錄,如:http://example.com/<baseurl>", - "LabelBaseUrl": "根路徑:", + "LabelBaseUrl": "根路徑", "LabelAutomaticDiscoveryHelp": "允許程式通過UDP 7359 連接埠自動偵測Jellyfin 。", "LabelAutomaticDiscovery": "啟動自動探索", - "LabelAutomaticallyRefreshInternetMetadataEvery": "從網路自動抓取中繼資料:", + "LabelAutomaticallyRefreshInternetMetadataEvery": "從網路自動抓取中繼資料", "LabelAutoDiscoveryTracingHelp": "若啟用後,將會記錄自動探索連接埠的封包。", "LabelAutoDiscoveryTracing": "開啟自動追蹤。", - "LabelAuthProvider": "認證提供者:", - "LabelAudioSampleRate": "音訊取樣率:", - "LabelAudioCodec": "音訊編碼:", - "LabelAudioChannels": "音訊聲道:", - "LabelAudioBitrate": "音訊位元率:", - "LabelAudioBitDepth": "音訊位元深度:", + "LabelAuthProvider": "認證提供者", + "LabelAudioSampleRate": "音訊取樣率", + "LabelAudioCodec": "音訊編碼", + "LabelAudioChannels": "音訊聲道", + "LabelAudioBitrate": "音訊位元率", + "LabelAudioBitDepth": "音訊位元深度", "LabelAppNameExample": "例如:689的主機、777的 Jellyfin", "LabelAppName": "APP 名稱", "LabelAllowHWTranscoding": "允許硬體轉檔", - "LabelAllowedRemoteAddressesMode": "遠端 IP 位址過濾模式:", - "LabelAllowedRemoteAddresses": "遠端 IP 位址過濾:", - "LabelAlbumArtPN": "專輯封面 PN :", + "LabelAllowedRemoteAddressesMode": "遠端 IP 位址過濾模式", + "LabelAllowedRemoteAddresses": "遠端 IP 位址過濾", + "LabelAlbumArtPN": "專輯封面 PN", "LabelAlbumArtMaxWidth": "專輯封面最大寬度", "LabelAlbumArtMaxResHelp": "「upnp:albumArtURI」屬性設定專輯封面最高解析度。", "LabelAlbumArtMaxHeight": "專輯封面最大高度", @@ -884,40 +884,40 @@ "HeaderContainerProfile": "影片載體設定", "HeaderConnectToServer": "連接至伺服器", "HeaderConnectionFailure": "連接失敗", - "LabelType": "類型:", - "LabelTVHomeScreen": "電視模式主畫面:", - "LabelTunerType": "調解器類型:", - "LabelTunerIpAddress": "調諧器 IP 位址:", + "LabelType": "類型", + "LabelTVHomeScreen": "電視模式主畫面", + "LabelTunerType": "調解器類型", + "LabelTunerIpAddress": "調諧器 IP 位址", "LabelTranscodingThreadCountHelp": "選擇轉檔時要使用的最大執行緒數,減少執行緒數將降低 CPU 使用率,但轉換速度可能不足以提供流暢的播放體驗。", - "LabelTranscodingThreadCount": "轉檔執行緒數:", - "LabelTranscodingProgress": "轉檔進度:", - "LabelTranscodingFramerate": "轉檔幀率:", - "LabelTranscodes": "轉檔:", - "LabelTranscodePath": "轉檔路徑:", - "LabelTrackNumber": "追蹤編號:", + "LabelTranscodingThreadCount": "轉檔執行緒數", + "LabelTranscodingProgress": "轉檔進度", + "LabelTranscodingFramerate": "轉檔幀率", + "LabelTranscodes": "轉檔", + "LabelTranscodePath": "轉檔路徑", + "LabelTrackNumber": "追蹤編號", "LabelTonemappingThresholdHelp": "色調映射算法會對每個場景進行微調。此參數會被用作判斷畫面有無改變。如果當前的影格/幀的平均亮度及「移動平均值」高於閾值,畫面的峰值亮度及平均值將會被重新計算。建議閾值為0.8(預設:0.2)。", - "LabelTonemappingThreshold": "色調映射閾值:", - "LabelTonemappingRange": "色調映射範圍:", + "LabelTonemappingThreshold": "色調映射閾值", + "LabelTonemappingRange": "色調映射範圍", "LabelTonemappingPeakHelp": "用該值覆蓋信號/標稱/參考峰值。當顯示元數據中嵌入的峰值資訊不可靠時,或從較低範圍到較高範圍的色調映射時,此選項很有用。建議值和預設值分別為 100 和 0。", - "LabelTonemappingPeak": "色調映射峰值:", + "LabelTonemappingPeak": "色調映射峰值", "LabelTonemappingParamHelp": "調整色調映射算法。建議值和預設值均為 NaN。通常將其留空。", - "LabelTonemappingParam": "色調映射參數:", + "LabelTonemappingParam": "色調映射參數", "LabelTonemappingDesatHelp": "降低超過此亮度級別的亮部飽和度。此值越大,將保留更多的顏色資訊。此設置可以平滑地變成白色,從而有助於防止超高亮顯示出不自然的顏色。這使圖像感覺更自然,但以減少超出範圍的顏色的相關資訊為代價。建議值和預設值分別為 0 和 0.5。", - "LabelTonemappingDesat": "色調映射降低飽和度:", - "LabelTonemappingAlgorithm": "選擇要使用的色調映射算法:", - "LabelTitle": "標題:", - "LabelTheme": "主題:", - "LabelTextSize": "文字大小:", - "LabelTextColor": "文字顏色:", - "LabelTextBackgroundColor": "文字背景顏色:", - "LabelTagline": "個性宣言:", - "LabelTag": "標記:", - "LabelSyncPlayTimeSyncOffset": "時間偏移:", - "LabelSyncPlayTimeSyncDevice": "時間與某人同步:", - "LabelSyncPlaySyncMethod": "同步方式:", + "LabelTonemappingDesat": "色調映射降低飽和度", + "LabelTonemappingAlgorithm": "選擇要使用的色調映射算法", + "LabelTitle": "標題", + "LabelTheme": "主題", + "LabelTextSize": "文字大小", + "LabelTextColor": "文字顏色", + "LabelTextBackgroundColor": "文字背景顏色", + "LabelTagline": "個性宣言", + "LabelTag": "標記", + "LabelSyncPlayTimeSyncOffset": "時間偏移", + "LabelSyncPlayTimeSyncDevice": "時間與某人同步", + "LabelSyncPlaySyncMethod": "同步方式", "LabelSyncPlayResumePlaybackDescription": "加入播放群組", "LabelSyncPlayResumePlayback": "繼續本地播放", - "LabelSyncPlayPlaybackDiff": "播放時間差距:", + "LabelSyncPlayPlaybackDiff": "播放時間差距", "LabelSyncPlayNewGroupDescription": "建立新的群組", "LabelSyncPlayNewGroup": "建立群組", "LabelSyncPlayLeaveGroupDescription": "停用SyncPlay", @@ -928,47 +928,47 @@ "LabelSyncPlayAccessJoinGroups": "允許使用者加入群組", "LabelSyncPlayAccessCreateAndJoinGroups": "允許使用者建立與加入群組", "LabelSyncPlayAccess": "SyncPlay 存取控制", - "LabelSupportedMediaTypes": "支援的媒體類型:", - "LabelSubtitleVerticalPosition": "垂直位置:", + "LabelSupportedMediaTypes": "支援的媒體類型", + "LabelSubtitleVerticalPosition": "垂直位置", "LabelSubtitlePlaybackMode": "字幕播放模式", "LabelSubtitleFormatHelp": "如:SRT", - "LabelSubtitleDownloaders": "字幕下載器:", - "LabelStreamType": "串流類型:", - "LabelStopWhenPossible": "當可能時自動停止:", + "LabelSubtitleDownloaders": "字幕下載器", + "LabelStreamType": "串流類型", + "LabelStopWhenPossible": "當可能時自動停止", "LabelStopping": "停止", - "LabelStartWhenPossible": "當可能時自動開始:", + "LabelStartWhenPossible": "當可能時自動開始", "LabelStable": "穩定版", "LabelSSDPTracingFilterHelp": "自選 IP 地址,用於過濾記錄的 SSDP 流量。", - "LabelSSDPTracingFilter": "SSDP 篩選:", - "LabelSportsCategories": "體育分類:", - "LabelSpecialSeasonsDisplayName": "SP 季顯示名稱:", - "LabelSource": "來源:", - "LabelSortTitle": "排序標題:", - "LabelSortOrder": "排列順序:", - "LabelSortBy": "排序按照:", + "LabelSSDPTracingFilter": "SSDP 篩選", + "LabelSportsCategories": "體育分類", + "LabelSpecialSeasonsDisplayName": "SP 季顯示名稱", + "LabelSource": "來源", + "LabelSortTitle": "排序標題", + "LabelSortOrder": "排列順序", + "LabelSortBy": "排序按照", "LabelSonyAggregationFlagsHelp": "決定在「 urn:schemas-dlna-org:device-1-0」namespace 中的「aggregationFlags」元素的內容。", - "LabelSonyAggregationFlags": "Sony 整合標誌:", + "LabelSonyAggregationFlags": "Sony 整合標誌", "LabelSlowResponseTime": "反應緩慢判斷時間(毫秒)", "LabelSlowResponseEnabled": "當回應伺服器過慢時記錄警告訊息", "LabelSkipIfGraphicalSubsPresent": "跳過有內嵌字幕的影片", "LabelSkipIfAudioTrackPresent": "如果預設音軌的語言和下載語言一樣則跳過", - "LabelSkipForwardLength": "快轉長度:", - "LabelSkipBackLength": "跳過長度:", - "LabelSize": "大小:", - "LabelSimultaneousConnectionLimit": "同時串流限制:", - "LabelServerName": "伺服器名稱:", + "LabelSkipForwardLength": "快轉長度", + "LabelSkipBackLength": "跳過長度", + "LabelSize": "大小", + "LabelSimultaneousConnectionLimit": "同時串流限制", + "LabelServerName": "伺服器名稱", "LabelServerHostHelp": "192.168.1.100:8096 或是 https://myserver.com", - "LabelServerHost": "主機:", - "LabelSeriesRecordingPath": "影集錄影路徑:", - "LabelSerialNumber": "序號:", - "LabelSendNotificationToUsers": "傳送通知給:", - "LabelSelectVersionToInstall": "選擇要安裝的版本:", + "LabelServerHost": "主機", + "LabelSeriesRecordingPath": "影集錄影路徑", + "LabelSerialNumber": "序號", + "LabelSendNotificationToUsers": "傳送通知給", + "LabelSelectVersionToInstall": "選擇要安裝的版本", "LabelSelectFolderGroupsHelp": "未選中的資料夾將在其自己的檢視中顯示。", - "LabelSelectFolderGroups": "自動將以下資料夾中的內容分組,例如電影、音樂和電視:", - "LabelSeasonNumber": "季:", - "LabelScreensaver": "螢幕保護程式:", + "LabelSelectFolderGroups": "自動將以下資料夾中的內容分組,例如電影、音樂和電視", + "LabelSeasonNumber": "季", + "LabelScreensaver": "螢幕保護程式", "LabelScheduledTaskLastRan": "最後執行 {0},花費時間 {1}。", - "LabelRuntimeMinutes": "播放時間:", + "LabelRuntimeMinutes": "播放時間", "LabelRequireHttpsHelp": "開啟後伺服器將自動將所有 HTTP 請求導向 HTTPS。若伺服器沒有啟用 HTTPS 則不生效。", "LabelRequireHttps": "強制 HTTPS", "LabelRepositoryUrlHelp": "儲存庫的位置。", @@ -976,16 +976,16 @@ "LabelRepositoryNameHelp": "取一個能讓你辨識的名稱。", "LabelRepositoryName": "儲存庫名稱", "LabelRemoteClientBitrateLimitHelp": "所有網路裝置都能夠調整流位元率限制,這對於防止設備請求比網路連接所能處理的更高的位元率非常有用。這可能會導致伺服器上的 CPU 負載增加,以便將影片轉檔到較低的位元率。", - "LabelRemoteClientBitrateLimit": "網際網路串流傳輸位元率限制(Mbps):", - "LabelReleaseDate": "釋出日期:", - "LabelRefreshMode": "更新模式:", + "LabelRemoteClientBitrateLimit": "網際網路串流傳輸位元率限制(Mbps)", + "LabelReleaseDate": "釋出日期", + "LabelRefreshMode": "更新模式", "LabelRecordingPathHelp": "指定用於存儲轉檔的位置,留空將使用伺服器的程式根目錄。", - "LabelRecordingPath": "預設錄影路徑:", - "LabelRecord": "錄影:", - "LabelReasonForTranscoding": "轉檔原因:", - "LabelQuickConnectCode": "Quick Connect 代號:", + "LabelRecordingPath": "預設錄影路徑", + "LabelRecord": "錄影", + "LabelReasonForTranscoding": "轉檔原因", + "LabelQuickConnectCode": "Quick Connect 代號", "LabelPublishedServerUriHelp": "根據接口或客戶端 IP 位址,覆蓋 Jellyfin 使用的 URI。", - "LabelPublishedServerUri": "公開伺服器 URI:", + "LabelPublishedServerUri": "公開伺服器 URI", "HeaderConfirmRevokeApiKey": "撤銷 API 金鑰", "HeaderConfirmProfileDeletion": "確認刪除個人資料", "HeaderConfirmPluginInstallation": "確認附加元件安裝", @@ -997,7 +997,7 @@ "HeaderCastAndCrew": "演員與工作人員", "HeaderCancelSeries": "取消系列", "HeaderCancelRecording": "取消錄製", - "HeaderBlockItemsWithNoRating": "封鎖沒有評級或設置不允許的內容:", + "HeaderBlockItemsWithNoRating": "封鎖沒有評級或設置不允許的內容", "HeaderAutoDiscovery": "探索網域", "HeaderAudioSettings": "音訊設定", "HeaderAudioBooks": "有聲書", @@ -1060,7 +1060,7 @@ "MarkUnplayed": "標示為未觀看", "MarkPlayed": "標示為已觀看", "ManageRecording": "管理錄影", - "LabelAccessDay": "星期:", + "LabelAccessDay": "星期", "HeaderSyncPlayPlaybackSettings": "播放", "HeaderSyncPlaySettings": "同步播放設定", "ErrorPlayerNotFound": "找不到這個媒體所需的播放器。", @@ -1068,7 +1068,7 @@ "Arranger": "編曲", "LabelAutomaticallyAddToCollectionHelp": "當至少有兩部電影具有相同的系列名稱時,將自動加入到同一系列中。", "LabelAutomaticallyAddToCollection": "自動加入至系列", - "LabelAirsBeforeEpisode": "預告:", + "LabelAirsBeforeEpisode": "預告", "HeaderSyncPlayTimeSyncSettings": "時間同步", "ButtonExitApp": "離開應用程式", "Digital": "數碼", @@ -1080,11 +1080,11 @@ "ButtonClose": "關閉", "ButtonBackspace": "返回", "AddToFavorites": "添加至我的最愛", - "LabelSortName": "排列名稱:", - "LabelOriginalName": "原始名稱:", + "LabelSortName": "排列名稱", + "LabelOriginalName": "原始名稱", "LabelMaxVideoResolution": "轉檔影片的最高解象度", "LabelMaxDaysForNextUpHelp": "設定劇集在未觀看的狀態下,於「按下來」中顯示日數上限。", - "LabelMaxDaysForNextUp": "在「按下來」中顯示日數上限:", + "LabelMaxDaysForNextUp": "在「按下來」中顯示日數上限", "ItemDetails": "項目詳細資料", "GoogleCastUnsupported": "不支援 Google Cast", "EnableRewatchingNextUp": "允許「接下來」顯示重看的影片", @@ -1101,7 +1101,7 @@ "HeaderDummyChapter": "章節圖片", "IgnoreDtsHelp": "禁用此選項或可解決部份問題,如無法正常播放外部音訊。", "DownloadAll": "下載全部", - "LabelDummyChapterDuration": "間距:", + "LabelDummyChapterDuration": "間距", "LabelDummyChapterDurationHelp": "章節圖片擷取間距(秒)。", "DeletedScene": "刪減片段", "EnableSplashScreen": "啟用 「啟動畫面」(Splash Screen)", @@ -1129,14 +1129,14 @@ "MessageSyncPlayJoinGroupDenied": "無法加入群組。", "MessageSyncPlayLibraryAccessDenied": "內容存取受限。", "LabelStereoDownmixAlgorithm": "立體聲混縮算法(Stereo Downmix Algorithm)", - "LabelSyncPlaySettingsExtraTimeOffset": "額外時間修正:", + "LabelSyncPlaySettingsExtraTimeOffset": "額外時間修正", "MessageSyncPlayGroupDoesNotExist": "無法加入不存在的群組。", - "MessageTheFollowingLocationWillBeRemovedFromLibrary": "以下的資料夾路徑將會被移除:", + "MessageTheFollowingLocationWillBeRemovedFromLibrary": "以下的資料夾路徑將會被移除", "MessageUnableToConnectToServer": "無法連接到所選的伺服器,請先檢查伺服器的運作情況。", "MessageUnauthorizedUser": "您目前未被允許連接至伺服器。請聯繫伺服器的管理員查詢。", - "LabelDummyChapterCount": "上限:", + "LabelDummyChapterCount": "上限", "LabelDummyChapterCountHelp": "媒體的章節圖片的擷取數量上限。", - "LabelChapterImageResolution": "解像度:", + "LabelChapterImageResolution": "解像度", "LabelChapterImageResolutionHelp": "章節圖片擷取的解像度。", "HeaderRecordingMetadataSaving": "錄影節目元數據", "UseEpisodeImagesInNextUp": "在「接下來」及「繼續觀看」區中,以相關集數的圖片作顯示", From e89bb3448cde8d5107d861a6ab3f6bfdc4c2f184 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:30:53 +0000 Subject: [PATCH 098/112] Translated using Weblate (Chinese (Traditional)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hant/ --- src/strings/zh-tw.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/strings/zh-tw.json b/src/strings/zh-tw.json index 169a7d7974..3187e7e26c 100644 --- a/src/strings/zh-tw.json +++ b/src/strings/zh-tw.json @@ -401,7 +401,7 @@ "HeaderAddUpdateImage": "新增/更新圖片", "HeaderAlbumArtists": "專輯演出者", "HeaderAlert": "通知", - "HeaderAllowMediaDeletionFrom": "允許從以下位置刪除媒體:", + "HeaderAllowMediaDeletionFrom": "允許從以下位置刪除媒體", "HeaderApiKey": "API 金鑰", "HeaderApiKeys": "API 金鑰", "HeaderApiKeysHelp": "外部應用程式需要有一個 API 金鑰以用於和伺服器溝通。金鑰會在使用者登入時自動發行,也可以手動產生一個金鑰。", @@ -409,7 +409,7 @@ "HeaderAppearsOn": "同時出現於", "HeaderAudioBooks": "有聲書", "HeaderAudioSettings": "音訊設定", - "HeaderBlockItemsWithNoRating": "封鎖沒有評級或設置不允許的內容:", + "HeaderBlockItemsWithNoRating": "封鎖沒有評級或設置不允許的內容", "HeaderBranding": "品牌", "HeaderCancelRecording": "取消錄製", "HeaderCancelSeries": "取消系列", @@ -1611,7 +1611,7 @@ "AudioIsExternal": "外部音訊串流", "LabelVppTonemappingBrightness": "VPP 色調映射亮度增益", "EnableSplashScreen": "啟用啟動畫面", - "LabelVppTonemappingContrastHelp": "在 VPP 色調映射中使用對比度增益。 推薦值和預設值是 1。", + "LabelVppTonemappingContrastHelp": "在 VPP 色調映射中使用對比度增益。 推薦值和預設值是 1。", "Clip": "花絮", "Larger": "較大的", "Sample": "樣本", From 6f57af22404cb9d3d285d2ca16ef95f5b49073f1 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:49 +0000 Subject: [PATCH 099/112] Translated using Weblate (Japanese) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ja/ --- src/strings/ja.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/ja.json b/src/strings/ja.json index acb3a7d78f..2f69db4268 100644 --- a/src/strings/ja.json +++ b/src/strings/ja.json @@ -251,7 +251,7 @@ "HeaderAppearsOn": "表示", "HeaderAudioBooks": "オーディオブック", "HeaderAudioSettings": "音声設定", - "HeaderBlockItemsWithNoRating": "評価情報がない、または認識できないアイテムをブロックします。", + "HeaderBlockItemsWithNoRating": "評価情報がない、または認識できないアイテムをブロックします", "HeaderBranding": "ブランディング", "HeaderCancelRecording": "録画の停止", "HeaderCancelSeries": "シリーズをキャンセル", From 43947204cd5cebc0e3c0fdeb47fda1530f0b4533 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:29:41 +0000 Subject: [PATCH 100/112] Translated using Weblate (Serbian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sr/ --- src/strings/sr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/sr.json b/src/strings/sr.json index 05d6d5d63b..e9bc2945c8 100644 --- a/src/strings/sr.json +++ b/src/strings/sr.json @@ -1598,7 +1598,7 @@ "Typewriter": "Писаћа машина", "TypeOptionPluralVideo": "видео снимци", "TypeOptionPluralMusicAlbum": "Музички албуми", - "EnableGamepadHelp": "Слушајте унос са било ког повезаног контролера.", + "EnableGamepadHelp": "Слушајте унос са било ког повезаног контролера", "AudioBitrateNotSupported": "Брзина у битовима звука није подржана", "VideoFramerateNotSupported": "Брзина кадрова видео снимка није подржана", "AudioProfileNotSupported": "Профил аудио кодека није подржан", From 3250ac78ff3b580dd73c482aa4be26c3ee472a1e Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:58 +0000 Subject: [PATCH 101/112] Translated using Weblate (Marathi) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/mr/ --- src/strings/mr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/mr.json b/src/strings/mr.json index 02a5230106..5572b7bba8 100644 --- a/src/strings/mr.json +++ b/src/strings/mr.json @@ -274,7 +274,7 @@ "AudioBitrateNotSupported": "ऑडियो बिटरेट समर्थित नाही", "VideoCodecNotSupported": "व्हिडियो कोडेक समर्थित नाही", "AudioCodecNotSupported": "ऑडियो कोडेक समर्थित नाही", - "EnableGamepadHelp": "कोणत्याही जोडलेल्या कंट्रोलरपासून इन्पुट येतं का ऐका.", + "EnableGamepadHelp": "कोणत्याही जोडलेल्या कंट्रोलरपासून इन्पुट येतं का ऐका", "ContainerBitrateExceedsLimit": "व्हिडियोचा बिटरेट मर्यादेपेक्षा जास्त आहे", "LabelHardwareEncodingOptions": "हार्डवेअर एन्कोडिंग पर्याय", "Sync": "सिंक", From e4a4583c971d886b506d0d30add1c7ad5a07a747 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:13:08 +0000 Subject: [PATCH 102/112] Translated using Weblate (Urdu (Pakistan)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ur_PK/ --- src/strings/ur_PK.json | 556 ++++++++++++++++++++--------------------- 1 file changed, 278 insertions(+), 278 deletions(-) diff --git a/src/strings/ur_PK.json b/src/strings/ur_PK.json index 6ca45ad344..fb460d55ad 100644 --- a/src/strings/ur_PK.json +++ b/src/strings/ur_PK.json @@ -19,7 +19,7 @@ "ValueSpecialEpisodeName": "خصوصی - {0}", "Sync": "مطابقت پذیری", "Songs": "گانے", - "Shows": "دکھاتا ہے۔", + "Shows": "دکھاتا ہے", "Playlists": "پلے لسٹس", "Photos": "تصاویر", "MusicVideos": "میوزک ویڈیوز", @@ -31,20 +31,20 @@ "AllowedRemoteAddressesHelp": "کوما سے الگ کردہ IP پتوں کی فہرست یا نیٹ ورکس کے لیے IP/netmask اندراجات جنہیں دور سے جڑنے کی اجازت ہوگی۔ اگر خالی چھوڑ دیا جائے تو تمام ریموٹ پتوں کی اجازت ہوگی۔", "AllowFfmpegThrottlingHelp": "جب کوئی ٹرانس کوڈ یا ریمکس موجودہ پلے بیک پوزیشن سے کافی آگے نکل جاتا ہے، تو اس عمل کو روک دیں تاکہ یہ کم وسائل استعمال کرے۔ اکثر تلاش کیے بغیر دیکھتے وقت یہ سب سے زیادہ مفید ہے۔ اگر آپ پلے بیک کے مسائل کا سامنا کرتے ہیں تو اسے آف کریں۔", "AllowHWTranscodingHelp": "ٹیونر کو فلائی پر اسٹریمز کو ٹرانس کوڈ کرنے کی اجازت دیں۔ اس سے سرور کو درکار ٹرانس کوڈنگ کو کم کرنے میں مدد مل سکتی ہے۔", - "AllowMediaConversion": "میڈیا کی تبدیلی کی اجازت دیں۔", + "AllowMediaConversion": "میڈیا کی تبدیلی کی اجازت دیں", "AllowMediaConversionHelp": "کنورٹ میڈیا فیچر تک رسائی فراہم کریں یا انکار کریں۔", "AllowOnTheFlySubtitleExtractionHelp": "ایمبیڈڈ سب ٹائٹلز کو ویڈیوز سے نکالا جا سکتا ہے اور کلائنٹس کو سادہ متن میں پہنچایا جا سکتا ہے، تاکہ ویڈیو ٹرانس کوڈنگ کو روکنے میں مدد مل سکے۔ کچھ سسٹمز پر اس میں لمبا وقت لگ سکتا ہے اور نکالنے کے عمل کے دوران ویڈیو پلے بیک کو روک سکتا ہے۔ اسے غیر فعال کریں تاکہ ایمبیڈڈ سب ٹائٹلز کو ویڈیو ٹرانس کوڈنگ کے ساتھ جلا دیا جائے جب وہ کلائنٹ ڈیوائس کے ذریعہ مقامی طور پر تعاون یافتہ نہ ہوں۔", "AllowTonemappingHelp": "ٹون میپنگ تصویر کی تفصیلات اور رنگوں کو برقرار رکھتے ہوئے ویڈیو کی متحرک رینج کو HDR سے SDR میں تبدیل کر سکتی ہے، جو کہ اصل منظر کی نمائندگی کے لیے بہت اہم معلومات ہیں۔ فی الحال صرف HDR10 یا HLG ویڈیوز کے ساتھ کام کرتا ہے۔ اس کے لیے متعلقہ OpenCL یا CUDA رن ٹائم کی ضرورت ہے۔", "All": "تمام", - "AddToPlayQueue": "نشر کی قطار میں شامل کریں۔", + "AddToPlayQueue": "نشر کی قطار میں شامل کریں", "AirDate": "نشر کی تاریخ", "AllowFfmpegThrottling": "تھروٹل ٹرانس کوڈز", - "AllowRemoteAccess": "اس سرور سے ریموٹ کنکشن کی اجازت دیں۔", - "AddToCollection": "مجموعہ میں شامل کریں۔", + "AllowRemoteAccess": "اس سرور سے ریموٹ کنکشن کی اجازت دیں", + "AddToCollection": "مجموعہ میں شامل کریں", "AllLibraries": "تمام لائبریریاں", - "AllLanguages": "تمام زبانیں۔", - "AddToFavorites": "پسندیدہ میں شامل کریں۔", - "Aired": "نشر کیا گیا۔", + "AllLanguages": "تمام زبانیں", + "AddToFavorites": "پسندیدہ میں شامل کریں", + "Aired": "نشر کیا گیا", "Album": "البم", "AlbumArtist": "البم آرٹسٹ", "AllowRemoteAccessHelp": "اگر غیر نشان زد کیا گیا تو، تمام ریموٹ کنکشن بلاک ہو جائیں گے۔", @@ -52,26 +52,26 @@ "AllEpisodes": "تمام اقساط", "AllChannels": "تمام چینلز", "AnyLanguage": "کوئی بھی زبان", - "AlwaysPlaySubtitles": "ہمیشہ نشر کریں۔", + "AlwaysPlaySubtitles": "ہمیشہ نشر کریں", "AddToPlaylist": "پلے لسٹ میں شامل", "AdditionalNotificationServices": "اضافی اطلاعاتی خدمات کو انسٹال کرنے کے لیے پلگ ان کیٹلاگ کو براؤز کریں۔", - "AllowOnTheFlySubtitleExtraction": "فلائی پر سب ٹائٹل نکالنے کی اجازت دیں۔", + "AllowOnTheFlySubtitleExtraction": "فلائی پر سب ٹائٹل نکالنے کی اجازت دیں", "HeaderPassword": "پاس ورڈ", "LabelSyncPlayAccess": "SyncPlay رسائی", "Disc": "ڈسک", - "EnableQuickConnect": "اس سرور پر فوری کنیکٹ کو فعال کریں۔", + "EnableQuickConnect": "اس سرور پر فوری کنیکٹ کو فعال کریں", "LabelModelName": "ماڈل کا نام", "AroundTime": "تقریباً {0}", "LabelModelNumber": "ماڈل نمبر", "LabelModelDescription": "ماڈل کی تفصیل", "LabelSerialNumber": "سیریل نمبر", - "Unreleased": "ابھی تک جاری نہیں ہوا۔", + "Unreleased": "ابھی تک جاری نہیں ہوا", "AgeValue": "({0} سال پرانا)", "HeaderPlayback": "میڈیا پلے بیک", "HeaderRemoteControl": "ریموٹ کنٹرول", "ApiKeysCaption": "فی الحال فعال API کیز کی فہرست", "Arranger": "بندوبست کرنے والا", - "AsManyAsPossible": "جتنے بھی ہو سکتے ہیں۔", + "AsManyAsPossible": "جتنے بھی ہو سکتے ہیں", "Authorize": "اختیار دینا", "AuthProviderHelp": "اس صارف کے پاس ورڈ کی توثیق کرنے کے لیے ایک تصدیقی فراہم کنندہ کو منتخب کریں۔", "Backdrops": "پس منظر", @@ -80,20 +80,20 @@ "BookLibraryHelp": "آڈیو اور متنی کتابیں معاون ہیں۔ {0} کتاب کے نام کی گائیڈ {1} کا جائزہ لیں۔", "BurnSubtitlesHelp": "اس بات کا تعین کریں کہ کیا ویڈیوز کو ٹرانس کوڈنگ کرتے وقت سرور کو سب ٹائٹلز میں جلنا چاہیے۔ اس سے گریز کرنے سے کارکردگی بہت بہتر ہوگی۔ تصویر پر مبنی فارمیٹس (VobSub، PGS، SUB، IDX، وغیرہ) اور کچھ ASS یا SSA سب ٹائٹلز کو جلانے کے لیے آٹو کو منتخب کریں۔", "ButtonBackspace": "بیک اسپیس", - "ButtonChangeServer": "سرور کو تبدیل کریں۔", + "ButtonChangeServer": "سرور کو تبدیل کریں", "ButtonClose": "بند کریں", "ButtonMore": "مزید", "ButtonOk": "ٹھیک ہے", "ButtonQuickStartGuide": "جلدی شروعات کیلئے رہنمائی", - "ButtonExitApp": "درخواست سے باہر نکلیں۔", + "ButtonExitApp": "درخواست سے باہر نکلیں", "ButtonSpace": "خلا", - "CancelRecording": "ریکارڈنگ منسوخ کریں۔", + "CancelRecording": "ریکارڈنگ منسوخ کریں", "ChannelAccessHelp": "اس صارف کے ساتھ اشتراک کرنے کے لیے چینلز کو منتخب کریں۔ منتظمین میٹا ڈیٹا مینیجر کا استعمال کرتے ہوئے تمام چینلز میں ترمیم کر سکیں گے۔", "ChannelNameOnly": "صرف چینل {0}", "CinemaModeConfigurationHelp": "سینما موڈ مرکزی خصوصیت سے پہلے ٹریلرز اور حسب ضرورت تعارف چلانے کی صلاحیت کے ساتھ تھیٹر کے تجربے کو سیدھے آپ کے کمرے میں لاتا ہے۔", "ColorTransfer": "رنگ کی منتقلی", "Conductor": "موصل", - "ConfigureDateAdded": "سیٹ اپ کریں کہ ڈیش بورڈ > لائبریریز > NFO سیٹنگز میں 'تاریخ شامل کرنے' کے لیے میٹا ڈیٹا کا تعین کیسے کیا جاتا ہے۔", + "ConfigureDateAdded": "سیٹ اپ کریں کہ ڈیش بورڈ > لائبریریز > NFO سیٹنگز میں 'تاریخ شامل کرنے' کے لیے میٹا ڈیٹا کا تعین کیسے کیا جاتا ہے", "ConfirmDeleteItems": "ان آئٹمز کو حذف کرنے سے وہ فائل سسٹم اور آپ کی میڈیا لائبریری دونوں سے حذف ہو جائیں گے۔ کیا آپ واقعی جاری رکھنا چاہتے ہیں؟", "ConfirmEndPlayerSession": "کیا آپ جیلیفن کو {0} کو بند کرنا چاہیں گے؟", "CriticRating": "ناقدین کی درجہ بندی", @@ -107,16 +107,16 @@ "DeviceAccessHelp": "یہ صرف ان آلات پر لاگو ہوتا ہے جن کی منفرد شناخت کی جا سکتی ہے اور وہ براؤزر تک رسائی کو نہیں روکیں گے۔ صارف کے آلے تک رسائی کو فلٹر کرنے سے وہ نئے آلات استعمال کرنے سے روک دے گا جب تک کہ وہ یہاں منظور نہیں ہو جاتے۔", "Digital": "ڈیجیٹل", "DirectPlayHelp": "سورس فائل اس کلائنٹ کے ساتھ مکمل طور پر مطابقت رکھتی ہے، اور سیشن بغیر کسی ترمیم کے فائل وصول کر رہا ہے۔", - "OptionRequirePerfectSubtitleMatch": "صرف ان سب ٹائٹلز کو ڈاؤن لوڈ کریں جو ویڈیو فائلوں کے لیے بہترین ہیں۔", - "QuickConnectDeactivated": "لاگ ان کی درخواست منظور ہونے سے پہلے فوری کنیکٹ کو غیر فعال کر دیا گیا تھا۔", + "OptionRequirePerfectSubtitleMatch": "صرف ان سب ٹائٹلز کو ڈاؤن لوڈ کریں جو ویڈیو فائلوں کے لیے بہترین ہیں", + "QuickConnectDeactivated": "لاگ ان کی درخواست منظور ہونے سے پہلے فوری کنیکٹ کو غیر فعال کر دیا گیا تھا", "DirectStreamHelp1": "ویڈیو سٹریم ڈیوائس کے ساتھ مطابقت رکھتا ہے، لیکن اس میں غیر مطابقت پذیر آڈیو فارمیٹ (DTS، Dolby TrueHD، وغیرہ) یا آڈیو چینلز کی تعداد ہے۔ ڈیوائس پر بھیجے جانے سے پہلے ویڈیو اسٹریم کو بغیر کسی نقصان کے دوبارہ پیک کیا جائے گا۔ صرف آڈیو اسٹریم کو ٹرانس کوڈ کیا جائے گا۔", "EnablePlugin": "فعال", - "DisableCustomCss": "سرور کے فراہم کردہ حسب ضرورت CSS کوڈ کو غیر فعال کریں۔", + "DisableCustomCss": "سرور کے فراہم کردہ حسب ضرورت CSS کوڈ کو غیر فعال کریں", "Disconnect": "منقطع کرنا", "EasyPasswordHelp": "آپ کا آسان پن کوڈ معاون کلائنٹس پر آف لائن رسائی کے لیے استعمال کیا جاتا ہے اور اسے نیٹ ورک میں آسانی سے سائن ان کرنے کے لیے بھی استعمال کیا جا سکتا ہے۔", - "EnableDecodingColorDepth10Vp9": "VP9 کے لیے 10 بٹ ہارڈویئر ڈی کوڈنگ کو فعال کریں۔", - "EnableNextVideoInfoOverlay": "پلے بیک کے دوران اگلی ویڈیو کی معلومات دکھائیں۔", - "EnableRewatchingNextUp": "نیکسٹ اپ میں دوبارہ دیکھنے کو فعال کریں۔", + "EnableDecodingColorDepth10Vp9": "VP9 کے لیے 10 بٹ ہارڈویئر ڈی کوڈنگ کو فعال کریں", + "EnableNextVideoInfoOverlay": "پلے بیک کے دوران اگلی ویڈیو کی معلومات دکھائیں", + "EnableRewatchingNextUp": "نیکسٹ اپ میں دوبارہ دیکھنے کو فعال کریں", "EnableRewatchingNextUpHelp": "'Next Up' سیکشنز میں پہلے سے دیکھے گئے ایپی سوڈز دکھانے کو فعال کریں۔", "EnableThemeVideosHelp": "لائبریری کو براؤز کرتے وقت تھیم ویڈیوز کو پس منظر میں چلائیں۔", "Engineer": "ساؤنڈ انجینئر", @@ -138,15 +138,15 @@ "LabelKidsCategories": "بچوں کے زمرے", "LabelSeasonNumber": "سیزن نمبر", "MediaInfoTitle": "عنوان", - "UnknownAudioStreamInfo": "آڈیو اسٹریم کی معلومات نامعلوم ہے۔", + "UnknownAudioStreamInfo": "آڈیو اسٹریم کی معلومات نامعلوم ہے", "ExtractChapterImagesHelp": "باب کی تصاویر کو نکالنے سے کلائنٹس کو گرافیکل سین سلیکشن مینیو ڈسپلے کرنے کا موقع ملے گا۔ یہ عمل سست ہو سکتا ہے، بہت زیادہ وسائل ہو سکتے ہیں اور اس کے لیے کئی گیگا بائٹس کی جگہ درکار ہو سکتی ہے۔ یہ اس وقت چلتا ہے جب ویڈیوز دریافت ہوتے ہیں، اور رات کے وقت طے شدہ کام کے طور پر بھی۔ شیڈول طے شدہ کاموں کے علاقے میں قابل ترتیب ہے۔ اس کام کو زیادہ سے زیادہ استعمال کے اوقات میں چلانے کی سفارش نہیں کی جاتی ہے۔", "FFmpegSavePathNotFound": "ہم آپ کے داخل کردہ راستے کا استعمال کرتے ہوئے FFmpeg تلاش کرنے سے قاصر ہیں۔ FFprobe بھی ضروری ہے اور اسی فولڈر میں موجود ہونا چاہیے۔ یہ اجزاء عام طور پر ایک ہی ڈاؤن لوڈ میں ایک ساتھ بنڈل ہوتے ہیں۔ براہ کرم راستہ چیک کریں اور دوبارہ کوشش کریں۔", "Friday": "جمعہ", "Fullscreen": "مکمل اسکرین یا بڑی اسکرین", "GoogleCastUnsupported": "Google Cast غیر تعاون یافتہ", - "GroupBySeries": "سیریز کے لحاظ سے گروپ کریں۔", - "GuideProviderSelectListings": "فہرستیں منتخب کریں۔", - "DisablePlugin": "غیر فعال کریں۔", + "GroupBySeries": "سیریز کے لحاظ سے گروپ کریں", + "GuideProviderSelectListings": "فہرستیں منتخب کریں", + "DisablePlugin": "غیر فعال کریں", "H264CrfHelp": "'کنسٹنٹ ریٹ فیکٹر' (CRF) x264 اور x265 انکوڈر کے لیے ڈیفالٹ کوالٹی سیٹنگ ہے۔ آپ 0 اور 51 کے درمیان قدریں سیٹ کر سکتے ہیں، جہاں کم اقدار کے نتیجے میں بہتر معیار ہو گا (اعلی فائل سائز کی قیمت پر)۔ سنے اقدار 18 اور 28 کے درمیان ہیں۔ x264 کے لیے ڈیفالٹ 23 ہے، اور x265 کے لیے 28 ہے، لہذا آپ اسے نقطہ آغاز کے طور پر استعمال کر سکتے ہیں۔", "HardwareAccelerationWarning": "ہارڈویئر ایکسلریشن کو فعال کرنا کچھ ماحول میں عدم استحکام کا سبب بن سکتا ہے۔ یقینی بنائیں کہ آپ کا آپریٹنگ سسٹم اور ویڈیو ڈرائیور مکمل طور پر اپ ٹو ڈیٹ ہیں۔ اگر آپ کو اسے فعال کرنے کے بعد ویڈیو چلانے میں دشواری ہوتی ہے، تو آپ کو سیٹنگ کو واپس کوئی نہیں میں تبدیل کرنا ہوگا۔", "HeaderAddToPlaylist": "پلے لسٹ میں شامل", @@ -155,19 +155,19 @@ "HeaderBlockItemsWithNoRating": "بغیر یا غیر تسلیم شدہ درجہ بندی کی معلومات والے آئٹمز کو مسدود کریں", "HeaderBranding": "برانڈنگ", "HeaderCodecProfileHelp": "کوڈیک پروفائلز مخصوص کوڈیکس چلاتے وقت ڈیوائس کی حدود کی نشاندہی کرتے ہیں۔ اگر کوئی حد لاگو ہوتی ہے تو میڈیا کو ٹرانس کوڈ کیا جائے گا، چاہے کوڈیک براہ راست پلے بیک کے لیے ترتیب دیا گیا ہو۔", - "HeaderConfirmProfileDeletion": "پروفائل ڈیلیٹ کرنے کی تصدیق کریں۔", + "HeaderConfirmProfileDeletion": "پروفائل ڈیلیٹ کرنے کی تصدیق کریں", "HeaderContainerProfile": "کنٹینر پروفائل", "HeaderContainerProfileHelp": "مخصوص فارمیٹس چلاتے وقت کنٹینر پروفائلز ڈیوائس کی حدود کی نشاندہی کرتے ہیں۔ اگر کوئی حد لاگو ہوتی ہے تو میڈیا کو ٹرانس کوڈ کیا جائے گا، چاہے فارمیٹ براہ راست پلے بیک کے لیے ترتیب دیا گیا ہو۔", "HeaderContinueReading": "پڑھنا جاری رکھیے", "HeaderDebugging": "ڈیبگنگ اور ٹریسنگ", - "HeaderDeleteDevice": "ڈیوائس کو حذف کریں۔", - "HeaderDeleteItem": "آئٹم کو حذف کریں۔", + "HeaderDeleteDevice": "ڈیوائس کو حذف کریں", + "HeaderDeleteItem": "آئٹم کو حذف کریں", "HeaderDeviceAccess": "ڈیوائس تک رسائی", "HeaderDirectPlayProfile": "براہ راست پلے بیک پروفائل", "HeaderDirectPlayProfileHelp": "یہ بتانے کے لیے براہ راست پلے بیک پروفائلز شامل کریں کہ ڈیوائس کون سے فارمیٹس کو مقامی طور پر ہینڈل کر سکتی ہے۔", "HeaderDVR": "ڈی وی آر", "HeaderEnabledFieldsHelp": "کسی فیلڈ کو لاک کرنے اور اس کے ڈیٹا کو تبدیل ہونے سے روکنے کے لیے اسے غیر چیک کریں۔", - "HeaderFrequentlyPlayed": "اکثر کھیلا جاتا ہے۔", + "HeaderFrequentlyPlayed": "اکثر کھیلا جاتا ہے", "HeaderIdentificationCriteriaHelp": "کم از کم ایک شناختی معیار درج کریں۔", "HeaderInstantMix": "فوری مکس", "HeaderLibraries": "لائبریریاں", @@ -176,35 +176,35 @@ "HeaderNetworking": "آئی پی پروٹوکولز", "HeaderNewDevices": "نئے آلات", "HeaderNextEpisodePlayingInValue": "اگلی قسط {0} میں چل رہی ہے", - "HeaderPinCodeReset": "آسان پن کوڈ دوبارہ ترتیب دیں۔", + "HeaderPinCodeReset": "آسان پن کوڈ دوبارہ ترتیب دیں", "HeaderPluginInstallation": "پلگ ان کی تنصیب", "HeaderPortRanges": "فائر وال اور پراکسی سیٹنگز", - "HeaderRecentlyPlayed": "حال ہی میں کھیلا گیا۔", - "HeaderRemoveMediaFolder": "میڈیا فولڈر کو ہٹا دیں۔", - "HeaderSelectCertificatePath": "سرٹیفکیٹ کا راستہ منتخب کریں۔", + "HeaderRecentlyPlayed": "حال ہی میں کھیلا گیا", + "HeaderRemoveMediaFolder": "میڈیا فولڈر کو ہٹا دیں", + "HeaderSelectCertificatePath": "سرٹیفکیٹ کا راستہ منتخب کریں", "HeaderXmlSettings": "XML ترتیبات", - "LabelSyncPlayHaltPlayback": "مقامی پلے بیک کو روکیں۔", + "LabelSyncPlayHaltPlayback": "مقامی پلے بیک کو روکیں", "HeaderSelectServerCachePathHelp": "براؤز کریں یا سرور کیش فائلوں کے لیے استعمال کرنے کا راستہ درج کریں۔ فولڈر قابل تحریر ہونا چاہیے۔", - "HeaderStopRecording": "ریکارڈنگ بند کریں۔", + "HeaderStopRecording": "ریکارڈنگ بند کریں", "HeaderSubtitleProfiles": "سب ٹائٹل پروفائلز", "HeaderSyncPlaySettings": "SyncPlay کی ترتیبات", "HeaderSyncPlayPlaybackSettings": "پلے بیک", - "HeaderSyncPlayTimeSyncSettings": "وقت کی مطابقت پذیری۔", + "HeaderSyncPlayTimeSyncSettings": "وقت کی مطابقت پذیری", "HeaderTranscodingProfile": "ٹرانس کوڈنگ پروفائل", "HeaderTranscodingProfileHelp": "ٹرانس کوڈنگ پروفائلز شامل کریں یہ بتانے کے لیے کہ جب ٹرانس کوڈنگ کی ضرورت ہو تو کون سے فارمیٹس استعمال کیے جائیں۔", "HeaderUser": "صارف", "HttpsRequiresCert": "محفوظ کنکشنز کو فعال کرنے کے لیے، آپ کو ایک قابل اعتماد SSL سرٹیفکیٹ فراہم کرنے کی ضرورت ہوگی، جیسے Let's Encrypt۔ براہ کرم یا تو سرٹیفکیٹ فراہم کریں، یا محفوظ کنکشن کو غیر فعال کریں۔", "InstantMix": "فوری مکس", "Items": "اشیاء", - "DoNotRecord": "ریکارڈ نہ کریں۔", + "DoNotRecord": "ریکارڈ نہ کریں", "KnownProxiesHelp": "کوما سے الگ کردہ IP پتوں کی فہرست یا معلوم پراکسیز کے میزبان ناموں کی فہرست جو آپ کے Jellyfin مثال سے منسلک ہوتے وقت استعمال ہوتی ہے۔ یہ 'X-Forwarded-For' ہیڈر کا صحیح استعمال کرنے کے لیے ضروری ہے۔ محفوظ کرنے کے بعد دوبارہ شروع کرنے کی ضرورت ہے۔", "DrmChannelsNotImported": "DRM والے چینلز درآمد نہیں کیے جائیں گے۔", - "EnablePhotos": "تصاویر دکھائیں۔", + "EnablePhotos": "تصاویر دکھائیں", "LabelAlbumArtHelp": "PN البم آرٹ کے لیے استعمال کیا جاتا ہے، 'upnp:albumArtURI' پر 'dlna:profileID' وصف کے اندر۔ تصویر کے سائز سے قطع نظر، کچھ آلات کو ایک مخصوص قدر کی ضرورت ہوتی ہے۔", "LabelAlbumArtists": "البم کے فنکار", "LabelAlbumArtMaxHeight": "البم آرٹ کی زیادہ سے زیادہ اونچائی", "LabelAppNameExample": "مثال: Sickbeard، Sonarr", - "LabelSyncPlayLeaveGroupDescription": "SyncPlay کو غیر فعال کریں۔", + "LabelSyncPlayLeaveGroupDescription": "SyncPlay کو غیر فعال کریں", "LabelBaseUrlHelp": "سرور یو آر ایل میں ایک حسب ضرورت ذیلی ڈائرکٹری شامل کریں۔ مثال کے طور پر: http://example.com/<baseurl>", "LabelBlockContentWithTags": "ٹیگز والے آئٹمز کو مسدود کریں", "LabelCachePathHelp": "سرور کیش فائلوں جیسے امیجز کے لیے حسب ضرورت مقام کی وضاحت کریں۔ سرور ڈیفالٹ استعمال کرنے کے لیے خالی چھوڑ دیں۔", @@ -216,12 +216,12 @@ "LabelDashboardTheme": "سرور ڈیش بورڈ تھیم", "LabelDeathDate": "تاریخ وفات", "HeaderForKids": "بچوں کے لیے", - "ButtonResetEasyPassword": "ایزی پن کوڈ کو دوبارہ ترتیب دیں۔", + "ButtonResetEasyPassword": "ایزی پن کوڈ کو دوبارہ ترتیب دیں", "LabelSyncPlayPlaybackDiff": "پلے بیک وقت کا فرق", "LabelDefaultUserHelp": "اس بات کا تعین کریں کہ کنیکٹڈ ڈیوائسز پر کون سی صارف لائبریری ڈسپلے ہونی چاہیے۔ پروفائلز کا استعمال کرتے ہوئے ہر ڈیوائس کے لیے اسے اوور رائیڈ کیا جا سکتا ہے۔", "LabelDisableCustomCss": "سرور سے فراہم کردہ تھیمنگ/برانڈنگ کے لیے حسب ضرورت CSS کوڈ کو غیر فعال کریں۔", "EnableDisplayMirroring": "آئینہ دار ڈسپلے", - "ExitFullscreen": "پوری اسکرین سے باہر نکلیں۔", + "ExitFullscreen": "پوری اسکرین سے باہر نکلیں", "Favorite": "پسندیدہ", "Features": "خصوصیات", "HeaderEasyPinCode": "آسان پن کوڈ", @@ -244,18 +244,18 @@ "LabelHardwareAccelerationTypeHelp": "ہارڈ ویئر ایکسلریشن کے لیے اضافی کنفیگریشن کی ضرورت ہوتی ہے۔", "LabelHardwareEncoding": "ہارڈ ویئر انکوڈنگ", "ButtonBack": "پیچھے", - "ButtonCancel": "منسوخ کریں۔", + "ButtonCancel": "منسوخ کریں", "HeaderActiveDevices": "فعال آلات", "LabelIconMaxResHelp": "'upnp:icon' پراپرٹی کے ذریعے سامنے آنے والے آئیکنز کی زیادہ سے زیادہ ریزولوشن۔", - "LabelInNetworkSignInWithEasyPassword": "میرے ایزی پن کوڈ کے ساتھ ان نیٹ ورک سائن ان کو فعال کریں۔", - "ButtonRename": "نام تبدیل کریں۔", + "LabelInNetworkSignInWithEasyPassword": "میرے ایزی پن کوڈ کے ساتھ ان نیٹ ورک سائن ان کو فعال کریں", + "ButtonRename": "نام تبدیل کریں", "HeaderAdmin": "انتظامیہ", - "ButtonResume": "دوبارہ شروع کریں۔", + "ButtonResume": "دوبارہ شروع کریں", "HeaderApiKey": "API کلید", "EndsAtValue": "{0} پر ختم ہوتا ہے", - "ButtonSelectView": "منظر کو منتخب کریں۔", + "ButtonSelectView": "منظر کو منتخب کریں", "ButtonSend": "بھیجیں", - "HeaderCancelSeries": "سیریز منسوخ کریں۔", + "HeaderCancelSeries": "سیریز منسوخ کریں", "ButtonShutdown": "شٹ ڈاؤن", "HeaderCastAndCrew": "کاسٹ اور عملہ", "ButtonSignIn": "سائن ان", @@ -263,24 +263,24 @@ "ButtonSignOut": "باہر جائیں", "LabelInternetQuality": "انٹرنیٹ کا معیار", "LabelKeepUpTo": "تک رکھیں", - "LabelKodiMetadataEnablePathSubstitution": "راستے کے متبادل کو فعال کریں۔", + "LabelKodiMetadataEnablePathSubstitution": "راستے کے متبادل کو فعال کریں", "LabelLanguage": "زبان", "LabelLibraryPageSizeHelp": "لائبریری کے صفحے پر دکھانے کے لیے آئٹمز کی مقدار سیٹ کریں۔ صفحہ بندی کو غیر فعال کرنے کے لیے 0 پر سیٹ کریں۔", "LabelMaxDaysForNextUp": "'Next Up' میں زیادہ سے زیادہ دن", "LabelLocalCustomCss": "اسٹائل کے لیے حسب ضرورت CSS کوڈ جو صرف اس کلائنٹ پر لاگو ہوتا ہے۔ آپ سرور کسٹم سی ایس ایس کوڈ کو غیر فعال کرنا چاہتے ہیں۔", - "LabelLockItemToPreventChanges": "مستقبل میں ہونے والی تبدیلیوں کو روکنے کے لیے اس آئٹم کو لاک کریں۔", + "LabelLockItemToPreventChanges": "مستقبل میں ہونے والی تبدیلیوں کو روکنے کے لیے اس آئٹم کو لاک کریں", "LabelManufacturer": "مینوفیکچرر", "LabelMaxChromecastBitrate": "Google Cast سٹریمنگ کا معیار", "LabelMaxMuxingQueueSizeHelp": "پیکٹوں کی زیادہ سے زیادہ تعداد جو تمام اسٹریمز کے شروع ہونے کا انتظار کرتے ہوئے بفر کیے جا سکتے ہیں۔ اسے بڑھانے کی کوشش کریں اگر آپ ابھی بھی FFmpeg لاگز میں \"آؤٹ پٹ اسٹریم کے لیے بہت سارے پیکٹ بفر کیے گئے\" کی غلطی کو پورا کرتے ہیں۔ تجویز کردہ قیمت 2048 ہے۔", "LabelMaxResumePercentageHelp": "اگر اس وقت کے بعد روک دیا جائے تو عنوانات کو مکمل طور پر چلایا جاتا ہے۔", "LabelMessageTitle": "پیغام کا عنوان", "HeaderDateIssued": "تاریخ جاری کردی گئی ہے", - "ButtonUseQuickConnect": "کوئیک کنیکٹ استعمال کریں۔", - "ButtonAddServer": "سرور شامل کریں۔", + "ButtonUseQuickConnect": "کوئیک کنیکٹ استعمال کریں", + "ButtonAddServer": "سرور شامل کریں", "Box": "ڈبہ", - "ButtonAddImage": "تصویر شامل کریں۔", - "ButtonAddScheduledTaskTrigger": "ٹرگر شامل کریں۔", - "HeaderDeleteItems": "آئٹمز کو حذف کریں۔", + "ButtonAddImage": "تصویر شامل کریں", + "ButtonAddScheduledTaskTrigger": "ٹرگر شامل کریں", + "HeaderDeleteItems": "آئٹمز کو حذف کریں", "LabelMetadataDownloadersHelp": "اپنے پسندیدہ میٹا ڈیٹا ڈاؤنلوڈرز کو ترجیحی ترتیب میں فعال اور درجہ دیں۔ کم ترجیحی ڈاؤنلوڈرز کو صرف گمشدہ معلومات کو بھرنے کے لیے استعمال کیا جائے گا۔", "LabelMetadataDownloadLanguage": "ڈاؤن لوڈ کی ترجیحی زبان", "LabelMetadataReadersHelp": "اپنے ترجیحی مقامی میٹا ڈیٹا ذرائع کو ترجیحی ترتیب میں درجہ بندی کریں۔ پہلی فائل جو ملی ہے اسے پڑھ لیا جائے گا۔", @@ -289,9 +289,9 @@ "LabelMovieCategories": "فلم کے زمرے", "LabelMoviePrefixHelp": "اگر فلم کے عنوانات پر کوئی سابقہ لاگو ہوتا ہے تو اسے یہاں درج کریں تاکہ سرور اسے صحیح طریقے سے سنبھال سکے۔", "LabelMovieRecordingPath": "مووی ریکارڈنگ کا راستہ", - "LabelNotificationEnabled": "اس اطلاع کو فعال کریں۔", + "LabelNotificationEnabled": "اس اطلاع کو فعال کریں", "LabelNumber": "نمبر", - "HeaderDeleteTaskTrigger": "ٹاسک ٹرگر کو حذف کریں۔", + "HeaderDeleteTaskTrigger": "ٹاسک ٹرگر کو حذف کریں", "LabelNumberOfGuideDays": "ڈاؤن لوڈ کرنے کے لیے گائیڈ ڈیٹا کے دنوں کی تعداد", "LabelNumberOfGuideDaysHelp": "مزید دنوں کے قابل گائیڈ ڈیٹا کو ڈاؤن لوڈ کرنا پہلے سے مزید شیڈول کرنے اور مزید فہرستیں دیکھنے کی صلاحیت فراہم کرتا ہے، لیکن اسے ڈاؤن لوڈ ہونے میں بھی زیادہ وقت لگے گا۔ چینلز کی تعداد کی بنیاد پر آٹو چنے گا۔", "LabelOpenclDeviceHelp": "یہ اوپن سی ایل ڈیوائس ہے جو ٹون میپنگ کے لیے استعمال ہوتی ہے۔ ڈاٹ کی بائیں طرف پلیٹ فارم نمبر ہے، اور دائیں طرف پلیٹ فارم پر ڈیوائس نمبر ہے۔ پہلے سے طے شدہ قدر 0.0 ہے۔ OpenCL ہارڈویئر ایکسلریشن طریقہ پر مشتمل FFmpeg ایپلیکیشن فائل درکار ہے۔", @@ -302,7 +302,7 @@ "LabelPasswordConfirm": "پاس ورڈ کی تصدیق)", "LabelPlayerDimensions": "کھلاڑی کے طول و عرض", "LabelPlayMethod": "کھیلنے کا طریقہ", - "HeaderDetectMyDevices": "میرے آلات کا پتہ لگائیں۔", + "HeaderDetectMyDevices": "میرے آلات کا پتہ لگائیں", "LabelPostProcessor": "پوسٹ پروسیسنگ درخواست", "LabelProfileCodecs": "کوڈیکس", "LabelProfileCodecsHelp": "کوما سے الگ کیا گیا۔ اسے تمام کوڈیکس پر لاگو کرنے کے لیے خالی چھوڑا جا سکتا ہے۔", @@ -318,23 +318,23 @@ "ClientSettings": "کلائنٹ کی ترتیبات", "ColorSpace": "رنگین جگہ", "DeleteImageConfirmation": "کیا آپ واقعی اس تصویر کو حذف کرنا چاہتے ہیں؟", - "DeleteUser": "صارف کو حذف کریں۔", + "DeleteUser": "صارف کو حذف کریں", "LabelRemoteClientBitrateLimitHelp": "نیٹ ورک کے تمام آلات کے لیے ایک اختیاری فی اسٹریم بٹریٹ کی حد۔ یہ آلات کو آپ کے انٹرنیٹ کنکشن سے زیادہ بٹریٹ کی درخواست کرنے سے روکنے کے لیے مفید ہے۔ اس کے نتیجے میں آپ کے سرور پر سی پی یو کا بوجھ بڑھ سکتا ہے تاکہ پرواز پر ویڈیوز کو کم بٹریٹ پر ٹرانس کوڈ کیا جا سکے۔", "LabelRepositoryUrl": "ذخیرہ URL", "LabelRequireHttpsHelp": "اگر چیک کیا جاتا ہے، تو سرور خود بخود HTTP پر تمام درخواستوں کو HTTPS پر بھیج دے گا۔ اگر سرور HTTPS پر نہیں سن رہا ہے تو اس کا کوئی اثر نہیں ہوگا۔", "LabelSaveLocalMetadataHelp": "آرٹ ورک کو میڈیا فولڈرز میں محفوظ کرنے سے وہ ایسی جگہ پر رکھے جائیں گے جہاں ان میں آسانی سے ترمیم کی جا سکے۔", "LabelSize": "سائز", - "LabelSkipIfAudioTrackPresent": "اگر ڈیفالٹ آڈیو ٹریک ڈاؤن لوڈ کی زبان سے میل کھاتا ہے تو اسے چھوڑ دیں۔", + "LabelSkipIfAudioTrackPresent": "اگر ڈیفالٹ آڈیو ٹریک ڈاؤن لوڈ کی زبان سے میل کھاتا ہے تو اسے چھوڑ دیں", "LabelSkipIfAudioTrackPresentHelp": "آڈیو زبان سے قطع نظر تمام ویڈیوز کے ذیلی عنوانات کو یقینی بنانے کے لیے اس سے نشان ہٹا دیں۔", - "LabelSkipIfGraphicalSubsPresent": "اگر ویڈیو پہلے ہی ایمبیڈڈ سب ٹائٹلز پر مشتمل ہے تو اسے چھوڑ دیں۔", + "LabelSkipIfGraphicalSubsPresent": "اگر ویڈیو پہلے ہی ایمبیڈڈ سب ٹائٹلز پر مشتمل ہے تو اسے چھوڑ دیں", "LabelSkipIfGraphicalSubsPresentHelp": "ذیلی عنوانات کے متنی ورژن رکھنے کے نتیجے میں زیادہ موثر ترسیل ہوگی اور ویڈیو ٹرانس کوڈنگ کے امکانات کم ہوجائیں گے۔", - "LabelSlowResponseEnabled": "اگر سرور جواب دینے میں سست تھا تو انتباہی پیغام کو لاگ کریں۔", + "LabelSlowResponseEnabled": "اگر سرور جواب دینے میں سست تھا تو انتباہی پیغام کو لاگ کریں", "LabelSonyAggregationFlagsHelp": "'urn:schemas-sonycom:av' نام کی جگہ میں 'aggregationFlags' عنصر کے مواد کا تعین کریں۔", "LabelSubtitleDownloaders": "سب ٹائٹل ڈاؤنلوڈرز", "LabelSupportedMediaTypes": "تعاون یافتہ میڈیا کی اقسام", - "LabelSyncPlayAccessJoinGroups": "صارف کو گروپوں میں شامل ہونے کی اجازت دیں۔", - "LabelSyncPlayLeaveGroup": "گروپ چھوڑ دیں۔", - "LabelSyncPlayResumePlayback": "مقامی پلے بیک دوبارہ شروع کریں۔", + "LabelSyncPlayAccessJoinGroups": "صارف کو گروپوں میں شامل ہونے کی اجازت دیں", + "LabelSyncPlayLeaveGroup": "گروپ چھوڑ دیں", + "LabelSyncPlayResumePlayback": "مقامی پلے بیک دوبارہ شروع کریں", "LabelSyncPlayTimeSyncDevice": "وقت کے ساتھ مطابقت پذیری", "LabelSyncPlayTimeSyncOffset": "ٹائم آفسیٹ", "LabelSyncPlaySettingsExtraTimeOffset": "اضافی وقت آفسیٹ", @@ -349,7 +349,7 @@ "LabelSyncPlaySettingsMinDelaySkipToSync": "SkipToSync کم از کم تاخیر", "LabelSyncPlaySettingsMinDelaySkipToSyncHelp": "پلے بیک میں کم از کم تاخیر (ms میں) جس کے بعد SkipToSync پلے بیک پوزیشن کو درست کرنے کی کوشش کرتا ہے۔", "LabelSyncPlaySettingsSpeedToSyncHelp": "مطابقت پذیری کی اصلاح کا طریقہ جو پلے بیک کو تیز کرنے پر مشتمل ہوتا ہے۔ مطابقت پذیری کی اصلاح کا فعال ہونا ضروری ہے۔", - "LabelSyncPlaySettingsSkipToSync": "SkipToSync کو فعال کریں۔", + "LabelSyncPlaySettingsSkipToSync": "SkipToSync کو فعال کریں", "LabelSyncPlaySettingsSkipToSyncHelp": "مطابقت پذیری کی اصلاح کا طریقہ جو تخمینہ شدہ پوزیشن کی تلاش پر مشتمل ہے۔ مطابقت پذیری کی اصلاح کا فعال ہونا ضروری ہے۔", "LabelTextColor": "متن کا رنگ", "LabelTextWeight": "متن کا وزن", @@ -358,7 +358,7 @@ "DeinterlaceMethodHelp": "سافٹ ویئر کو انٹر لیسڈ مواد کو ٹرانس کوڈنگ کرتے وقت استعمال کرنے کے لیے deinterlacing طریقہ منتخب کریں۔ جب ہارڈویئر ایکسلریشن کو سپورٹ کرنے والے ہارڈویئر ڈیانٹرلیسنگ کو فعال کیا جاتا ہے تو اس ترتیب کے بجائے ہارڈویئر ڈیینٹرلیسر استعمال کیا جائے گا۔", "HeaderSendMessage": "پیغام بھیجیں", "LabelXDlnaCapHelp": "'urn:schemas-dlna-org:device-1-0' نام کی جگہ میں 'X_DLNACAP' عنصر کے مواد کا تعین کریں۔", - "HeaderSetupLibrary": "اپنی میڈیا لائبریریاں ترتیب دیں۔", + "HeaderSetupLibrary": "اپنی میڈیا لائبریریاں ترتیب دیں", "HeaderUpcomingOnTV": "ٹی وی پر آنے والا", "HeaderVideoType": "ویڈیو کی قسم", "Help": "مدد", @@ -371,7 +371,7 @@ "LabelDiscNumber": "ڈسک نمبر", "LabelDropShadow": "ڈراپ شیڈو", "LabelEmbedAlbumArtDidlHelp": "کچھ آلات البم آرٹ حاصل کرنے کے لیے اس طریقہ کو ترجیح دیتے ہیں۔ دوسرے اس اختیار کے فعال ہونے کے ساتھ کھیلنے میں ناکام ہو سکتے ہیں۔", - "LabelEnableDlnaPlayTo": "DLNA خصوصیت 'Play To' کو فعال کریں۔", + "LabelEnableDlnaPlayTo": "DLNA خصوصیت 'Play To' کو فعال کریں", "LabelTonemappingDesatHelp": "چمک کی اس سطح سے تجاوز کرنے والی ہائی لائٹس کے لیے ڈی سیچوریشن کا اطلاق کریں۔ پیرامیٹر جتنا زیادہ ہوگا، رنگ کی معلومات اتنی ہی زیادہ محفوظ ہوں گی۔ یہ ترتیب سپر ہائی لائٹس کے لیے غیر فطری طور پر اڑنے والے رنگوں کو روکنے میں مدد کرتی ہے، اس کی بجائے (آسانی سے) سفید میں تبدیل ہو کر۔ یہ تصاویر کو زیادہ قدرتی محسوس کرتا ہے، حد سے باہر رنگوں کے بارے میں معلومات کو کم کرنے کی قیمت پر۔ تجویز کردہ اور طے شدہ اقدار 0 اور 0.5 ہیں۔", "LabelEnableHardwareDecodingFor": "اس کے لیے ہارڈویئر ڈی کوڈنگ کو فعال کریں", "LabelTonemappingParam": "ٹون میپنگ پیرم", @@ -440,13 +440,13 @@ "OptionAllowContentDownloadHelp": "صارفین میڈیا کو ڈاؤن لوڈ کر سکتے ہیں اور اسے اپنے آلات پر اسٹور کر سکتے ہیں۔ یہ مطابقت پذیری کی خصوصیت کی طرح نہیں ہے۔ کتابی لائبریریوں کو مناسب طریقے سے کام کرنے کے لیے اسے فعال کرنے کی ضرورت ہوتی ہے۔", "OptionAllowLinkSharingHelp": "صرف میڈیا کی معلومات پر مشتمل ویب صفحات کا اشتراک کیا جاتا ہے۔ میڈیا فائلوں کو کبھی بھی عوامی طور پر شیئر نہیں کیا جاتا ہے۔ شیئرز کا وقت محدود ہے اور {0} دنوں کے بعد ختم ہو جائے گا۔", "OptionAllowMediaPlaybackTranscodingHelp": "ٹرانس کوڈنگ تک رسائی کو محدود کرنا غیر تعاون یافتہ میڈیا فارمیٹس کی وجہ سے کلائنٹس میں پلے بیک کی ناکامی کا سبب بن سکتا ہے۔", - "OptionAllowRemoteControlOthers": "دوسرے صارفین کے ریموٹ کنٹرول کی اجازت دیں۔", + "OptionAllowRemoteControlOthers": "دوسرے صارفین کے ریموٹ کنٹرول کی اجازت دیں", "LabelMaxBackdropsPerItem": "فی آئٹم بیک ڈراپس کی زیادہ سے زیادہ تعداد", - "OptionAllowVideoPlaybackRemuxing": "ویڈیو پلے بیک کی اجازت دیں جس کو دوبارہ انکوڈنگ کے بغیر تبدیلی کی ضرورت ہے۔", - "OptionDateShowAdded": "تاریخ شو شامل کیا گیا۔", - "OptionDateAddedFileTime": "فائل بنانے کی تاریخ استعمال کریں۔", + "OptionAllowVideoPlaybackRemuxing": "ویڈیو پلے بیک کی اجازت دیں جس کو دوبارہ انکوڈنگ کے بغیر تبدیلی کی ضرورت ہے", + "OptionDateShowAdded": "تاریخ شو شامل کیا گیا", + "OptionDateAddedFileTime": "فائل بنانے کی تاریخ استعمال کریں", "OptionDisableUserHelp": "سرور اس صارف سے کسی بھی کنکشن کی اجازت نہیں دے گا۔ موجودہ رابطے اچانک ختم ہو جائیں گے۔", - "OptionEnableExternalContentInSuggestions": "تجاویز میں بیرونی مواد کو فعال کریں۔", + "OptionEnableExternalContentInSuggestions": "تجاویز میں بیرونی مواد کو فعال کریں", "LabelMaxStreamingBitrate": "زیادہ سے زیادہ سلسلہ بندی کا معیار", "LabelMaxStreamingBitrateHelp": "سلسلہ بندی کرتے وقت زیادہ سے زیادہ بٹ ریٹ کی وضاحت کریں۔", "LabelMessageText": "پیغام کا متن", @@ -468,42 +468,42 @@ "LabelMinAudiobookResumeHelp": "اگر اس وقت سے پہلے روک دیا جائے تو عنوانات کو بغیر کھیلے ہوئے فرض کیا جاتا ہے۔", "PlaybackErrorPlaceHolder": "یہ فزیکل میڈیا کے لیے پلیس ہولڈر ہے جسے جیلیفن نہیں چلا سکتا۔ براہ کرم چلانے کے لیے ڈسک داخل کریں۔", "PlaybackRate": "پلے بیک کی رفتار", - "PlayNextEpisodeAutomatically": "اگلا ایپی سوڈ خود بخود چلائیں۔", + "PlayNextEpisodeAutomatically": "اگلا ایپی سوڈ خود بخود چلائیں", "PleaseAddAtLeastOneFolder": "براہ کرم 'فولڈرز' سیکشن میں '+' بٹن پر کلک کرکے اس لائبریری میں کم از کم ایک فولڈر شامل کریں۔", "PleaseConfirmPluginInstallation": "براہ کرم ٹھیک پر کلک کریں اس بات کی تصدیق کرنے کے لیے کہ آپ نے اوپر پڑھ لیا ہے اور پلگ ان کی تنصیب کے ساتھ آگے بڑھنا چاہتے ہیں۔", "PosterCard": "پوسٹر کارڈ", "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "اگر دستیاب ہو تو ایمبیڈڈ میٹا ڈیٹا سے ایپی سوڈ کی معلومات استعمال کریں۔", "LabelMusicStreamingTranscodingBitrate": "میوزک ٹرانس کوڈنگ بٹ ریٹ", "LabelNewPassword": "نیا پاس ورڈ", - "EnableTonemapping": "ٹون میپنگ کو فعال کریں۔", + "EnableTonemapping": "ٹون میپنگ کو فعال کریں", "PreferEmbeddedTitlesOverFileNamesHelp": "جب کوئی انٹرنیٹ میٹا ڈیٹا یا مقامی میٹا ڈیٹا دستیاب نہ ہو تو استعمال کرنے کے لیے ڈسپلے ٹائٹل کا تعین کریں۔", "AllowEmbeddedSubtitlesHelp": "میڈیا کنٹینرز میں پیک کیے گئے سب ٹائٹلز کو غیر فعال کریں۔ مکمل لائبریری ریفریش کی ضرورت ہے۔", "PluginFromRepo": "{0} مخزن سے {1}", "QuickConnectInvalidCode": "غلط کوئیک کنیکٹ کوڈ", - "QuickConnectNotActive": "Quick Connect اس سرور پر فعال نہیں ہے۔", - "QuickConnectNotAvailable": "اپنے سرور ایڈمنسٹریٹر سے فوری کنیکٹ کو فعال کرنے کے لیے کہیں۔", + "QuickConnectNotActive": "Quick Connect اس سرور پر فعال نہیں ہے", + "QuickConnectNotAvailable": "اپنے سرور ایڈمنسٹریٹر سے فوری کنیکٹ کو فعال کرنے کے لیے کہیں", "RecordingCancelled": "ریکارڈنگ منسوخ کر دی گئی۔", "Recordings": "ریکارڈنگز", "RecordingScheduled": "ریکارڈنگ کا شیڈول۔", "RecordSeries": "ریکارڈ سیریز", "RefreshDialogHelp": "میٹا ڈیٹا کو سیٹنگز اور انٹرنیٹ سروسز کی بنیاد پر ریفریش کیا جاتا ہے جو ڈیش بورڈ میں فعال ہیں۔", "ButtonLibraryAccess": "لائبریری تک رسائی", - "RememberAudioSelections": "پچھلی آئٹم کی بنیاد پر آڈیو ٹریک سیٹ کریں۔", + "RememberAudioSelections": "پچھلی آئٹم کی بنیاد پر آڈیو ٹریک سیٹ کریں", "RememberAudioSelectionsHelp": "آڈیو ٹریک کو آخری ویڈیو کے قریب ترین میچ پر سیٹ کرنے کی کوشش کریں۔", - "RememberSubtitleSelections": "پچھلی آئٹم کی بنیاد پر سب ٹائٹل ٹریک سیٹ کریں۔", + "RememberSubtitleSelections": "پچھلی آئٹم کی بنیاد پر سب ٹائٹل ٹریک سیٹ کریں", "LabelOriginalAspectRatio": "اصل پہلو تناسب", "LabelOverview": "جائزہ", "RememberSubtitleSelectionsHelp": "سب ٹائٹل ٹریک کو آخری ویڈیو کے قریب ترین میچ پر سیٹ کرنے کی کوشش کریں۔", - "RemoveFromCollection": "مجموعہ سے ہٹا دیں۔", + "RemoveFromCollection": "مجموعہ سے ہٹا دیں", "SaveChanges": "تبدیلیاں محفوظ کرو", - "ScanForNewAndUpdatedFiles": "نئی اور اپ ڈیٹ فائلوں کے لیے اسکین کریں۔", + "ScanForNewAndUpdatedFiles": "نئی اور اپ ڈیٹ فائلوں کے لیے اسکین کریں", "ScreenResolution": "سکرین ریزولوشن", - "SearchForMissingMetadata": "گمشدہ میٹا ڈیٹا کی تلاش کریں۔", + "SearchForMissingMetadata": "گمشدہ میٹا ڈیٹا کی تلاش کریں", "SearchResults": "تلاش کے نتائج", "Season": "موسم", "SeriesRecordingScheduled": "سیریز کی ریکارڈنگ شیڈول کی گئی۔", "SettingsWarning": "ان اقدار کو تبدیل کرنے سے عدم استحکام یا کنیکٹیویٹی کی ناکامی ہو سکتی ہے۔ اگر آپ کو کوئی مسئلہ درپیش ہے، تو ہم انہیں واپس ڈیفالٹ میں تبدیل کرنے کی تجویز کرتے ہیں۔", - "ShowTitle": "عنوان دکھائیں۔", + "ShowTitle": "عنوان دکھائیں", "Shuffle": "شفل", "SimultaneousConnectionLimitHelp": "ایک ساتھ چلنے والے اسٹریمز کی زیادہ سے زیادہ تعداد۔ بغیر کسی حد کے 0 درج کریں۔", "SkipEpisodesAlreadyInMyLibraryHelp": "ایپی سوڈز کا موازنہ سیزن اور ایپی سوڈ نمبرز کا استعمال کرتے ہوئے کیا جائے گا، جب دستیاب ہو۔", @@ -531,14 +531,14 @@ "TagsValue": "ٹیگز: {0}", "TextSent": "متن بھیج دیا گیا۔", "ThemeVideos": "تھیم ویڈیوز", - "TheseSettingsAffectSubtitlesOnThisDevice": "یہ ترتیبات اس ڈیوائس پر سب ٹائٹلز کو متاثر کرتی ہیں۔", + "TheseSettingsAffectSubtitlesOnThisDevice": "یہ ترتیبات اس ڈیوائس پر سب ٹائٹلز کو متاثر کرتی ہیں", "TitleHostingSettings": "ہوسٹنگ کی ترتیبات", "TitlePlayback": "پلے بیک", "TonemappingRangeHelp": "آؤٹ پٹ رنگ کی حد منتخب کریں۔ آٹو ان پٹ رینج کے برابر ہے۔", "TypeOptionPluralSeries": "ٹی وی کے پروگرام", "Typewriter": "ٹائپ رائٹر", - "Unmute": "چالو کریں۔", - "Unplayed": "کھیلا نہیں گیا۔", + "Unmute": "چالو کریں", + "Unplayed": "کھیلا نہیں گیا", "Unrated": "غیر درجہ بندی", "ButtonPause": "توقف", "LabelTonemappingDesat": "ٹون میپنگ ڈیسیٹ", @@ -546,14 +546,14 @@ "UnsupportedPlayback": "جیلیفن DRM کے ذریعے محفوظ کردہ مواد کو ڈکرپٹ نہیں کر سکتا لیکن تمام مواد کو اس سے قطع نظر آزمایا جائے گا، بشمول محفوظ عنوانات۔ کچھ فائلیں انکرپشن یا دیگر غیر تعاون یافتہ خصوصیات، جیسے انٹرایکٹو ٹائٹلز کی وجہ سے مکمل طور پر سیاہ دکھائی دے سکتی ہیں۔", "LabelServerHost": "میزبان", "LabelServerNameHelp": "یہ نام سرور کی شناخت کے لیے استعمال کیا جائے گا اور سرور کے میزبان نام پر ڈیفالٹ ہوگا۔", - "Upload": "اپ لوڈ کریں۔", + "Upload": "اپ لوڈ کریں", "LabelSkipForwardLength": "آگے کی لمبائی کو چھوڑیں", - "UseDoubleRateDeinterlacing": "ڈانٹرلیسنگ کرتے وقت فریم کی شرح کو دوگنا کریں۔", + "UseDoubleRateDeinterlacing": "ڈانٹرلیسنگ کرتے وقت فریم کی شرح کو دوگنا کریں", "HeaderIdentifyItemHelp": "تلاش کا ایک یا زیادہ معیار درج کریں۔ تلاش کے نتائج کو بڑھانے کے لیے معیار کو ہٹا دیں۔", "LabelSpecialSeasonsDisplayName": "خصوصی سیزن ڈسپلے نام", "LabelSSDPTracingFilter": "SSDP فلٹر", "LabelStartWhenPossible": "جب ممکن ہو شروع کریں", - "LabelEnableIP4": "IPv4 کو فعال کریں۔", + "LabelEnableIP4": "IPv4 کو فعال کریں", "EnableExternalVideoPlayersHelp": "ویڈیو پلے بیک شروع کرنے پر ایک بیرونی پلیئر مینو دکھایا جائے گا۔", "LabelWeb": "ویب", "UseDoubleRateDeinterlacingHelp": "یہ سیٹنگ ڈی انٹرلیسنگ کے وقت فیلڈ ریٹ کا استعمال کرتی ہے، جسے اکثر باب ڈانٹرلیسنگ کہا جاتا ہے، جو ویڈیو کے فریم ریٹ کو دوگنا کر دیتا ہے تاکہ مکمل حرکت فراہم کی جا سکے جیسا کہ آپ ٹی وی پر انٹر لیس ویڈیو دیکھتے وقت دیکھیں گے۔", @@ -567,18 +567,18 @@ "Writer": "لکھاری", "Writers": "لکھنے والے", "XmlDocumentAttributeListHelp": "یہ اوصاف ہر XML جواب کے بنیادی عنصر پر لاگو ہوتے ہیں۔", - "ButtonScanAllLibraries": "تمام لائبریریوں کو اسکین کریں۔", + "ButtonScanAllLibraries": "تمام لائبریریوں کو اسکین کریں", "Data": "ڈیٹا", "LabelPlaylist": "پلے لسٹ", "LabelUser": "صارف", "LabelUserMaxActiveSessions": "بیک وقت یوزر سیشنز کی زیادہ سے زیادہ تعداد", "XmlTvKidsCategoriesHelp": "ان زمروں والے پروگرام بچوں کے پروگرام کے طور پر دکھائے جائیں گے۔ متعدد کو '|' سے الگ کریں۔", - "Delete": "حذف کریں۔", + "Delete": "حذف کریں", "HeaderTracks": "ٹریکس", "XmlTvMovieCategoriesHelp": "ان زمروں والے پروگرام فلموں کے طور پر دکھائے جائیں گے۔ متعدد کو '|' سے الگ کریں۔", "XmlTvNewsCategoriesHelp": "ان زمروں کے پروگرام خبروں کے پروگرام کے طور پر دکھائے جائیں گے۔ متعدد کو '|' سے الگ کریں۔", "XmlTvSportsCategoriesHelp": "ان زمروں والے پروگرام کھیلوں کے پروگرام کے طور پر دکھائے جائیں گے۔ متعدد کو '|' سے الگ کریں۔", - "HeaderSelectFallbackFontPath": "فال بیک فونٹ فولڈر پاتھ منتخب کریں۔", + "HeaderSelectFallbackFontPath": "فال بیک فونٹ فولڈر پاتھ منتخب کریں", "Audio": "آڈیو", "CommunityRating": "کمیونٹی کی درجہ بندی", "LabelFallbackFontPath": "فال بیک فونٹ فولڈر کا راستہ", @@ -586,27 +586,27 @@ "List": "فہرست", "OptionEveryday": "ہر روز", "Movie": "فلم", - "CopyStreamURL": "سٹریم یو آر ایل کاپی کریں۔", + "CopyStreamURL": "سٹریم یو آر ایل کاپی کریں", "LabelAirsAfterSeason": "موسم کے بعد نشر", "Menu": "مینو", - "LabelEnableIP6": "IPv6 کو فعال کریں۔", + "LabelEnableIP6": "IPv6 کو فعال کریں", "LabelSyncPlayNewGroup": "نیا گروپ", "LabelTranscodingProgress": "ٹرانس کوڈنگ کی پیشرفت", "MessagePleaseEnsureInternetMetadata": "براہ کرم یقینی بنائیں کہ انٹرنیٹ میٹا ڈیٹا کی ڈاؤن لوڈنگ فعال ہے۔", "MessageConfirmDeleteTunerDevice": "کیا آپ واقعی اس آلہ کو حذف کرنا چاہتے ہیں؟", - "SaveSubtitlesIntoMediaFolders": "میڈیا فولڈرز میں سب ٹائٹلز محفوظ کریں۔", + "SaveSubtitlesIntoMediaFolders": "میڈیا فولڈرز میں سب ٹائٹلز محفوظ کریں", "HeaderSecondsValue": "{0} سیکنڈز", - "HeaderAppearsOn": "پر ظاہر ہوتا ہے۔", + "HeaderAppearsOn": "پر ظاہر ہوتا ہے", "LabelChromecastVersion": "گوگل کاسٹ ورژن", "ItemCount": "{0} آئٹمز", - "HeaderSelectServerCachePath": "سرور کیشے کا راستہ منتخب کریں۔", + "HeaderSelectServerCachePath": "سرور کیشے کا راستہ منتخب کریں", "ButtonGotIt": "یہ مل گیا", "HeaderProfileServerSettingsHelp": "یہ اقدار کنٹرول کرتی ہیں کہ سرور کس طرح اپنے آپ کو کلائنٹس کے سامنے پیش کرے گا۔", "LeaveBlankToNotSetAPassword": "آپ کوئی پاس ورڈ سیٹ نہ کرنے کے لیے اس فیلڈ کو خالی چھوڑ سکتے ہیں۔", - "DisplayMissingEpisodesWithinSeasons": "سیزن کے اندر غائب ایپی سوڈز دکھائیں۔", + "DisplayMissingEpisodesWithinSeasons": "سیزن کے اندر غائب ایپی سوڈز دکھائیں", "HeaderSeriesStatus": "سیریز کی حیثیت", "ButtonArrowRight": "دائیں", - "OptionIgnoreTranscodeByteRangeRequests": "ٹرانس کوڈ بائٹ رینج کی درخواستوں کو نظر انداز کریں۔", + "OptionIgnoreTranscodeByteRangeRequests": "ٹرانس کوڈ بائٹ رینج کی درخواستوں کو نظر انداز کریں", "MessageInvalidUser": "غلط صارف نام یا پاس ورڈ. دوبارہ کوشش کریں.", "LabelSyncPlaySyncMethod": "مطابقت پذیری کا طریقہ", "RecommendationStarring": "ستارہ {0}", @@ -619,9 +619,9 @@ "PasswordResetConfirmation": "کیا آپ واقعی پاس ورڈ دوبارہ ترتیب دینا چاہتے ہیں؟", "LabelDownMixAudioScale": "ڈاؤن مکسنگ کرتے وقت آڈیو بوسٹ", "MessageNoServersAvailable": "خودکار سرور دریافت کا استعمال کرتے ہوئے کوئی سرور نہیں ملا۔", - "HeaderAddUser": "صارف شامل کریں۔", + "HeaderAddUser": "صارف شامل کریں", "LabelEnableIP4Help": "IPv4 فعالیت کو فعال کریں۔", - "LabelGroupMoviesIntoCollections": "فلموں کو مجموعوں میں گروپ کریں۔", + "LabelGroupMoviesIntoCollections": "فلموں کو مجموعوں میں گروپ کریں", "LabelStatus": "حالت", "LabelDisplayName": "ڈسپلے کا نام", "HeaderIdentification": "شناخت", @@ -641,38 +641,38 @@ "LabelDirectStreamingInfo": "براہ راست سلسلہ بندی کی معلومات", "LabelRemuxingInfo": "Remuxing معلومات", "LabelSyncPlayInfo": "SyncPlay کی معلومات", - "ReplaceAllMetadata": "تمام میٹا ڈیٹا کو تبدیل کریں۔", - "PreferFmp4HlsContainer": "fMP4-HLS میڈیا کنٹینر کو ترجیح دیں۔", + "ReplaceAllMetadata": "تمام میٹا ڈیٹا کو تبدیل کریں", + "PreferFmp4HlsContainer": "fMP4-HLS میڈیا کنٹینر کو ترجیح دیں", "PreferFmp4HlsContainerHelp": "FMP4 کو HLS کے لیے بطور ڈیفالٹ کنٹینر استعمال کرنے کو ترجیح دیں، جس سے معاون آلات پر HEVC مواد کو براہ راست نشر کرنا ممکن ہو سکے۔", "LabelAllowedAudioChannels": "زیادہ سے زیادہ اجازت یافتہ آڈیو چینلز", "LabelSelectMono": "مونو", "YoutubeNotFound": "ویڈیو نہیں ملی.", "MessageChromecastConnectionError": "آپ کا Google Cast وصول کنندہ جیلیفن سرور سے رابطہ کرنے سے قاصر ہے۔ براہ کرم کنکشن چیک کریں اور دوبارہ کوشش کریں۔", "MessagePlaybackError": "آپ کے Google Cast وصول کنندہ پر اس فائل کو چلانے میں ایک خرابی تھی۔", - "EnableVppTonemapping": "VPP ٹون میپنگ کو فعال کریں۔", - "Controls": "کنٹرول کرتا ہے۔", - "LabelEnableGamepad": "گیم پیڈ کو فعال کریں۔", + "EnableVppTonemapping": "VPP ٹون میپنگ کو فعال کریں", + "Controls": "کنٹرول کرتا ہے", + "LabelEnableGamepad": "گیم پیڈ کو فعال کریں", "LabelPostProcessorArgumentsHelp": "{path} کو ریکارڈنگ فائل کے راستے کے طور پر استعمال کریں۔", - "AudioCodecNotSupported": "آڈیو کوڈیک تعاون یافتہ نہیں ہے۔", - "SubtitleCodecNotSupported": "سب ٹائٹل کوڈیک تعاون یافتہ نہیں ہے۔", - "VideoCodecNotSupported": "ویڈیو کوڈیک تعاون یافتہ نہیں ہے۔", - "AudioBitrateNotSupported": "آڈیو کا بٹ ریٹ تعاون یافتہ نہیں ہے۔", - "VideoResolutionNotSupported": "ویڈیو کی ریزولوشن تعاون یافتہ نہیں ہے۔", - "AudioProfileNotSupported": "آڈیو کوڈیک کا پروفائل تعاون یافتہ نہیں ہے۔", - "AudioSampleRateNotSupported": "آڈیو کے نمونے کی شرح تعاون یافتہ نہیں ہے۔", - "AnamorphicVideoNotSupported": "Anamorphic ویڈیو تعاون یافتہ نہیں ہے۔", - "InterlacedVideoNotSupported": "باہم منسلک ویڈیو تعاون یافتہ نہیں ہے۔", - "SecondaryAudioNotSupported": "ثانوی آڈیو ٹریکس تعاون یافتہ نہیں ہیں۔", - "RefFramesNotSupported": "حوالہ فریم تعاون یافتہ نہیں ہیں۔", - "VideoBitDepthNotSupported": "ویڈیو کی تھوڑا سا گہرائی تعاون یافتہ نہیں ہے۔", - "VideoFramerateNotSupported": "ویڈیو کا فریم ریٹ تعاون یافتہ نہیں ہے۔", - "VideoLevelNotSupported": "ویڈیو کوڈیک کی سطح تعاون یافتہ نہیں ہے۔", - "VideoProfileNotSupported": "ویڈیو کوڈیک کا پروفائل تعاون یافتہ نہیں ہے۔", + "AudioCodecNotSupported": "آڈیو کوڈیک تعاون یافتہ نہیں ہے", + "SubtitleCodecNotSupported": "سب ٹائٹل کوڈیک تعاون یافتہ نہیں ہے", + "VideoCodecNotSupported": "ویڈیو کوڈیک تعاون یافتہ نہیں ہے", + "AudioBitrateNotSupported": "آڈیو کا بٹ ریٹ تعاون یافتہ نہیں ہے", + "VideoResolutionNotSupported": "ویڈیو کی ریزولوشن تعاون یافتہ نہیں ہے", + "AudioProfileNotSupported": "آڈیو کوڈیک کا پروفائل تعاون یافتہ نہیں ہے", + "AudioSampleRateNotSupported": "آڈیو کے نمونے کی شرح تعاون یافتہ نہیں ہے", + "AnamorphicVideoNotSupported": "Anamorphic ویڈیو تعاون یافتہ نہیں ہے", + "InterlacedVideoNotSupported": "باہم منسلک ویڈیو تعاون یافتہ نہیں ہے", + "SecondaryAudioNotSupported": "ثانوی آڈیو ٹریکس تعاون یافتہ نہیں ہیں", + "RefFramesNotSupported": "حوالہ فریم تعاون یافتہ نہیں ہیں", + "VideoBitDepthNotSupported": "ویڈیو کی تھوڑا سا گہرائی تعاون یافتہ نہیں ہے", + "VideoFramerateNotSupported": "ویڈیو کا فریم ریٹ تعاون یافتہ نہیں ہے", + "VideoLevelNotSupported": "ویڈیو کوڈیک کی سطح تعاون یافتہ نہیں ہے", + "VideoProfileNotSupported": "ویڈیو کوڈیک کا پروفائل تعاون یافتہ نہیں ہے", "LabelHardwareEncodingOptions": "ہارڈ ویئر انکوڈنگ کے اختیارات", - "DirectPlayError": "براہ راست پلے بیک شروع کرنے میں ایک خرابی تھی۔", + "DirectPlayError": "براہ راست پلے بیک شروع کرنے میں ایک خرابی تھی", "LabelOriginalTitle": "اصل عنوان", "BehindTheScenes": "پردے کے پیچھے", - "OptionAllowVideoPlaybackTranscoding": "ویڈیو پلے بیک کی اجازت دیں جس میں ٹرانس کوڈنگ کی ضرورت ہوتی ہے۔", + "OptionAllowVideoPlaybackTranscoding": "ویڈیو پلے بیک کی اجازت دیں جس میں ٹرانس کوڈنگ کی ضرورت ہوتی ہے", "Settings": "ترتیبات", "DeletedScene": "حذف شدہ منظر", "Framerate": "فریم کی شرح", @@ -685,12 +685,12 @@ "LabelVppTonemappingBrightnessHelp": "وی پی پی ٹون میپنگ میں برائٹنس گین کا اطلاق کریں۔ تجویز کردہ اور طے شدہ دونوں قدریں 0 ہیں۔", "LabelVppTonemappingContrast": "VPP ٹون میپنگ کے برعکس فائدہ", "LabelVppTonemappingContrastHelp": "VPP ٹون میپنگ میں کنٹراسٹ گین کا اطلاق کریں۔ تجویز کردہ اور پہلے سے طے شدہ اقدار 1.2 اور 1 ہیں۔", - "VideoRangeTypeNotSupported": "ویڈیو کی رینج کی قسم تعاون یافتہ نہیں ہے۔", + "VideoRangeTypeNotSupported": "ویڈیو کی رینج کی قسم تعاون یافتہ نہیں ہے", "LabelVideoRangeType": "ویڈیو رینج کی قسم", "MediaInfoVideoRangeType": "ویڈیو رینج کی قسم", "MediaInfoDoViTitle": "ڈی وی ٹائٹل", "MediaInfoRpuPresentFlag": "DV rpu پیش سیٹ پرچم", - "OptionAutomaticallyGroupSeries": "خودکار طور پر سیریز کو ضم کریں جو متعدد فولڈرز میں پھیلی ہوئی ہیں۔", + "OptionAutomaticallyGroupSeries": "خودکار طور پر سیریز کو ضم کریں جو متعدد فولڈرز میں پھیلی ہوئی ہیں", "MediaInfoBlPresentFlag": "DV bl پیش سیٹ پرچم", "LabelUseNotificationServices": "درج ذیل خدمات کا استعمال کریں", "MediaInfoDvBlSignalCompatibilityId": "DV bl سگنل مطابقت کی شناخت", @@ -699,10 +699,10 @@ "HeaderLatestRecordings": "تازہ ترین ریکارڈنگز", "LabelSubtitlePlaybackMode": "سب ٹائٹل موڈ", "LabelHardwareAccelerationType": "ہارڈ وئر کی صلاحیت بہتر بنانا", - "PreferEmbeddedTitlesOverFileNames": "فائل ناموں پر ایمبیڈڈ ٹائٹلز کو ترجیح دیں۔", + "PreferEmbeddedTitlesOverFileNames": "فائل ناموں پر ایمبیڈڈ ٹائٹلز کو ترجیح دیں", "OptionPlayCount": "گنتی کھیلیں", "LabelEnableDlnaPlayToHelp": "اپنے نیٹ ورک کے اندر موجود آلات کا پتہ لگائیں اور انہیں دور سے کنٹرول کرنے کی صلاحیت پیش کریں۔", - "HeaderUploadSubtitle": "سب ٹائٹل اپ لوڈ کریں۔", + "HeaderUploadSubtitle": "سب ٹائٹل اپ لوڈ کریں", "LabelUserLoginAttemptsBeforeLockout": "صارف کے لاک آؤٹ ہونے سے پہلے لاگ ان کی ناکام کوشش", "EnablePhotosHelp": "تصاویر کا پتہ لگایا جائے گا اور دیگر میڈیا فائلوں کے ساتھ دکھایا جائے گا۔", "LabelColorPrimaries": "رنگ پرائمری", @@ -712,7 +712,7 @@ "MessageSyncPlayCreateGroupDenied": "گروپ بنانے کے لیے اجازت درکار ہے۔", "MediaInfoBitrate": "بٹریٹ", "EnableBlurHashHelp": "وہ تصاویر جو اب بھی لوڈ ہو رہی ہیں ایک منفرد پلیس ہولڈر کے ساتھ دکھائی جائیں گی۔", - "ButtonCast": "ڈیوائس پر کاسٹ کریں۔", + "ButtonCast": "ڈیوائس پر کاسٹ کریں", "Played": "کھیلا", "PlayFromBeginning": "شروع سے کھیلیں", "LabelNewsCategories": "خبروں کے زمرے", @@ -726,38 +726,38 @@ "Restart": "دوبارہ شروع کریں", "MoreUsersCanBeAddedLater": "بعد میں ڈیش بورڈ کے اندر سے مزید صارفین کو شامل کیا جا سکتا ہے۔", "HeaderKodiMetadataHelp": "NFO میٹا ڈیٹا کو فعال یا غیر فعال کرنے کے لیے، ایک لائبریری میں ترمیم کریں اور 'میٹا ڈیٹا سیور' سیکشن تلاش کریں۔", - "LabelEnableDlnaServer": "DLNA سرور کو فعال کریں۔", - "QuickConnectAuthorizeCode": "لاگ ان کرنے کے لیے کوڈ {0} درج کریں۔", + "LabelEnableDlnaServer": "DLNA سرور کو فعال کریں", + "QuickConnectAuthorizeCode": "لاگ ان کرنے کے لیے کوڈ {0} درج کریں", "LabelTVHomeScreen": "ٹی وی موڈ ہوم اسکرین", "LabelContentType": "مواد کی قسم", "ServerNameIsShuttingDown": "{0} پر سرور بند ہو رہا ہے۔", "ExtraLarge": "اضافی بڑا", - "HeaderDownloadSync": "ڈاؤن لوڈ اور مطابقت پذیری کریں۔", + "HeaderDownloadSync": "ڈاؤن لوڈ اور مطابقت پذیری کریں", "HeaderAdditionalParts": "اضافی حصے", "ShowIndicatorsFor": "کے لیے اشارے دکھائیں", "LabelDateAddedBehavior": "نئے مواد کے لیے تاریخ شامل کی گئی رویہ", "LabelReleaseDate": "تاریخ رہائی", "LabelFriendlyName": "دوستانہ نام", - "ButtonUninstall": "ان انسٹال کریں۔", + "ButtonUninstall": "ان انسٹال کریں", "PlayCount": "گنتی کھیلیں", "OptionReleaseDate": "تاریخ رہائی", - "OptionAllowContentDownload": "میڈیا ڈاؤن لوڈ کی اجازت دیں۔", + "OptionAllowContentDownload": "میڈیا ڈاؤن لوڈ کی اجازت دیں", "EnableAutoCast": "ڈیفالٹ کے طور پر مقرر", "HeaderParentalRatings": "والدین کی درجہ بندی", "HeaderYears": "سال", - "OptionReportByteRangeSeekingWhenTranscoding": "رپورٹ کریں کہ سرور ٹرانس کوڈنگ کرتے وقت بائٹ کی تلاش کو سپورٹ کرتا ہے۔", + "OptionReportByteRangeSeekingWhenTranscoding": "رپورٹ کریں کہ سرور ٹرانس کوڈنگ کرتے وقت بائٹ کی تلاش کو سپورٹ کرتا ہے", "MediaInfoColorTransfer": "رنگ کی منتقلی", "LabelEnableDlnaDebugLoggingHelp": "بڑی لاگ فائلیں بنائیں اور ان کا استعمال صرف خرابیوں کا سراغ لگانے کے مقاصد کے لیے کیا جانا چاہیے۔", "HeaderDefaultRecordingSettings": "پہلے سے طے شدہ ریکارڈنگ کی ترتیبات", - "HeaderSyncPlayEnabled": "SyncPlay فعال ہے۔", - "LabelSaveLocalMetadata": "آرٹ ورک کو میڈیا فولڈر میں محفوظ کریں۔", + "HeaderSyncPlayEnabled": "SyncPlay فعال ہے", + "LabelSaveLocalMetadata": "آرٹ ورک کو میڈیا فولڈر میں محفوظ کریں", "MessageSyncPlayGroupWait": "{0} بفرنگ کر رہا ہے…", - "Browse": "براؤز کریں۔", + "Browse": "براؤز کریں", "HeaderSortOrder": "ترتیب", "Preview": "پیش نظارہ", "LabelValue": "قدر", "Image": "تصویر", - "DateAdded": "تاریخ شامل کی گئی۔", + "DateAdded": "تاریخ شامل کی گئی", "SettingsSaved": "ترتیبات محفوظ ہو گئیں۔", "OptionForceRemoteSourceTranscoding": "ریموٹ میڈیا ذرائع جیسے لائیو ٹی وی کی زبردستی ٹرانس کوڈنگ", "EnableCinemaMode": "سنیما موڈ", @@ -773,7 +773,7 @@ "InstallingPackage": "انسٹال ہو رہا ہے {0} (ورژن {1})", "LabelServerHostHelp": "192.168.1.100:8096 یا https://myserver.com", "ServerNameIsRestarting": "{0} پر سرور دوبارہ شروع ہو رہا ہے۔", - "HeaderAddUpdateImage": "تصویر شامل/اپ ڈیٹ کریں۔", + "HeaderAddUpdateImage": "تصویر شامل/اپ ڈیٹ کریں", "HeaderContinueListening": "سننا جاری رکھیں", "FileNotFound": "فائل نہیں ملی.", "HeaderRecordingPostProcessing": "ریکارڈنگ پوسٹ پروسیسنگ", @@ -782,18 +782,18 @@ "ButtonWebsite": "ویب سائٹ", "Share": "بانٹیں", "HeaderSeasons": "موسم", - "LabelEnableDlnaDebugLogging": "DLNA ڈیبگ لاگنگ کو فعال کریں۔", + "LabelEnableDlnaDebugLogging": "DLNA ڈیبگ لاگنگ کو فعال کریں", "LabelAlbumArtPN": "البم آرٹ PN", - "RemoveFromPlaylist": "پلے لسٹ سے ہٹا دیں۔", - "AllowEmbeddedSubtitles": "ایمبیڈڈ سب ٹائٹلز کی مختلف اقسام کو غیر فعال کریں۔", + "RemoveFromPlaylist": "پلے لسٹ سے ہٹا دیں", + "AllowEmbeddedSubtitles": "ایمبیڈڈ سب ٹائٹلز کی مختلف اقسام کو غیر فعال کریں", "LabelEndDate": "آخری تاریخ", "OptionMaxActiveSessionsHelp": "0 کی قدر خصوصیت کو غیر فعال کر دے گی۔", "HeaderTaskTriggers": "ٹاسک ٹرگرز", "RememberMe": "مجھے پہچانتے ہو", - "HeaderCancelRecording": "ریکارڈنگ منسوخ کریں۔", + "HeaderCancelRecording": "ریکارڈنگ منسوخ کریں", "MediaInfoInterlaced": "آپس میں جڑا ہوا", "FastForward": "تیزی سے آگے", - "LabelEmbedAlbumArtDidl": "ڈی آئی ڈی ایل میں البم آرٹ ایمبیڈ کریں۔", + "LabelEmbedAlbumArtDidl": "ڈی آئی ڈی ایل میں البم آرٹ ایمبیڈ کریں", "LabelDisplayLanguageHelp": "جیلیفن کا ترجمہ ایک جاری منصوبہ ہے۔", "AspectRatio": "پہلو کا تناسب", "LabelRepositoryNameHelp": "اس ذخیرے کو آپ کے سرور میں شامل کردہ کسی دوسرے سے ممتاز کرنے کے لیے ایک حسب ضرورت نام۔", @@ -803,23 +803,23 @@ "HeaderPreferredMetadataLanguage": "ترجیحی میٹا ڈیٹا زبان", "BoxRear": "باکس (پیچھے)", "LastSeen": "آخری بار دیکھا گیا {0}", - "Connect": "جڑیں۔", + "Connect": "جڑیں", "LabelTimeLimitHours": "وقت کی حد (گھنٹے)", "LabelTime": "وقت", "OptionCriticRating": "ناقدین کی درجہ بندی", "OptionDisplayFolderViewHelp": "اپنی دوسری میڈیا لائبریریوں کے ساتھ فولڈرز ڈسپلے کریں۔ اگر آپ سادہ فولڈر کا نظارہ کرنا چاہتے ہیں تو یہ مفید ہو سکتا ہے۔", "MoreFromValue": "{0} سے مزید", "LabelYoureDone": "آپ کا کام ہو گیا!", - "Refresh": "ریفریش کریں۔", + "Refresh": "ریفریش کریں", "ButtonManualLogin": "دستی لاگ ان", "Large": "بڑا", "LabelProfileContainer": "کنٹینر", "LabelTriggerType": "محرک کی قسم", "LabelProtocolInfo": "پروٹوکول کی معلومات", - "ClearQueue": "قطار صاف کریں۔", + "ClearQueue": "قطار صاف کریں", "LabelRuntimeMinutes": "رن ٹائم", "LabelAudioLanguagePreference": "ترجیحی آڈیو زبان", - "ShowLess": "کم دکھائیں۔", + "ShowLess": "کم دکھائیں", "HeaderTuners": "ٹیونرز", "News": "خبریں", "OptionNew": "نئی…", @@ -831,20 +831,20 @@ "RefreshQueued": "ریفریش قطار۔", "Photo": "تصویر", "LabelEpisodeNumber": "قسط نمبر", - "HeaderSyncPlaySelectGroup": "ایک گروپ میں شامل ہوں۔", + "HeaderSyncPlaySelectGroup": "ایک گروپ میں شامل ہوں", "LabelEncoderPreset": "انکوڈنگ پیش سیٹ", "HeaderPleaseSignIn": "سائن ان کریں", "MediaInfoProfile": "پروفائل", "LabelRecord": "ریکارڈ", - "Ended": "ختم ہوا۔", - "HeaderSelectTranscodingPath": "ٹرانس کوڈنگ عارضی راستہ منتخب کریں۔", + "Ended": "ختم ہوا", + "HeaderSelectTranscodingPath": "ٹرانس کوڈنگ عارضی راستہ منتخب کریں", "LabelAirDays": "ہوا کے دن", "LabelAlbumArtMaxWidth": "البم آرٹ کی زیادہ سے زیادہ چوڑائی", - "EditMetadata": "میٹا ڈیٹا میں ترمیم کریں۔", + "EditMetadata": "میٹا ڈیٹا میں ترمیم کریں", "HeaderServerSettings": "سرور کی ترتیبات", "SelectAdminUsername": "براہ کرم ایڈمن اکاؤنٹ کے لیے صارف نام منتخب کریں۔", "DirectPlaying": "براہ راست کھیلنا", - "PreviousTrack": "پچھلے پر جائیں۔", + "PreviousTrack": "پچھلے پر جائیں", "LabelFont": "فونٹ", "OptionDaily": "روزانہ", "LabelSimultaneousConnectionLimit": "بیک وقت سلسلہ کی حد", @@ -853,7 +853,7 @@ "MessageSyncPlayPlaybackPermissionRequired": "پلے بیک کی اجازت درکار ہے۔", "OptionHlsSegmentedSubtitles": "HLS سیگمنٹڈ سب ٹائٹلز", "LabelCreateHttpPortMap": "HTTP ٹریفک کے ساتھ ساتھ HTTPS کے لیے خودکار پورٹ میپنگ کو فعال کریں۔", - "RepeatEpisodes": "اقساط کو دہرائیں۔", + "RepeatEpisodes": "اقساط کو دہرائیں", "LabelAccessStart": "وقت آغاز", "HeaderServerAddressSettings": "سرور ایڈریس کی ترتیبات", "LabelRecordingPath": "پہلے سے طے شدہ ریکارڈنگ کا راستہ", @@ -861,7 +861,7 @@ "LabelMetadata": "میٹا ڈیٹا", "Play": "کھیلیں", "LabelEnableDlnaServerHelp": "اپنے نیٹ ورک پر موجود UPnP آلات کو مواد کو براؤز کرنے اور چلانے کی اجازت دیں۔", - "SelectServer": "سرور کو منتخب کریں۔", + "SelectServer": "سرور کو منتخب کریں", "LabelPublishedServerUri": "شائع شدہ سرور URIs", "LabelChannels": "چینلز", "LabelH265Crf": "H.265 انکوڈنگ CRF", @@ -874,13 +874,13 @@ "AskAdminToCreateLibrary": "ایک منتظم سے لائبریری بنانے کو کہیں۔", "Auto": "آٹو", "EncoderPresetHelp": "کارکردگی کو بہتر بنانے کے لیے ایک تیز قدر یا معیار کو بہتر بنانے کے لیے ایک سست قدر منتخب کریں۔", - "HeaderDeleteDevices": "تمام آلات کو حذف کریں۔", - "HeaderThisUserIsCurrentlyDisabled": "یہ صارف فی الحال غیر فعال ہے۔", + "HeaderDeleteDevices": "تمام آلات کو حذف کریں", + "HeaderThisUserIsCurrentlyDisabled": "یہ صارف فی الحال غیر فعال ہے", "LabelAccessDay": "ہفتے کا دن", "LabelNewName": "نیا نام", "LabelParentalRating": "والدین کی درجہ بندی", "LabelXDlnaDoc": "ڈیوائس کلاس ID", - "OptionAllowUserToManageServer": "اس صارف کو سرور کا نظم کرنے کی اجازت دیں۔", + "OptionAllowUserToManageServer": "اس صارف کو سرور کا نظم کرنے کی اجازت دیں", "HeaderGuideProviders": "ٹی وی گائیڈ ڈیٹا فراہم کرنے والے", "SeriesYearToPresent": "{0} - حاضر", "Small": "چھوٹا", @@ -905,22 +905,22 @@ "HeaderDevices": "آلات", "ContinueWatching": "دیکھنا جاری رکھیں", "OptionTrackName": "ٹریک کا نام", - "HeaderConfirmPluginInstallation": "پلگ ان کی تنصیب کی تصدیق کریں۔", + "HeaderConfirmPluginInstallation": "پلگ ان کی تنصیب کی تصدیق کریں", "HeaderUploadImage": "تصویر انٹرنیٹ پر ڈالنا", "MediaInfoBitDepth": "بٹ گہرائی", "LabelScheduledTaskLastRan": "آخری دوڑ {0}، لے کر {1}۔", "LabelAuthProvider": "تصدیق فراہم کنندہ", - "ReplaceExistingImages": "موجودہ تصاویر کو تبدیل کریں۔", + "ReplaceExistingImages": "موجودہ تصاویر کو تبدیل کریں", "LabelLibraryPageSize": "لائبریری صفحہ کا سائز", "Saturday": "ہفتہ", - "HeaderUninstallPlugin": "پلگ ان ان انسٹال کریں۔", + "HeaderUninstallPlugin": "پلگ ان ان انسٹال کریں", "HeaderRevisionHistory": "نظرثانی کی تاریخ", "ButtonOpen": "کھولیں۔", "PasswordSaved": "پاس ورڈ محفوظ ہو گیا۔", "NoSubtitleSearchResultsFound": "کوئی نتیجہ نہیں.", "LabelManufacturerUrl": "مینوفیکچرر URL", "MillisecondsUnit": "MS", - "LabelKodiMetadataEnableExtraThumbs": "ایکسٹرافانارٹ کو ایکسٹرا تھمبس فیلڈ میں کاپی کریں۔", + "LabelKodiMetadataEnableExtraThumbs": "ایکسٹرافانارٹ کو ایکسٹرا تھمبس فیلڈ میں کاپی کریں", "Directors": "ڈائریکٹرز", "DropShadow": "ڈراپ شیڈو", "New": "نئی", @@ -929,26 +929,26 @@ "RepeatMode": "ریپیٹ موڈ", "LabelCustomRating": "حسب ضرورت درجہ بندی", "LabelBaseUrl": "بنیادی URL", - "Search": "تلاش کریں۔", + "Search": "تلاش کریں", "LabelRefreshMode": "ریفریش موڈ", "LabelSubtitleFormatHelp": "مثال: srt", "Bwdif": "BWDIF", "HeaderApiKeys": "API کیز", - "HeaderPasswordReset": "پاس ورڈ ری سیٹ کریں۔", + "HeaderPasswordReset": "پاس ورڈ ری سیٹ کریں", "HeaderResponseProfileHelp": "رسپانس پروفائلز مخصوص قسم کا میڈیا چلاتے وقت ڈیوائس پر بھیجی گئی معلومات کو حسب ضرورت بنانے کا طریقہ فراہم کرتے ہیں۔", "HeaderSubtitleDownloads": "سب ٹائٹل ڈاؤن لوڈز", "EnableDetailsBanner": "تفصیلات کا بینر", "LabelHDHomerunPortRangeHelp": "HDHomeRun UDP پورٹ رینج کو اس قدر تک محدود کرتا ہے۔ (پہلے سے طے شدہ 1024 - 645535 ہے)۔", "Edit": "ترمیم", "LabelTonemappingThreshold": "ٹون میپنگ کی حد", - "HeaderRemoveMediaLocation": "میڈیا کی جگہ کو ہٹا دیں۔", + "HeaderRemoveMediaLocation": "میڈیا کی جگہ کو ہٹا دیں", "RecommendationBecauseYouLike": "کیونکہ آپ کو {0} پسند ہے", - "HeaderAddUpdateSubtitle": "سب ٹائٹل شامل کریں/اپ ڈیٹ کریں۔", + "HeaderAddUpdateSubtitle": "سب ٹائٹل شامل کریں/اپ ڈیٹ کریں", "LabelEnableDlnaClientDiscoveryIntervalHelp": "دو SSDP تلاشوں کے درمیان سیکنڈوں میں دورانیہ کا تعین کریں۔", "No": "نہیں", "MessageConfirmDeleteGuideProvider": "کیا آپ واقعی اس گائیڈ فراہم کنندہ کو حذف کرنا چاہتے ہیں؟", "ImportFavoriteChannelsHelp": "صرف وہی چینلز درآمد کیے جائیں گے جنہیں ٹیونر ڈیوائس پر پسندیدہ کے بطور نشان زد کیا گیا ہے۔", - "OptionAllowMediaPlayback": "میڈیا پلے بیک کی اجازت دیں۔", + "OptionAllowMediaPlayback": "میڈیا پلے بیک کی اجازت دیں", "PerfectMatch": "کامل میچ", "OnlyImageFormats": "صرف تصویری فارمیٹس (VobSub, PGS, SUB)", "HeaderXmlDocumentAttribute": "XML دستاویز کی خصوصیت", @@ -956,31 +956,31 @@ "LabelImportOnlyFavoriteChannels": "پسندیدہ کے بطور نشان زد چینلز تک محدود رکھیں", "HeaderAlert": "الرٹ", "LabelTonemappingRange": "ٹون میپنگ کی حد", - "EditImages": "تصاویر میں ترمیم کریں۔", + "EditImages": "تصاویر میں ترمیم کریں", "HeaderHttpsSettings": "HTTPS ترتیبات", - "LabelDisplaySpecialsWithinSeasons": "ان سیزن میں خصوصی ڈسپلے کریں جن میں وہ نشر ہوئے تھے۔", + "LabelDisplaySpecialsWithinSeasons": "ان سیزن میں خصوصی ڈسپلے کریں جن میں وہ نشر ہوئے تھے", "LabelKodiMetadataDateFormatHelp": "NFO فائلوں میں موجود تمام تاریخوں کو اس فارمیٹ کا استعمال کرتے ہوئے پارس کیا جائے گا۔", - "LabelExtractChaptersDuringLibraryScan": "لائبریری اسکین کے دوران باب کی تصاویر نکالیں۔", + "LabelExtractChaptersDuringLibraryScan": "لائبریری اسکین کے دوران باب کی تصاویر نکالیں", "HeaderPaths": "راستے", "SeriesDisplayOrderHelp": "اقساط کو ہوا کی تاریخ، DVD آرڈر، یا مطلق نمبر کے ذریعے ترتیب دیں۔", "MediaIsBeingConverted": "میڈیا کو ایک ایسے فارمیٹ میں تبدیل کیا جا رہا ہے جو میڈیا کو چلانے والے آلے کے ساتھ مطابقت رکھتا ہے۔", "PathNotFound": "راستہ نہ مل سکا۔ براہ کرم یقینی بنائیں کہ راستہ درست ہے اور دوبارہ کوشش کریں۔", "QuickConnectDescription": "Quick Connect کے ساتھ سائن ان کرنے کے لیے، اس ڈیوائس پر 'Quick Connect' بٹن کو منتخب کریں جس سے آپ لاگ ان ہو رہے ہیں اور نیچے دکھایا گیا کوڈ درج کریں۔", - "EnableBlurHash": "تصاویر کے لیے دھندلے پلیس ہولڈرز کو فعال کریں۔", - "LabelEnableBlastAliveMessages": "زندہ پیغامات کو دھماکے سے اڑا دیں۔", + "EnableBlurHash": "تصاویر کے لیے دھندلے پلیس ہولڈرز کو فعال کریں", + "LabelEnableBlastAliveMessages": "زندہ پیغامات کو دھماکے سے اڑا دیں", "HeaderMusicQuality": "میوزک کوالٹی", "MessageNoMovieSuggestionsAvailable": "فلم کی کوئی تجویز فی الحال دستیاب نہیں ہے۔ اپنی فلمیں دیکھنا اور درجہ بندی کرنا شروع کریں، اور پھر اپنی سفارشات دیکھنے کے لیے واپس آئیں۔", "LabelBindToLocalNetworkAddress": "مقامی نیٹ ورک ایڈریس سے منسلک کریں", "LabelPleaseRestart": "تبدیلیاں ویب کلائنٹ کو دستی طور پر دوبارہ لوڈ کرنے کے بعد لاگو ہوں گی۔", "HeaderSeriesOptions": "سیریز کے اختیارات", - "OptionAllowRemoteSharedDevices": "مشترکہ آلات کے ریموٹ کنٹرول کی اجازت دیں۔", + "OptionAllowRemoteSharedDevices": "مشترکہ آلات کے ریموٹ کنٹرول کی اجازت دیں", "HeaderSubtitleProfile": "سب ٹائٹل پروفائل", "MusicArtist": "میوزک آرٹسٹ", "HDPrograms": "ایچ ڈی پروگرام", "HeaderOnNow": "ابھی پر", "LabelAirsBeforeEpisode": "قسط سے پہلے نشر", - "RepeatOne": "ایک دہرائیں۔", - "OptionEnableAccessToAllChannels": "تمام چینلز تک رسائی کو فعال کریں۔", + "RepeatOne": "ایک دہرائیں", + "OptionEnableAccessToAllChannels": "تمام چینلز تک رسائی کو فعال کریں", "AllComplexFormats": "تمام پیچیدہ فارمیٹس (ASS, SSA, VobSub, PGS, SUB, IDX, …)", "LabelAutomaticDiscovery": "آٹو ڈسکوری کو فعال کریں", "OptionDvd": "ڈی وی ڈی", @@ -992,7 +992,7 @@ "HeaderAccessSchedule": "رسائی کا شیڈول", "ServerUpdateNeeded": "اس سرور کو اپ ڈیٹ کرنے کی ضرورت ہے۔ تازہ ترین ورژن ڈاؤن لوڈ کرنے کے لیے، براہ کرم ملاحظہ کریں {0}", "LabelMinResumeDuration": "دوبارہ شروع کرنے کا کم از کم دورانیہ", - "UseEpisodeImagesInNextUp": "'Next Up' اور 'Continue Watching' سیکشنز میں ایپی سوڈ کی تصاویر استعمال کریں۔", + "UseEpisodeImagesInNextUp": "'Next Up' اور 'Continue Watching' سیکشنز میں ایپی سوڈ کی تصاویر استعمال کریں", "HeaderVideos": "ویڈیوز", "SeriesSettings": "سیریز کی ترتیبات", "OptionWeekly": "ہفتہ وار", @@ -1000,7 +1000,7 @@ "MusicAlbum": "میوزک البم", "MediaInfoContainer": "کنٹینر", "LabelDateTimeLocale": "تاریخ وقت کا مقام", - "ButtonStart": "شروع کریں۔", + "ButtonStart": "شروع کریں", "RecentlyWatched": "حال ہی میں دیکھا", "HeaderFetcherSettings": "فیچر کی ترتیبات", "HeaderSubtitleProfilesHelp": "سب ٹائٹل پروفائلز ان سب ٹائٹل فارمیٹس کی وضاحت کرتے ہیں جو ڈیوائس کے ذریعے تعاون یافتہ ہیں۔", @@ -1013,14 +1013,14 @@ "HeaderLibraryOrder": "لائبریری آرڈر", "LabelKodiMetadataUserHelp": "دیگر ایپلیکیشنز کے استعمال کے لیے گھڑی کا ڈیٹا NFO فائلوں میں محفوظ کریں۔", "LabelPath": "راستہ", - "ShowParentImages": "سیریز کی تصاویر دکھائیں۔", + "ShowParentImages": "سیریز کی تصاویر دکھائیں", "Suggestions": "تجاویز", "Up": "اوپر", "LabelHomeNetworkQuality": "ہوم نیٹ ورک کا معیار", - "LabelPlayDefaultAudioTrack": "زبان سے قطع نظر ڈیفالٹ آڈیو ٹریک چلائیں۔", + "LabelPlayDefaultAudioTrack": "زبان سے قطع نظر ڈیفالٹ آڈیو ٹریک چلائیں", "MediaInfoRefFrames": "ریفری فریمز", "ConfirmDeleteImage": "تصویر کو حذف کریں؟", - "SearchForCollectionInternetMetadata": "آرٹ ورک اور میٹا ڈیٹا کے لیے انٹرنیٹ پر تلاش کریں۔", + "SearchForCollectionInternetMetadata": "آرٹ ورک اور میٹا ڈیٹا کے لیے انٹرنیٹ پر تلاش کریں", "MessageConfirmRemoveMediaLocation": "کیا آپ واقعی اس مقام کو ہٹانا چاہتے ہیں؟", "MessageSyncPlayGroupDoesNotExist": "گروپ میں شامل ہونے میں ناکام کیونکہ یہ موجود نہیں ہے۔", "MessageCreateAccountAt": "{0} پر ایک اکاؤنٹ بنائیں", @@ -1039,19 +1039,19 @@ "ButtonTogglePlaylist": "پلے لسٹ", "LabelParentNumber": "والدین کا نمبر", "LabelCorruptedFrames": "خراب فریم", - "OptionPlainStorageFolders": "تمام فولڈرز کو سادہ اسٹوریج فولڈر کے طور پر ڈسپلے کریں۔", + "OptionPlainStorageFolders": "تمام فولڈرز کو سادہ اسٹوریج فولڈر کے طور پر ڈسپلے کریں", "DailyAt": "روزانہ {0} پر", "Raised": "اٹھایا", "LabelEvent": "تقریب", "LabelMethod": "طریقہ", - "ManageLibrary": "لائبریری کا انتظام کریں۔", + "ManageLibrary": "لائبریری کا انتظام کریں", "HeaderPlayAll": "سارے کھیلو", "LabelTag": "ٹیگ", "LabelIdentificationFieldHelp": "کیس غیر حساس ذیلی اسٹرنگ یا ریجیکس اظہار۔", "MessageConfirmRevokeApiKey": "کیا آپ واقعی اس API کلید کو منسوخ کرنا چاہتے ہیں؟ اس سرور سے ایپلیکیشن کا کنکشن اچانک ختم ہو جائے گا۔", "YoutubeDenied": "درخواست کردہ ویڈیو کو ایمبیڈڈ پلیئرز میں چلانے کی اجازت نہیں ہے۔", "MediaInfoTimestamp": "ٹائم اسٹیمپ", - "MarkPlayed": "مارک نے کھیلا۔", + "MarkPlayed": "مارک نے کھیلا", "LabelRemoteClientBitrateLimit": "انٹرنیٹ اسٹریمنگ بٹریٹ کی حد (Mbps)", "HeaderKeepRecording": "ریکارڈنگ کرتے رہیں", "ButtonSplit": "تقسیم", @@ -1061,12 +1061,12 @@ "MessageConfirmShutdown": "کیا آپ واقعی سرور کو بند کرنا چاہتے ہیں؟", "HeaderStartNow": "اب شروع کریں", "Sports": "کھیل", - "HeaderDeleteProvider": "فراہم کنندہ کو حذف کریں۔", + "HeaderDeleteProvider": "فراہم کنندہ کو حذف کریں", "MessageConfirmProfileDeletion": "کیا آپ واقعی اس پروفائل کو حذف کرنا چاہتے ہیں؟", "OptionWeekdays": "ہفتے کے دن", "LabelName": "نام", "LabelSelectFolderGroupsHelp": "غیر چیک شدہ فولڈرز خود ان کے اپنے نظارے میں ظاہر ہوں گے۔", - "RepeatAll": "سب کو دہرائیں۔", + "RepeatAll": "سب کو دہرائیں", "HeaderSystemDlnaProfiles": "سسٹم پروفائلز", "HeaderFetchImages": "تصاویر حاصل کریں", "TabLogs": "نوشتہ جات", @@ -1078,9 +1078,9 @@ "HeaderHttpHeaders": "HTTP ہیڈر", "TabCatalog": "تفصیلی فہر ست", "LabelVaapiDeviceHelp": "یہ رینڈر نوڈ ہے جو ہارڈویئر ایکسلریشن کے لیے استعمال ہوتا ہے۔", - "SearchForSubtitles": "سب ٹائٹلز تلاش کریں۔", + "SearchForSubtitles": "سب ٹائٹلز تلاش کریں", "LabelHomeScreenSectionValue": "ہوم اسکرین سیکشن {0}", - "LabelSyncPlayAccessCreateAndJoinGroups": "صارف کو گروپ بنانے اور ان میں شامل ہونے کی اجازت دیں۔", + "LabelSyncPlayAccessCreateAndJoinGroups": "صارف کو گروپ بنانے اور ان میں شامل ہونے کی اجازت دیں", "LabelUnstable": "غیر مستحکم", "Rate": "شرح", "DownloadsValue": "{0} ڈاؤن لوڈز", @@ -1093,7 +1093,7 @@ "TabParentalControl": "والدین کا کنٹرول", "HeaderOtherItems": "دیگر اشیاء", "MessageImageTypeNotSelected": "براہ کرم ڈراپ ڈاؤن مینو سے تصویر کی قسم منتخب کریں۔", - "HeaderPlaybackError": "پلے بیک کی خرابی۔", + "HeaderPlaybackError": "پلے بیک کی خرابی", "MetadataManager": "میٹا ڈیٹا مینیجر", "DashboardServerName": "سرور: {0}", "LabelDefaultUser": "پہلے سے طے شدہ صارف", @@ -1106,7 +1106,7 @@ "LabelProtocol": "پروٹوکول", "HeaderIdentificationHeader": "شناختی ہیڈر", "General": "جنرل", - "OptionDateEpisodeAdded": "تاریخ قسط شامل کر دی گئی۔", + "OptionDateEpisodeAdded": "تاریخ قسط شامل کر دی گئی", "LabelProfileAudioCodecs": "آڈیو کوڈیکس", "OptionEnableM2tsModeHelp": "MPEG-TS میں انکوڈنگ کرتے وقت M2TS موڈ کو فعال کریں۔", "PleaseRestartServerName": "براہ کرم جیلیفن کو {0} پر دوبارہ شروع کریں۔", @@ -1114,17 +1114,17 @@ "ValueVideoCodec": "ویڈیو کوڈیک: {0}", "WeeklyAt": "{1} پر {0}", "Episodes": "اقساط", - "EnableEnhancedNvdecDecoder": "بہتر NVDEC ڈیکوڈر کو فعال کریں۔", + "EnableEnhancedNvdecDecoder": "بہتر NVDEC ڈیکوڈر کو فعال کریں", "MessageReenableUser": "دوبارہ فعال کرنے کے لیے نیچے دیکھیں", "IntelLowPowerEncHelp": "کم پاور انکوڈنگ غیر ضروری CPU-GPU مطابقت پذیری کو برقرار رکھ سکتی ہے۔ اگر i915 HuC فرم ویئر کو کنفیگر نہیں کیا گیا ہے تو لینکس پر ان کا غیر فعال ہونا ضروری ہے۔", "MediaInfoDvVersionMajor": "ڈی وی ورژن میجر", "MediaInfoDvVersionMinor": "DV ورژن معمولی", "MediaInfoDvProfile": "ڈی وی پروفائل", "MediaInfoDvLevel": "ڈی وی کی سطح", - "MoveLeft": "بائیں منتقل کریں۔", + "MoveLeft": "بائیں منتقل کریں", "MediaInfoElPresentFlag": "ڈی وی ایل پیش سیٹ پرچم", "Subtitle": "ذیلی عنوان", - "EnableFallbackFont": "فال بیک فونٹس کو فعال کریں۔", + "EnableFallbackFont": "فال بیک فونٹس کو فعال کریں", "LabelMusicStreamingTranscodingBitrateHelp": "میوزک اسٹریم کرتے وقت زیادہ سے زیادہ بٹ ریٹ متعین کریں۔", "HeaderPhotoAlbums": "فوٹو البمز", "NewCollectionNameExample": "مثال: سٹار وار مجموعہ", @@ -1136,7 +1136,7 @@ "Save": "محفوظ کریں۔", "LabelMaxMuxingQueueSize": "زیادہ سے زیادہ مکسنگ قطار کا سائز", "HeaderConnectionFailure": "کنکشن کی ناکامی", - "HeaderConnectToServer": "سرور سے جڑیں۔", + "HeaderConnectToServer": "سرور سے جڑیں", "UninstallPluginConfirmation": "کیا آپ واقعی {0} کو اَن انسٹال کرنا چاہتے ہیں؟", "LabelPasswordRecoveryPinCode": "خفیہ نمبر", "LabelDefaultScreen": "ڈیفالٹ اسکرین", @@ -1153,15 +1153,15 @@ "Smaller": "چھوٹا", "ChangingMetadataImageSettingsNewContent": "میٹا ڈیٹا یا آرٹ ورک ڈاؤن لوڈ کرنے کی ترتیبات میں تبدیلیاں صرف آپ کی لائبریری میں شامل کردہ نئے مواد پر لاگو ہوں گی۔ موجودہ عنوانات میں تبدیلیوں کو لاگو کرنے کے لیے، آپ کو ان کے میٹا ڈیٹا کو دستی طور پر تازہ کرنا ہوگا۔", "MoreMediaInfo": "میڈیا کی معلومات", - "HeaderConfigureRemoteAccess": "ریموٹ رسائی سیٹ اپ کریں۔", + "HeaderConfigureRemoteAccess": "ریموٹ رسائی سیٹ اپ کریں", "HeaderRunningTasks": "رننگ ٹاسکس", "ValueCodec": "کوڈیک: {0}", "ValueDiscNumber": "ڈسک {0}", - "MessageNoRepositories": "کوئی ذخیرہ نہیں", + "MessageNoRepositories": "کوئی ذخیرہ نہی۔", "HeaderChannelAccess": "چینل تک رسائی", "LabelVideoResolution": "ویڈیو ریزولوشن", - "EnableGamepadHelp": "کسی بھی منسلک کنٹرولرز سے ان پٹ کے لیے سنیں۔", - "AudioChannelsNotSupported": "آڈیو چینلز کی تعداد تعاون یافتہ نہیں ہے۔", + "EnableGamepadHelp": "کسی بھی منسلک کنٹرولرز سے ان پٹ کے لیے سنیں", + "AudioChannelsNotSupported": "آڈیو چینلز کی تعداد تعاون یافتہ نہیں ہے", "OnlyForcedSubtitles": "صرف مجبور", "Overview": "جائزہ", "HeaderLibrarySettings": "لائبریری کی ترتیبات", @@ -1170,21 +1170,21 @@ "ButtonParentalControl": "والدین کا کنٹرول", "LabelAirTime": "ہوا کا وقت", "OptionParentalRating": "والدین کی درجہ بندی", - "HeaderSelectMetadataPath": "میٹا ڈیٹا پاتھ منتخب کریں۔", + "HeaderSelectMetadataPath": "میٹا ڈیٹا پاتھ منتخب کریں", "MediaInfoColorSpace": "رنگین جگہ", - "OptionEstimateContentLength": "ٹرانس کوڈنگ کرتے وقت مواد کی لمبائی کا اندازہ لگائیں۔", + "OptionEstimateContentLength": "ٹرانس کوڈنگ کرتے وقت مواد کی لمبائی کا اندازہ لگائیں", "OptionUnairedEpisode": "غیر نشر شدہ اقساط", "MessageNoPluginConfiguration": "اس پلگ ان میں سیٹ اپ کرنے کے لیے کوئی سیٹنگ نہیں ہے۔", "LabelTranscodingThreadCount": "ٹرانس کوڈنگ تھریڈ کی گنتی", "MediaInfoLevel": "سطح", "LabelCurrentPassword": "موجودہ خفیہ لفظ", - "LabelEnableRealtimeMonitor": "حقیقی وقت کی نگرانی کو فعال کریں۔", + "LabelEnableRealtimeMonitor": "حقیقی وقت کی نگرانی کو فعال کریں", "LabelSelectVersionToInstall": "انسٹال کرنے کے لیے ورژن منتخب کریں", "Premieres": "پریمیئرز", "FileReadError": "فائل پڑھتے وقت ایک خرابی پیش آگئی۔", "MessageNoPluginsInstalled": "آپ کے پاس کوئی پلگ ان انسٹال نہیں ہے۔", "Extras": "اضافی", - "LabelEnableAutomaticPortMap": "خودکار پورٹ میپنگ کو فعال کریں۔", + "LabelEnableAutomaticPortMap": "خودکار پورٹ میپنگ کو فعال کریں", "HeaderMetadataSettings": "میٹا ڈیٹا کی ترتیبات", "HeaderUsers": "صارفین", "LabelDownloadLanguages": "زبانیں ڈاؤن لوڈ کریں", @@ -1193,27 +1193,27 @@ "ValueOneEpisode": "1 ایپی سوڈ", "TabCodecs": "کوڈیکس", "Guide": "رہنما", - "LabelEnableHttps": "HTTPS کو فعال کریں۔", + "LabelEnableHttps": "HTTPS کو فعال کریں", "MessageSyncPlayIsDisabled": "SyncPlay استعمال کرنے کے لیے اجازت درکار ہے۔", "Yesterday": "کل", "MessageSyncPlayUserLeft": "{0} نے گروپ چھوڑ دیا ہے۔", "HeaderLatestMedia": "تازہ ترین میڈیا", - "PreferEmbeddedEpisodeInfosOverFileNames": "فائل ناموں پر ایمبیڈڈ ایپی سوڈ کی معلومات کو ترجیح دیں۔", + "PreferEmbeddedEpisodeInfosOverFileNames": "فائل ناموں پر ایمبیڈڈ ایپی سوڈ کی معلومات کو ترجیح دیں", "LabelCancelled": "منسوخ", "LabelPublicHttpPort": "عوامی HTTP پورٹ نمبر", "LabelSonyAggregationFlags": "سونی جمع جھنڈے", - "ButtonRefreshGuideData": "گائیڈ ڈیٹا ریفریش کریں۔", + "ButtonRefreshGuideData": "گائیڈ ڈیٹا ریفریش کریں", "OptionProtocolHttp": "HTTP", "Series": "سلسلہ", "Backdrop": "پس منظر", "TrackCount": "{0} ٹریکس", "Mute": "خاموش", "TabRepositories": "مخزن", - "ButtonAddMediaLibrary": "میڈیا لائبریری شامل کریں۔", + "ButtonAddMediaLibrary": "میڈیا لائبریری شامل کریں", "MediaInfoPath": "راستہ", "Runtime": "رن ٹائم", - "CancelSeries": "سیریز منسوخ کریں۔", - "MarkUnplayed": "غیر چلائے گئے نشان زد کریں۔", + "CancelSeries": "سیریز منسوخ کریں", + "MarkUnplayed": "غیر چلائے گئے نشان زد کریں", "ButtonEditOtherUserPreferences": "اس صارف کے پروفائل، تصویر اور ذاتی ترجیحات میں ترمیم کریں۔", "HeaderMoreLikeThis": "مزید اس طرح", "LabelVaapiDevice": "VA-API ڈیوائس", @@ -1222,14 +1222,14 @@ "ButtonStop": "رک جاؤ", "MessageLeaveEmptyToInherit": "پیرنٹ آئٹم یا عالمی ڈیفالٹ قدر سے وراثت کی ترتیبات کو خالی چھوڑ دیں۔", "SpecialFeatures": "خاص خوبیاں", - "Identify": "شناخت کریں۔", + "Identify": "شناخت کریں", "LabelStopping": "روکنا", - "SkipEpisodesAlreadyInMyLibrary": "وہ اقساط ریکارڈ نہ کریں جو میری لائبریری میں پہلے سے موجود ہیں۔", - "HeaderInstall": "انسٹال کریں۔", + "SkipEpisodesAlreadyInMyLibrary": "وہ اقساط ریکارڈ نہ کریں جو میری لائبریری میں پہلے سے موجود ہیں", + "HeaderInstall": "انسٹال کریں", "OptionIgnoreTranscodeByteRangeRequestsHelp": "ان درخواستوں کا احترام کیا جائے گا لیکن بائٹ رینج ہیڈر کو نظر انداز کر دیا جائے گا۔", "TellUsAboutYourself": "کچھ اپنے بارے میں بتائیں", "OptionIsHD": "ایچ ڈی", - "OptionAllowAudioPlaybackTranscoding": "آڈیو پلے بیک کی اجازت دیں جس کے لیے ٹرانس کوڈنگ کی ضرورت ہے۔", + "OptionAllowAudioPlaybackTranscoding": "آڈیو پلے بیک کی اجازت دیں جس کے لیے ٹرانس کوڈنگ کی ضرورت ہے", "LabelIconMaxHeight": "آئیکن کی زیادہ سے زیادہ اونچائی", "LabelLoginDisclaimer": "لاگ ان دستبرداری", "LabelSSDPTracingFilterHelp": "اختیاری IP پتہ جس پر لاگ ان SSDP ٹریفک کو فلٹر کرنا ہے۔", @@ -1240,7 +1240,7 @@ "DashboardArchitecture": "فن تعمیر: {0}", "LabelUserLibrary": "یوزر لائبریری", "HeaderTypeImageFetchers": "تصویر لانے والے ({0})", - "LabelSyncPlayHaltPlaybackDescription": "اور موجودہ پلے لسٹ اپ ڈیٹس کو نظر انداز کریں۔", + "LabelSyncPlayHaltPlaybackDescription": "اور موجودہ پلے لسٹ اپ ڈیٹس کو نظر انداز کریں", "LabelUserAgent": "صارف ایجنٹ", "LabelLocalHttpServerPortNumberHelp": "HTTP سرور کے لیے TCP پورٹ نمبر۔", "LabelAutomaticDiscoveryHelp": "ایپلی کیشنز کو UDP پورٹ 7359 کا استعمال کر کے خود بخود جیلیفن کا پتہ لگانے کی اجازت دیں۔", @@ -1252,8 +1252,8 @@ "Name": "نام", "LabelImageFetchersHelp": "ترجیحی ترتیب کے لحاظ سے اپنے پسندیدہ امیج فیچرز کو فعال اور درجہ دیں۔", "AllowVppTonemappingHelp": "مکمل انٹیل ڈرائیور پر مبنی ٹون میپنگ۔ فی الحال HDR10 ویڈیوز کے ساتھ صرف مخصوص ہارڈ ویئر پر کام کرتا ہے۔ دوسرے OpenCL نفاذ کے مقابلے میں اس کی ترجیح زیادہ ہے۔", - "NextTrack": "اگلے پر جائیں۔", - "EnableStreamLooping": "لائیو سٹریمز کو آٹو لوپ کریں۔", + "NextTrack": "اگلے پر جائیں", + "EnableStreamLooping": "لائیو سٹریمز کو آٹو لوپ کریں", "LabelPlaybackInfo": "پلے بیک کی معلومات", "LabelffmpegPathHelp": "FFmpeg ایپلیکیشن فائل یا FFmpeg پر مشتمل فولڈر کا راستہ۔", "ValueTimeLimitSingleHour": "وقت کی حد: 1 گھنٹہ", @@ -1270,7 +1270,7 @@ "LabelBirthDate": "تاریخ پیدائش", "HeaderAudioSettings": "آڈیو کی ترتیبات", "MediaInfoAnamorphic": "انامورفک", - "AllowHevcEncoding": "HEVC فارمیٹ میں انکوڈنگ کی اجازت دیں۔", + "AllowHevcEncoding": "HEVC فارمیٹ میں انکوڈنگ کی اجازت دیں", "ButtonAudioTracks": "آڈیو ٹریکس", "LabelTextBackgroundColor": "متن کے پس منظر کا رنگ", "ConfirmDeleteItem": "اس آئٹم کو حذف کرنے سے یہ فائل سسٹم اور آپ کی میڈیا لائبریری دونوں سے حذف ہو جائے گا۔ کیا آپ واقعی جاری رکھنا چاہتے ہیں؟", @@ -1284,8 +1284,8 @@ "HeaderLatestMusic": "تازہ ترین موسیقی", "Vertical": "عمودی", "OptionHideUserFromLoginHelp": "نجی یا پوشیدہ ایڈمنسٹریٹر اکاؤنٹس کے لیے مفید ہے۔ صارف کو اپنا صارف نام اور پاس ورڈ درج کرکے دستی طور پر سائن ان کرنے کی ضرورت ہوگی۔", - "OptionAllowSyncTranscoding": "میڈیا کو ڈاؤن لوڈ اور مطابقت پذیری کی اجازت دیں جس کے لیے ٹرانس کوڈنگ کی ضرورت ہے۔", - "EditSubtitles": "ذیلی عنوانات میں ترمیم کریں۔", + "OptionAllowSyncTranscoding": "میڈیا کو ڈاؤن لوڈ اور مطابقت پذیری کی اجازت دیں جس کے لیے ٹرانس کوڈنگ کی ضرورت ہے", + "EditSubtitles": "ذیلی عنوانات میں ترمیم کریں", "OptionExternallyDownloaded": "بیرونی ڈاؤن لوڈ", "GuestStar": "مہمان ستارہ", "RecommendationDirectedBy": "ہدایت کار {0}", @@ -1295,20 +1295,20 @@ "MessageNoTrailersFound": "انٹرنیٹ ٹریلرز کی لائبریری شامل کر کے اپنے مووی کے تجربے کو بڑھانے کے لیے ٹریلرز چینل انسٹال کریں۔", "LabelTheme": "خیالیہ", "LabelDisplayOrder": "ڈسپلے آرڈر", - "OptionAllowLinkSharing": "سوشل میڈیا شیئرنگ کی اجازت دیں۔", + "OptionAllowLinkSharing": "سوشل میڈیا شیئرنگ کی اجازت دیں", "MediaInfoSize": "سائز", "LabelAirsBeforeSeason": "موسم سے پہلے نشر", "Copied": "کاپی", "Copy": "کاپی", "CopyFailed": "کاپی نہیں ہو سکا", "HeaderExternalIds": "بیرونی IDs", - "LabelKodiMetadataSaveImagePaths": "NFO فائلوں میں تصویری راستے محفوظ کریں۔", - "OptionEmbedSubtitles": "کنٹینر کے اندر سرایت کریں۔", - "OptionEnableForAllTuners": "تمام ٹیونر آلات کے لیے فعال کریں۔", - "OptionEquals": "برابر ہے۔", + "LabelKodiMetadataSaveImagePaths": "NFO فائلوں میں تصویری راستے محفوظ کریں", + "OptionEmbedSubtitles": "کنٹینر کے اندر سرایت کریں", + "OptionEnableForAllTuners": "تمام ٹیونر آلات کے لیے فعال کریں", + "OptionEquals": "برابر ہے", "HeaderSelectMetadataPathHelp": "وہ راستہ براؤز کریں یا داخل کریں جسے آپ میٹا ڈیٹا کے لیے استعمال کرنا چاہتے ہیں۔ فولڈر قابل تحریر ہونا چاہیے۔", "ReleaseGroup": "ریلیز گروپ", - "Repeat": "دہرائیں۔", + "Repeat": "دہرائیں", "LabelSubtitleVerticalPosition": "عمودی پوزیشن", "Sort": "ترتیب دیں", "StopPlayback": "پلے بیک بند کرو", @@ -1318,7 +1318,7 @@ "Tuesday": "منگل", "LabelSyncPlayAccessNone": "اس صارف کے لیے غیر فعال", "ValueOneAlbum": "1 البم", - "OptionDisableUser": "اس صارف کو غیر فعال کریں۔", + "OptionDisableUser": "اس صارف کو غیر فعال کریں", "OptionRegex": "ریجیکس", "OptionDatePlayed": "کھیلے جانے کی تاریخ", "XmlTvPathHelp": "XMLTV فائل کا راستہ۔ جیلیفن اس فائل کو پڑھے گا اور وقتاً فوقتاً اسے اپ ڈیٹس کے لیے چیک کرے گا۔ آپ فائل بنانے اور اپ ڈیٹ کرنے کے ذمہ دار ہیں۔", @@ -1342,13 +1342,13 @@ "PasswordResetComplete": "پاس ورڈ دوبارہ ترتیب دیا گیا ہے۔", "LabelMoviePrefix": "فلم کا سابقہ", "LabelUserLibraryHelp": "منتخب کریں کہ کون سی صارف لائبریری کو آلہ پر ڈسپلے کرنا ہے۔ پہلے سے طے شدہ ترتیب کو وراثت میں لینے کے لیے خالی چھوڑ دیں۔", - "DeleteImage": "تصویر کو حذف کریں۔", - "LabelSyncPlayResumePlaybackDescription": "بیک گروپ پلے بیک میں شامل ہوں۔", + "DeleteImage": "تصویر کو حذف کریں", + "LabelSyncPlayResumePlaybackDescription": "بیک گروپ پلے بیک میں شامل ہوں", "HeaderImageOptions": "تصویری اختیارات", "TabOther": "دیگر", - "LabelRequireHttps": "HTTPS کی ضرورت ہے۔", + "LabelRequireHttps": "HTTPS کی ضرورت ہے", "HeaderSelectFallbackFontPathHelp": "ASS/SSA سب ٹائٹلز پیش کرنے کے لیے استعمال کرنے کے لیے فال بیک فونٹ فولڈر کا راستہ براؤز کریں یا داخل کریں۔", - "DisplayInMyMedia": "ہوم اسکرین پر ڈسپلے کریں۔", + "DisplayInMyMedia": "ہوم اسکرین پر ڈسپلے کریں", "LabelCurrentStatus": "موجودہ صورت حال", "OptionAdminUsers": "منتظمین", "MessageSyncPlayJoinGroupDenied": "گروپ میں شامل نہیں ہو سکتا۔", @@ -1364,14 +1364,14 @@ "LabelImageType": "تصویر کی قسم", "MessageDeleteTaskTrigger": "کیا آپ واقعی اس ٹاسک ٹرگر کو حذف کرنا چاہتے ہیں؟", "HeaderStatus": "حالت", - "ManageRecording": "ریکارڈنگ کا انتظام کریں۔", + "ManageRecording": "ریکارڈنگ کا انتظام کریں", "ButtonTrailer": "ٹریلر", "HeaderProfileInformation": "ذاتی معلومات", "HeaderLiveTvTunerSetup": "لائیو ٹی وی ٹونر سیٹ اپ", "PlayNext": "اگلا کھیلیں", "LabelPlaceOfBirth": "جائے پیدائش", "PlaceFavoriteChannelsAtBeginning": "شروع میں پسندیدہ چینلز رکھیں", - "ConfirmDeletion": "حذف کرنے کی تصدیق کریں۔", + "ConfirmDeletion": "حذف کرنے کی تصدیق کریں", "MediaInfoCodec": "کوڈیک", "YoutubePlaybackError": "درخواست کردہ ویڈیو نہیں چلائی جا سکتی۔", "LabelCache": "کیش", @@ -1379,13 +1379,13 @@ "TabNotifications": "اطلاعات", "HeaderResponseProfile": "جوابی پروفائل", "PasswordMatchError": "پاس ورڈ اور پاس ورڈ کی تصدیق مماثل ہونی چاہیے۔", - "HeaderAddToCollection": "مجموعہ میں شامل کریں۔", + "HeaderAddToCollection": "مجموعہ میں شامل کریں", "OptionAllowRemoteSharedDevicesHelp": "DLNA ڈیوائسز کو اس وقت تک مشترکہ سمجھا جاتا ہے جب تک کہ صارف ان کو کنٹرول کرنا شروع نہیں کرتا ہے۔", - "OptionEnableM2tsMode": "M2TS موڈ کو فعال کریں۔", + "OptionEnableM2tsMode": "M2TS موڈ کو فعال کریں", "EnableNextVideoInfoOverlayHelp": "ویڈیو کے آخر میں، موجودہ پلے لسٹ میں آنے والی اگلی ویڈیو کے بارے میں معلومات دکھائیں۔", "LabelStopWhenPossible": "جب ممکن ہو روکیں", "LabelZipCode": "زپ کوڈ", - "DeleteMedia": "میڈیا کو حذف کریں۔", + "DeleteMedia": "میڈیا کو حذف کریں", "LabelTunerIpAddress": "ٹونر آئی پی ایڈریس", "LabelDeinterlaceMethod": "ڈانٹرلیسنگ کا طریقہ", "ViewPlaybackInfo": "پلے بیک کی معلومات دیکھیں", @@ -1394,7 +1394,7 @@ "MediaInfoResolution": "قرارداد", "Images": "امیجز", "OptionOnInterval": "وقفے پر", - "QuickConnectAuthorizeSuccess": "درخواست کی اجازت دی گئی۔", + "QuickConnectAuthorizeSuccess": "درخواست کی اجازت دی گئی", "TabStreaming": "سلسلہ بندی", "HeaderActiveRecordings": "فعال ریکارڈنگز", "MessagePleaseWait": "برائے مہربانی انتظار کریں. اس میں ایک منٹ لگ سکتا ہے۔", @@ -1415,12 +1415,12 @@ "MediaInfoColorPrimaries": "رنگین پرائمریز", "HeaderSortBy": "ترتیب دیں", "Label3DFormat": "3D فارمیٹ", - "HeaderConfirmRevokeApiKey": "API کلید کو منسوخ کریں۔", + "HeaderConfirmRevokeApiKey": "API کلید کو منسوخ کریں", "LabelDisplayMode": "ڈسپلے موڈ", "LabelCollection": "مجموعہ", "Subtitles": "سب ٹائٹلز", "LabelSendNotificationToUsers": "اطلاع بھیجیں", - "LabelAutomaticallyAddToCollection": "خودکار طور پر مجموعہ میں شامل کریں۔", + "LabelAutomaticallyAddToCollection": "خودکار طور پر مجموعہ میں شامل کریں", "TabContainers": "کنٹینرز", "LabelAutomaticallyAddToCollectionHelp": "جب کم از کم 2 فلموں کا ایک ہی مجموعہ کا نام ہوگا، تو وہ خودکار طور پر مجموعہ میں شامل ہو جائیں گی۔", "LabelBlastMessageInterval": "زندہ پیغام کا وقفہ", @@ -1429,14 +1429,14 @@ "LabelDateAddedBehaviorHelp": "اگر میٹا ڈیٹا ویلیو موجود ہے، تو یہ ہمیشہ ان میں سے کسی ایک آپشن سے پہلے استعمال کی جائے گی۔", "LabelEasyPinCode": "آسان پن کوڈ", "LabelEnableIP6Help": "IPv6 فعالیت کو فعال کریں۔", - "Continuing": "جاری ہے۔", + "Continuing": "جاری ہے", "ChannelNumber": "چینل نمبر", - "LabelSyncPlaySettingsDescription": "SyncPlay کی ترجیحات کو تبدیل کریں۔", + "LabelSyncPlaySettingsDescription": "SyncPlay کی ترجیحات کو تبدیل کریں", "HeaderSubtitleAppearance": "ذیلی عنوان کی ظاہری شکل", "HeaderVideoTypes": "ویڈیو کی اقسام", "Filters": "فلٹرز", "LabelAccessEnd": "اختتامی وقت", - "LabelSyncPlaySettingsSpeedToSync": "SpeedToSync کو فعال کریں۔", + "LabelSyncPlaySettingsSpeedToSync": "SpeedToSync کو فعال کریں", "Never": "کبھی نہیں", "PreviousChapter": "پچھلا باب", "HeaderCodecProfile": "کوڈیک پروفائل", @@ -1446,17 +1446,17 @@ "MediaInfoVideoRange": "ویڈیو کی حد", "TypeOptionPluralMusicArtist": "موسیقی کے فنکار", "HeaderDeveloperInfo": "ڈویلپر کی معلومات", - "LabelVersionInstalled": "{0} انسٹال ہوا۔", - "HeaderEditImages": "امیجز میں ترمیم کریں۔", + "LabelVersionInstalled": "{0} انسٹال ہوا", + "HeaderEditImages": "امیجز میں ترمیم کریں", "OptionMissingEpisode": "مسنگ ایپی سوڈز", "ViewAlbum": "البم دیکھیں", "ViewAlbumArtist": "البم آرٹسٹ دیکھیں", - "LabelAllowHWTranscoding": "ہارڈویئر ٹرانس کوڈنگ کی اجازت دیں۔", + "LabelAllowHWTranscoding": "ہارڈویئر ٹرانس کوڈنگ کی اجازت دیں", "DashboardOperatingSystem": "آپریٹنگ سسٹم: {0}", - "ContainerNotSupported": "کنٹینر تعاون یافتہ نہیں ہے۔", - "HeaderSelectPath": "راستہ منتخب کریں۔", + "ContainerNotSupported": "کنٹینر تعاون یافتہ نہیں ہے", + "HeaderSelectPath": "راستہ منتخب کریں", "LabelBitrate": "بٹریٹ", - "AudioBitDepthNotSupported": "آڈیو کی تھوڑا سا گہرائی تعاون یافتہ نہیں ہے۔", + "AudioBitDepthNotSupported": "آڈیو کی تھوڑا سا گہرائی تعاون یافتہ نہیں ہے", "People": "لوگ", "Depressed": "اداس", "Horizontal": "افقی", @@ -1465,25 +1465,25 @@ "Anytime": "کسی بھی وقت", "LabelSelectStereo": "سٹیریو", "ValueEpisodeCount": "{0} ایپی سوڈز", - "EnableHardwareEncoding": "ہارڈویئر انکوڈنگ کو فعال کریں۔", + "EnableHardwareEncoding": "ہارڈویئر انکوڈنگ کو فعال کریں", "TabNetworking": "نیٹ ورکنگ", "LabelRepositoryName": "مخزن کا نام", "OnApplicationStartup": "درخواست کے آغاز پر", "ThemeSongs": "تھیم گانے", "Next": "اگلے", - "OptionDisplayFolderView": "سادہ میڈیا فولڈرز دکھانے کے لیے فولڈر کا منظر دکھائیں۔", + "OptionDisplayFolderView": "سادہ میڈیا فولڈرز دکھانے کے لیے فولڈر کا منظر دکھائیں", "Home": "گھر", "HeaderRecordingOptions": "ریکارڈنگ کے اختیارات", "ThumbCard": "انگوٹھا کارڈ", "LabelCustomCertificatePath": "حسب ضرورت SSL سرٹیفکیٹ کا راستہ", "Categories": "اقسام", - "ButtonRevoke": "منسوخ کریں۔", + "ButtonRevoke": "منسوخ کریں", "TabDashboard": "ڈیش بورڈ", "LabelAudioBitrate": "آڈیو بٹریٹ", "SeriesCancelled": "سیریز منسوخ کر دی گئی۔", "LabelHttpsPort": "مقامی HTTPS پورٹ نمبر", "OptionRandom": "بے ترتیب", - "ButtonAddUser": "صارف شامل کریں۔", + "ButtonAddUser": "صارف شامل کریں", "RecommendationBecauseYouWatched": "کیونکہ آپ نے {0} دیکھا", "LabelTranscodePath": "ٹرانس کوڈ کا راستہ", "LabelProfileContainersHelp": "کوما سے الگ کیا گیا۔ اسے تمام کنٹینرز پر لاگو کرنے کے لیے خالی چھوڑا جا سکتا ہے۔", @@ -1506,7 +1506,7 @@ "ResetPassword": "پاس ورڈ ری سیٹ", "Ascending": "صعودی", "OptionProtocolHls": "HTTP لائیو سٹریمنگ (HLS)", - "OptionAllowBrowsingLiveTv": "لائیو ٹی وی تک رسائی کی اجازت دیں۔", + "OptionAllowBrowsingLiveTv": "لائیو ٹی وی تک رسائی کی اجازت دیں", "OnlyForcedSubtitlesHelp": "صرف ان سب ٹائٹلز کو لوڈ کیا جائے گا جنہیں زبردستی کے بطور نشان زد کیا گیا ہے۔", "Uniform": "وردی", "LabelTranscodes": "ٹرانس کوڈز", @@ -1514,13 +1514,13 @@ "LabelUDPPortRange": "UDP کمیونیکیشن رینج", "LabelIsForced": "مجبور", "SendMessage": "پیغام بھیجیں", - "HeaderTypeText": "متن درج کریں۔", + "HeaderTypeText": "متن درج کریں", "Desktop": "ڈیسک ٹاپ", "LabelNewPasswordConfirm": "نئے پاس ورڈ کی تصدیق", - "EnableDecodingColorDepth10Hevc": "HEVC کے لیے 10 بٹ ہارڈویئر ڈی کوڈنگ کو فعال کریں۔", + "EnableDecodingColorDepth10Hevc": "HEVC کے لیے 10 بٹ ہارڈویئر ڈی کوڈنگ کو فعال کریں", "LabelVideoCodec": "ویڈیو کوڈیک", "LabelAllowedRemoteAddresses": "ریموٹ آئی پی ایڈریس فلٹر", - "ButtonSelectDirectory": "ڈائرکٹری منتخب کریں۔", + "ButtonSelectDirectory": "ڈائرکٹری منتخب کریں", "SortName": "ترتیب دیں نام", "Casual": "آرام دہ اور پرسکون", "Console": "تسلی", @@ -1537,11 +1537,11 @@ "Bold": "بولڈ", "OptionReportByteRangeSeekingWhenTranscodingHelp": "یہ کچھ ایسے آلات کے لیے درکار ہے جو وقت کی اچھی طرح تلاش نہیں کرتے ہیں۔", "OptionTvdbRating": "ٹی وی ڈی بی کی درجہ بندی", - "RefreshMetadata": "میٹا ڈیٹا ریفریش کریں۔", + "RefreshMetadata": "میٹا ڈیٹا ریفریش کریں", "UserAgentHelp": "ایک حسب ضرورت 'یوزر-ایجنٹ' HTTP ہیڈر فراہم کریں۔", "Remuxing": "Remuxing", "YoutubeBadRequest": "غلط فرمائش.", - "EnableCardLayout": "بصری کارڈ باکس ڈسپلے کریں۔", + "EnableCardLayout": "بصری کارڈ باکس ڈسپلے کریں", "EnableStreamLoopingHelp": "اگر لائیو اسٹریمز میں صرف چند سیکنڈ کا ڈیٹا ہوتا ہے اور اسے مسلسل درخواست کرنے کی ضرورت ہوتی ہے تو اسے فعال کریں۔ ضرورت نہ ہونے پر اسے فعال کرنے سے مسائل پیدا ہو سکتے ہیں۔", "LabelDay": "ہفتے کا دن", "LabelSource": "ذریعہ", @@ -1568,9 +1568,9 @@ "OptionAutomaticallyGroupSeriesHelp": "اس لائبریری کے اندر متعدد فولڈرز میں پھیلی ہوئی سیریز خود بخود ایک سیریز میں ضم ہو جائیں گی۔", "OptionBluray": "بی ڈی", "OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)", - "OptionDateAddedImportTime": "لائبریری میں اسکین شدہ تاریخ کا استعمال کریں۔", - "OptionEnableAccessFromAllDevices": "تمام آلات سے رسائی کو فعال کریں۔", - "OptionEnableAccessToAllLibraries": "تمام لائبریریوں تک رسائی کو فعال کریں۔", + "OptionDateAddedImportTime": "لائبریری میں اسکین شدہ تاریخ کا استعمال کریں", + "OptionEnableAccessFromAllDevices": "تمام آلات سے رسائی کو فعال کریں", + "OptionEnableAccessToAllLibraries": "تمام لائبریریوں تک رسائی کو فعال کریں", "OptionHasThemeSong": "مرکزی نغمہ", "OptionLoginAttemptsBeforeLockoutHelp": "صفر کی قدر کا مطلب ہے کہ عام صارفین کے لیے تین اور منتظمین کے لیے پانچ کا ڈیفالٹ وراثت میں ملنا۔ اسے -1 پر سیٹ کرنے سے فیچر غیر فعال ہو جائے گا۔", "OptionMax": "زیادہ سے زیادہ", @@ -1578,20 +1578,20 @@ "OtherArtist": "دوسرے فنکار", "PackageInstallCompleted": "{0} (ورژن {1}) کی تنصیب مکمل ہو گئی۔", "PlaybackData": "پلے بیک کی معلومات", - "AllowEmbeddedSubtitlesAllowAllOption": "سب کو اجازت دیں۔", - "AllowEmbeddedSubtitlesAllowNoneOption": "کسی کو اجازت نہ دیں۔", - "AllowEmbeddedSubtitlesAllowImageOption": "تصویر کی اجازت دیں۔", - "AllowEmbeddedSubtitlesAllowTextOption": "متن کی اجازت دیں۔", + "AllowEmbeddedSubtitlesAllowAllOption": "سب کو اجازت دیں", + "AllowEmbeddedSubtitlesAllowNoneOption": "کسی کو اجازت نہ دیں", + "AllowEmbeddedSubtitlesAllowImageOption": "تصویر کی اجازت دیں", + "AllowEmbeddedSubtitlesAllowTextOption": "متن کی اجازت دیں", "Premiere": "پریمیئر", "Print": "پرنٹ کریں", "Production": "پیداوار", "Quality": "معیار", "QuickConnect": "فوری کنیکٹ", - "QuickConnectActivationSuccessful": "کامیابی سے چالو ہو گیا۔", + "QuickConnectActivationSuccessful": "کامیابی سے چالو ہو گیا", "Record": "ریکارڈ", - "ShowYear": "سال دکھائیں۔", - "ContainerBitrateExceedsLimit": "ویڈیو کا بٹ ریٹ حد سے زیادہ ہے۔", - "PreferSystemNativeHwDecoder": "OS مقامی DXVA یا VA-API ہارڈویئر ڈیکوڈرز کو ترجیح دیں۔", + "ShowYear": "سال دکھائیں", + "ContainerBitrateExceedsLimit": "ویڈیو کا بٹ ریٹ حد سے زیادہ ہے", + "PreferSystemNativeHwDecoder": "OS مقامی DXVA یا VA-API ہارڈویئر ڈیکوڈرز کو ترجیح دیں", "ItemDetails": "آئٹم کی تفصیلات", "LabelDisplayLanguage": "ڈسپلے کی زبان", "LabelFailed": "ناکام", @@ -1600,9 +1600,9 @@ "LabelMetadataPathHelp": "ڈاؤن لوڈ کردہ آرٹ ورک اور میٹا ڈیٹا کے لیے اپنی مرضی کے مطابق مقام کی وضاحت کریں۔", "LabelSortName": "ترتیب دیں نام", "LabelSyncPlaySettingsMinDelaySpeedToSyncHelp": "کم از کم پلے بیک تاخیر (ms میں) جس کے بعد SpeedToSync پلے بیک پوزیشن کو درست کرنے کی کوشش کرتا ہے۔", - "OptionAllowManageLiveTv": "لائیو ٹی وی ریکارڈنگ کے انتظام کی اجازت دیں۔", - "OptionExtractChapterImage": "باب کی تصویر نکالنے کو فعال کریں۔", - "OptionHideUser": "اس صارف کو لاگ ان اسکرینوں سے چھپائیں۔", + "OptionAllowManageLiveTv": "لائیو ٹی وی ریکارڈنگ کے انتظام کی اجازت دیں", + "OptionExtractChapterImage": "باب کی تصویر نکالنے کو فعال کریں", + "OptionHideUser": "اس صارف کو لاگ ان اسکرینوں سے چھپائیں", "OptionIsSD": "ایس ڈی", "TabMyPlugins": "میرے پلگ انز", "TvLibraryHelp": "{0}ٹی وی کے نام کی گائیڈ{1} کا جائزہ لیں۔", @@ -1619,11 +1619,11 @@ "LabelSlowResponseTime": "ms میں وقت جس کے بعد جواب سست سمجھا جاتا ہے", "TabAdvanced": "اعلی درجے کی", "HeaderAccessScheduleHelp": "مخصوص اوقات تک رسائی کو محدود کرنے کے لیے رسائی کا شیڈول بنائیں۔", - "EnableSplashScreen": "سپلیش اسکرین کو فعال کریں۔", + "EnableSplashScreen": "سپلیش اسکرین کو فعال کریں", "OptionLoginAttemptsBeforeLockout": "لاک آؤٹ ہونے سے پہلے اس بات کا تعین کریں کہ لاگ ان کی کتنی غلط کوششیں کی جا سکتی ہیں۔", "OptionPremiereDate": "پریمیئر کی تاریخ", "OptionResElement": "'res' عنصر", - "OptionSaveMetadataAsHidden": "میٹا ڈیٹا اور امیجز کو پوشیدہ فائلوں کے طور پر محفوظ کریں۔", + "OptionSaveMetadataAsHidden": "میٹا ڈیٹا اور امیجز کو پوشیدہ فائلوں کے طور پر محفوظ کریں", "OptionSaveMetadataAsHiddenHelp": "اسے تبدیل کرنے کا اطلاق مستقبل میں محفوظ کیے گئے نئے میٹا ڈیٹا پر ہوگا۔ موجودہ میٹا ڈیٹا فائلوں کو اگلی بار سرور کے ذریعہ محفوظ کرنے پر اپ ڈیٹ کیا جائے گا۔", "Schedule": "شیڈول", "TonemappingAlgorithmHelp": "ٹون میپنگ کو ٹھیک بنایا جا سکتا ہے۔ اگر آپ ان اختیارات سے واقف نہیں ہیں تو صرف ڈیفالٹ رکھیں۔ تجویز کردہ قدر 'BT.2390' ہے۔", @@ -1646,11 +1646,11 @@ "WelcomeToProject": "جیلیفن میں خوش آمدید!", "Whitelist": "وائٹ لسٹ", "WriteAccessRequired": "جیلیفن کو اس فولڈر تک تحریری رسائی درکار ہے۔ براہ کرم تحریری رسائی کو یقینی بنائیں اور دوبارہ کوشش کریں۔", - "EnableIntelLowPowerH264HwEncoder": "Intel Low-Power H.264 ہارڈویئر انکوڈر کو فعال کریں۔", - "EnableIntelLowPowerHevcHwEncoder": "Intel Low-Power HEVC ہارڈویئر انکوڈر کو فعال کریں۔", - "AudioIsExternal": "آڈیو سلسلہ بیرونی ہے۔", - "VideoBitrateNotSupported": "ویڈیو کا بٹ ریٹ تعاون یافتہ نہیں ہے۔", - "UnknownVideoStreamInfo": "ویڈیو اسٹریم کی معلومات نامعلوم ہے۔", + "EnableIntelLowPowerH264HwEncoder": "Intel Low-Power H.264 ہارڈویئر انکوڈر کو فعال کریں", + "EnableIntelLowPowerHevcHwEncoder": "Intel Low-Power HEVC ہارڈویئر انکوڈر کو فعال کریں", + "AudioIsExternal": "آڈیو سلسلہ بیرونی ہے", + "VideoBitrateNotSupported": "ویڈیو کا بٹ ریٹ تعاون یافتہ نہیں ہے", + "UnknownVideoStreamInfo": "ویڈیو اسٹریم کی معلومات نامعلوم ہے", "SelectAll": "تمام منتخب کریں", "Clip": "فیچرٹی", "MessageUnauthorizedUser": "آپ اس وقت سرور تک رسائی کے مجاز نہیں ہیں۔ مزید معلومات کے لیے براہ کرم اپنے سرور ایڈمنسٹریٹر سے رابطہ کریں۔", @@ -1669,6 +1669,6 @@ "LiveTV": "لائیو ٹی وی", "Localization": "لوکلائزیشن", "OptionDateAdded": "شامل کرنے کی تاریخ", - "OptionPlainVideoItems": "تمام ویڈیوز کو سادہ ویڈیو آئٹمز کے طور پر ڈسپلے کریں۔", + "OptionPlainVideoItems": "تمام ویڈیوز کو سادہ ویڈیو آئٹمز کے طور پر ڈسپلے کریں", "MessageRenameMediaFolder": "میڈیا لائبریری کا نام تبدیل کرنے سے تمام میٹا ڈیٹا ضائع ہو جائے گا، احتیاط کے ساتھ آگے بڑھیں۔" } From 0ae6a89c1b9149c7302d8fd17e27415e9e8018d8 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:20 +0000 Subject: [PATCH 103/112] Translated using Weblate (Esperanto) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/eo/ --- src/strings/eo.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/eo.json b/src/strings/eo.json index 387fd4f994..eefb15d5ac 100644 --- a/src/strings/eo.json +++ b/src/strings/eo.json @@ -1243,7 +1243,7 @@ "OnlyForcedSubtitlesHelp": "Nur subtekstoj ŝarĝitos markitaj kiel forcitaj.", "LabelSelectFolderGroupsHelp": "Dosierujoj malelektitaj montriĝos mem laŭ sia propra vido.", "AllowRemoteAccessHelp": "Se malelektita, ĉiuj foraj konektoj estos blokitaj.", - "EnableGamepadHelp": "Aŭskulti pri enigo de iuj konektitaj regiloj.", + "EnableGamepadHelp": "Aŭskulti pri enigo de iuj konektitaj regiloj", "OptionEnableM2tsModeHelp": "Ebligi M2TS-reĝimon dum kodado al MPEG-TS.", "SubtitleAppearanceSettingsDisclaimer": "La sekvaj parametroj ne validas por la grafikaj subtekstoj menciitaj supre aŭ ASS/SSA subtekstoj kiuj enigas siajn proprajn stilojn.", "KnownProxiesHelp": "Komo apartigita listo de IP-adresoj aŭ gastignomoj de konataj prokuriloj uzataj kiam vi konektas al via Jellyfin-ekzemplo. Ĉi tio estas bezonata por ĝuste uzi \"X-Forwarded-For\" ĉapojn. Necesas relanĉon post savado.", From b3d5298a4d59ae01d00f3ee4c99ea33d3e3d5de7 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:29:44 +0000 Subject: [PATCH 104/112] Translated using Weblate (Tamil) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ta/ --- src/strings/ta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/ta.json b/src/strings/ta.json index 3e2c2e3a9b..803171e6f1 100644 --- a/src/strings/ta.json +++ b/src/strings/ta.json @@ -1525,7 +1525,7 @@ "Framerate": "பிரேம் வீதம்", "DirectPlayHelp": "மூல கோப்பு இந்த கிளையனுடன் முற்றிலும் ஒத்துப்போகும், மேலும் அமர்வு மாற்றங்கள் இல்லாமல் கோப்பைப் பெறுகிறது.", "HeaderContinueReading": "தொடர்ந்து படிக்க", - "EnableGamepadHelp": "இணைக்கப்பட்ட எந்த கட்டுப்படுத்திகளிடமிருந்தும் உள்ளீட்டைக் கேளுங்கள்.", + "EnableGamepadHelp": "இணைக்கப்பட்ட எந்த கட்டுப்படுத்திகளிடமிருந்தும் உள்ளீட்டைக் கேளுங்கள்", "LabelEnableGamepad": "கேம்பேட்டை இயக்கு", "Controls": "கட்டுப்பாடுகள்", "TextSent": "உரை அனுப்பப்பட்டது.", From e6729af9425def5d58d6fc81311289f222b0ddbc Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:25 +0000 Subject: [PATCH 105/112] Translated using Weblate (Estonian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/et/ --- src/strings/et.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/et.json b/src/strings/et.json index c3e153e2f3..810edcea6d 100644 --- a/src/strings/et.json +++ b/src/strings/et.json @@ -1567,7 +1567,7 @@ "TypeOptionPluralMusicAlbum": "Muusika albumid", "TypeOptionPluralMovie": "Filmid", "SortByValue": "Järjesta {0}", - "EnableGamepadHelp": "Kuula ühendatud juhtseadmete sisendit.", + "EnableGamepadHelp": "Kuula ühendatud juhtseadmete sisendit", "LabelOriginalMediaInfo": "Algsed meedia andmed", "RemuxHelp2": "Remuksimine kasutab väga vähe jõudlust, ilma et meedia kvaliteet väheneks.", "WeeklyAt": "{0}s kell {1}", From 4e24a2b2b5ae9b653274e7d11d943b66c1588586 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:28 +0000 Subject: [PATCH 106/112] Translated using Weblate (Basque) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/eu/ --- src/strings/eu.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/strings/eu.json b/src/strings/eu.json index c6dde7d0fc..07059abc46 100644 --- a/src/strings/eu.json +++ b/src/strings/eu.json @@ -48,7 +48,7 @@ "SubtitleCodecNotSupported": "Azpitituluen kodea ez da bateragarria", "ContainerNotSupported": "Ez da onartzen edukiontzia", "AudioCodecNotSupported": "Audio-kodea ez da bateragarria", - "EnableGamepadHelp": "Entzun konektatutako edozein kontrolatzaileren sarrera.", + "EnableGamepadHelp": "Entzun konektatutako edozein kontrolatzaileren sarrera", "LabelEnableGamepad": "Gaikuntza Agintea", "Controls": "Kontrolak", "AllowVppTonemappingHelp": "Hardwarean oinarritutako tonuen mapaketa osoa, OpenCL iragazkia erabili gabe. Une honetan txertatutako HDR10 metadatuekin bideoak transkodifikatzean bakarrik funtzionatzen du.", @@ -305,8 +305,8 @@ "Record": "Grabatu", "RecommendationStarring": "Protagonista: {0}", "RecommendationDirectedBy": "Zuzendaria: {0}", - "RecommendationBecauseYouWatched": "{0} ikusi duzunez…", - "RecommendationBecauseYouLike": "{0} gustatu zaizunez…", + "RecommendationBecauseYouWatched": "{0} ikusi duzunez", + "RecommendationBecauseYouLike": "{0} gustatu zaizunez", "RecentlyWatched": "Duela gutxi ikusitakoak", "Rate": "Kalifikatzen du", "Raised": "Goratuak", From 5f86d89ca6410de7486fa86b4af5fdfc05208952 Mon Sep 17 00:00:00 2001 From: Alan Azar Date: Fri, 5 May 2023 11:28:55 +0000 Subject: [PATCH 107/112] Translated using Weblate (Malagasy) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/mg/ --- src/strings/mg.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/mg.json b/src/strings/mg.json index 54e2956c06..9cb6c466f8 100644 --- a/src/strings/mg.json +++ b/src/strings/mg.json @@ -35,7 +35,7 @@ "AllowHevcEncoding": "Avela hamadika format HEVC", "AllowHWTranscodingHelp": "Avela ny tuner hiasa sady mamadika format. Mety hanampy amin'ny fampihenana ny asa takian'ny serveur izany.", "AllowMediaConversionHelp": "Avela na lavina ny fidirana amin'ny asa famadihana format.", - "AllowOnTheFlySubtitleExtraction": "Avela hamaky dikanteny eny ampandehanana.", + "AllowOnTheFlySubtitleExtraction": "Avela hamaky dikanteny eny ampandehanana", "AllowOnTheFlySubtitleExtractionHelp": "Azo alaina avy amin'ilay video ny dikanteny ao anatiny ary aseho amin'ny soratra tsotra, mba hisorohana ny famadihana video. Mety haharitra ela izany ka hampiato ny famakiana horonan-tsary mandritra ny dingan'ny fitrandrahana. Atsaharo raha avela ho dikanteny miaraka amin'ny famadihana horonan-tsary.", "AllowRemoteAccess": "Avela hifandray amin'ny hafa ity serveur ity", "AllowRemoteAccessHelp": "Raha tsy marihina dia ho voasakana ny fifandraisana lavitra rehetra." From 865df884fda10a229782656ffb7ff6fa8069cc73 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Fri, 5 May 2023 11:47:08 -0400 Subject: [PATCH 108/112] Add useWebConfig hook --- src/RootApp.tsx | 17 +++++++++------- src/hooks/useWebConfig.tsx | 40 ++++++++++++++++++++++++++++++++++++++ src/types/webConfig.ts | 20 +++++++++++++++++++ 3 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 src/hooks/useWebConfig.tsx create mode 100644 src/types/webConfig.ts diff --git a/src/RootApp.tsx b/src/RootApp.tsx index 0159b155ab..a44e25d565 100644 --- a/src/RootApp.tsx +++ b/src/RootApp.tsx @@ -5,6 +5,7 @@ import React from 'react'; import StableApp from './apps/stable/App'; import { HistoryRouter } from './components/router/HistoryRouter'; import { ApiProvider } from './hooks/useApi'; +import { WebConfigProvider } from './hooks/useWebConfig'; const ExperimentalApp = loadable(() => import('./apps/experimental/App')); @@ -13,13 +14,15 @@ const RootApp = ({ history }: { history: History }) => { return ( - - { - layoutMode === 'experimental' ? - : - - } - + + + { + layoutMode === 'experimental' ? + : + + } + + ); }; diff --git a/src/hooks/useWebConfig.tsx b/src/hooks/useWebConfig.tsx new file mode 100644 index 0000000000..528afcee0f --- /dev/null +++ b/src/hooks/useWebConfig.tsx @@ -0,0 +1,40 @@ +import React, { createContext, FC, useContext, useEffect, useState } from 'react'; + +import type { WebConfig } from '../types/webConfig'; +import defaultConfig from '../config.json'; +import fetchLocal from '../utils/fetchLocal'; + +export const WebConfigContext = createContext(defaultConfig); +export const useWebConfig = () => useContext(WebConfigContext); + +export const WebConfigProvider: FC = ({ children }) => { + const [ config, setConfig ] = useState(defaultConfig); + + useEffect(() => { + const fetchConfig = async () => { + try { + const response = await fetchLocal('config.json', { cache: 'no-cache' }); + + if (!response.ok) { + throw new Error('network response was not ok'); + } + + const configData = await response.json(); + setConfig(configData); + } catch (err) { + console.warn('[WebConfigProvider] failed to fetch config file', err); + } + }; + + fetchConfig() + .catch(() => { + // This should never happen since fetchConfig catches errors internally + }); + }, [ setConfig ]); + + return ( + + {children} + + ); +}; diff --git a/src/types/webConfig.ts b/src/types/webConfig.ts new file mode 100644 index 0000000000..5ef164c247 --- /dev/null +++ b/src/types/webConfig.ts @@ -0,0 +1,20 @@ +interface Theme { + name: string + id: string + color: string +} + +interface MenuLink { + name: string + icon?: string + url: string +} + +export interface WebConfig { + includeCorsCredentials?: boolean + multiserver?: boolean + themes?: Theme[] + menuLinks?: MenuLink[] + servers?: string[] + plugins?: string[] +} From 7bbddba9ff76868ae33d0a356d5e815d0c46d527 Mon Sep 17 00:00:00 2001 From: rushmash Date: Fri, 5 May 2023 23:24:31 +0000 Subject: [PATCH 109/112] Translated using Weblate (Belarusian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/ --- src/strings/be-by.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/strings/be-by.json b/src/strings/be-by.json index 8155444794..d00ed700a3 100644 --- a/src/strings/be-by.json +++ b/src/strings/be-by.json @@ -72,7 +72,7 @@ "AllowFfmpegThrottlingHelp": "Калі перакадзіраванне або рэмукс будзе дастаткова далёка ад бягучай пазіцыі прайгравання, прыпыніце працэс, каб ён спажываў менш рэсурсаў. Гэта найбольш карысна пры праглядзе без частага пошуку. Выключыце гэта, калі ўзнікнуць праблемы з прайграваннем.", "AllowOnTheFlySubtitleExtractionHelp": "Убудаваныя субтытры можна атрымаць з відэа і даставіць кліентам у выглядзе звычайнага тэксту, каб прадухіліць перакадзіраванне відэа. У некаторых сістэмах гэта можа заняць шмат часу і прывесці да спынення прайгравання відэа падчас працэсу здабывання. Адключыце гэта, каб убудаваныя субтытры запісваліся пры перакадзіраванні відэа, калі яны не падтрымліваюцца кліенцкай прыладай.", "AllowRemoteAccessHelp": "Калі не пазначыць, усе аддаленыя злучэнні будуць заблакіраваны.", - "AllowTonemappingHelp": "Адлюстраванне тонаў можа пераўтварыць дынамічны дыяпазон відэа з HDR у SDR, захоўваючы дэталі выявы і колеры, якія з'яўляюцца вельмі важнай інфармацыяй для прадстаўлення арыгінальнай сцэны. У цяперашні час працуе толькі з відэа HDR10 або HLG. Для гэтага патрабуецца адпаведнае асяроддзе выканання OpenCL або CUDA.", + "AllowTonemappingHelp": "Адлюстраванне тонаў можа пераўтварыць дынамічны дыяпазон відэа з HDR у SDR, захоўваючы дэталі выявы і колеры, якія з'яўляюцца вельмі важнай інфармацыяй для прадстаўлення арыгінальнай сцэны. У цяперашні час працуе толькі з відэа 10bit HDR10, HLG і DoVi. Для гэтага патрабуецца адпаведнае асяроддзе выканання OpenCL або CUDA.", "AlwaysPlaySubtitles": "Заўсёды граць", "ApiKeysCaption": "Спіс уключаных на дадзены момант ключоў API", "AroundTime": "Каля {0}", @@ -1383,9 +1383,9 @@ "Clip": "Кліп", "Sample": "Прыклад", "LabelVppTonemappingBrightness": "Узмацненне яркасці танальнага адлюстравання VPP", - "LabelVppTonemappingBrightnessHelp": "Прымяніць узмацненне яркасці ў танальным адлюстраванні VPP. І рэкамендаванае, і стандартнае значэнне роўна 0.", + "LabelVppTonemappingBrightnessHelp": "Прымяніць узмацненне яркасці ў танальным адлюстраванні VPP. Рэкамендаванае значэнне 16, значэнне па змаўчанні 0.", "LabelVppTonemappingContrast": "Узмацненне кантраснасці танальнага адлюстравання VPP", - "LabelVppTonemappingContrastHelp": "Прымяніць узмацненне кантрасту ў танальным адлюстраванні VPP. Рэкамендуемыя значэнні і значэнні па змаўчанні - 1,2 і 1.", + "LabelVppTonemappingContrastHelp": "Прымяніць узмацненне кантрасту ў танальным адлюстраванні VPP. Рэкамендуемыя значэнні і значэнні па змаўчанні - 1.", "VideoRangeTypeNotSupported": "Тып дыяпазону відэа не падтрымліваецца", "LabelVideoRangeType": "Тып дыяпазону відэа", "MediaInfoVideoRangeType": "Тып дыяпазону відэа", @@ -1707,5 +1707,8 @@ "LabelParallelImageEncodingLimit": "Ліміт паралельнага кадавання выявы", "LabelParallelImageEncodingLimitHelp": "Максімальная колькасць кадавання малюнкаў, якія могуць працаваць паралельна. Пры ўсталёўцы 0 вы выбіраеце ліміт на аснове спецыфікацый вашай сістэмы.", "LabelEnableAudioVbr": "Уключыць кадыроўку гуку VBR", - "LabelEnableAudioVbrHelp": "Пераменны бітрэйт забяспечвае лепшае суадносіны якасці да сярэдняга, але ў некаторых рэдкіх выпадках можа выклікаць праблемы з буферызацыяй і сумяшчальнасцю." + "LabelEnableAudioVbrHelp": "Пераменны бітрэйт забяспечвае лепшае суадносіны якасці да сярэдняга, але ў некаторых рэдкіх выпадках можа выклікаць праблемы з буферызацыяй і сумяшчальнасцю.", + "TonemappingModeHelp": "Выберыце рэжым танальнага адлюстравання. Калі вы бачыце, што блікі блякнуць, паспрабуйце пераключыцца ў рэжым RGB.", + "LabelTonemappingMode": "Рэжым танальнага адлюстравання", + "Select": "Выбраць" } From 226cdb1a4fa5dd71d076aa7b7cf8a090e6d4571e Mon Sep 17 00:00:00 2001 From: hoanghuy309 Date: Sat, 6 May 2023 13:09:40 +0000 Subject: [PATCH 110/112] Translated using Weblate (Vietnamese) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/vi/ --- src/strings/vi.json | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/strings/vi.json b/src/strings/vi.json index baffd15217..2400d65478 100644 --- a/src/strings/vi.json +++ b/src/strings/vi.json @@ -1334,7 +1334,7 @@ "LabelTonemappingDesat": "Khử bão hòa tông màu", "LabelTonemappingDesatHelp": "Áp dụng khử bão hòa cho các điểm sáng vượt quá độ sáng này. Thông số này càng cao thì thông tin màu càng được bảo toàn. Cài đặt này giúp ngăn các màu bị lóa không tự nhiên để tạo ra những vùng siêu nổi bật, bằng cách chuyển thành màu trắng (mềm mại). Nó làm cho hình ảnh trông tự nhiên, với hao phí giảm thông tin về các màu nằm ngoài phạm vi. Các giá trị được đề xuất và mặc định là 0 và 0,5.", "LabelTonemappingRange": "Phạm vi ánh xạ tông màu", - "AllowTonemappingHelp": "Ánh xạ tông màu có thể biến đổi dải động video từ HDR sang SDR mà vẫn duy trì chi tiết và màu sắc hình ảnh, đây là thông tin rất quan trọng để thể hiện cảnh gốc. Hiện chỉ hoạt động với video HDR10 hoặc HLG. Điều này yêu cầu thời gian chạy OpenCL hoặc CUDA tương ứng.", + "AllowTonemappingHelp": "Ánh xạ tông màu có thể biến đổi dải động video từ HDR sang SDR mà vẫn giữ chi tiết và màu sắc hình ảnh, đó là thông tin rất quan trọng để thể hiện cảnh gốc. Hiện chỉ hoạt động với video 10bit HDR10, HLG và DoVi. Việc này yêu cầu OpenCL hoặc CUDA runtime tương ứng.", "EnableTonemapping": "Bật Ánh xạ tông màu", "LabelOpenclDevice": "Thiết bị OpenCL", "LabelColorPrimaries": "Màu cơ bản", @@ -1652,9 +1652,9 @@ "MediaInfoDoViTitle": "Tiêu đề DV", "MediaInfoVideoRangeType": "Loại dải động video", "LabelVideoRangeType": "Loại dải động video", - "LabelVppTonemappingContrastHelp": "Áp dụng độ tăng tương phản trong ánh xạ tông màu VPP. Giá trị đề xuất và mặc định là 1,2 và 1.", + "LabelVppTonemappingContrastHelp": "Áp dụng tăng tương phản trong ánh xạ tông màu VPP. Cả giá trị đề xuất và mặc định đều là 1.", "LabelVppTonemappingContrast": "Độ tương phản ánh xạ tông màu VPP", - "LabelVppTonemappingBrightnessHelp": "Áp dụng tăng độ sáng trong ánh xạ tông màu VPP. Giá trị đề xuất và giá trị mặc định đều là 0.", + "LabelVppTonemappingBrightnessHelp": "Áp dụng tăng độ sáng trong ánh xạ tông màu VPP. Giá trị đề xuất và mặc định là 16 và 0.", "LabelVppTonemappingBrightness": "Tăng độ sáng ánh xạ tông màu VPP", "ScreenResolution": "Độ Phân Giải Màn Hình", "RememberSubtitleSelectionsHelp": "Cố gắng đặt phụ đề phù hợp nhất với video cuối cùng.", @@ -1712,5 +1712,9 @@ "LabelParallelImageEncodingLimit": "Giới hạn mã hóa hình ảnh song song", "MediaInfoDvBlSignalCompatibilityId": "Id tương thích tính hiệu DV bl", "LabelEnableAudioVbr": "Bật mã hóa âm thanh VBR", - "LabelEnableAudioVbrHelp": "Tốc độ bit thay đổi mang lại chất lượng tốt hơn so với tỷ lệ bit trung bình, nhưng trong một số trường hợp hiếm gặp, có thể gây ra sự cố về khả năng tương thích và bộ đệm." + "LabelEnableAudioVbrHelp": "Tốc độ bit thay đổi mang lại chất lượng tốt hơn so với tỷ lệ bit trung bình, nhưng trong một số trường hợp hiếm gặp, có thể gây ra sự cố về khả năng tương thích và bộ đệm.", + "LabelTonemappingMode": "Chế độ ánh xạ tông màu", + "Short": "Ngắn", + "Select": "Chọn", + "TonemappingModeHelp": "Chọn chế độ ánh xạ tông màu. Nếu bạn thấy các điểm sáng bị cháy sáng, hãy thử chuyển sang chế độ RGB." } From ed79a9a5fd7e156272a9d706f224a7711874af20 Mon Sep 17 00:00:00 2001 From: TheSharingBrother Date: Sat, 6 May 2023 15:53:18 +0000 Subject: [PATCH 111/112] Translated using Weblate (Hindi) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/hi/ --- src/strings/hi-in.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/strings/hi-in.json b/src/strings/hi-in.json index 32dab32ead..2607740cfe 100644 --- a/src/strings/hi-in.json +++ b/src/strings/hi-in.json @@ -149,5 +149,6 @@ "Larger": "और बड़ा", "ListPaging": "{2} का {0}-{1}", "Shows": "शो", - "ValueSpecialEpisodeName": "विशेष" + "ValueSpecialEpisodeName": "विशेष - {0}", + "Sync": "समाकलयति" } From 7ddfdb02debeca6316e5e035621acc05c266a3f9 Mon Sep 17 00:00:00 2001 From: Brett Healey Date: Sat, 6 May 2023 18:44:41 +0000 Subject: [PATCH 112/112] Translated using Weblate (Welsh) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/cy/ --- src/strings/cy.json | 50 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/strings/cy.json b/src/strings/cy.json index fd7bf7474b..61954c975b 100644 --- a/src/strings/cy.json +++ b/src/strings/cy.json @@ -594,5 +594,53 @@ "HeaderLatestRecordings": "Recordiadau Diweddaraf", "HeaderLatestMusic": "Cerddoriaeth Diweddaraf", "HeaderLatestMovies": "Ffilmiau Diweddaraf", - "MixedMoviesShows": "Rhaglenni teledu a Ffilmiau Cymysg" + "MixedMoviesShows": "Rhaglenni teledu a Ffilmiau Cymysg", + "Featurette": "Nodwedd", + "LabelVideoInfo": "Gwybodaeth Fideo", + "SubtitleCyan": "Cyan", + "YoutubePlaybackError": "Ni ellir chwarae fideo y gofynnwyd amdani.", + "TypeOptionPluralMusicAlbum": "Albymau Cerddoriaeth", + "AllowedRemoteAddressesHelp": "Rhestr o gyfeiriadau IP wedi'u gwahanu gan goma neu gofnodion IP/mwgwd rhwyd ar gyfer rhwydweithiau y caniateir iddynt gysylltu o bell. Os caiff ei adael yn wag, bydd pob cyfeiriad o bell yn cael ei ganiatáu.", + "AllowFfmpegThrottlingHelp": "Pan fydd trawsgod neu remux yn mynd yn ddigon pell o'r sefyllfa chwarae bresennol, stopiwch y broses fel y bydd yn defnyddio llai o adnoddau.Mae hyn yn fwyaf defnyddiol wrth wylio heb geisio yn aml.Diffoddwch hwn os ydych chi'n profi problemau chwarae.", + "AllowHWTranscodingHelp": "Caniatáu i'r tiwniwr drawsgodio ffrydiau ar y hedfan.Gall hyn helpu i leihau'r trawsgodio sydd ei angen ar y gweinydd.", + "AllowOnTheFlySubtitleExtractionHelp": "Gellir echdynnu is-deitlau mewnosodedig o fideos a'u cyflwyno i gleientiaid mewn testun plaen, er mwyn helpu i atal trawsgodio fideo. Ar rai systemau gall hyn gymryd amser hir ac achosi i chwarae fideo stopio yn ystod y broses echdynnu. Analluoga hwn i gael is-deitlau wedi'u mewnosod wedi'u llosgi i mewn gyda thrawsgodio fideo pan nad ydynt yn cael eu cefnogi'n frodorol gan ddyfais y cleient.", + "AllowTonemappingHelp": "Gall mapio tôn drawsnewid ystod ddeinamig fideo o HDR i SDR wrth gynnal manylion delwedd a lliwiau, sy'n wybodaeth bwysig iawn ar gyfer cynrychioli'r olygfa wreiddiol. Ar hyn o bryd yn gweithio dim ond gyda fideos 10bit HDR10, HLG a DoVi. Mae hyn yn gofyn am yr amser rhedeg OpenCL neu CUDA cyfatebol.", + "LabelTonemappingMode": "Modd mapio tôn", + "Short": "Byr", + "SubtitleLightGray": "Llwyd Ysgafn", + "StopRecording": "Stopio recordio", + "SubtitleRed": "Coch", + "SubtitleMagenta": "Magenta", + "TabDirectPlay": "Chwarae Uniongyrchol", + "SubtitleWhite": "Gwyn", + "TitleHardwareAcceleration": "Cyflymiad Caledwedd", + "TabParentalControl": "Rheolaeth Rhieni", + "DeletedScene": "Golygfa wedi'i dileu", + "ContainerNotSupported": "Nid yw'r cynhwysydd yn cael ei gefnogi", + "EnableIntelLowPowerH264HwEncoder": "Galluogi amgodiwr caledwedd Intel Low-Power H.264.", + "Sample": "Sampl", + "BehindTheScenes": "Tu ôl i'r Llenni", + "Clip": "Clip", + "Select": "Dewiswch", + "LabelVppTonemappingContrastHelp": "Cymhwyso cynnydd cyferbyniad wrth fapio tôn VPP. Y gwerthoedd a argymhellir a'r gwerthoedd diofyn yw 1.", + "SelectAll": "Dewiswch Pawb", + "VideoLevelNotSupported": "Ni chefnogir lefel y codec fideo", + "YoutubeBadRequest": "Cais drwg.", + "Remuxing": "Remuxing", + "LabelPlaybackInfo": "Gwybodaeth Chwarae", + "LabelAudioInfo": "Gwybodaeth Sain", + "HeaderSelectFallbackFontPath": "Dewiswch Llwybr Ffolder Ffontiau Fallback", + "WelcomeToProject": "Croeso i Jellyfin!", + "ValueSongCount": "{0} Caneuon", + "ValueContainer": "Cynhwysydd: {0}", + "UnsupportedPlayback": "Ni all Jellyfin ddadgryptio cynnwys sydd wedi'i warchod gan DRM ond bydd yr holl gynnwys yn cael ei roi ar brawf beth bynnag, gan gynnwys teitlau gwarchodedig. Gall rhai ffeiliau ymddangos yn hollol ddu oherwydd amgryptio neu nodweddion eraill nad ydynt yn cael eu cefnogi, megis teitlau rhyngweithiol.", + "TypeOptionPluralBoxSet": "Setiau Blwch", + "TellUsAboutYourself": "Dywedwch wrthym amdanoch chi'ch hun", + "SubtitleBlack": "Du", + "SubtitleBlue": "Glas", + "SubtitleGray": "Llwyd", + "SubtitleYellow": "Melyn", + "SubtitleGreen": "Gwyrdd", + "SmallCaps": "Capiau Bach", + "ShowAdvancedSettings": "Dangos gosodiadau uwch" }