From 7dc762053b0d101f4e4ac8c7c415c842912a9fc0 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 4 Apr 2020 16:28:50 +0200 Subject: [PATCH 01/52] Add polyfill linting --- .eslintrc.yml | 1 + package.json | 1 + yarn.lock | 68 ++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index f501f33546..8c9a20043e 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -22,6 +22,7 @@ extends: - plugin:import/errors - plugin:import/warnings - plugin:eslint-comments/recommended + - plugin:compat/recommended globals: # Browser globals diff --git a/package.json b/package.json index bac0d7e251..86d1fffcc8 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "cssnano": "^4.1.10", "del": "^5.1.0", "eslint": "^6.8.0", + "eslint-plugin-compat": "^3.5.1", "eslint-plugin-eslint-comments": "^3.1.2", "eslint-plugin-import": "^2.20.2", "eslint-plugin-promise": "^4.2.1", diff --git a/yarn.lock b/yarn.lock index ac4a39b6ec..817a8e0ae8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -710,7 +710,7 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": +"@babel/runtime@^7.7.7", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": version "7.9.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== @@ -1471,6 +1471,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +ast-metadata-inferer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ast-metadata-inferer/-/ast-metadata-inferer-0.1.1.tgz#66e24fae9d30ca961fac4880b7fc466f09b25165" + integrity sha512-hc9w8Qrgg9Lf9iFcZVhNjUnhrd2BBpTlyCnegPVvCe6O0yMrF57a6Cmh7k+xUsfUOMh9wajOL5AsGOBNEyTCcw== + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -1965,6 +1970,16 @@ browserslist@^4.0.0, browserslist@^4.11.0, browserslist@^4.6.4, browserslist@^4. node-releases "^1.1.52" pkg-up "^3.1.0" +browserslist@^4.8.2: + version "4.11.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.11.1.tgz#92f855ee88d6e050e7e7311d987992014f1a1f1b" + integrity sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g== + dependencies: + caniuse-lite "^1.0.30001038" + electron-to-chromium "^1.3.390" + node-releases "^1.1.53" + pkg-up "^2.0.0" + bs-recipes@1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/bs-recipes/-/bs-recipes-1.3.4.tgz#0d2d4d48a718c8c044769fdc4f89592dc8b69585" @@ -2210,11 +2225,21 @@ caniuse-db@^1.0.30000639: resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001036.tgz#8761fb6cd423ef2d3f8d96a21d898932252dc477" integrity sha512-plRkihXQyiDaFUXC7x/jAIXXTKiiaWvfAagsruh/vmstnRQ+a2a95HyENxiTr5WrkPSvmFUIvsRUalVFyeh2/w== +caniuse-db@^1.0.30001017: + version "1.0.30001039" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001039.tgz#b5e8c3bb07a144341644729fa2a5eb2c0deaf47d" + integrity sha512-XVk5KMAi8/DI28tQXKuq1PDyuPoD9Ypnda3ctF04TlB+LYIb+bgHq0ZDfNOn0+4cwLENJC0093Vuf0dhkjXQ7Q== + caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001035, caniuse-lite@^1.0.30001036: version "1.0.30001036" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001036.tgz#930ea5272010d8bf190d859159d757c0b398caf0" integrity sha512-jU8CIFIj2oR7r4W+5AKcsvWNVIb6Q6OZE3UsrXrZBHFtreT4YgTeOJtTucp+zSedEpTi3L5wASSP0LYIE3if6w== +caniuse-lite@^1.0.30001038: + version "1.0.30001039" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001039.tgz#b3814a1c38ffeb23567f8323500c09526a577bbe" + integrity sha512-SezbWCTT34eyFoWHgx8UWso7YtvtM7oosmFoXbCkdC6qJzRfBTeTgE9REtKtiuKXuMwWTZEvdnFNGAyVMorv8Q== + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -3633,6 +3658,11 @@ electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.380: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.382.tgz#cad02da655c33f7a3d6ca7525bd35c17e90f3a8f" integrity sha512-gJfxOcgnBlXhfnUUObsq3n3ReU8CT6S8je97HndYRkKsNZMJJ38zO/pI5aqO7L3Myfq+E3pqPyKK/ynyLEQfBA== +electron-to-chromium@^1.3.390: + version "1.3.397" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.397.tgz#db640c2e67b08d590a504c20b56904537aa2bafa" + integrity sha512-zcUd1p/7yzTSdWkCTrqGvbnEOASy96d0RJL/lc5BDJoO23Z3G/VHd0yIPbguDU9n8QNUTCigLO7oEdtOb7fp2A== + elliptic@^6.0.0: version "6.5.2" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" @@ -3891,6 +3921,19 @@ eslint-module-utils@^2.4.1: debug "^2.6.9" pkg-dir "^2.0.0" +eslint-plugin-compat@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-compat/-/eslint-plugin-compat-3.5.1.tgz#09f9c05dcfa9b5cd69345d7ab333749813ed8b14" + integrity sha512-dhfW12vZxxKLEVhrPoblmEopgwpYU2Sd4GdXj5OSfbQ+as9+1aY+S5pqnJYJvXXNWFFJ6aspLkCyk4NMQ/pgtA== + dependencies: + "@babel/runtime" "^7.7.7" + ast-metadata-inferer "^0.1.1" + browserslist "^4.8.2" + caniuse-db "^1.0.30001017" + lodash.memoize "4.1.2" + mdn-browser-compat-data "^1.0.3" + semver "^6.3.0" + eslint-plugin-eslint-comments@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.1.2.tgz#4ef6c488dbe06aa1627fea107b3e5d059fc8a395" @@ -4235,7 +4278,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@^3.0.0, extend@~3.0.2: +extend@3.0.2, extend@^3.0.0, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== @@ -6901,7 +6944,7 @@ lodash.keys@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash.memoize@^4.1.2: +lodash.memoize@4.1.2, lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= @@ -7186,6 +7229,13 @@ mdast-util-compact@^1.0.0: dependencies: unist-util-visit "^1.1.0" +mdn-browser-compat-data@^1.0.3: + version "1.0.16" + resolved "https://registry.yarnpkg.com/mdn-browser-compat-data/-/mdn-browser-compat-data-1.0.16.tgz#64f79c50d730108390205ed16e781e702ee1e16d" + integrity sha512-g3bkROyUKH5avfQ2Ou2ejtyfGNe7++Axv89+czZuS5EetQsvM1Cw8P/zDoq3SpE72tIrhhVJ74901q15J2Hm4A== + dependencies: + extend "3.0.2" + mdn-data@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" @@ -7656,6 +7706,11 @@ node-releases@^1.1.52: dependencies: semver "^6.3.0" +node-releases@^1.1.53: + version "1.1.53" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4" + integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ== + node-sass@^4.13.1, node-sass@^4.8.3: version "4.13.1" resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.13.1.tgz#9db5689696bb2eec2c32b98bfea4c7a2e992d0a3" @@ -8477,6 +8532,13 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + pkg-up@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" From 3c2bba341816229886b4926d940bf43890015f0a Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 4 Apr 2020 16:41:46 +0200 Subject: [PATCH 02/52] Add current Polyfills to the ESLint config --- .eslintrc.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.eslintrc.yml b/.eslintrc.yml index 8c9a20043e..57df44775a 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -86,3 +86,17 @@ rules: promise/no-return-wrap: ["warn"] # TODO: Remove after ES6 migration is complete import/no-unresolved: ["warn"] + +settings: + polyfills: + # Native Promises Only + - Promise + # whatwg-fetch + - fetch + # document-register-element + - document.registerElement + # resize-observer-polyfill + - ResizeObserver + # Core-js + - Array.from + - Object.assign From 0c2cdfe741fd87e0b3edcf695fdd5ceacaf5cd84 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 4 Apr 2020 21:29:53 +0200 Subject: [PATCH 03/52] Add polyfills to fix errors and ignore conditional lines --- .eslintrc.yml | 71 ++++++++++++++++++- package.json | 2 + src/bundle.js | 10 +++ src/components/appRouter.js | 2 + src/components/apphost.js | 1 + src/components/htmlMediaHelper.js | 2 +- src/components/images/imageLoader.js | 4 -- src/components/input/gamepadtokey.js | 10 +-- src/components/input/keyboardnavigation.js | 4 +- src/components/itemcontextmenu.js | 8 ++- .../lazyloader/lazyloader-scroll.js | 4 -- src/components/notifications/notifications.js | 2 + .../playback/playbackorientation.js | 2 + src/controllers/playback/videoosd.js | 4 +- src/scripts/browser.js | 1 + src/scripts/site.js | 12 +++- yarn.lock | 10 +++ 17 files changed, 129 insertions(+), 20 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 57df44775a..64ee42cc0f 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -97,6 +97,75 @@ settings: - document.registerElement # resize-observer-polyfill - ResizeObserver + # fast-text-encoding + - TextEncoder + # intersection-observer + - IntersectionObserver # Core-js - - Array.from - Object.assign + - Object.is + - Object.setPrototypeOf + - Object.toString + - Object.freeze + - Object.seal + - Object.preventExtensions + - Object.isFrozen + - Object.isSealed + - Object.isExtensible + - Object.getOwnPropertyDescriptor + - Object.getPrototypeOf + - Object.keys + - Object.getOwnPropertyNames + - Function.name + - Function.hasInstance + - Array.from + - Array.arrayOf + - Array.copyWithin + - Array.fill + - Array.find + - Array.findIndex + - Array.iterator + - String.fromCodePoint + - String.raw + - String.iterator + - String.codePointAt + - String.endsWith + - String.includes + - String.repeat + - String.startsWith + - String.trim + - String.anchor + - String.big + - String.blink + - String.bold + - String.fixed + - String.fontcolor + - String.fontsize + - String.italics + - String.link + - String.small + - String.strike + - String.sub + - String.sup + - RegExp + - Number + - Math + - Date + - async + - Symbol + - Map + - Set + - WeakMap + - WeakSet + - ArrayBuffer + - DataView + - Int8Array + - Uint8Array + - Uint8ClampedArray + - Int16Array + - Uint16Array + - Int32Array + - Uint32Array + - Float32Array + - Float64Array + - Reflect diff --git a/package.json b/package.json index 86d1fffcc8..5360c1b98f 100644 --- a/package.json +++ b/package.json @@ -58,9 +58,11 @@ "core-js": "^3.6.4", "date-fns": "^2.11.1", "document-register-element": "^1.14.3", + "fast-text-encoding": "^1.0.1", "flv.js": "^1.5.0", "hls.js": "^0.13.1", "howler": "^2.1.3", + "intersection-observer": "^0.7.0", "jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto", "jquery": "^3.4.1", "jstree": "^3.3.7", diff --git a/src/bundle.js b/src/bundle.js index 316f42c94a..ed6518447f 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -123,3 +123,13 @@ var date_fns_locale = require("date-fns/locale"); _define("date-fns/locale", function () { return date_fns_locale; }); + +var fast_text_encoding = require("fast-text-encoding"); +_define("fast-text-encoding", function () { + return fast_text_encoding; +}); + +var intersection_observer = require("intersection-observer"); +_define("intersection-observer", function () { + return intersection_observer; +}); diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 62bfb3cf40..c4ecede60f 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -268,6 +268,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM } function getMaxBandwidth() { + /* eslint-disable compat/compat */ if (navigator.connection) { var max = navigator.connection.downlinkMax; if (max && max > 0 && max < Number.POSITIVE_INFINITY) { @@ -279,6 +280,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM return max; } } + /* eslint-enable compat/compat */ return null; } diff --git a/src/components/apphost.js b/src/components/apphost.js index 868416b369..294ecb09f0 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -453,6 +453,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f if (doc) { doc.addEventListener(visibilityChange, function () { + /* eslint-disable-next-line compat/compat */ if (document[visibilityState]) { onAppHidden(); } else { diff --git a/src/components/htmlMediaHelper.js b/src/components/htmlMediaHelper.js index 338b8e6fef..5270ba4b9e 100644 --- a/src/components/htmlMediaHelper.js +++ b/src/components/htmlMediaHelper.js @@ -31,7 +31,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve } function enableHlsShakaPlayer(item, mediaSource, mediaType) { - + /* eslint-disable-next-line compat/compat */ if (!!window.MediaSource && !!MediaSource.isTypeSupported) { if (canPlayNativeHls()) { diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 764be06fd1..28b6923c33 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -1,10 +1,6 @@ define(['lazyLoader', 'imageFetcher', 'layoutManager', 'browser', 'appSettings', 'userSettings', 'require', 'css!./style'], function (lazyLoader, imageFetcher, layoutManager, browser, appSettings, userSettings, require) { 'use strict'; - var requestIdleCallback = window.requestIdleCallback || function (fn) { - fn(); - }; - var self = {}; function fillImage(elem, source, enableEffects) { diff --git a/src/components/input/gamepadtokey.js b/src/components/input/gamepadtokey.js index 5356bcbb45..71cbe87cd6 100644 --- a/src/components/input/gamepadtokey.js +++ b/src/components/input/gamepadtokey.js @@ -184,7 +184,7 @@ require(['apphost'], function (appHost) { function allowInput() { // This would be nice but always seems to return true with electron - if (!isElectron && document.hidden) { + if (!isElectron && document.hidden) { /* eslint-disable-line compat/compat */ return false; } @@ -254,7 +254,7 @@ require(['apphost'], function (appHost) { var inputLoopTimer; function runInputLoop() { // Get the latest gamepad state. - var gamepads = navigator.getGamepads(); + var gamepads = navigator.getGamepads(); /* eslint-disable-line compat/compat */ for (var i = 0, len = gamepads.length; i < len; i++) { var gamepad = gamepads[i]; if (!gamepad) { @@ -362,7 +362,7 @@ require(['apphost'], function (appHost) { } function isGamepadConnected() { - var gamepads = navigator.getGamepads(); + var gamepads = navigator.getGamepads(); /* eslint-disable-line compat/compat */ for (var i = 0, len = gamepads.length; i < len; i++) { var gamepad = gamepads[i]; if (gamepad && gamepad.connected) { @@ -373,6 +373,7 @@ require(['apphost'], function (appHost) { } function onFocusOrGamepadAttach(e) { + /* eslint-disable-next-line compat/compat */ if (isGamepadConnected() && document.hasFocus()) { console.log("Gamepad connected! Starting input loop"); startInputLoop(); @@ -380,6 +381,7 @@ require(['apphost'], function (appHost) { } function onFocusOrGamepadDetach(e) { + /* eslint-disable-next-line compat/compat */ if (!isGamepadConnected() || !document.hasFocus()) { console.log("Gamepad disconnected! No other gamepads are connected, stopping input loop"); stopInputLoop(); @@ -401,7 +403,7 @@ require(['apphost'], function (appHost) { if (window.navigator && typeof window.navigator.gamepadInputEmulation === "string") { // We want the gamepad to provide gamepad VK keyboard events rather than moving a // mouse like cursor. Set to "keyboard", the gamepad will provide such keyboard events - // and provide input to the DOM navigator.getGamepads API. + // and provide input to tonFocusOrGamepadDetachhe DOM navigator.getGamepads API. window.navigator.gamepadInputEmulation = "gamepad"; } diff --git a/src/components/input/keyboardnavigation.js b/src/components/input/keyboardnavigation.js index d356854a3e..3c80063f4f 100644 --- a/src/components/input/keyboardnavigation.js +++ b/src/components/input/keyboardnavigation.js @@ -159,7 +159,9 @@ function attachGamepadScript(e) { } // No need to check for gamepads manually at load time, the eventhandler will be fired for that -window.addEventListener("gamepadconnected", attachGamepadScript); +if (navigator.getGamepads) { /* eslint-disable-line compat/compat */ + window.addEventListener("gamepadconnected", attachGamepadScript); +} export default { enable: enable, diff --git a/src/components/itemcontextmenu.js b/src/components/itemcontextmenu.js index bdbcfc782b..9d683aa27c 100644 --- a/src/components/itemcontextmenu.js +++ b/src/components/itemcontextmenu.js @@ -352,6 +352,7 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter", document.body.appendChild(textArea); textArea.focus(); textArea.select(); + if (document.execCommand("copy")) { require(["toast"], function (toast) { toast(globalize.translate("CopyStreamURLSuccess")); @@ -361,14 +362,19 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter", } document.body.removeChild(textArea); }; + + /* eslint-disable-next-line compat/compat */ if (navigator.clipboard === undefined) { textAreaCopy(); } else { + /* eslint-disable-next-line compat/compat */ navigator.clipboard.writeText(downloadHref).then(function () { require(["toast"], function (toast) { toast(globalize.translate("CopyStreamURLSuccess")); }); - }, textAreaCopy); + }).catch(function () { + textAreaCopy(); + }); } getResolveFunction(resolve, id)(); break; diff --git a/src/components/lazyloader/lazyloader-scroll.js b/src/components/lazyloader/lazyloader-scroll.js index d5120146ce..4930f6376c 100644 --- a/src/components/lazyloader/lazyloader-scroll.js +++ b/src/components/lazyloader/lazyloader-scroll.js @@ -4,10 +4,6 @@ define(['visibleinviewport', 'dom', 'browser'], function (visibleinviewport, dom var thresholdX; var thresholdY; - var requestIdleCallback = window.requestIdleCallback || function (fn) { - fn(); - }; - function resetThresholds() { var threshold = 0.3; diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index c8a79a3627..8ba870613b 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -6,6 +6,7 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'requir document.removeEventListener('keydown', onOneDocumentClick); if (window.Notification) { + /* eslint-disable-next-line compat/compat */ Notification.requestPermission(); } } @@ -26,6 +27,7 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'requir } function resetRegistration() { + /* eslint-disable-next-line compat/compat */ var serviceWorker = navigator.serviceWorker; if (serviceWorker) { serviceWorker.ready.then(function (registration) { diff --git a/src/components/playback/playbackorientation.js b/src/components/playback/playbackorientation.js index 5b178dbf08..5836298ead 100644 --- a/src/components/playback/playbackorientation.js +++ b/src/components/playback/playbackorientation.js @@ -17,6 +17,7 @@ define(['playbackManager', 'layoutManager', 'events'], function (playbackManager var isLocalVideo = player.isLocalPlayer && !player.isExternalPlayer && playbackManager.isPlayingVideo(player); if (isLocalVideo && layoutManager.mobile) { + /* eslint-disable-next-line compat/compat */ var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation || (screen.orientation && screen.orientation.lock); if (lockOrientation) { @@ -40,6 +41,7 @@ define(['playbackManager', 'layoutManager', 'events'], function (playbackManager if (orientationLocked && !playbackStopInfo.nextMediaType) { + /* eslint-disable-next-line compat/compat */ var unlockOrientation = screen.unlockOrientation || screen.mozUnlockOrientation || screen.msUnlockOrientation || (screen.orientation && screen.orientation.unlock); if (unlockOrientation) { diff --git a/src/controllers/playback/videoosd.js b/src/controllers/playback/videoosd.js index c61fd14a7a..f71eb0e095 100644 --- a/src/controllers/playback/videoosd.js +++ b/src/controllers/playback/videoosd.js @@ -1152,7 +1152,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med case "GamepadDPadLeft": case "GamepadLeftThumbstickLeft": // Ignores gamepad events that are always triggered, even when not focused. - if (document.hasFocus()) { + if (document.hasFocus()) { /* eslint-disable-line compat/compat */ playbackManager.rewind(currentPlayer); showOsd(); } @@ -1161,7 +1161,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med case "GamepadDPadRight": case "GamepadLeftThumbstickRight": // Ignores gamepad events that are always triggered, even when not focused. - if (document.hasFocus()) { + if (document.hasFocus()) { /* eslint-disable-line compat/compat */ playbackManager.fastForward(currentPlayer); showOsd(); } diff --git a/src/scripts/browser.js b/src/scripts/browser.js index 19153bb19f..f89df82c0c 100644 --- a/src/scripts/browser.js +++ b/src/scripts/browser.js @@ -292,6 +292,7 @@ define([], function () { } if (typeof document !== 'undefined') { + /* eslint-disable-next-line compat/compat */ if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0)) { browser.touch = true; } diff --git a/src/scripts/site.js b/src/scripts/site.js index 5eb3c2a346..f39088b380 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -612,13 +612,17 @@ var AppInfo = {}; } function registerServiceWorker() { - if (navigator.serviceWorker && "cordova" !== self.appMode && "android" !== self.appMode) { + /* eslint-disable compat/compat */ + if (navigator.serviceWorker && self.appMode !== "cordova" && self.appMode !== "android") { try { navigator.serviceWorker.register("serviceworker.js"); } catch (err) { console.error("error registering serviceWorker: " + err); } + } else { + console.warn("serviceWorker unsupported"); } + /* eslint-enable compat/compat */ } function onWebComponentsReady(browser) { @@ -696,7 +700,9 @@ var AppInfo = {}; "jellyfin-noto", "date-fns", "page", - "polyfill" + "polyfill", + "fast-text-encoding", + "intersection-observer" ] }, urlArgs: urlArgs, @@ -705,6 +711,8 @@ var AppInfo = {}; }); require(["polyfill"]); + require(["fast-text-encoding"]); + require(["intersection-observer"]); // Expose jQuery globally require(["jQuery"], function(jQuery) { diff --git a/yarn.lock b/yarn.lock index 817a8e0ae8..9b0484b163 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4365,6 +4365,11 @@ fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-text-encoding@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.1.tgz#4a428566f74fc55ebdd447555b1eb4d9cf514455" + integrity sha512-x4FEgaz3zNRtJfLFqJmHWxkMDDvXVtaznj2V9jiP8ACUJrUgist4bP9FmDL2Vew2Y9mEQI/tG4GqabaitYp9CQ== + fastq@^1.6.0: version "1.6.1" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.1.tgz#4570c74f2ded173e71cf0beb08ac70bb85826791" @@ -5977,6 +5982,11 @@ interpret@1.2.0, interpret@^1.1.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== +intersection-observer@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.7.0.tgz#ee16bee978db53516ead2f0a8154b09b400bbdc9" + integrity sha512-Id0Fij0HsB/vKWGeBe9PxeY45ttRiBmhFyyt/geBdDHBYNctMRTE3dC1U3ujzz3lap+hVXlEcVaB56kZP/eEUg== + into-stream@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" From e338c1e9364accca61e7ab0d10de5e1aa7c19f4d Mon Sep 17 00:00:00 2001 From: Julien Machiels Date: Sat, 4 Apr 2020 21:47:47 +0200 Subject: [PATCH 04/52] Correct typo in gamepadtokey Co-Authored-By: dkanada --- src/components/input/gamepadtokey.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/input/gamepadtokey.js b/src/components/input/gamepadtokey.js index 71cbe87cd6..c2cf5005f1 100644 --- a/src/components/input/gamepadtokey.js +++ b/src/components/input/gamepadtokey.js @@ -403,7 +403,7 @@ require(['apphost'], function (appHost) { if (window.navigator && typeof window.navigator.gamepadInputEmulation === "string") { // We want the gamepad to provide gamepad VK keyboard events rather than moving a // mouse like cursor. Set to "keyboard", the gamepad will provide such keyboard events - // and provide input to tonFocusOrGamepadDetachhe DOM navigator.getGamepads API. + // and provide input to the DOM navigator.getGamepads API. window.navigator.gamepadInputEmulation = "gamepad"; } From 36eb5564c1ba69924bd79539399c77b4a885b27a Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 6 Apr 2020 22:03:09 +0200 Subject: [PATCH 05/52] Fix all Critical bugs from Sonarqube --- src/components/appRouter.js | 3 ++- src/components/homesections/homesections.js | 2 +- src/components/htmlaudioplayer/plugin.js | 2 +- src/components/nowplayingbar/nowplayingbar.js | 2 +- src/components/playback/playbackmanager.js | 2 +- src/components/slideshow/slideshow.js | 3 +-- src/controllers/auth/selectserver.js | 2 +- src/controllers/movies/moviegenres.js | 6 +++--- src/controllers/music/musicgenres.js | 6 +++--- src/controllers/music/musicplaylists.js | 2 +- src/controllers/shows/tvgenres.js | 6 +++--- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 23934467be..ab30609e59 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -577,7 +577,8 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM function showDirect(path) { return new Promise(function(resolve, reject) { - resolveOnNextShow = resolve, page.show(baseUrl()+path); + resolveOnNextShow = resolve; + resolve = page.show(baseUrl() + path); }); } diff --git a/src/components/homesections/homesections.js b/src/components/homesections/homesections.js index 94e36f9d28..cb4866a1cc 100644 --- a/src/components/homesections/homesections.js +++ b/src/components/homesections/homesections.js @@ -131,7 +131,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } else if (section === 'librarytiles' || section === 'smalllibrarytiles' || section === 'smalllibrarytiles-automobile' || section === 'librarytiles-automobile') { loadLibraryTiles(elem, apiClient, user, userSettings, 'smallBackdrop', userViews, allSections); } else if (section === 'librarybuttons') { - loadlibraryButtons(elem, apiClient, user, userSettings, userViews, allSections); + loadlibraryButtons(elem, apiClient, user, userSettings, userViews); } else if (section === 'resume') { loadResumeVideo(elem, apiClient, userId); } else if (section === 'resumeaudio') { diff --git a/src/components/htmlaudioplayer/plugin.js b/src/components/htmlaudioplayer/plugin.js index 8cae76bbee..90f954d503 100644 --- a/src/components/htmlaudioplayer/plugin.js +++ b/src/components/htmlaudioplayer/plugin.js @@ -101,7 +101,7 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp self._timeUpdated = false; self._currentTime = null; - var elem = createMediaElement(options); + var elem = createMediaElement(); return setCurrentSrc(elem, options); }; diff --git a/src/components/nowplayingbar/nowplayingbar.js b/src/components/nowplayingbar/nowplayingbar.js index 8da9b9c053..8205211b4f 100644 --- a/src/components/nowplayingbar/nowplayingbar.js +++ b/src/components/nowplayingbar/nowplayingbar.js @@ -241,7 +241,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', elem.addEventListener('click', function (e) { if (!dom.parentWithTag(e.target, ['BUTTON', 'INPUT', 'A'])) { - showRemoteControl(0); + showRemoteControl(); } }); } diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index e9f7447691..2ea4c67cfb 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3140,7 +3140,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla AllowVideoStreamCopy: false, AllowAudioStreamCopy: currentlyPreventsAudioStreamCopy || currentlyPreventsVideoStreamCopy ? false : null - }, true); + }); return; } diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index 26dc303def..d2bf1bb727 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -307,8 +307,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f */ function getSwiperSlideHtmlFromItem(item) { return getSwiperSlideHtmlFromSlide({ - imageUrl: getImgUrl(item), - originalImage: getImgUrl(item, true), + originalImage: getImgUrl(item), //title: item.Name, //description: item.Overview Id: item.Id, diff --git a/src/controllers/auth/selectserver.js b/src/controllers/auth/selectserver.js index e766dbdb5c..2d27742119 100644 --- a/src/controllers/auth/selectserver.js +++ b/src/controllers/auth/selectserver.js @@ -95,7 +95,7 @@ define(["loading", "appRouter", "layoutManager", "appSettings", "apphost", "focu } function showServerConnectionFailure() { - alertText(globalize.translate("MessageUnableToConnectToServer"), globalize.translate("HeaderConnectionFailure")); + alertText(globalize.translate("MessageUnableToConnectToServer")); } return function (view, params) { diff --git a/src/controllers/movies/moviegenres.js b/src/controllers/movies/moviegenres.js index d51a2e4789..bb395f337c 100644 --- a/src/controllers/movies/moviegenres.js +++ b/src/controllers/movies/moviegenres.js @@ -184,12 +184,12 @@ define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader }; self.getCurrentViewStyle = function () { - return getPageData(tabContent).view; + return getPageData().view; }; self.setCurrentViewStyle = function (viewStyle) { - getPageData(tabContent).view = viewStyle; - libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle); + getPageData().view = viewStyle; + libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle); fullyReload(); }; diff --git a/src/controllers/music/musicgenres.js b/src/controllers/music/musicgenres.js index b465a4d350..c1338bc222 100644 --- a/src/controllers/music/musicgenres.js +++ b/src/controllers/music/musicgenres.js @@ -107,12 +107,12 @@ define(["libraryBrowser", "cardBuilder", "apphost", "imageLoader", "loading"], f }; self.getCurrentViewStyle = function () { - return getPageData(tabContent).view; + return getPageData().view; }; self.setCurrentViewStyle = function (viewStyle) { - getPageData(tabContent).view = viewStyle; - libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle); + getPageData().view = viewStyle; + libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle); fullyReload(); }; diff --git a/src/controllers/music/musicplaylists.js b/src/controllers/music/musicplaylists.js index fd458c88ac..795eaba795 100644 --- a/src/controllers/music/musicplaylists.js +++ b/src/controllers/music/musicplaylists.js @@ -69,7 +69,7 @@ define(["libraryBrowser", "cardBuilder", "apphost", "imageLoader", "loading"], f var data = {}; self.getCurrentViewStyle = function () { - return getPageData(tabContent).view; + return getPageData().view; }; var promise; diff --git a/src/controllers/shows/tvgenres.js b/src/controllers/shows/tvgenres.js index 9c37e04e7c..9a0823a6b9 100644 --- a/src/controllers/shows/tvgenres.js +++ b/src/controllers/shows/tvgenres.js @@ -177,12 +177,12 @@ define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader }; self.getCurrentViewStyle = function () { - return getPageData(tabContent).view; + return getPageData().view; }; self.setCurrentViewStyle = function (viewStyle) { - getPageData(tabContent).view = viewStyle; - libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle); + getPageData().view = viewStyle; + libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle); fullyReload(); }; From 6a24de84a0ad91de200f6178c6447fe73c040adb Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 6 Apr 2020 23:15:35 +0200 Subject: [PATCH 06/52] Convert dfnshelper switch to lookup table --- src/scripts/dfnshelper.js | 143 +++++++++++++------------------------- 1 file changed, 50 insertions(+), 93 deletions(-) diff --git a/src/scripts/dfnshelper.js b/src/scripts/dfnshelper.js index 379190842b..8fc89da943 100644 --- a/src/scripts/dfnshelper.js +++ b/src/scripts/dfnshelper.js @@ -1,99 +1,56 @@ -import { ar, be, bg, ca, cs, da, de, el, enGB, enUS, es, faIR, fi, fr, frCA, he, hi, hr, hu, id, it, kk, ko, lt, ms, nb, nl, pl, ptBR, pt, ro, ru, sk, sl, sv, tr, uk, vi, zhCN, zhTW } from 'date-fns/locale'; +import { ar, be, bg, ca, cs, da, de, el, enGB, enUS, es, faIR, fi, fr, frCA, he, hi, hr, hu, id, it, kk, ko, lt, ms, nb, + nl, pl, ptBR, pt, ro, ru, sk, sl, sv, tr, uk, vi, zhCN, zhTW } from 'date-fns/locale'; import globalize from 'globalize'; +const dateLocales = (locale) => ({ + 'ar': ar, + 'be-by': be, + 'bg-bg': bg, + 'ca': ca, + 'cs': cs, + 'da': da, + 'de': de, + 'el': el, + 'en-gb': enGB, + 'en-us': enUS, + 'es': es, + 'es-ar': es, + 'es-mx': es, + 'fa': faIR, + 'fi': fi, + 'fr': fr, + 'fr-ca': frCA, + 'gsw': de, + 'he': he, + 'hi-in': hi, + 'hr': hr, + 'hu': hu, + 'id': id, + 'it': it, + 'kk': kk, + 'ko': ko, + 'lt-lt': lt, + 'ms': ms, + 'nb': nb, + 'nl': nl, + 'pl': pl, + 'pt-br': ptBR, + 'pt-pt': pt, + 'ro': ro, + 'ru': ru, + 'sk': sk, + 'sl-si': sl, + 'sv': sv, + 'tr': tr, + 'uk': uk, + 'vi': vi, + 'zh-cn': zhCN, + 'zh-hk': zhCN, + 'zh-tw': zhTW +})[locale]; + export function getLocale() { - switch (globalize.getCurrentLocale()) { - case 'ar': - return ar; - case 'be-by': - return be; - case 'bg-bg': - return bg; - case 'ca': - return ca; - case 'cs': - return cs; - case 'da': - return da; - case 'de': - return de; - case 'el': - return el; - case 'en-gb': - return enGB; - case 'en-us': - return enUS; - case 'es': - return es; - case 'es-ar': - return es; - case 'es-mx': - return es; - case 'fa': - return faIR; - case 'fi': - return fi; - case 'fr': - return fr; - case 'fr-ca': - return frCA; - case 'gsw': - return de; - case 'he': - return he; - case 'hi-in': - return hi; - case 'hr': - return hr; - case 'hu': - return hu; - case 'id': - return id; - case 'it': - return it; - case 'kk': - return kk; - case 'ko': - return ko; - case 'lt-lt': - return lt; - case 'ms': - return ms; - case 'nb': - return nb; - case 'nl': - return nl; - case 'pl': - return pl; - case 'pt-br': - return ptBR; - case 'pt-pt': - return pt; - case 'ro': - return ro; - case 'ru': - return ru; - case 'sk': - return sk; - case 'sl-si': - return sl; - case 'sv': - return sv; - case 'tr': - return tr; - case 'uk': - return uk; - case 'vi': - return vi; - case 'zh-cn': - return zhCN; - case 'zh-hk': - return zhCN; - case 'zh-tw': - return zhTW; - default: - return enUS; - } + return dateLocales(globalize.getCurrentLocale() || enUS); } export const localeWithSuffix = { addSuffix: true, locale: getLocale() }; From a1132e9a9d492896b739500f6527bec79e8500be Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 6 Apr 2020 23:43:03 +0200 Subject: [PATCH 07/52] Correct comma operator use in appRouter --- src/components/appRouter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/appRouter.js b/src/components/appRouter.js index ab30609e59..4446f8c053 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -578,7 +578,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM function showDirect(path) { return new Promise(function(resolve, reject) { resolveOnNextShow = resolve; - resolve = page.show(baseUrl() + path); + page.show(baseUrl() + path); }); } From abb8d56db3713541ef6bae4b3a824fbc10ca680f Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 6 Apr 2020 23:44:38 +0200 Subject: [PATCH 08/52] Cleanup all Legacy components --- src/legacy/dashboard.js | 10 +++++++--- src/legacy/fnchecked.js | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/legacy/dashboard.js b/src/legacy/dashboard.js index 69c47d3b1f..63c5eb0faa 100644 --- a/src/legacy/dashboard.js +++ b/src/legacy/dashboard.js @@ -3,16 +3,20 @@ Dashboard.confirm = function(message, title, callback) { require(["confirm"], function(confirm) { confirm(message, title).then(function() { callback(!0); - }, function() { + }).catch(function() { callback(!1); }); }); -}, Dashboard.showLoadingMsg = function() { +}; + +Dashboard.showLoadingMsg = function() { "use strict"; require(["loading"], function(loading) { loading.show(); }); -}, Dashboard.hideLoadingMsg = function() { +}; + +Dashboard.hideLoadingMsg = function() { "use strict"; require(["loading"], function(loading) { loading.hide(); diff --git a/src/legacy/fnchecked.js b/src/legacy/fnchecked.js index 1f5a5f6014..b815668f93 100644 --- a/src/legacy/fnchecked.js +++ b/src/legacy/fnchecked.js @@ -4,7 +4,9 @@ define(["jQuery"], function($) { return !0 === value || !1 === value ? $(this).each(function() { this.checked = value; }) : this.length && this[0].checked; - }, $.fn.checkboxradio = function() { + }; + + $.fn.checkboxradio = function() { return this; }; }); From 440ae17e7d9270796ff69ac03694c2dedf125ccc Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 6 Apr 2020 23:44:51 +0200 Subject: [PATCH 09/52] Clean gulpfile --- gulpfile.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 0eb5593541..973c400263 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -62,7 +62,7 @@ function serve() { port: 8080 }); - let events = ['add', 'change']; + const events = ['add', 'change']; watch(options.javascript.query).on('all', function (event, path) { if (events.includes(event)) { @@ -105,7 +105,7 @@ function clean() { return del(['dist/']); } -let pipelineJavascript = lazypipe() +const pipelineJavascript = lazypipe() .pipe(function () { return mode.development(sourcemaps.init({ loadMaps: true })); }) @@ -140,7 +140,7 @@ function apploader(standalone) { .pipe(pipelineJavascript()) .pipe(dest('dist/')) .pipe(browserSync.stream()); - }; + } task.displayName = 'apploader'; From ef1cf2c404ffd88a44723a27b0209a4cd91245a3 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 6 Apr 2020 23:45:09 +0200 Subject: [PATCH 10/52] Clean bundle.js --- src/bundle.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/bundle.js b/src/bundle.js index 11379c9d87..277f840a0b 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -85,15 +85,15 @@ _define("webcomponents", function() { }); // libass-wasm -var libass_wasm = require("libass-wasm"); +var libassWasm = require("libass-wasm"); _define("JavascriptSubtitlesOctopus", function() { - return libass_wasm; + return libassWasm; }); // material-icons -var material_icons = require("material-design-icons-iconfont/dist/material-design-icons.css"); +var materialIcons = require("material-design-icons-iconfont/dist/material-design-icons.css"); _define("material-icons", function() { - return material_icons; + return materialIcons; }); // noto font @@ -120,12 +120,12 @@ _define("classlist-polyfill", function () { }); // Date-FNS -var date_fns = require("date-fns"); +var dateFns = require("date-fns"); _define("date-fns", function () { - return date_fns; + return dateFns; }); -var date_fns_locale = require("date-fns/locale"); +var dateFnsLocale = require("date-fns/locale"); _define("date-fns/locale", function () { - return date_fns_locale; + return dateFnsLocale; }); From 0fa74f34d51ba74930cf90501810dd820470638a Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 6 Apr 2020 23:45:39 +0200 Subject: [PATCH 11/52] Clean apploader --- src/scripts/apploader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripts/apploader.js b/src/scripts/apploader.js index e8a63217a8..7001c4c614 100644 --- a/src/scripts/apploader.js +++ b/src/scripts/apploader.js @@ -8,7 +8,7 @@ var script = document.createElement("script"); if (self.dashboardVersion) { - src += "?v=" + self.dashboardVersion; + src += `?v=${self.dashboardVersion}`; } script.src = src; From fb6766c832531a043a33542401efd845834b7a03 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 6 Apr 2020 23:45:50 +0200 Subject: [PATCH 12/52] Clean autobackdrops --- src/scripts/autobackdrops.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/scripts/autobackdrops.js b/src/scripts/autobackdrops.js index 09f89fad6f..fcc49d968b 100644 --- a/src/scripts/autobackdrops.js +++ b/src/scripts/autobackdrops.js @@ -1,16 +1,18 @@ define(["backdrop", "userSettings", "libraryMenu"], function (backdrop, userSettings, libraryMenu) { "use strict"; + var cache = {}; + function enabled() { return userSettings.enableBackdrops(); } function getBackdropItemIds(apiClient, userId, types, parentId) { - var key = "backdrops2_" + userId + (types || "") + (parentId || ""); + var key = `backdrops2_${userId + (types || "") + (parentId || "")}`; var data = cache[key]; if (data) { - console.debug("Found backdrop id list in cache. Key: " + key); + console.debug(`Found backdrop id list in cache. Key: ${key}`); data = JSON.parse(data); return Promise.resolve(data); } @@ -54,7 +56,6 @@ define(["backdrop", "userSettings", "libraryMenu"], function (backdrop, userSett } } - var cache = {}; pageClassOn("pageshow", "page", function () { var page = this; From b7661c29774a980c0a39959b9232062802f66a12 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 6 Apr 2020 23:49:44 +0200 Subject: [PATCH 13/52] Clean playlistedit --- src/scripts/playlistedit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripts/playlistedit.js b/src/scripts/playlistedit.js index 32a3a960a4..bca9f02734 100644 --- a/src/scripts/playlistedit.js +++ b/src/scripts/playlistedit.js @@ -8,7 +8,7 @@ define(["listView"], function (listView) { EnableImageTypes: "Primary,Backdrop,Banner,Thumb", UserId: ApiClient.getCurrentUserId() }; - return ApiClient.getJSON(ApiClient.getUrl("Playlists/" + itemId + "/Items", query)); + return ApiClient.getJSON(ApiClient.getUrl(`Playlists/${itemId}/Items`, query)); }; } From 43f6f985aa340cd573202e9e2ad5ab23ca6a9c88 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Tue, 7 Apr 2020 00:09:07 +0200 Subject: [PATCH 14/52] Clean inputManager --- src/scripts/inputManager.js | 194 ++++++++++-------------------------- 1 file changed, 51 insertions(+), 143 deletions(-) diff --git a/src/scripts/inputManager.js b/src/scripts/inputManager.js index 4d62ff9f20..c4490ef19d 100644 --- a/src/scripts/inputManager.js +++ b/src/scripts/inputManager.js @@ -48,7 +48,7 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], funct return true; } - function handleCommand(name, options) { + function handleCommand(commandName, options) { lastInputTime = new Date().getTime(); @@ -71,7 +71,7 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], funct if (eventListenerCount) { var customEvent = new CustomEvent("command", { detail: { - command: name + command: commandName }, bubbles: true, cancelable: true @@ -84,155 +84,63 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], funct } } - switch (name) { - case 'up': - focusManager.moveUp(sourceElement); - break; - case 'down': - focusManager.moveDown(sourceElement); - break; - case 'left': - focusManager.moveLeft(sourceElement); - break; - case 'right': - focusManager.moveRight(sourceElement); - break; - case 'home': - appRouter.goHome(); - break; - case 'settings': - appRouter.showSettings(); - break; - case 'back': + const keyActions = (command) => ({ + 'up': focusManager.moveUp(sourceElement), + 'down': focusManager.moveDown(sourceElement), + 'left': focusManager.moveLeft(sourceElement), + 'right': focusManager.moveRight(sourceElement), + 'home': appRouter.goHome(), + 'settings': appRouter.showSettings(), + 'back': () => { if (appRouter.canGoBack()) { appRouter.back(); } else if (appHost.supports('exit')) { appHost.exit(); } - break; - case 'forward': - break; - case 'select': - select(sourceElement); - break; - case 'pageup': - break; - case 'pagedown': - break; - case 'end': - break; - case 'menu': - break; - case 'info': - break; - case 'nextchapter': - playbackManager.nextChapter(); - break; - case 'next': - case 'nexttrack': - playbackManager.nextTrack(); - break; - case 'previous': - case 'previoustrack': - playbackManager.previousTrack(); - break; - case 'previouschapter': - playbackManager.previousChapter(); - break; - case 'guide': - appRouter.showGuide(); - break; - case 'recordedtv': - appRouter.showRecordedTV(); - break; - case 'record': - break; - case 'livetv': - appRouter.showLiveTV(); - break; - case 'mute': - playbackManager.setMute(true); - break; - case 'unmute': - playbackManager.setMute(false); - break; - case 'togglemute': - playbackManager.toggleMute(); - break; - case 'channelup': - playbackManager.channelUp(); - break; - case 'channeldown': - playbackManager.channelDown(); - break; - case 'volumedown': - playbackManager.volumeDown(); - break; - case 'volumeup': - playbackManager.volumeUp(); - break; - case 'play': - playbackManager.unpause(); - break; - case 'pause': - playbackManager.pause(); - break; - case 'playpause': - playbackManager.playPause(); - break; - case 'stop': + }, + 'select': select(sourceElement), + 'nextchapter': playbackManager.nextChapter(), + 'next': playbackManager.nextTrack(), + 'nexttrack': playbackManager.nextTrack(), + 'previous': playbackManager.previousTrack(), + 'previoustrack': playbackManager.previousTrack(), + 'previouschapter': playbackManager.previousChapter(), + 'guide': appRouter.showGuide(), + 'recordedtv': appRouter.showRecordedTV(), + 'livetv': appRouter.showLiveTV(), + 'mute': playbackManager.setMute(true), + 'unmute': playbackManager.setMute(false), + 'togglemute': playbackManager.toggleMute(), + 'channelup': playbackManager.channelUp(), + 'channeldown': playbackManager.channelDown(), + 'volumedown': playbackManager.volumeDown(), + 'volumeup': playbackManager.volumeUp(), + 'play': playbackManager.unpause(), + 'pause': playbackManager.pause(), + 'playpause': playbackManager.playPause(), + 'stop': () => { if (checkCommandTime('stop')) { playbackManager.stop(); } - break; - case 'changezoom': - playbackManager.toggleAspectRatio(); - break; - case 'changeaudiotrack': - playbackManager.changeAudioStream(); - break; - case 'changesubtitletrack': - playbackManager.changeSubtitleStream(); - break; - case 'search': - appRouter.showSearch(); - break; - case 'favorites': - appRouter.showFavorites(); - break; - case 'fastforward': - playbackManager.fastForward(); - break; - case 'rewind': - playbackManager.rewind(); - break; - case 'togglefullscreen': - playbackManager.toggleFullscreen(); - break; - case 'disabledisplaymirror': - playbackManager.enableDisplayMirroring(false); - break; - case 'enabledisplaymirror': - playbackManager.enableDisplayMirroring(true); - break; - case 'toggledisplaymirror': - playbackManager.toggleDisplayMirroring(); - break; - case 'nowplaying': - appRouter.showNowPlaying(); - break; - case 'repeatnone': - playbackManager.setRepeatMode('RepeatNone'); - break; - case 'repeatall': - playbackManager.setRepeatMode('RepeatAll'); - break; - case 'repeatone': - playbackManager.setRepeatMode('RepeatOne'); - break; - default: - break; - } + }, + 'changezoom': playbackManager.toggleAspectRatio(), + 'changeaudiotrack': playbackManager.changeAudioStream(), + 'changesubtitletrack': playbackManager.changeSubtitleStream(), + 'search': appRouter.showSearch(), + 'favorites': appRouter.showFavorites(), + 'fastforward': playbackManager.fastForward(), + 'rewind': playbackManager.rewind(), + 'togglefullscreen': playbackManager.toggleFullscreen(), + 'disabledisplaymirror': playbackManager.enableDisplayMirroring(false), + 'enabledisplaymirror': playbackManager.enableDisplayMirroring(true), + 'toggledisplaymirror': playbackManager.toggleDisplayMirroring(), + 'nowplaying': appRouter.showNowPlaying(), + 'repeatnone': playbackManager.setRepeatMode('RepeatNone'), + 'repeatall': playbackManager.setRepeatMode('RepeatAll'), + 'repeatone': playbackManager.setRepeatMode('RepeatOne') + })[command]; + + keyActions(commandName); } dom.addEventListener(document, 'click', notify, { From e5c8d2b23b9236f7fc609648f566a5f244900f6b Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Tue, 7 Apr 2020 00:14:06 +0200 Subject: [PATCH 15/52] Convert inputManager to ES6 --- package.json | 3 ++- src/scripts/inputManager.js | 44 +++++++++++++++++++++---------------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index b112d0be60..9db655eda7 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,8 @@ "src/components/sanatizefilename.js", "src/scripts/settings/webSettings.js", "src/components/scrollManager.js", - "src/scripts/dfnshelper.js" + "src/scripts/dfnshelper.js", + "src/scripts/inputManager.js" ], "plugins": [ "@babel/plugin-transform-modules-amd" diff --git a/src/scripts/inputManager.js b/src/scripts/inputManager.js index c4490ef19d..8a049ac4fb 100644 --- a/src/scripts/inputManager.js +++ b/src/scripts/inputManager.js @@ -1,32 +1,37 @@ -define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], function (playbackManager, focusManager, appRouter, dom, appHost) { - 'use strict'; +import playbackManager from 'playbackManager'; +import focusManager from 'focusManager'; +import appRouter from 'appRouter'; +import dom from 'dom'; +import appHost from 'apphost'; + +/* eslint-disable indent */ var lastInputTime = new Date().getTime(); - function notify() { + export function notify() { lastInputTime = new Date().getTime(); handleCommand('unknown'); } - function notifyMouseMove() { + export function notifyMouseMove() { lastInputTime = new Date().getTime(); } - function idleTime() { + export function idleTime() { return new Date().getTime() - lastInputTime; } - function select(sourceElement) { + export function select(sourceElement) { sourceElement.click(); } var eventListenerCount = 0; - function on(scope, fn) { + export function on(scope, fn) { eventListenerCount++; dom.addEventListener(scope, 'command', fn, {}); } - function off(scope, fn) { + export function off(scope, fn) { if (eventListenerCount) { eventListenerCount--; } @@ -48,7 +53,7 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], funct return true; } - function handleCommand(commandName, options) { + export function handleCommand(commandName, options) { lastInputTime = new Date().getTime(); @@ -147,13 +152,14 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], funct passive: true }); - return { - trigger: handleCommand, - handle: handleCommand, - notify: notify, - notifyMouseMove: notifyMouseMove, - idleTime: idleTime, - on: on, - off: off - }; -}); +/* eslint-enable indent */ + +export default { + trigger: handleCommand, + handle: handleCommand, + notify: notify, + notifyMouseMove: notifyMouseMove, + idleTime: idleTime, + on: on, + off: off +}; From a5d8775611dedbd580ba6886c2aee796b8efd1f5 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Tue, 7 Apr 2020 19:11:53 +0200 Subject: [PATCH 16/52] Make inputManager look-up table work properly --- src/scripts/inputManager.js | 166 +++++++++++++++++++++++++++--------- 1 file changed, 124 insertions(+), 42 deletions(-) diff --git a/src/scripts/inputManager.js b/src/scripts/inputManager.js index 8a049ac4fb..39fe8f4ae6 100644 --- a/src/scripts/inputManager.js +++ b/src/scripts/inputManager.js @@ -90,12 +90,24 @@ import appHost from 'apphost'; } const keyActions = (command) => ({ - 'up': focusManager.moveUp(sourceElement), - 'down': focusManager.moveDown(sourceElement), - 'left': focusManager.moveLeft(sourceElement), - 'right': focusManager.moveRight(sourceElement), - 'home': appRouter.goHome(), - 'settings': appRouter.showSettings(), + 'up': () => { + focusManager.moveUp(sourceElement); + }, + 'down': () => { + focusManager.moveDown(sourceElement); + }, + 'left': () => { + focusManager.moveLeft(sourceElement); + }, + 'right': () => { + focusManager.moveRight(sourceElement) + }, + 'home': () => { + appRouter.goHome(); + }, + 'settings': () => { + appRouter.showSettings(); + }, 'back': () => { if (appRouter.canGoBack()) { appRouter.back(); @@ -103,49 +115,119 @@ import appHost from 'apphost'; appHost.exit(); } }, - 'select': select(sourceElement), - 'nextchapter': playbackManager.nextChapter(), - 'next': playbackManager.nextTrack(), - 'nexttrack': playbackManager.nextTrack(), - 'previous': playbackManager.previousTrack(), - 'previoustrack': playbackManager.previousTrack(), - 'previouschapter': playbackManager.previousChapter(), - 'guide': appRouter.showGuide(), - 'recordedtv': appRouter.showRecordedTV(), - 'livetv': appRouter.showLiveTV(), - 'mute': playbackManager.setMute(true), - 'unmute': playbackManager.setMute(false), - 'togglemute': playbackManager.toggleMute(), - 'channelup': playbackManager.channelUp(), - 'channeldown': playbackManager.channelDown(), - 'volumedown': playbackManager.volumeDown(), - 'volumeup': playbackManager.volumeUp(), - 'play': playbackManager.unpause(), - 'pause': playbackManager.pause(), - 'playpause': playbackManager.playPause(), + 'select': () => { + select(sourceElement); + }, + 'nextchapter': () => { + playbackManager.nextChapter(); + }, + 'next': () => { + playbackManager.nextTrack(); + }, + 'nexttrack': () => { + playbackManager.nextTrack(); + }, + 'previous': () => { + playbackManager.previousTrack(); + }, + 'previoustrack': () => { + playbackManager.previousTrack(); + }, + 'previouschapter': () => { + playbackManager.previousChapter(); + }, + 'guide': () => { + appRouter.showGuide(); + }, + 'recordedtv': () => { + appRouter.showRecordedTV(); + }, + 'livetv': () => { + appRouter.showLiveTV(); + }, + 'mute': () => { + playbackManager.setMute(true); + }, + 'unmute': () => { + playbackManager.setMute(false); + }, + 'togglemute': () => { + playbackManager.toggleMute(); + }, + 'channelup': () => { + playbackManager.channelUp(); + }, + 'channeldown': () => { + playbackManager.channelDown(); + }, + 'volumedown': () => { + playbackManager.volumeDown(); + }, + 'volumeup': () => { + playbackManager.volumeUp(); + }, + 'play': () => { + playbackManager.unpause(); + }, + 'pause': () => { + playbackManager.pause(); + }, + 'playpause': () => { + playbackManager.playPause(); + }, 'stop': () => { if (checkCommandTime('stop')) { playbackManager.stop(); } }, - 'changezoom': playbackManager.toggleAspectRatio(), - 'changeaudiotrack': playbackManager.changeAudioStream(), - 'changesubtitletrack': playbackManager.changeSubtitleStream(), - 'search': appRouter.showSearch(), - 'favorites': appRouter.showFavorites(), - 'fastforward': playbackManager.fastForward(), - 'rewind': playbackManager.rewind(), - 'togglefullscreen': playbackManager.toggleFullscreen(), - 'disabledisplaymirror': playbackManager.enableDisplayMirroring(false), - 'enabledisplaymirror': playbackManager.enableDisplayMirroring(true), - 'toggledisplaymirror': playbackManager.toggleDisplayMirroring(), - 'nowplaying': appRouter.showNowPlaying(), - 'repeatnone': playbackManager.setRepeatMode('RepeatNone'), - 'repeatall': playbackManager.setRepeatMode('RepeatAll'), - 'repeatone': playbackManager.setRepeatMode('RepeatOne') + 'changezoom': () => { + playbackManager.toggleAspectRatio(); + }, + 'changeaudiotrack': () => { + playbackManager.changeAudioStream(); + }, + 'changesubtitletrack': () => { + playbackManager.changeSubtitleStream(); + }, + 'search': () => { + appRouter.showSearch(); + }, + 'favorites': () => { + appRouter.showFavorites(); + }, + 'fastforward': () => { + playbackManager.fastForward(); + }, + 'rewind': () => { + playbackManager.rewind(); + }, + 'togglefullscreen': () => { + playbackManager.toggleFullscreen(); + }, + 'disabledisplaymirror': () => { + playbackManager.enableDisplayMirroring(false); + }, + 'enabledisplaymirror': () => { + playbackManager.enableDisplayMirroring(true); + }, + 'toggledisplaymirror': () => { + playbackManager.toggleDisplayMirroring(); + }, + 'nowplaying': () => { + appRouter.showNowPlaying(); + }, + 'repeatnone': () => { + playbackManager.setRepeatMode('RepeatNone'); + }, + 'repeatall': () => { + playbackManager.setRepeatMode('RepeatAll'); + }, + 'repeatone': () => { + playbackManager.setRepeatMode('RepeatOne'); + } })[command]; - keyActions(commandName); + keyActions(commandName).call(); } dom.addEventListener(document, 'click', notify, { From 77d8226dd34a1c3a365ee16fe852ed04ad6f69ab Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Tue, 7 Apr 2020 19:46:47 +0200 Subject: [PATCH 17/52] Add Japanese locale to dfnshelper --- src/scripts/dfnshelper.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/scripts/dfnshelper.js b/src/scripts/dfnshelper.js index 8fc89da943..a36426b65a 100644 --- a/src/scripts/dfnshelper.js +++ b/src/scripts/dfnshelper.js @@ -1,4 +1,4 @@ -import { ar, be, bg, ca, cs, da, de, el, enGB, enUS, es, faIR, fi, fr, frCA, he, hi, hr, hu, id, it, kk, ko, lt, ms, nb, +import { ar, be, bg, ca, cs, da, de, el, enGB, enUS, es, faIR, fi, fr, frCA, he, hi, hr, hu, id, it, ja, kk, ko, lt, ms, nb, nl, pl, ptBR, pt, ro, ru, sk, sl, sv, tr, uk, vi, zhCN, zhTW } from 'date-fns/locale'; import globalize from 'globalize'; @@ -27,6 +27,7 @@ const dateLocales = (locale) => ({ 'hu': hu, 'id': id, 'it': it, + 'ja': ja, 'kk': kk, 'ko': ko, 'lt-lt': lt, @@ -50,7 +51,9 @@ const dateLocales = (locale) => ({ })[locale]; export function getLocale() { - return dateLocales(globalize.getCurrentLocale() || enUS); + console.warn(globalize.getCurrentLocale()); + console.warn(dateLocales(globalize.getCurrentLocale())); + return dateLocales(globalize.getCurrentLocale()) || enUS; } export const localeWithSuffix = { addSuffix: true, locale: getLocale() }; From 33855a655f22af2a1666c8eb8771ad7e98f87599 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Tue, 7 Apr 2020 19:49:22 +0200 Subject: [PATCH 18/52] Add error handling to command processor in inputManager --- src/scripts/inputManager.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/scripts/inputManager.js b/src/scripts/inputManager.js index 39fe8f4ae6..826a9f802b 100644 --- a/src/scripts/inputManager.js +++ b/src/scripts/inputManager.js @@ -100,7 +100,7 @@ import appHost from 'apphost'; focusManager.moveLeft(sourceElement); }, 'right': () => { - focusManager.moveRight(sourceElement) + focusManager.moveRight(sourceElement); }, 'home': () => { appRouter.goHome(); @@ -227,7 +227,11 @@ import appHost from 'apphost'; } })[command]; - keyActions(commandName).call(); + try { + keyActions(commandName).call(); + } catch (error) { + console.debug(`inputManager: tried to process command with no action assigned: ${commandName}`); + } } dom.addEventListener(document, 'click', notify, { From 56ff47658b799119dad8eccd1f60a5bb1b46123d Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 9 Apr 2020 19:20:18 +0200 Subject: [PATCH 19/52] Correct document.visibilityState --- src/components/apphost.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/apphost.js b/src/components/apphost.js index 294ecb09f0..ff113b7a9f 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -454,7 +454,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f if (doc) { doc.addEventListener(visibilityChange, function () { /* eslint-disable-next-line compat/compat */ - if (document[visibilityState]) { + if (document.visibilityState) { onAppHidden(); } else { onAppVisible(); From 89979a00a32cc7ce5945c35b3cb21618a548a7bc Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 9 Apr 2020 19:47:45 +0200 Subject: [PATCH 20/52] Fix issues in dfnshelper and inputManager --- src/scripts/dfnshelper.js | 2 -- src/scripts/inputManager.js | 24 ++++++++++++------------ 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/scripts/dfnshelper.js b/src/scripts/dfnshelper.js index a36426b65a..3f82e6ba7c 100644 --- a/src/scripts/dfnshelper.js +++ b/src/scripts/dfnshelper.js @@ -51,8 +51,6 @@ const dateLocales = (locale) => ({ })[locale]; export function getLocale() { - console.warn(globalize.getCurrentLocale()); - console.warn(dateLocales(globalize.getCurrentLocale())); return dateLocales(globalize.getCurrentLocale()) || enUS; } diff --git a/src/scripts/inputManager.js b/src/scripts/inputManager.js index 826a9f802b..cbbece63bc 100644 --- a/src/scripts/inputManager.js +++ b/src/scripts/inputManager.js @@ -6,7 +6,7 @@ import appHost from 'apphost'; /* eslint-disable indent */ - var lastInputTime = new Date().getTime(); + let lastInputTime = new Date().getTime(); export function notify() { lastInputTime = new Date().getTime(); @@ -25,7 +25,7 @@ import appHost from 'apphost'; sourceElement.click(); } - var eventListenerCount = 0; + let eventListenerCount = 0; export function on(scope, fn) { eventListenerCount++; dom.addEventListener(scope, 'command', fn, {}); @@ -38,12 +38,12 @@ import appHost from 'apphost'; dom.removeEventListener(scope, 'command', fn, {}); } - var commandTimes = {}; + let commandTimes = {}; function checkCommandTime(command) { - var last = commandTimes[command] || 0; - var now = new Date().getTime(); + let last = commandTimes[command] || 0; + const now = new Date().getTime(); if ((now - last) < 1000) { return false; @@ -57,7 +57,7 @@ import appHost from 'apphost'; lastInputTime = new Date().getTime(); - var sourceElement = (options ? options.sourceElement : null); + let sourceElement = (options ? options.sourceElement : null); if (sourceElement) { sourceElement = focusManager.focusableParent(sourceElement); @@ -66,7 +66,7 @@ import appHost from 'apphost'; if (!sourceElement) { sourceElement = document.activeElement || window; - var dlg = document.querySelector('.dialogContainer .dialog.opened'); + const dlg = document.querySelector('.dialogContainer .dialog.opened'); if (dlg && (!sourceElement || !dlg.contains(sourceElement))) { sourceElement = dlg; @@ -74,7 +74,7 @@ import appHost from 'apphost'; } if (eventListenerCount) { - var customEvent = new CustomEvent("command", { + const customEvent = new CustomEvent("command", { detail: { command: commandName }, @@ -82,7 +82,7 @@ import appHost from 'apphost'; cancelable: true }); - var eventResult = sourceElement.dispatchEvent(customEvent); + const eventResult = sourceElement.dispatchEvent(customEvent); if (!eventResult) { // event cancelled return; @@ -227,10 +227,10 @@ import appHost from 'apphost'; } })[command]; - try { - keyActions(commandName).call(); - } catch (error) { + if (keyActions(commandName) === undefined) { console.debug(`inputManager: tried to process command with no action assigned: ${commandName}`); + } else { + keyActions(commandName).call(); } } From ee09d9479bacdf4d226617d6e7492198e7948432 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 9 Apr 2020 20:09:51 +0200 Subject: [PATCH 21/52] Use development mode for dev server --- package.json | 2 +- webpack.common.js | 1 - webpack.dev.js | 1 + webpack.prod.js | 1 - 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index af74087e77..bd5a4f6def 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "Firefox ESR" ], "scripts": { - "serve": "gulp serve", + "serve": "gulp serve --development", "prepare": "gulp --production", "build:development": "gulp --development", "build:production": "gulp --production", diff --git a/webpack.common.js b/webpack.common.js index c87ccdbc0d..5d63456830 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -1,6 +1,5 @@ const path = require("path"); -const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const CopyPlugin = require("copy-webpack-plugin"); const Assets = [ diff --git a/webpack.dev.js b/webpack.dev.js index f39e027a17..beca8ea4fb 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -9,6 +9,7 @@ module.exports = merge(common, { path: path.resolve(__dirname, "dist"), libraryTarget: "amd-require" }, + devtool: '#inline-source-map', module: { rules: [ { diff --git a/webpack.prod.js b/webpack.prod.js index a6fb07091d..80d40f3450 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -1,4 +1,3 @@ -const path = require("path"); const common = require("./webpack.common"); const merge = require("webpack-merge"); From c3bc69ca57ac2469c6dd34718bdf35ee9152b9e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20S=C3=B8ndergaard=20Petersen?= Date: Thu, 9 Apr 2020 23:23:39 +0000 Subject: [PATCH 22/52] Translated using Weblate (Danish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/da/ --- src/strings/da.json | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/strings/da.json b/src/strings/da.json index 22ddc52200..b2edba2f33 100644 --- a/src/strings/da.json +++ b/src/strings/da.json @@ -12,11 +12,11 @@ "AllChannels": "Alle kanaler", "AllEpisodes": "Alle episoder", "AllLibraries": "Alle biblioteker", - "AllowHWTranscodingHelp": "Hvis aktiveret, omkoder tuneren streams on-the-fly. Dette kan hjælpe med at reducere omkodning der kræves af Jellyfin Server.", + "AllowHWTranscodingHelp": "Lader tuneren omkode streams on-the-fly. Dette kan hjælpe med at reducere omkodning der kræves af serveren.", "AllowMediaConversion": "Tillad media konvertering", "AllowMediaConversionHelp": "Giv eller nægt adgang til Konvertér Media featuren.", "AllowOnTheFlySubtitleExtraction": "Tillad udtræk af undertekster on-the-fly", - "AllowOnTheFlySubtitleExtractionHelp": "Indeholdte undertekster kan trækkes ud af videoer og leveres til Jellyfin apps i ren tekst for at afhjælpe video kodning. På nogle systemer kan dette tage lang tid og forårsage at afspilning kan hænge mens den udtrækker. Slå dette fra, for at have undertekster brændt ind i video kodningen når det er supporteret på klient enheden.", + "AllowOnTheFlySubtitleExtractionHelp": "Indeholdte undertekster kan trækkes ud af videoer og leveres til klienter i ren tekst for at afhjælpe video kodning. På nogle systemer kan dette tage lang tid og forårsage at afspilning kan hænge mens den udtrækker. Slå dette fra, for at have undertekster brændt ind i video kodningen når det er supporteret på klient enheden.", "AllowRemoteAccess": "Tillad fjernadgang til denne Jellyfin Server.", "AllowRemoteAccessHelp": "Hvis ikke markeret, vil alle fjernforbindelser blive blokeret.", "AllowedRemoteAddressesHelp": "Komma seperareret liste over IP adresser og netmasker der har ret til fjernadgang. Hvis blank er alle adresser tilladte.", @@ -1092,9 +1092,9 @@ "Absolute": "Absolut", "AccessRestrictedTryAgainLater": "Adgang er begrænset. Prøv igen senere.", "Aired": "Blev sendt", - "AllComplexFormats": "Alle komplekse formater (ASS, SSA, VOBSUB, PGS, SUB/IDX osv.)", + "AllComplexFormats": "Alle Komplekse Formater (ASS, SSA, VOBSUB, PGS, SUB,IDX osv.)", "AllLanguages": "Alle sprog", - "AlwaysPlaySubtitles": "Afspil altid undertekster", + "AlwaysPlaySubtitles": "Afspil Altid", "AlwaysPlaySubtitlesHelp": "Undertekster, der matcher dine sprogindstillinger, vil altid blive indlæst uanset lydsprog.", "HeaderLiveTV": "Live-TV", "Shows": "Serier", @@ -1532,5 +1532,9 @@ "LabelServerName": "Server navn:", "LabelUserLoginAttemptsBeforeLockout": "Fejlede loginforsøg før bruger lukkes ude:", "HeaderRestartingServer": "Genstarter Server", - "ButtonAddImage": "Tilføj billede" + "ButtonAddImage": "Tilføj billede", + "AllowFfmpegThrottlingHelp": "Når en omkodning eller remux kommer langt nok foran den nuværende afspildings position, pauses processen så der bruges færre resurser. Dette er mest brugbart når man ikke springer i filmen. Slå dette fra hvis du har problemer med playback.", + "AllowFfmpegThrottling": "Begræns Omkodning", + "AlbumArtist": "Album Artist", + "Album": "Album" } From 528376526835e1041052f3f4dd3f49ccd1f02821 Mon Sep 17 00:00:00 2001 From: sabretou Date: Fri, 10 Apr 2020 13:19:14 +0000 Subject: [PATCH 23/52] Added translation using Weblate (Marathi) --- src/strings/mr.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/strings/mr.json diff --git a/src/strings/mr.json b/src/strings/mr.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/src/strings/mr.json @@ -0,0 +1 @@ +{} From d616d39cc60bb8d13a96a72d538fd62c8b71b23b Mon Sep 17 00:00:00 2001 From: sabretou Date: Fri, 10 Apr 2020 13:19:35 +0000 Subject: [PATCH 24/52] Translated using Weblate (Marathi) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/mr/ --- src/strings/mr.json | 61 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/src/strings/mr.json b/src/strings/mr.json index 0967ef424b..497add8c35 100644 --- a/src/strings/mr.json +++ b/src/strings/mr.json @@ -1 +1,60 @@ -{} +{ + "ButtonOpen": "उघडा", + "ButtonOk": "ऑन", + "ButtonOff": "ऑफ", + "ButtonNextTrack": "पुढचा ट्रॅक", + "ButtonNew": "नवीन", + "ButtonNetwork": "नेटवर्क", + "ButtonMore": "अजून", + "ButtonLearnMore": "अधिक माहिती", + "ButtonInfo": "माहिती", + "ButtonHelp": "मदत", + "ButtonGuide": "गाईड", + "ButtonGotIt": "समजले", + "ButtonForgotPassword": "पासवर्ड विसरलो", + "ButtonEditImages": "चित्र संपादित करा", + "ButtonEdit": "संपादित करा", + "ButtonDownload": "डाउनलोड करा", + "ButtonDown": "खाली", + "ButtonDeleteImage": "चित्र काढून टाका", + "ButtonDelete": "काढून टाका", + "ButtonChangeServer": "सर्व्हर बदला", + "ButtonCancel": "रद्द करा", + "ButtonBack": "मागे", + "ButtonAudioTracks": "ऑडिओ ट्रॅक", + "ButtonArrowUp": "वर", + "ButtonArrowRight": "उजवीकडे", + "ButtonArrowLeft": "डावीकडे", + "ButtonArrowDown": "खाली", + "ButtonAddUser": "प्रयोक्ता जोडा", + "ButtonAddServer": "सर्व्हर जोडा", + "ButtonAdd": "जोडा", + "Books": "पुस्तकं", + "Blacklist": "ब्लॅकलिस्ट", + "BirthPlaceValue": "जन्म ठिकाण: {0}", + "BirthLocation": "जन्मस्थान", + "BirthDateValue": "जन्म: {0}", + "Backdrops": "पार्श्वभूमी", + "Backdrop": "पार्श्वभूमी", + "Auto": "आपोआप", + "Audio": "ऑडिओ", + "AttributeNew": "नवीन", + "AspectRatio": "अ‍ॅस्पेक्ट रेशो", + "AsManyAsPossible": "जमतील तितके", + "Artists": "संगीतकार", + "Artist": "संगीतकार", + "Anytime": "कधीही", + "AnyLanguage": "कोणतीही भाषा", + "AlwaysPlaySubtitles": "नेहमीच प्ले करा", + "AllLibraries": "सर्व संग्रहालय", + "AllLanguages": "सर्व भाषा", + "AllEpisodes": "सर्व भाग", + "AllChannels": "सर्व वाहिन्या", + "All": "सर्व", + "Albums": "अल्बम", + "AlbumArtist": "अल्बम संगीतकार", + "Album": "अल्बम", + "AddedOnValue": "{0} जोडले", + "Add": "जोडा", + "Actor": "अभिनेता" +} From 6599362a28bd6a1f610acccbbfe082a4bb4e4e5d Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Fri, 10 Apr 2020 20:15:38 +0200 Subject: [PATCH 25/52] Simplify visibility change event in appHost --- src/components/apphost.js | 36 ++++++++++++++---------------------- yarn.lock | 4 ---- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/src/components/apphost.js b/src/components/apphost.js index 65e82614fe..dacb62d103 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -426,35 +426,27 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f } }; - var doc = self.document; var isHidden = false; - if (doc) { - if (void 0 !== doc.visibilityState) { + if (self.document) { + if (self.document.visibilityState !== undefined) { visibilityChange = "visibilitychange"; visibilityState = "hidden"; - } else { - if (void 0 !== doc.mozHidden) { - visibilityChange = "mozvisibilitychange"; - visibilityState = "mozVisibilityState"; - } else { - if (void 0 !== doc.msHidden) { - visibilityChange = "msvisibilitychange"; - visibilityState = "msVisibilityState"; - } else { - if (void 0 !== doc.webkitHidden) { - visibilityChange = "webkitvisibilitychange"; - visibilityState = "webkitVisibilityState"; - } - } - } + } else if (self.document.mozHidden !== undefined) { + visibilityChange = "mozvisibilitychange"; + visibilityState = "mozVisibilityState"; + } else if (self.document.msHidden !== undefined) { + visibilityChange = "msvisibilitychange"; + visibilityState = "msVisibilityState"; + } else if (self.document.webkitHidden !== undefined) { + visibilityChange = "webkitvisibilitychange"; + visibilityState = "webkitVisibilityState"; } } - if (doc) { - doc.addEventListener(visibilityChange, function () { - /* eslint-disable-next-line compat/compat */ - if (document.visibilityState) { + if (self.document) { + document.addEventListener(visibilityChange, function () { + if (visibilityState) { onAppHidden(); } else { onAppVisible(); diff --git a/yarn.lock b/yarn.lock index 6c2ba33ec6..03437af39b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6743,10 +6743,6 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -"libass-wasm@https://github.com/jellyfin/JavascriptSubtitlesOctopus#4.0.0-jf": - version "4.0.0" - resolved "https://github.com/jellyfin/JavascriptSubtitlesOctopus#7e6b75dcab9f7dad12719983510d05242803707c" - "libass-wasm@https://github.com/jellyfin/JavascriptSubtitlesOctopus#4.0.0-jf-cordova": version "4.0.0" resolved "https://github.com/jellyfin/JavascriptSubtitlesOctopus#b38056588bfaebc18a8353cb1757de0a815ac879" From 93b1dd53b53884f46b8c5fe0a441c6db77983583 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Fri, 10 Apr 2020 21:16:36 +0200 Subject: [PATCH 26/52] Correct app visibility event in appHost --- src/components/apphost.js | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/components/apphost.js b/src/components/apphost.js index dacb62d103..5985609ccc 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -351,8 +351,6 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f var deviceName; var appName = "Jellyfin Web"; var appVersion = "10.5.0"; - var visibilityChange; - var visibilityState; var appHost = { getWindowState: function () { @@ -427,26 +425,24 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f }; var isHidden = false; + var hidden; + var visibilityChange; - if (self.document) { - if (self.document.visibilityState !== undefined) { - visibilityChange = "visibilitychange"; - visibilityState = "hidden"; - } else if (self.document.mozHidden !== undefined) { - visibilityChange = "mozvisibilitychange"; - visibilityState = "mozVisibilityState"; - } else if (self.document.msHidden !== undefined) { - visibilityChange = "msvisibilitychange"; - visibilityState = "msVisibilityState"; - } else if (self.document.webkitHidden !== undefined) { - visibilityChange = "webkitvisibilitychange"; - visibilityState = "webkitVisibilityState"; - } + if (typeof document.hidden !== "undefined") { /* eslint-disable-line compat/compat */ + hidden = "hidden"; + visibilityChange = "visibilitychange"; + } else if (typeof document.msHidden !== "undefined") { + hidden = "msHidden"; + visibilityChange = "msvisibilitychange"; + } else if (typeof document.webkitHidden !== "undefined") { + hidden = "webkitHidden"; + visibilityChange = "webkitvisibilitychange"; } if (self.document) { document.addEventListener(visibilityChange, function () { - if (visibilityState) { + /* eslint-disable-next-line compat/compat */ + if (document[hidden]) { onAppHidden(); } else { onAppVisible(); From 84b69fa0e75169e964b4eada67a52247094c5b62 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Fri, 10 Apr 2020 21:20:21 +0200 Subject: [PATCH 27/52] Remove IE/Edge-specific case in app visibility handler As Edge 12+ supports the Visibility API, we don't need the MS-specific API handling --- src/components/apphost.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/apphost.js b/src/components/apphost.js index 5985609ccc..93e1dbd02c 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -431,9 +431,6 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f if (typeof document.hidden !== "undefined") { /* eslint-disable-line compat/compat */ hidden = "hidden"; visibilityChange = "visibilitychange"; - } else if (typeof document.msHidden !== "undefined") { - hidden = "msHidden"; - visibilityChange = "msvisibilitychange"; } else if (typeof document.webkitHidden !== "undefined") { hidden = "webkitHidden"; visibilityChange = "webkitvisibilitychange"; @@ -447,7 +444,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f } else { onAppVisible(); } - }); + }, false); } if (self.addEventListener) { From 0b061fb1ffaba8569b67820e47c1a183adb894a4 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Fri, 10 Apr 2020 21:42:27 +0200 Subject: [PATCH 28/52] Remove self.document from page visibility event --- src/components/apphost.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/apphost.js b/src/components/apphost.js index 93e1dbd02c..56e9c93521 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -436,16 +436,14 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f visibilityChange = "webkitvisibilitychange"; } - if (self.document) { - document.addEventListener(visibilityChange, function () { - /* eslint-disable-next-line compat/compat */ - if (document[hidden]) { - onAppHidden(); - } else { - onAppVisible(); - } - }, false); - } + document.addEventListener(visibilityChange, function () { + /* eslint-disable-next-line compat/compat */ + if (document[hidden]) { + onAppHidden(); + } else { + onAppVisible(); + } + }, false); if (self.addEventListener) { self.addEventListener("focus", onAppVisible); From 9d859d4fd3d70173b1e7edb7c5df4e4806301941 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Fri, 10 Apr 2020 22:58:18 +0200 Subject: [PATCH 29/52] Fetch action only once in inputManager --- src/scripts/inputManager.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/scripts/inputManager.js b/src/scripts/inputManager.js index cbbece63bc..1f65230154 100644 --- a/src/scripts/inputManager.js +++ b/src/scripts/inputManager.js @@ -227,10 +227,11 @@ import appHost from 'apphost'; } })[command]; - if (keyActions(commandName) === undefined) { - console.debug(`inputManager: tried to process command with no action assigned: ${commandName}`); + const action = keyActions(commandName); + if (action !== undefined) { + action.call(); } else { - keyActions(commandName).call(); + console.debug(`inputManager: tried to process command with no action assigned: ${commandName}`); } } From 0a0c639bad3ca860df7c6615cf5ea9458a51bfcd Mon Sep 17 00:00:00 2001 From: Julien Machiels Date: Fri, 10 Apr 2020 23:35:09 +0200 Subject: [PATCH 30/52] Update src/scripts/inputManager.js Use const instead of let Co-Authored-By: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com> --- src/scripts/inputManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripts/inputManager.js b/src/scripts/inputManager.js index 1f65230154..cacc6c99a3 100644 --- a/src/scripts/inputManager.js +++ b/src/scripts/inputManager.js @@ -42,7 +42,7 @@ import appHost from 'apphost'; function checkCommandTime(command) { - let last = commandTimes[command] || 0; + const last = commandTimes[command] || 0; const now = new Date().getTime(); if ((now - last) < 1000) { From ed4c532c596dde21bc70b01ae2461aabb8c5aa18 Mon Sep 17 00:00:00 2001 From: Alex van Stekelenborg Date: Fri, 10 Apr 2020 18:21:45 +0000 Subject: [PATCH 31/52] Translated using Weblate (Spanish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es/ --- src/strings/es.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/strings/es.json b/src/strings/es.json index cd3e5ade0e..3f059509f9 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1500,5 +1500,7 @@ "BoxSet": "Box Set", "Artist": "Artista", "AlbumArtist": "Artista del álbum", - "Album": "Álbum" + "Album": "Álbum", + "LabelDeinterlaceMethod": "Metodo de desentrelazar:", + "DeinterlaceMethodHelp": "Seleccione el método de desentrelazar para el transcodificar de contenido entrelazado." } From 4f77dc67f429ef9fb2c854c3467ea35909916d86 Mon Sep 17 00:00:00 2001 From: Cristian Date: Fri, 10 Apr 2020 19:17:11 +0000 Subject: [PATCH 32/52] Translated using Weblate (Spanish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es/ --- src/strings/es.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/strings/es.json b/src/strings/es.json index 3f059509f9..48af75b1fc 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1502,5 +1502,7 @@ "AlbumArtist": "Artista del álbum", "Album": "Álbum", "LabelDeinterlaceMethod": "Metodo de desentrelazar:", - "DeinterlaceMethodHelp": "Seleccione el método de desentrelazar para el transcodificar de contenido entrelazado." + "DeinterlaceMethodHelp": "Seleccione el método de desentrelazar para el transcodificar de contenido entrelazado.", + "LabelLibraryPageSize": "Tamaño de la página de la biblioteca:", + "LabelLibraryPageSizeHelp": "Establece la cantidad de artículos a mostrar en una página de la biblioteca. Ponlo en 0 para desactivar la paginación." } From 8cfe6facb8e5c11b4e98f7a5247921ef6fcb8b16 Mon Sep 17 00:00:00 2001 From: nextlooper42 Date: Fri, 10 Apr 2020 15:06:23 +0000 Subject: [PATCH 33/52] Translated using Weblate (Slovak) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sk/ --- src/strings/sk.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/strings/sk.json b/src/strings/sk.json index bbe23001fa..a076e9048b 100644 --- a/src/strings/sk.json +++ b/src/strings/sk.json @@ -1498,5 +1498,7 @@ "Episode": "Epizóda", "BoxSet": "Box Set", "Artist": "Umelec", - "AlbumArtist": "Umelec albumu" + "AlbumArtist": "Umelec albumu", + "LabelLibraryPageSizeHelp": "Určuje množstvo položiek na zobrazenie na stránke knižnice. Nastavte 0 pre vypnutie stránkovania.", + "LabelLibraryPageSize": "Veľkosť stránky knižnice:" } From 4fca211b2efa78b240a10bf5b68b5077043c1b2d Mon Sep 17 00:00:00 2001 From: Nyanmisaka <799610810@qq.com> Date: Fri, 10 Apr 2020 15:51:52 +0000 Subject: [PATCH 34/52] 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, 3 insertions(+), 1 deletion(-) diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index acdfb2d5ed..ba125ed5e8 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -1502,5 +1502,7 @@ "YadifBob": "Yadif Bob", "Yadif": "Yadif", "LabelDeinterlaceMethod": "反交错方法:", - "DeinterlaceMethodHelp": "选择对隔行扫描内容进行转码时所用的反交错方法。" + "DeinterlaceMethodHelp": "选择对隔行扫描内容进行转码时所用的反交错方法。", + "LabelLibraryPageSize": "媒体库分页阈值:", + "LabelLibraryPageSizeHelp": "设置媒体库页面每页要显示的最多媒体个数。设置为 0 以禁用分页。" } From dd54466c365b988cf40da7afa924a30313db9d07 Mon Sep 17 00:00:00 2001 From: Abdul Khaliq Date: Sat, 11 Apr 2020 13:11:12 +0000 Subject: [PATCH 35/52] Added translation using Weblate (Urdu (Pakistan)) --- src/strings/ur_PK.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/strings/ur_PK.json diff --git a/src/strings/ur_PK.json b/src/strings/ur_PK.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/src/strings/ur_PK.json @@ -0,0 +1 @@ +{} From e238ffe31fa8294ef26ec048b6c4cef9cc392260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Libor=20Fil=C3=ADpek?= Date: Sat, 11 Apr 2020 14:47:28 +0000 Subject: [PATCH 36/52] Translated using Weblate (Czech) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/cs/ --- src/strings/cs.json | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/strings/cs.json b/src/strings/cs.json index 0a65fc1000..4f0745b425 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -999,9 +999,9 @@ "OptionWeekly": "Týdenní", "OriginalAirDateValue": "Datum vysílání originálu: {0}", "Overview": "Přehled/Obsah", - "PackageInstallCancelled": "Instalace {0} zrušena.", - "PackageInstallCompleted": "Instalace {0} dokončena.", - "PackageInstallFailed": "Instalace {0} selhala.", + "PackageInstallCancelled": "Instalace {0} (verze {1}) zrušena.", + "PackageInstallCompleted": "Instalace {0} (verze {1}) dokončena.", + "PackageInstallFailed": "Instalace {0} (verze {1}) selhala.", "ParentalRating": "Rodičovské hodnocení", "PasswordMatchError": "Heslo a potvrzení hesla musí souhlasit.", "PasswordResetComplete": "Heslo bylo obnoveno.", @@ -1022,7 +1022,7 @@ "PlayNext": "Přehrát další", "PlayNextEpisodeAutomatically": "Automaticky přehrávat další epizodu", "PlayOnAnotherDevice": "Přehrát na jiném zařízení", - "PlaybackErrorNoCompatibleStream": "Žádné kompatibilní streamy nejsou v současné době k dispozici. Zkuste to prosím později, nebo pro více podrobností kontaktujte svého správce systému.", + "PlaybackErrorNoCompatibleStream": "Tento klient není kompatibilní s médiem a server neodesílá kompatibilní formát médií.", "PlaybackErrorNotAllowed": "V současné době nejste oprávněni přehrávat tento obsah. Pro více informací se obraťte se na správce systému.", "PlaybackErrorPlaceHolder": "Chcete-li toto video přehrát, vložte disk.", "Played": "Přehráno", @@ -1223,7 +1223,7 @@ "AirDate": "Datum vysílání", "Aired": "Vysíláno", "Alerts": "Upozornění", - "AllComplexFormats": "Všechny komplexní formáty (ASS, SSA, VOBSUB, PGS, SUB/IDX, atd.)", + "AllComplexFormats": "Všechny komplexní formáty (ASS, SSA, VOBSUB, PGS, SUB/IDX, atd.)", "AllLibraries": "Všechny knihovny", "AllowDeletionFromAll": "Povolit smazání médií ze všech knihoven", "AllowMediaConversion": "Povolit konverzi médií", @@ -1248,7 +1248,7 @@ "Blacklist": "Černá listina", "BobAndWeaveWithHelp": "Bob and weave (vyšší kvalita, ale pomalejší)", "Browse": "Procházet", - "BurnSubtitlesHelp": "Určuje, zda má server vypalovat titulky při překódování videa. Vynechání tohoto zlepší výkon serveru. Chcete-li vypálit grafické formáty (VOBSUB, PGS, SUB / IDX atd.) a některé titulky ASS / SSA, vyberte možnost Auto.", + "BurnSubtitlesHelp": "Určuje, zda má server vypalovat titulky při překódování videa. Vynechání tohoto zlepší výkon serveru. Chcete-li vypálit grafické formáty (VOBSUB, PGS, SUB / IDX atd.) a některé titulky ASS nebo SSA, vyberte možnost Auto.", "ButtonInfo": "Info", "ButtonMenu": "Menu", "ButtonOk": "Ok", @@ -1594,5 +1594,13 @@ "PersonRole": "jako {0}", "ListPaging": "{0}-{1} ze {2}", "WriteAccessRequired": "Jellyfin Server potřebuje oprávnění pro zápis v této složce. Zkontrolujte oprávnění a zkuste to znovu.", - "PathNotFound": "Cesta nebyla nalezena. Zkontrolujte, zda je platná a zkuste to znovu." + "PathNotFound": "Cesta nebyla nalezena. Zkontrolujte, zda je platná a zkuste to znovu.", + "WeeklyAt": "V {0} v {1}", + "LastSeen": "Naposledy zobrazené {0}", + "YadifBob": "Yadif Bob", + "Yadif": "Yadif", + "LabelLibraryPageSizeHelp": "Určuje počet položek k zobrazení na stránce knihovny. Nastavte na 0 pro vypnutí stránkování.", + "LabelLibraryPageSize": "Velikost stránky knihovny:", + "LabelDeinterlaceMethod": "Metoda odstranění prokládání:", + "DeinterlaceMethodHelp": "Vyberte metodu odstranění prokládání obrazu při překódování obsahu." } From 1ca550f5f7bfdd470e85d982373a441bc9203943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Dur=C3=A1n?= Date: Sat, 11 Apr 2020 21:18:27 +0000 Subject: [PATCH 37/52] Translated using Weblate (Spanish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es/ --- src/strings/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/es.json b/src/strings/es.json index 48af75b1fc..1bb9a76537 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -310,7 +310,7 @@ "HeaderLatestMovies": "Últimas películas", "HeaderLatestMusic": "Última música", "HeaderLatestRecordings": "Últimas grabaciones", - "HeaderLibraries": "Blibliotecas", + "HeaderLibraries": "Bibliotecas", "HeaderLibraryAccess": "Acceso a la biblioteca", "HeaderLibraryFolders": "Carpetas de la biblioteca", "HeaderLibraryOrder": "Orden de la biblioteca", From 61899b3e0813c122f0cc213d4a0c0558628001a8 Mon Sep 17 00:00:00 2001 From: amirmasoud Date: Sat, 11 Apr 2020 11:55:20 +0000 Subject: [PATCH 38/52] Translated using Weblate (Persian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fa/ --- src/strings/fa.json | 238 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 203 insertions(+), 35 deletions(-) diff --git a/src/strings/fa.json b/src/strings/fa.json index 3a737a6be0..c6aca6726e 100644 --- a/src/strings/fa.json +++ b/src/strings/fa.json @@ -1,8 +1,8 @@ { "All": "همه", - "AllowMediaConversion": "اجازه تبدیل رسانه ها", - "AllowMediaConversionHelp": "دادن یا ندادن دسترسی به ویژگی تبدیل رسانه ها", - "AllowRemoteAccess": "اجازه دادن اتصال از راه دور به سرور Jellyfin", + "AllowMediaConversion": "اجازه تبدیل رسانه‌ها", + "AllowMediaConversionHelp": "دادن یا ندادن دسترسی به ویژگی تبدیل رسانه‌ها.", + "AllowRemoteAccess": "اجازه بدهید اتصال‌های از راه دور به این سرور Jellyfin متصل شوند.", "AllowRemoteAccessHelp": "اگرانتخاب نشود، تمامی اتصال های از راه دور بلوکه می شوند.", "Browse": "مرور کردن", "ButtonAddUser": "افزودن کاربر", @@ -19,11 +19,11 @@ "ButtonSort": "مرتب سازی", "DeleteMedia": "حذف رسانه", "Disabled": "غیرفعال شده", - "FolderTypeBooks": "کتاب ها", - "FolderTypeMovies": "سینمایی ها", - "FolderTypeMusic": "موسیقی", - "FolderTypeMusicVideos": "موزیک ویدئوها", - "FolderTypeTvShows": "سریال تلویزیونی", + "FolderTypeBooks": "کتاب‌ها", + "FolderTypeMovies": "فیلم‌ها", + "FolderTypeMusic": "موسیقی‌ها", + "FolderTypeMusicVideos": "موزیک ویدیوها", + "FolderTypeTvShows": "سریال‌های تلویزیونی", "HeaderAddUser": "اضافه کردن کاربر", "HeaderContinueWatching": "ادامه تماشا", "HeaderCustomDlnaProfiles": "پروفایل های سفارشی", @@ -45,15 +45,15 @@ "HeaderTypeImageFetchers": "{0} هماهنگ کننده تصویر", "HeaderUsers": "کاربران", "LabelAudioLanguagePreference": "اولویت زبان صدا:", - "LabelContentType": "نوع محتوی", - "LabelCountry": "کشور", + "LabelContentType": "نوع محتوا:", + "LabelCountry": "کشور:", "LabelCurrentPassword": "رمز فعلی:", - "LabelCustomCertificatePath": "مسیر اختصصای گواهینامه SSL:", + "LabelCustomCertificatePath": "مسیر اختصاصی گواهینامه SSL:", "LabelCustomCertificatePathHelp": "پچ به فایل PKCS #12 حاوی یک گواهینامه و کلید خصوصی است تا پشتیبانی از TLS را در یک دامنه شخصی فعال کند.", "LabelDisplayMissingEpisodesWithinSeasons": "نمایش قسمت های ناموجود در بین فصل ها", "LabelFinish": "پایان", - "LabelLanguage": "زبان", - "LabelMaxParentalRating": "حداکثر درجه سنی مجاز والدین", + "LabelLanguage": "زبان:", + "LabelMaxParentalRating": "حداکثر امتیاز سنی مجاز والدین:", "LabelNewPassword": "رمز جدید:", "LabelNewPasswordConfirm": "تایید رمز جدید:", "LabelNext": "بعدی", @@ -95,9 +95,9 @@ "TabArtists": "هنرمندان", "TabEpisodes": "قسمت ها", "TabGenres": "ژانرها", - "TabLatest": "آخرین", - "TabMetadata": "اطلاعات محتوی", - "TabMusicVideos": "موزیک ویدیو ها", + "TabLatest": "جدیدترین‌ها", + "TabMetadata": "فراداده", + "TabMusicVideos": "موزیک ویدیوها", "TabNetworks": "شبکه ها", "TabNotifications": "اعلان ها", "TabPassword": "رمز عبور", @@ -109,10 +109,10 @@ "TabSuggestions": "پیشنهادات", "TabUpcoming": "بزودی", "TellUsAboutYourself": "در مورد خودتان به ما بگویید", - "ThisWizardWillGuideYou": "این ویزارد برای انجام تنظیمات به شما کمک می کند. برای شروع، لطفا زبان مورد نظر خود را انتخاب فرمایید", + "ThisWizardWillGuideYou": "این عمل برای انجام تنظیمات به شما کمک می‌کند. برای شروع، لطفا زبان مورد نظر خود را انتخاب کنید.", "UserProfilesIntro": "Jellyfin دارای پشتیبانی داخلی از پروفایل کاربران می باشد. با فعال سازی هر کاربر، او می تواند تنظیمات ، وضعیت پخش و کنترل والدین خاص خودش را داشته باشد.", "WelcomeToProject": "به Jellyfin خوش آمدید!", - "WizardCompleted": "همه چیزی که فعلا می خواهیم همین است.جمع آوری اطلاعات کتابخانه های شما هم اکنون توسط Jellyfin آغاز شده است. اپلیکیشن های ما را امتحان کنید و سپس بر روی پایان کلیک کنید تا پیشخوان سرور را مشاهده نمایید.", + "WizardCompleted": "همه چیزی که فعلا می‌خواهیم همین است. جمع آوری اطلاعات کتابخانه‌های شما هم اکنون توسط Jellyfin آغاز شده است. اپلیکیشن‌های ما را امتحان کنید و سپس بر روی پایان کلیک کنید تا پیشخوان سرور را مشاهده نمایید.", "Albums": "آلبوم‌ها", "Artists": "هنرمندان", "Books": "کتاب‌ها", @@ -127,7 +127,7 @@ "HeaderFavoriteAlbums": "آلبوم‌های مورد علاقه", "HeaderFavoriteArtists": "هنرمندان مورد علاقه", "HeaderFavoriteSongs": "آهنگ‌های مورد علاقه", - "HeaderLiveTV": "پخش زنده تلویزیون", + "HeaderLiveTV": "تلویزیون زنده", "Movies": "فیلم‌ها", "Photos": "عکس‌ها", "Playlists": "لیست‌های پخش", @@ -135,11 +135,11 @@ "Songs": "موسیقی‌ها", "Sync": "همگام‌سازی", "ValueSpecialEpisodeName": "ویژه - {0}", - "AllEpisodes": "تمام قسمت ها", - "AllLanguages": "تمام زبان ها", - "AllLibraries": "تمام کتابخانه ها", + "AllEpisodes": "تمام قسمت‌ها", + "AllLanguages": "تمام زبان‌ها", + "AllLibraries": "تمام کتابخانه‌ها", "AllowHWTranscodingHelp": "اگر فعال شود, اجازه می‌دهید تبدیل کیفیت در لحظه انجام شود. این ممکن است به کاهش کدگذاری لازم برای Jellyfin منجر بشود.", - "AllowOnTheFlySubtitleExtraction": "اجازه میدهد در لحظه زیرنویس بازشود", + "AllowOnTheFlySubtitleExtraction": "اجازه می‌دهد در لحظه زیرنویس بازشود", "Add": "افزودن", "Actor": "بازیگر", "AccessRestrictedTryAgainLater": "دسترسی در حال حاضر محدود شده است. لطفا دوباره تلاش کنید.", @@ -149,7 +149,7 @@ "ButtonSelectView": "انتخاب نما", "ButtonSelectServer": "انتخاب سرور", "ButtonSearch": "جستجو", - "ButtonScanAllLibraries": "پویش تمام کتابخانه‌ها", + "ButtonScanAllLibraries": "اسکن تمام کتابخانه‌ها", "ButtonRevoke": "ابطال", "ButtonResume": "ادامه", "ButtonRestart": "راه اندازی مجدد", @@ -215,9 +215,9 @@ "AroundTime": "حدود {0}", "Anytime": "هر زمانی", "AnyLanguage": "هر زبانی", - "AlwaysPlaySubtitles": "همیشه زیرنویس را نمایش بده", + "AlwaysPlaySubtitles": "همیشه پخش کن", "AllowFfmpegThrottling": "گلوگاه تبدیل کیفیت", - "AllChannels": "همه‌ی کانال‌ها", + "AllChannels": "همه کانال‌ها", "Alerts": "هشدارها", "Aired": "پخش شده", "AirDate": "تاریخ پخش", @@ -239,11 +239,11 @@ "EnableHardwareEncoding": "فعال سازی رمزگذاری سخت افزاری", "EnableExternalVideoPlayersHelp": "یک منوی پخش کننده ویدیوی خارجی، زمانی که شروع به پخش ویدیو می‌شود نمایش داده خواهد شد.", "EnableExternalVideoPlayers": "پخش کننده ویدیوی خارجی", - "EnableDisplayMirroring": "نمایش حالت آینه", + "EnableDisplayMirroring": "انعکاس نمایش", "EnableCinemaMode": "حالت سینما", "EnableBackdrops": "پشت‌زمینه‌ها", "EditSubtitles": "ویرایش زیرنویس‌ها", - "EditMetadata": "ویرایش ابرداده", + "EditMetadata": "ویرایش فراداده", "EditImages": "ویرایش عکس‌ها", "Edit": "ویرایش", "DropShadow": "سایه پشت زمینه", @@ -252,7 +252,7 @@ "Download": "بارگیری", "Down": "پایین", "DoNotRecord": "ضبط نکن", - "DisplayModeHelp": "نوع صفحه نمایشی که Jellyfin را اجرا می‌کنید را انتخاب کنید‌‌.", + "DisplayModeHelp": "سبک رابط کاربری مورد نظر خود را انتخاب کنید.", "DisplayMissingEpisodesWithinSeasons": "قسمت‌های ناموجود در فصل‌ها را نمایش بده", "DisplayInMyMedia": "نمایش در صفحه‌ی خانه", "Display": "نمایش", @@ -358,13 +358,13 @@ "HeaderLibraryFolders": "پوشه‌های کتابخانه", "HeaderLibraryAccess": "دسترسی به کتابخانه", "HeaderLibraries": "کتابخانه‌ها", - "HeaderLatestRecordings": "آخرین ضبط‌ها", - "HeaderLatestMusic": "آخرین آهنگ‌ها", - "HeaderLatestMovies": "آخرین فیلم‌ها", - "HeaderLatestMedia": "آخرین رسانه‌ها", + "HeaderLatestRecordings": "جدیدترین‌ ضبط‌ها", + "HeaderLatestMusic": "جدیدترین‌ آهنگ‌ها", + "HeaderLatestMovies": "جدیدترین‌ فیلم‌ها", + "HeaderLatestMedia": "جدیدترین‌ رسانه‌ها", "HeaderKeepSeries": "سریال ادامه دهید", "HeaderKeepRecording": "ضبط را ادامه دهید", - "HeaderItems": "موارد", + "HeaderItems": "آیتم‌ها", "HeaderInstall": "نصب", "HeaderImageSettings": "تنظیمات عکس", "HeaderIdentifyItemHelp": "یک یا بیشتر مورد برای جستجو وارد کنید. موارد را حذف کنید تا نتیجه جستجو را افزایش دهید.", @@ -415,5 +415,173 @@ "HeaderCancelSeries": "لغو سریال", "HeaderCancelRecording": "لغو ضبط", "HeaderBooks": "کتاب‌ها", - "HeaderBlockItemsWithNoRating": "موارد مسدود شده با نقص یا عدم وجود اطلاعات امتیاز:" + "HeaderBlockItemsWithNoRating": "موارد مسدود شده با نقص یا عدم وجود اطلاعات امتیاز:", + "LabelSkipIfAudioTrackPresentHelp": "این گزینه را عدم انتخاب کنید تا اطمینان حاصل کنید که همه ویدیوها فارغ از زبان صوت، زیرنویس دارند.", + "LabelSkipIfAudioTrackPresent": "اگر صدای پیش‌فرض با زبان دانلودی یکسان است پرش کن", + "LabelSkipForwardLength": "میزان رفتن به جلو:", + "LabelSkipBackLength": "میزان بازگشت به عقب:", + "LabelSkin": "پوسته:", + "LabelSize": "سایز:", + "LabelSimultaneousConnectionLimit": "محدودیت پخش همزمان:", + "LabelServerName": "نام سرور:", + "LabelServerHostHelp": "192.168.1.100:8096 یا https://myserver.com", + "LabelServerHost": "میزبان:", + "LabelSerialNumber": "شماره سریال", + "LabelSendNotificationToUsers": "ارسال اعلان به:", + "LabelSelectVersionToInstall": "نسخه مورد نظر برای نصب را انتخاب کنید:", + "LabelVersionInstalled": "{0} نصب شده است", + "EncoderPresetHelp": "یک مقدار سریع‌تر انتخاب کنید تا کارایی بهبود پیدا کند یا یک مقدار کُندتر انتخاب کنید تا کیفیت بهبود پیدا کند.", + "ShowYear": "نمایش سال", + "ShowTitle": "نمایش عنوان", + "ButtonAudioTracks": "آهنگ‌ها", + "AlbumArtist": "هنرمند آلبوم", + "Album": "آلبوم", + "HeaderAddScheduledTaskTrigger": "افزودن فعال‌ساز", + "HeaderActivity": "فعالیت‌ها", + "HeaderActiveRecordings": "ضبط‌های فعال", + "HeaderActiveDevices": "دستگاه‌های فعال", + "HeaderAccessScheduleHelp": "یک زمان‌بندی دسترسی ایجاد کنید تا دسترسی به ساعاتی مشخص محدود شود.", + "HeaderAccessSchedule": "زمان‌بندی دسترسی", + "HandledByProxy": "توسط reverse proxy مدیریت می‌شود", + "HDPrograms": "برنامه‌های HD", + "Filters": "صافی‌ها", + "FileReadError": "خطایی هنگام خواندن فایل رخ داد.", + "FileReadCancelled": "خواندن فایل لغو شد.", + "FileNotFound": "فایل پیدا نشد.", + "File": "فایل", + "FetchingData": "در حال دریافت داده‌های اضافی", + "Features": "برجسته‌ها", + "Favorite": "مورد علاقه", + "FastForward": "سریع جلو", + "Extras": "موارد اضافی", + "ExtraLarge": "فوق العاده بزرگ", + "BoxSet": "جعبه ست", + "Art": "هنر", + "Artist": "هنرمند", + "AllComplexFormats": "تمام فرمت‌های پیچیده (ASS, SSA, VOBSUB, PGS, SUB, IDX)", + "GuideProviderLogin": "ورود", + "Guide": "راهنما", + "GuestStar": "ستاره‌ی مهمان", + "GroupVersions": "نسخه‌های گروه", + "GroupBySeries": "گروه بندی بر اساس سریال‌ها", + "Genre": "ژانر", + "General": "عمومی", + "Fullscreen": "تمام صفحه", + "Friday": "جمعه", + "FormatValue": "قالب‌ها: {0}", + "FolderTypeUnset": "محتواهای مخلوط", + "TabMyPlugins": "افزونه‌های من", + "TabMusic": "موسیقی‌ها", + "TabMovies": "فیلم‌ها", + "TabLogs": "واقعه نگار‌ها", + "TabLiveTV": "تلویزیون زنده", + "LatestFromLibrary": "جدیدترین‌های {0}", + "Large": "بزرگ", + "LabelffmpegPath": "مسیر FFmpeg:", + "LabelZipCode": "کدپستی:", + "LabelYear": "سال:", + "LabelWeb": "وب:", + "LabelVideoResolution": "کیفیت ویدیو:", + "LabelVideo": "ویدیو", + "DashboardArchitecture": "معماری: {0}", + "DashboardOperatingSystem": "سیستم عامل: {0}", + "DashboardServerName": "سرور: {0}", + "DashboardVersionNumber": "نسخه: {0}", + "LabelVersion": "نسخه:", + "LabelValue": "مقدار:", + "LabelVaapiDevice": "دستگاه VA API:", + "LabelUsername": "نام کاربری:", + "LabelUserLibrary": "کتابخانه کاربر:", + "LabelUserAgent": "عامل کاربر:", + "LabelUser": "کاربر:", + "LabelUseNotificationServices": "استفاده از سرویس‌های زیر:", + "LabelTypeText": "متن", + "LabelType": "نوع:", + "LabelKodiMetadataEnablePathSubstitution": "فعال سازی تعویض مسیر", + "LabelKodiMetadataDateFormatHelp": "تمام تاریخ‌های موجود در فایل‌های NFO با استفاده از این قالب تجزیه می‌شوند.", + "LabelKodiMetadataDateFormat": "قالب تاریخ انتشار:", + "LabelKidsCategories": "دسته‌بندی‌های کودکان:", + "OnApplicationStartup": "هنگام شروع برنامه", + "EveryXHours": "هر {0} ساعت", + "EveryHour": "هر ساعت", + "EveryXMinutes": "هر {0} دقیقه", + "OnWakeFromSleep": "هنگام بیداری از خواب", + "WeeklyAt": "{0} در {1}", + "DailyAt": "روزانه در {0}", + "LastSeen": "آخرین بازدید {0}", + "PersonRole": "در نقش {0}", + "ListPaging": "{0}-{1} از {2}", + "Yesterday": "دیروز", + "Yes": "بلی", + "YadifBob": "Yadif Bob", + "Yadif": "Yadif", + "ValueConditions": "شرایط: {0}", + "ValueCodec": "کدک: {0}", + "ValueAudioCodec": "کدک صدا: {0}", + "ValueAlbumCount": "{0} آلبوم", + "Upload": "آپلود", + "Up": "بالا", + "Unrated": "بدون امتیاز", + "Unplayed": "پخش نشده", + "Unmute": "صدادار", + "UninstallPluginHeader": "حذف نصب افزونه", + "UninstallPluginConfirmation": "آیا اطمینان دارید که می‌خواهید {0} را حذف نصب کنید؟", + "Uniform": "یکپارچه", + "Tuesday": "سه‌شنبه", + "Transcoding": "کدگذاری", + "Trailers": "تریلرها", + "Track": "آهنگ", + "TrackCount": "{0} آهنگ", + "TitlePlayback": "پخش", + "TitleHostingSettings": "تنظیمات میزبانی", + "TitleHardwareAcceleration": "تسریع کننده سخت افزاری", + "Thursday": "پنج‌شنبه", + "Thumb": "بندانگشتی", + "ThemeVideos": "تم ویدیوها", + "ThemeSongs": "آهنگ‌های تم", + "TagsValue": "برچسب‌ها: {0}", + "Tags": "برچسب‌ها", + "TabUsers": "کاربران", + "Absolute": "کامل", + "Writer": "نویسنده", + "Whitelist": "لیست سفید", + "Wednesday": "چهارشنبه‌ها", + "Watched": "مشاهده شده", + "ViewPlaybackInfo": "مشاهده اطلاعات پخش", + "ViewArtist": "مشاهده هنرمند", + "ViewAlbum": "مشاهده آلبوم", + "VideoRange": "محدوده ویدیو", + "Vertical": "عمودی", + "ValueVideoCodec": "کدک ویدیو: {0}", + "ValueTimeLimitSingleHour": "محدودیت زمانی: 1 ساعت", + "ValueTimeLimitMultiHour": "محدودیت زمانی: {0} ساعت", + "ValueSongCount": "{0} آهنگ", + "ValueSeriesCount": "{0} سریال", + "ValueSeconds": "{0} ثانیه", + "ValueOneSong": "1 آهنگ", + "ValueOneSeries": "1 سریال", + "ValueOneMusicVideo": "1 موزیک ویدیو", + "ValueOneMovie": "1 فیلم", + "ValueOneEpisode": "1 قسمت", + "ValueOneAlbum": "1 آلبوم", + "ValueMusicVideoCount": "{0} موزیک ویدیو", + "ValueMovieCount": "{0} فیلم", + "ValueMinutes": "{0} دقیقه", + "ValueEpisodeCount": "{0} قسمت", + "ValueDiscNumber": "دیسک {0}", + "LabelImportOnlyFavoriteChannels": "محدود کردن کانال‌هایی که به عنوان مورد علاقه انتخاب شده‌اند", + "LabelDateAdded": "تاریخ اضافه شده:", + "LabelDashboardTheme": "تم داشبورد سرور:", + "LabelCustomRating": "امتیازدهی سفارشی:", + "LabelCustomDeviceDisplayName": "نام نمایشی:", + "LabelCustomCssHelp": "ظاهر سفارشی مورد نظر خود را در رابط وب اعمال کنید.", + "LabelCustomCss": "CSS سفارشی:", + "LabelCriticRating": "امتیاز منتقدان:", + "LabelCorruptedFrames": "فریم‌های خراب شده:", + "LabelImageType": "نوع عکس:", + "LabelIconMaxWidth": "حداکثر عرض آیکن:", + "LabelIconMaxHeight": "حداکثر ارتفاع آیکن:", + "LabelHttpsPort": "شماره پورت HTTPS محلی:", + "LabelHomeNetworkQuality": "کیفیت شبکه خانگی:", + "LabelHardwareAccelerationTypeHelp": "تسریع کننده سخت افزاری نیاز به پیکربندی اضافی دارد." } From 69198dcb92528d8f052a5c23a7e7e320eeee5950 Mon Sep 17 00:00:00 2001 From: Spiderfly Date: Sat, 11 Apr 2020 19:32:54 +0000 Subject: [PATCH 39/52] Translated using Weblate (Finnish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fi/ --- src/strings/fi.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/strings/fi.json b/src/strings/fi.json index 55c5a1fbcd..b915aefd39 100644 --- a/src/strings/fi.json +++ b/src/strings/fi.json @@ -164,7 +164,7 @@ "ButtonOff": "Pois päältä", "ButtonOk": "Ok", "ButtonOpen": "Avoin", - "BurnSubtitlesHelp": "Määrittää jos palvelimen pitäisi upottaa tekstitykset suoraan videotiedostoon muuntamisvaiheessa tekstitysformaatista riippuen. Upottamisen välttäminen parantaa palvelimen suorituskykyä. Valitse Automaattinen upottaaksesi sekä kuvapohjaiset- (esim. VOBSUB, PGS, SUB/IDX, jne.) että ASS/SSA tekstitysmuodot", + "BurnSubtitlesHelp": "Määrittää mikäli palvelimen pitäisi polttaa tekstitykset suoraan videoon muunnoksen aikana riippuen tekstitysten formaatista. Tekstitysten polttamisen välttäminen parantaa palvelimen suorituskykyä. Valitse Automaattinen polttaaksesi sekä kuva- (esim. VOBSUB, PGS, SUB/IDX, jne.) että tekstipohjaiset (ASS/SSA) formaatit.", "ButtonParentalControl": "Lapsilukko", "ButtonPause": "Tauko", "ButtonPlay": "Toista", @@ -267,7 +267,7 @@ "ButtonAddImage": "Lisää kuva", "Movies": "Elokuvat", "HeaderNextUp": "Seuraavaksi", - "HeaderLiveTV": "TV-lähetykset", + "HeaderLiveTV": "Suorat lähetykset", "HeaderFavoriteSongs": "Lempikappaleet", "HeaderFavoriteShows": "Lempisarjat", "HeaderFavoriteEpisodes": "Lempijaksot", @@ -319,5 +319,7 @@ "ErrorAddingXmlTvFile": "XMLTV-tiedostoa käyttäessä tapahtui virhe. Varmista, että tiedosto on olemassa ja kokeile uudestaan.", "ErrorAddingTunerDevice": "Viritintä lisätessä ilmeni ongelma. Varmista, että se on kytketty oikein ja kokeile uudestaan.", "EnableThemeVideosHelp": "Soita tunnusvideoita taustalla, selatessasi kirjastoa.", - "EnableThemeVideos": "Teeman videot" + "EnableThemeVideos": "Teeman videot", + "AlbumArtist": "Albumin Artisti", + "Album": "Albumi" } From 887b1d4d2f3c35e2321f28425c9643ec02e8294f Mon Sep 17 00:00:00 2001 From: Alexis BIZON Date: Sat, 11 Apr 2020 16:24:51 +0000 Subject: [PATCH 40/52] Translated using Weblate (French) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/ --- src/strings/fr.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/strings/fr.json b/src/strings/fr.json index 6db1113d49..b3dccb9051 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -1498,5 +1498,7 @@ "YadifBob": "Yadif Bob", "Yadif": "Yadif", "LabelDeinterlaceMethod": "Méthode de désentrelacement :", - "DeinterlaceMethodHelp": "Sélectionnes la méthode de désentrelacement à utiliser lors du transcodage de contenu entrelacé." + "DeinterlaceMethodHelp": "Sélectionnes la méthode de désentrelacement à utiliser lors du transcodage de contenu entrelacé.", + "LabelLibraryPageSize": "Taille de la page de la médiathèque :", + "LabelLibraryPageSizeHelp": "Définit la quantité d'éléments à afficher sur une page de médiathèque. Définir à 0 afin de désactiver la pagination." } From 49e026e6d8b1b200485d8052e7f996b28cdd205e Mon Sep 17 00:00:00 2001 From: millallo Date: Sat, 11 Apr 2020 10:29:35 +0000 Subject: [PATCH 41/52] Translated using Weblate (Italian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/it/ --- src/strings/it.json | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/strings/it.json b/src/strings/it.json index 2a69625b3d..2cd244a396 100644 --- a/src/strings/it.json +++ b/src/strings/it.json @@ -461,7 +461,7 @@ "Images": "Immagini", "ImportFavoriteChannelsHelp": "Se abilitata, solo i canali che sono contrassegnati come preferiti sul dispositivo di sintonizzazione verranno importati.", "ImportMissingEpisodesHelp": "Se abilitato, le informazioni relative agli episodi mancanti saranno importate nel database di Jellyfin e mostrate all'interno di Serie e Stagioni. Questo può causare scansioni della libreria più lente.", - "InstallingPackage": "Installazione di {0}", + "InstallingPackage": "Installazione di {0} (versione {1})", "InstantMix": "Mix istantaneo", "ItemCount": "{0} elementi", "Items": "Elementi", @@ -1035,9 +1035,9 @@ "OptionWeekly": "Settimanale", "OriginalAirDateValue": "Prima messa in onda (originale): {0}", "Overview": "Trama", - "PackageInstallCancelled": "Installazione di {0} annullata.", - "PackageInstallCompleted": "Installazione di {0} completa.", - "PackageInstallFailed": "Installazione di {0} fallita.", + "PackageInstallCancelled": "Installazione di {0} (versione {1}) annullata.", + "PackageInstallCompleted": "Installazione di {0} (versione {1}) completata.", + "PackageInstallFailed": "Installazione di {0} (versione {1}) fallita.", "ParentalRating": "Classificazione per genitori", "PasswordMatchError": "Le password non coincidono.", "PasswordResetComplete": "la password è stata ripristinata.", @@ -1457,7 +1457,7 @@ "CopyStreamURLError": "Si è verificato un errore nel copiare l'indirizzo.", "EnableFastImageFadeInHelp": "Abilita la dissolvenza veloce per le immagini caricate", "EnableFastImageFadeIn": "Dissolvenza immagine veloce", - "PlaybackErrorNoCompatibleStream": "C'era un problema con il profiling del client e il server non sta inviando un formato compatibile.", + "PlaybackErrorNoCompatibleStream": "Il client è incompatibile con il media e il server non sta inviando un formato compatibile.", "OptionForceRemoteSourceTranscoding": "Forza la transcodifica da fonti di media remoti (come LiveTV)", "NoCreatedLibraries": "Sembra che tu non abbia ancora creato delle librerie. {0}Vuoi crearne una adesso?{1}", "LabelVideoResolution": "Risoluzione video:", @@ -1471,5 +1471,31 @@ "PreferEmbeddedEpisodeInfosOverFileNames": "Preferisci le informazioni incorporate nell'episodio rispetto ai nomi dei file", "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Questo utilizza le informazioni dell'episodio provenienti dai metadata incorporati, se disponibili.", "ClientSettings": "Impostazioni del client", - "Album": "Album" + "Album": "Album", + "OnWakeFromSleep": "Al risveglio", + "Person": "Persona", + "LabelDeinterlaceMethod": "Metodo di deinterlacciamento:", + "DeinterlaceMethodHelp": "Metodo di deinterlacciamento da usare durante la transcodifica.", + "Artist": "Artista", + "OnApplicationStartup": "All'avvio", + "EveryXHours": "Ogni {0} ore", + "EveryHour": "Ogni ora", + "EveryXMinutes": "Ogni {0} minuti", + "WeeklyAt": "Tutti i {0} alle {1}", + "DailyAt": "Tutti i giorni alle {0}", + "LastSeen": "Visto l'ultima volta {0}", + "PersonRole": "nel ruolo di {0}", + "ListPaging": "{0}-{1} di {2}", + "WriteAccessRequired": "Jellyfin Server richiede il permesso di scrittura su questa cartella. Verificare l'autorizzazione e riprovare.", + "PathNotFound": "Percorso non trovato. Assicurarsi che sia valido e riprovare.", + "YadifBob": "Yadif Bob", + "Yadif": "Yadif", + "Track": "Traccia", + "Season": "Stagione", + "OtherArtist": "Altri Artisti", + "Movie": "Film", + "LabelLibraryPageSizeHelp": "Numero di elementi presenti nella paginazione della libreria. Il valore 0 disabilita la paginazione.", + "LabelLibraryPageSize": "Elementi nella paginazione della libreria:", + "Episode": "Episodio", + "BoxSet": "Cofanetto" } From 05cf2d77ecabb8fa1ddc9b6a3aeb26ba788e2729 Mon Sep 17 00:00:00 2001 From: darcostan Date: Sat, 11 Apr 2020 18:24:47 +0000 Subject: [PATCH 42/52] Translated using Weblate (Serbian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sr/ --- src/strings/sr.json | 106 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 4 deletions(-) diff --git a/src/strings/sr.json b/src/strings/sr.json index 5691cc68eb..dc329c1309 100644 --- a/src/strings/sr.json +++ b/src/strings/sr.json @@ -36,7 +36,7 @@ "ButtonOpen": "Отвори", "ButtonOk": "Ок", "ButtonOff": "Искључи", - "ButtonNextTrack": "Следећа трака", + "ButtonNextTrack": "Следећа нумера", "ButtonNew": "Ново", "ButtonNetwork": "Мрежа", "ButtonMore": "Више", @@ -51,7 +51,7 @@ "ButtonFullscreen": "Пун екран", "ButtonForgotPassword": "Заборављена шифра", "ButtonFilter": "Филтер", - "ButtonDownload": "Скини (даунлоадуј)", + "ButtonDownload": "Преузми", "ButtonDown": "Доле", "ButtonDeleteImage": "Обриши слику", "ButtonDelete": "Обриши", @@ -75,7 +75,7 @@ "BoxRear": "Омот (позади)", "Box": "Омот", "Blacklist": "Црна листа", - "BirthPlaceValue": "Место рођења", + "BirthPlaceValue": "Место рођења: {0}", "BirthLocation": "Место рођења", "BirthDateValue": "Рођен", "AutoBasedOnLanguageSetting": "Аутоматски (зависи од подешавања језика)", @@ -96,5 +96,103 @@ "All": "Све", "Alerts": "Упозорења", "Aired": "Емитовано", - "Absolute": "Апсолутно" + "Absolute": "Апсолутно", + "Default": "Уобичајено", + "DeathDateValue": "Преминуо: {0}", + "DatePlayed": "Датум емитовања", + "DateAdded": "Датум додавања", + "CustomDlnaProfilesHelp": "Направите прилагођени профил да бисте циљали на нови уређај или прегазили системски профил.", + "CriticRating": "Оцена критике", + "CopyStreamURLError": "Десила се грешка приликом копирања адресе.", + "CopyStreamURLSuccess": "Адреса копирана успешно.", + "CopyStreamURL": "Копирајте адресу стрим-а", + "Continuing": "Наставља", + "ContinueWatching": "Натавите гледање", + "Connect": "Повежи", + "ConfirmEndPlayerSession": "Да ли желите да искључите Јеллифин {0}?", + "ConfirmDeletion": "ПОтврдите брисање", + "ConfirmDeleteItems": "Брисањем ових ставки избрисаћете их и из система и из ваше библиотеке медија. Јесте ли сигурни да желите да наставите?", + "ConfirmDeleteItem": "Брисањем ове ставке избрисаћете је и из система и из ваше библиотеке медија. Јесте ли сигурни да желите да наставите?", + "ConfirmDeleteImage": "Обришите слику?", + "ConfigureDateAdded": "Конфигуришите како се датум додавања одређује на контролној табли Јеллифин Сервер-а под Подешавања библиотеке", + "Composer": "Композитор", + "CommunityRating": "Рејтинг заједнице", + "ColorTransfer": "Промена боја", + "ColorSpace": "Простор боја", + "ColorPrimaries": "Основне боје", + "ClientSettings": "Подешавања клијента", + "CinemaModeConfigurationHelp": "Режим биоскопа доноси позоришно искуство директно у вашу дневну собу са могућношћу приказинвања трејлера и прилагођених увода пре главне проекције.", + "ChannelNumber": "Број канала", + "ChannelNameOnly": "Само {0} канал", + "ChannelAccessHelp": "Изаберите канале које желите да делите са овим корисником. Администратори ће моћи да уређују све канале помоћу менаџера метаподатака.", + "ChangingMetadataImageSettingsNewContent": "Промене метаподатака или поставки преузимања уметничког дела примењују се само на нови садржај додат у вашу библиотеку. Да бисте применили промене на постојеће наслове, мора ћете ручно освежити њихове метаподатке.", + "Categories": "Категорије", + "CancelSeries": "Откажи серију", + "CancelRecording": "Откажи снимање", + "ButtonWebsite": "Веб сајт", + "ButtonViewWebsite": "Погледајте веб сајт", + "ButtonUp": "Горе", + "ButtonUninstall": "Деинсталирај", + "ButtonTrailer": "Трејлер", + "ButtonSubtitles": "Титлови", + "ButtonSubmit": "Пошаљите", + "ButtonSplit": "Подели", + "ButtonStop": "Заустави", + "ButtonStart": "Почни", + "ButtonSort": "Сортирај", + "ButtonSignOut": "Одјавите се", + "ButtonSignIn": "Пријавите се", + "ButtonShutdown": "Искључи", + "ButtonShuffle": "Промешај", + "ButtonSettings": "Подешавања", + "ButtonSend": "Пошаљи", + "ButtonSelectView": "Изаберите приказ", + "ButtonSelectServer": "Иѕаберите сервер", + "ButtonSelectDirectory": "Изаберите Директоријум", + "ButtonSearch": "Тражи", + "ButtonScanAllLibraries": "Скенирај све библиотеке", + "ButtonSave": "Сачувај", + "ButtonRevoke": "Опозови", + "ButtonResume": "Настави", + "ButtonRestart": "Покрени поново", + "ButtonResetPassword": "Ресетуј шифру", + "ButtonResetEasyPassword": "Ресетујте једноставан ПИН код", + "ButtonRepeat": "Пусти поново", + "ButtonRename": "Преименуј", + "ButtonRemove": "Уклони", + "ButtonRefreshGuideData": "Освежи податке водича", + "ButtonRefresh": "Освежи", + "ButtonQuickStartGuide": "Кратки водич за почетак", + "ButtonProfile": "Профил", + "ButtonPreviousTrack": "Претходна нумера", + "ButtonPlay": "Пусти", + "ButtonEditOtherUserPreferences": "Уредите профил корисника, слику и личне поставке.", + "ButtonEditImages": "Уреди слике", + "ButtonEdit": "Уреди", + "BurnSubtitlesHelp": "Одређује да ли сервер треба да кодира титлове приликом транскодирања видео записа. Избегавање тога увелико ће побољшати перформансе. Изаберите Аутоматски да бисте снимили формате засноване на слици (VOBSUB, PGS, SUB, IDX) и одређене ASS или SSA титлове.", + "BoxSet": "Бокс сет", + "BookLibraryHelp": "Подржани су аудио и текстуалне књиге. Прегледајте {0} водич за именовање књига {1}.", + "Banner": "Банер", + "Backdrops": "Позадине", + "Backdrop": "Позадина", + "Auto": "Ауто", + "AuthProviderHelp": "Изаберите провајдера аутентификације који ће се користити за аутентификацију лозинке овог корисника.", + "AspectRatio": "Однос страна", + "AskAdminToCreateLibrary": "Затражите од администратора да креира библиотеку.", + "Ascending": "Узлазни", + "AsManyAsPossible": "Што је више могуће", + "Artist": "Уметник", + "Art": "Уметност", + "Anytime": "Било када", + "AlwaysPlaySubtitlesHelp": "Титлови који одговарају језичким преференцијама учитават ће се без обзира на језик звука.", + "AllowedRemoteAddressesHelp": "Листа одвојена зарезима ИП адреса или уноса ИП / мрежне маске за мреже којима ће се омогућити даљинско повезивање. Ако је празно, све удаљене адресе ће бити дозвољене.", + "AllowRemoteAccessHelp": "Ако није укључено, све удаљене везе биће блокиране.", + "AllowFfmpegThrottlingHelp": "Кад се транскодовање довољно удаљи од тренутне позиције репродукције, паузирајте поступак тако да троши мање ресурса. Ово је најкорисније када се гледа без тражења. Искључите ово ако имате проблема са репродукцијом.", + "AllowFfmpegThrottling": "Регулише Транскодовање", + "AllowOnTheFlySubtitleExtractionHelp": "Уграђени титлови се могу издвојити из видео записа и доставити клијентима у обичном тексту како би се спречило транскодирање видео записа. У неким системима ово може дуго трајати и може проузроковати да се репродукција видео записа заустави током екстракције. Онемогућите ово да се уграђени титлови уграђују видео транскодирањем када их клијент не подржава.", + "AllComplexFormats": "Сви сложени формати (ASS, SSA, VOBSUB, PGS, SUB, IDX)", + "AlbumArtist": "Извођач албума", + "Album": "Албум", + "AirDate": "Премијера", + "AdditionalNotificationServices": "Прегледајте каталог додатака да бисте инсталирали сервисе за обавештења." } From f18997b7e3d9a681bd39adeba85b6f7eff4566ce Mon Sep 17 00:00:00 2001 From: amirmasoud Date: Sun, 12 Apr 2020 00:44:11 +0000 Subject: [PATCH 43/52] Translated using Weblate (Persian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fa/ --- src/strings/fa.json | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/strings/fa.json b/src/strings/fa.json index c6aca6726e..1e227b0e80 100644 --- a/src/strings/fa.json +++ b/src/strings/fa.json @@ -64,7 +64,7 @@ "LabelSecureConnectionsMode": "حالت اتصال ایمن:", "LabelSelectUsers": "انتخاب کاربران:", "LabelTimeLimitHours": "محدودیت زمان (ساعت):", - "LabelTypeMetadataDownloaders": "{0} دانلود کننده ی متاداده:", + "LabelTypeMetadataDownloaders": "{0} دانلود کننده فراداده:", "LabelYourFirstName": "اسم کوچک شما:", "LabelYoureDone": "به پایان رسید!", "LibraryAccessHelp": "انتخاب پوشه های رسانه برای اشتراک گذاری با این کاربر. مدیر سیستم میتواند با استفاده از مدیریت متاداده همه ی پوشه ها را ویرایش کند.", @@ -416,7 +416,7 @@ "HeaderCancelRecording": "لغو ضبط", "HeaderBooks": "کتاب‌ها", "HeaderBlockItemsWithNoRating": "موارد مسدود شده با نقص یا عدم وجود اطلاعات امتیاز:", - "LabelSkipIfAudioTrackPresentHelp": "این گزینه را عدم انتخاب کنید تا اطمینان حاصل کنید که همه ویدیوها فارغ از زبان صوت، زیرنویس دارند.", + "LabelSkipIfAudioTrackPresentHelp": "این گزینه را عدم انتخاب کنید تا اطمینان حاصل کنید که همه ویدیوها فارغ از زبان صوت، زیرنویس دارند.", "LabelSkipIfAudioTrackPresent": "اگر صدای پیش‌فرض با زبان دانلودی یکسان است پرش کن", "LabelSkipForwardLength": "میزان رفتن به جلو:", "LabelSkipBackLength": "میزان بازگشت به عقب:", @@ -583,5 +583,24 @@ "LabelIconMaxHeight": "حداکثر ارتفاع آیکن:", "LabelHttpsPort": "شماره پورت HTTPS محلی:", "LabelHomeNetworkQuality": "کیفیت شبکه خانگی:", - "LabelHardwareAccelerationTypeHelp": "تسریع کننده سخت افزاری نیاز به پیکربندی اضافی دارد." + "LabelHardwareAccelerationTypeHelp": "تسریع کننده سخت افزاری نیاز به پیکربندی اضافی دارد.", + "LabelSupportedMediaTypes": "نوع‌ رسانه‌های پشتیبانی شده:", + "LabelSubtitles": "زیرنویس‌ها", + "LabelSubtitlePlaybackMode": "حالت زیرنویس:", + "LabelSubtitleFormatHelp": "مثال: srt", + "LabelSubtitleDownloaders": "دانلود کننده زیرنویس:", + "LabelStreamType": "نوع پخش:", + "LabelStopping": "در حال توقف", + "LabelStopWhenPossible": "هنگامی که ممکن است متوقف شود:", + "LabelStatus": "وضعیت:", + "LabelStartWhenPossible": "هنگامی که ممکن است شروع شود:", + "LabelSportsCategories": "دسته‌بندی‌های ورزشی:", + "LabelSpecialSeasonsDisplayName": "نام نمایشی فصل مخصوص:", + "LabelSource": "منبع:", + "LabelSoundEffects": "جلوه‌های صدا:", + "LabelSortTitle": "مرتب‌سازی عنوان:", + "LabelSortOrder": "ترتیب مرتب‌سازی:", + "LabelSortBy": "مرتب‌سازی بر اساس:", + "LabelSonyAggregationFlags": "پرچم‌های جمع‌آوری سونی:", + "LabelSkipIfGraphicalSubsPresent": "صرف نظر کردن اگر ویدیو پیش از این زیرنویس چسبیده در خود دارد" } From c3eca06560cd275f6d98f800dbe94a27823714a2 Mon Sep 17 00:00:00 2001 From: TheGoose Date: Sun, 12 Apr 2020 06:58:46 +0000 Subject: [PATCH 44/52] 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 | 58 ++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/src/strings/en-gb.json b/src/strings/en-gb.json index 757ea55266..bca865ff6c 100644 --- a/src/strings/en-gb.json +++ b/src/strings/en-gb.json @@ -75,9 +75,9 @@ "AllowRemoteAccess": "Allow remote connections to this Jellyfin Server.", "AllowRemoteAccessHelp": "If unchecked, all remote connections will be blocked.", "AllowedRemoteAddressesHelp": "Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. If left blank, all remote addresses will be allowed.", - "AlwaysPlaySubtitles": "Always play subtitles", + "AlwaysPlaySubtitles": "Always Play", "AlwaysPlaySubtitlesHelp": "Subtitles matching the language preference will be loaded regardless of the audio language.", - "AnyLanguage": "Any language", + "AnyLanguage": "Any Language", "Anytime": "Anytime", "AroundTime": "Around {0}", "Art": "Art", @@ -100,7 +100,7 @@ "Box": "Box", "BoxRear": "Box (rear)", "Browse": "Browse", - "BurnSubtitlesHelp": "Determines if the server should burn in subtitles when converting video depending on the subtitle format. Avoiding burning in subtitles will improve server performance. Select Auto to burn image based formats (VOBSUB, PGS, SUB/IDX, etc) and certain ASS/SSA subtitles.", + "BurnSubtitlesHelp": "Determines if the server should burn in subtitles when transcoding videos. Avoiding this will greatly improve performance. Select Auto to burn image based formats (VOBSUB, PGS, SUB, IDX) and certain ASS or SSA subtitles.", "ButtonAdd": "Add", "ButtonAddMediaLibrary": "Add Media Library", "ButtonAddScheduledTaskTrigger": "Add Trigger", @@ -233,7 +233,7 @@ "DisplayInOtherHomeScreenSections": "Display in home screen sections such as latest media and continue watching", "DisplayMissingEpisodesWithinSeasons": "Display missing episodes within seasons", "DisplayMissingEpisodesWithinSeasonsHelp": "This must also be enabled for TV libraries in the server configuration.", - "DisplayModeHelp": "Select the type of screen you're running Jellyfin on.", + "DisplayModeHelp": "Select the layout style you want for the interface.", "DoNotRecord": "Do not record", "Down": "Down", "Download": "Download", @@ -617,9 +617,9 @@ "PasswordResetComplete": "The password has been reset.", "PasswordMatchError": "Password and password confirmation must match.", "ParentalRating": "Parental rating", - "PackageInstallFailed": "{0} installation failed.", - "PackageInstallCompleted": "{0} installation completed.", - "PackageInstallCancelled": "{0} installation cancelled.", + "PackageInstallFailed": "{0} (version {1}) installation failed.", + "PackageInstallCompleted": "{0} (version {1}) installation completed.", + "PackageInstallCancelled": "{0} (version {1}) installation cancelled.", "OriginalAirDateValue": "Original air date: {0}", "OptionWeekly": "Weekly", "OptionWeekends": "Weekends", @@ -690,12 +690,12 @@ "OptionAlbumArtist": "Album Artist", "OptionAlbum": "Album", "Option3D": "3D", - "OnlyImageFormats": "Only image formats (VOBSUB, PGS, SUB, etc)", + "OnlyImageFormats": "Only Image Formats (VOBSUB, PGS, SUB)", "OnlyForcedSubtitlesHelp": "Only subtitles marked as forced will be loaded.", "Normal": "Normal", "None": "None", "NoSubtitlesHelp": "Subtitles will not be loaded by default. They can still be turned on manually during playback.", - "NoSubtitles": "No subtitles", + "NoSubtitles": "None", "NoPluginConfigurationMessage": "This plugin has no settings to configure.", "NoNextUpItemsMessage": "None found. Start watching your shows!", "No": "No", @@ -871,7 +871,7 @@ "MessageConfirmProfileDeletion": "Are you sure you wish to delete this profile?", "LaunchWebAppOnStartup": "Launch the web interface when starting the server", "LabelYourFirstName": "Your first name:", - "OnlyForcedSubtitles": "Only forced subtitles", + "OnlyForcedSubtitles": "Only Forced", "Off": "Off", "NumLocationsValue": "{0} folders", "Name": "Name", @@ -1030,7 +1030,7 @@ "LabelEnableDlnaDebugLoggingHelp": "Create large log files and should only be used as needed for troubleshooting purposes.", "LabelEnableDlnaClientDiscoveryIntervalHelp": "Determines the duration in seconds between SSDP searches performed by Jellyfin.", "LabelEnableAutomaticPortMapHelp": "Attempt to automatically map the public port to the local port via UPnP. This may not work with some router models. Changes will not apply until after a server restart.", - "InstallingPackage": "Installing {0}", + "InstallingPackage": "Installing {0} (version {1})", "ImportMissingEpisodesHelp": "If enabled, information about missing episodes will be imported into your Jellyfin database and displayed within seasons and series. This may cause significantly longer library scans.", "HeaderSubtitleAppearance": "Subtitle Appearance", "LabelProtocol": "Protocol:", @@ -1472,7 +1472,39 @@ "CopyStreamURLError": "There was an error copying the URL.", "NoCreatedLibraries": "Seems like you haven't created any libraries yet. {0}Would you like to create one now?{1}", "AskAdminToCreateLibrary": "Ask an administrator to create a library.", - "PlaybackErrorNoCompatibleStream": "There was an issue with the client profiling and the server isn't sending a compatible media format.", + "PlaybackErrorNoCompatibleStream": "This client isn't compatible with the media and the server isn't sending a compatible media format.", "AllowFfmpegThrottlingHelp": "When a transcode or remux gets far enough ahead from the current playback position, pause the process so it will consume less resources. This is most useful when watching without seeking often. Turn this off if you experience playback issues.", - "AllowFfmpegThrottling": "Throttle Transcodes" + "AllowFfmpegThrottling": "Throttle Transcodes", + "OnApplicationStartup": "On application startup", + "EveryXHours": "Every {0} hours", + "EveryHour": "Every hour", + "EveryXMinutes": "Every {0} minutes", + "OnWakeFromSleep": "On wake from sleep", + "WeeklyAt": "{0}s at {1}", + "DailyAt": "Daily at {0}", + "LastSeen": "Last seen {0}", + "PersonRole": "as {0}", + "ListPaging": "{0}-{1} of {2}", + "WriteAccessRequired": "Jellyfin Server requires write access to this folder. Please ensure write access and try again.", + "PathNotFound": "The path could not be found. Please ensure the path is valid and try again.", + "YadifBob": "YADIF Bob", + "Yadif": "YADIF", + "Track": "Track", + "Season": "Season", + "ReleaseGroup": "Release Group", + "PreferEmbeddedEpisodeInfosOverFileNames": "Prefer embedded episode information over filenames", + "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "This uses the episode information from the embedded metadata if available.", + "Person": "Person", + "OtherArtist": "Other Artist", + "Movie": "Movie", + "LabelLibraryPageSizeHelp": "Sets the amount of items to show on a library page. Set to 0 in order to disable paging.", + "LabelLibraryPageSize": "Library page size:", + "LabelDeinterlaceMethod": "Deinterlacing method:", + "Episode": "Episode", + "DeinterlaceMethodHelp": "Select the deinterlacing method to use when transcoding interlaced content.", + "ClientSettings": "Client Settings", + "BoxSet": "Box Set", + "Artist": "Artist", + "AlbumArtist": "Album Artist", + "Album": "Album" } From 37ebb37c4a763adfa5e5d4ed8cd06fe3c42868c7 Mon Sep 17 00:00:00 2001 From: Adam Bokor Date: Sun, 12 Apr 2020 09:03:59 +0000 Subject: [PATCH 45/52] Translated using Weblate (Hungarian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/hu/ --- src/strings/hu.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/hu.json b/src/strings/hu.json index b704e03848..a439cc073f 100644 --- a/src/strings/hu.json +++ b/src/strings/hu.json @@ -786,7 +786,7 @@ "MediaInfoCodecTag": "Kódek címke", "Photos": "Fényképek", "Playlists": "Lejátszási listák", - "Shows": "Műsorok", + "Shows": "Sorozatok", "Songs": "Dalok", "ValueSpecialEpisodeName": "Special - {0}", "EnableThemeVideos": "Videók témák", From 2dd647589d68f8f35ae623a37a14278a97bd4a20 Mon Sep 17 00:00:00 2001 From: TheGoose Date: Sun, 12 Apr 2020 07:01:51 +0000 Subject: [PATCH 46/52] Translated using Weblate (English) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/en/ --- src/strings/en-us.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 7428087800..990145ee95 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1250,8 +1250,8 @@ "PluginInstalledMessage": "The plugin has been successfully installed. Jellyfin Server will need to be restarted for changes to take effect.", "PreferEmbeddedTitlesOverFileNames": "Prefer embedded titles over filenames", "PreferEmbeddedTitlesOverFileNamesHelp": "This determines the default display title when no internet metadata or local metadata is available.", - "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "This uses the episode informations from the embedded metadata if available.", - "PreferEmbeddedEpisodeInfosOverFileNames": "Prefer embedded episode informations over filenames", + "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "This uses the episode information from the embedded metadata if available.", + "PreferEmbeddedEpisodeInfosOverFileNames": "Prefer embedded episode information over filenames", "PreferredNotRequired": "Preferred, but not required", "Premiere": "Premiere", "Premieres": "Premieres", @@ -1483,8 +1483,8 @@ "XmlTvNewsCategoriesHelp": "Programs with these categories will be displayed as news programs. Separate multiple with '|'.", "XmlTvPathHelp": "A path to a XMLTV file. Jellyfin will read this file and periodically check it for updates. You are responsible for creating and updating the file.", "XmlTvSportsCategoriesHelp": "Programs with these categories will be displayed as sports programs. Separate multiple with '|'.", - "Yadif": "Yadif", - "YadifBob": "Yadif Bob", + "Yadif": "YADIF", + "YadifBob": "YADIF Bob", "Yes": "Yes", "Yesterday": "Yesterday", "PathNotFound": "The path could not be found. Please ensure the path is valid and try again.", From 0ba4c821f405f64172c29db1fcf1b4dddbc045a6 Mon Sep 17 00:00:00 2001 From: sabretou Date: Sun, 12 Apr 2020 08:14:48 +0000 Subject: [PATCH 47/52] Translated using Weblate (Marathi) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/mr/ --- src/strings/mr.json | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/strings/mr.json b/src/strings/mr.json index 497add8c35..381c609a9e 100644 --- a/src/strings/mr.json +++ b/src/strings/mr.json @@ -56,5 +56,46 @@ "Album": "अल्बम", "AddedOnValue": "{0} जोडले", "Add": "जोडा", - "Actor": "अभिनेता" + "Actor": "अभिनेता", + "EnableBackdrops": "पार्श्वभूमी", + "EditSubtitles": "सबटायटल संपादित करा", + "EditMetadata": "मेटाडेटा संपादित करा", + "EditImages": "चित्र संपादित करा", + "Edit": "संपादित करा", + "DrmChannelsNotImported": "डी.आर.एम. असलेल्या वाहिन्या आयात केल्या जाणार नाहीत.", + "DownloadsValue": "{0} डाउनलोड", + "Download": "डाउनलोड", + "Down": "खाली", + "DoNotRecord": "रेकॉर्ड करू नका", + "Directors": "दिग्दर्शक", + "Director": "दिग्दर्शक", + "Desktop": "डेस्कटॉप", + "DeleteImageConfirmation": "तुम्हाला नक्की हे चित्र काढून टाकायचे आहे का?", + "Delete": "काढून टाका", + "DeleteImage": "चित्र काढून टाका", + "ConfirmEndPlayerSession": "{0} येथील जेलिफिन बंद करावे का?", + "Composer": "संगीत दिग्दर्शक", + "Channels": "वाहिन्या", + "ChannelNumber": "वाहिनी क्रमांक", + "Categories": "वर्ग", + "CancelRecording": "रेकॉर्डिंग रद्द करा", + "ButtonWebsite": "संकेतस्थळ", + "ButtonViewWebsite": "संकेतस्थळ पाहा", + "ButtonUp": "वर", + "ButtonTrailer": "ट्रेलर", + "ButtonSubtitles": "सबटायटल", + "ButtonStop": "थांबा", + "ButtonStart": "सुरू करा", + "ButtonSettings": "सेटिंग्झ", + "ButtonSend": "पाठवा", + "ButtonSelectView": "दृष्य निवडा", + "ButtonSelectServer": "सर्व्हर निवडा", + "ButtonSelectDirectory": "डिरेक्टरी निवडा", + "ButtonSearch": "शोधा", + "ButtonScanAllLibraries": "सर्व संग्रहालय स्कॅन करा", + "ButtonRename": "नाव बदला", + "ButtonRemove": "काढून टाका", + "ButtonPreviousTrack": "मागचा ट्रॅक", + "ButtonPlay": "प्ले", + "ButtonPause": "पॉझ" } From 328342dbe0231aa6a1b7f97285fbd4606beb8f08 Mon Sep 17 00:00:00 2001 From: Louis Hermier Date: Sun, 12 Apr 2020 13:00:20 +0000 Subject: [PATCH 48/52] Translated using Weblate (French) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/ --- src/strings/fr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/strings/fr.json b/src/strings/fr.json index b3dccb9051..72ea6f3ed3 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -1495,8 +1495,8 @@ "ListPaging": "{0}-{1} de {2}", "WriteAccessRequired": "Le serveur Jellyfin a besoin d'un accès en écriture à ce dossier. Merci de vérifier l’accès en écriture et réessayez.", "PathNotFound": "Le chemin d'accès n'a pas pu être trouvé. Merci de le vérifier et de réessayer.", - "YadifBob": "Yadif Bob", - "Yadif": "Yadif", + "YadifBob": "YADIF Bob", + "Yadif": "YADIF", "LabelDeinterlaceMethod": "Méthode de désentrelacement :", "DeinterlaceMethodHelp": "Sélectionnes la méthode de désentrelacement à utiliser lors du transcodage de contenu entrelacé.", "LabelLibraryPageSize": "Taille de la page de la médiathèque :", From f38e5c72846ce6913e2a000c4c8821434bba4cb4 Mon Sep 17 00:00:00 2001 From: nextlooper42 Date: Sun, 12 Apr 2020 11:29:55 +0000 Subject: [PATCH 49/52] Translated using Weblate (Slovak) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sk/ --- src/strings/sk.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/strings/sk.json b/src/strings/sk.json index a076e9048b..7b80e3264b 100644 --- a/src/strings/sk.json +++ b/src/strings/sk.json @@ -1469,8 +1469,8 @@ "PlaybackErrorNoCompatibleStream": "Tento klient nie je kompatibilný s médiom a server neposiela kompatibilný mediálny formát.", "AllowFfmpegThrottlingHelp": "Keď sa transkódovanie alebo remuxovanie dostane do bodu, kedy je dostatočne vopred voči súčasnej polohe prehrávania, pozastaví proces aby spotrebovával menej zdrojov. Toto je najviac užitočné, keď sa pozerá obsah bez pretáčania. Vypnite túto možnosť, pokiaľ má vaše prehrávanie problémy.", "AllowFfmpegThrottling": "Obmedzenie transkódovania", - "PreferEmbeddedEpisodeInfosOverFileNames": "Preferovať vložené informácie o epizóde pred názvom súboru", - "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Toto využíva informácie o epizóde z vložených metadát, pokiaľ sú dostupne.", + "PreferEmbeddedEpisodeInfosOverFileNames": "Preferovať vložen[ informáciu o epizóde pred názvom súboru", + "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Toto využíva informáciu o epizóde z vložených metadát, pokiaľ sú dostupne.", "ClientSettings": "Nastavenie klienta", "Album": "Album", "DeinterlaceMethodHelp": "Vyberte metódu odstránenia prekladania obrazu videa pri transkódovaní prekladaného obsahu.", @@ -1486,8 +1486,8 @@ "ListPaging": "{0}-{1} z {2}", "WriteAccessRequired": "Jellyfin Server vyžaduje práva na zapisovanie do tohoto priečinku. Prosím, uistite sa že má práva na zapisovanie a skúste to znova.", "PathNotFound": "Táto cesta nebola nájdená. Prosím, uistite sa že cesta je správna a skúste to znovu.", - "YadifBob": "Yadif Bob", - "Yadif": "Yadif", + "YadifBob": "YADIF Bob", + "Yadif": "YADIF", "Track": "Stopa", "Season": "Séria", "ReleaseGroup": "Vydavateľ", From 9dbf4b63d6760551c51426dd632a3ada6fdedaab Mon Sep 17 00:00:00 2001 From: Nyanmisaka <799610810@qq.com> Date: Sun, 12 Apr 2020 10:20:39 +0000 Subject: [PATCH 50/52] 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 ba125ed5e8..671c183a1d 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -1499,8 +1499,8 @@ "EveryXMinutes": "每 {0} 分钟", "WriteAccessRequired": "Jellyfin 服务端需要此文件夹的写入权限。请确认是否拥有写入权限并重试。", "PathNotFound": "无法找到此路径。请确认路径有效并重试。", - "YadifBob": "Yadif Bob", - "Yadif": "Yadif", + "YadifBob": "YADIF Bob", + "Yadif": "YADIF", "LabelDeinterlaceMethod": "反交错方法:", "DeinterlaceMethodHelp": "选择对隔行扫描内容进行转码时所用的反交错方法。", "LabelLibraryPageSize": "媒体库分页阈值:", From aeaf93cc2f284db8a091de6b6fd60fd6fc3dae74 Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 13 Apr 2020 00:51:23 +0900 Subject: [PATCH 51/52] zip the built files before publish --- .ci/azure-pipelines.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 95bb416d2a..b225c963b5 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -62,10 +62,17 @@ jobs: - script: 'mv dist jellyfin-web' displayName: 'Rename Directory' + - task: ArchiveFiles@2 + displayName: 'Archive Directory' + inputs: + rootFolderOrFile: 'jellyfin-web' + includeRootFolder: true + archiveFile: 'jellyfin-web-$(BuildConfiguration)' + - task: PublishPipelineArtifact@1 displayName: 'Publish Release' inputs: - targetPath: '$(Build.SourcesDirectory)/jellyfin-web' + targetPath: '$(Build.SourcesDirectory)/jellyfin-web-$(BuildConfiguration).zip' artifactName: 'jellyfin-web-$(BuildConfiguration)' - job: Lint From 09ffe358ea81d7e77373513c2f58d426fe1f32be Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 13 Apr 2020 01:02:19 +0900 Subject: [PATCH 52/52] remove indentation from ci file --- .ci/azure-pipelines.yml | 144 ++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index b225c963b5..31f00754f5 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -12,94 +12,94 @@ pr: - '*' jobs: - - job: Build - displayName: 'Build' +- job: Build + displayName: 'Build' - strategy: - matrix: - Development: - BuildConfiguration: development - Production: - BuildConfiguration: production - Standalone: - BuildConfiguration: standalone + strategy: + matrix: + Development: + BuildConfiguration: development + Production: + BuildConfiguration: production + Standalone: + BuildConfiguration: standalone - pool: - vmImage: 'ubuntu-latest' + pool: + vmImage: 'ubuntu-latest' - steps: - - task: NodeTool@0 - displayName: 'Install Node' - inputs: - versionSpec: '12.x' + steps: + - task: NodeTool@0 + displayName: 'Install Node' + inputs: + versionSpec: '12.x' - - task: Cache@2 - displayName: 'Check Cache' - inputs: - key: 'yarn | yarn.lock' - path: 'node_modules' - cacheHitVar: CACHE_RESTORED + - task: Cache@2 + displayName: 'Check Cache' + inputs: + key: 'yarn | yarn.lock' + path: 'node_modules' + cacheHitVar: CACHE_RESTORED - - script: 'yarn install --frozen-lockfile' - displayName: 'Install Dependencies' - condition: ne(variables.CACHE_RESTORED, 'true') + - script: 'yarn install --frozen-lockfile' + displayName: 'Install Dependencies' + condition: ne(variables.CACHE_RESTORED, 'true') - - script: 'yarn build:development' - displayName: 'Build Development' - condition: eq(variables['BuildConfiguration'], 'development') + - script: 'yarn build:development' + displayName: 'Build Development' + condition: eq(variables['BuildConfiguration'], 'development') - - script: 'yarn build:production' - displayName: 'Build Bundle' - condition: eq(variables['BuildConfiguration'], 'production') + - script: 'yarn build:production' + displayName: 'Build Bundle' + condition: eq(variables['BuildConfiguration'], 'production') - - script: 'yarn build:standalone' - displayName: 'Build Standalone' - condition: eq(variables['BuildConfiguration'], 'standalone') + - script: 'yarn build:standalone' + displayName: 'Build Standalone' + condition: eq(variables['BuildConfiguration'], 'standalone') - - script: 'test -d dist' - displayName: 'Check Build' + - script: 'test -d dist' + displayName: 'Check Build' - - script: 'mv dist jellyfin-web' - displayName: 'Rename Directory' + - script: 'mv dist jellyfin-web' + displayName: 'Rename Directory' - - task: ArchiveFiles@2 - displayName: 'Archive Directory' - inputs: - rootFolderOrFile: 'jellyfin-web' - includeRootFolder: true - archiveFile: 'jellyfin-web-$(BuildConfiguration)' + - task: ArchiveFiles@2 + displayName: 'Archive Directory' + inputs: + rootFolderOrFile: 'jellyfin-web' + includeRootFolder: true + archiveFile: 'jellyfin-web-$(BuildConfiguration)' - - task: PublishPipelineArtifact@1 - displayName: 'Publish Release' - inputs: - targetPath: '$(Build.SourcesDirectory)/jellyfin-web-$(BuildConfiguration).zip' - artifactName: 'jellyfin-web-$(BuildConfiguration)' + - task: PublishPipelineArtifact@1 + displayName: 'Publish Release' + inputs: + targetPath: '$(Build.SourcesDirectory)/jellyfin-web-$(BuildConfiguration).zip' + artifactName: 'jellyfin-web-$(BuildConfiguration)' - - job: Lint - displayName: 'Lint' +- job: Lint + displayName: 'Lint' - pool: - vmImage: 'ubuntu-latest' + pool: + vmImage: 'ubuntu-latest' - steps: - - task: NodeTool@0 - displayName: 'Install Node' - inputs: - versionSpec: '12.x' + steps: + - task: NodeTool@0 + displayName: 'Install Node' + inputs: + versionSpec: '12.x' - - task: Cache@2 - displayName: 'Check Cache' - inputs: - key: 'yarn | yarn.lock' - path: 'node_modules' - cacheHitVar: CACHE_RESTORED + - task: Cache@2 + displayName: 'Check Cache' + inputs: + key: 'yarn | yarn.lock' + path: 'node_modules' + cacheHitVar: CACHE_RESTORED - - script: 'yarn install --frozen-lockfile' - displayName: 'Install Dependencies' - condition: ne(variables.CACHE_RESTORED, 'true') + - script: 'yarn install --frozen-lockfile' + displayName: 'Install Dependencies' + condition: ne(variables.CACHE_RESTORED, 'true') - - script: 'yarn run lint --quiet' - displayName: 'Run ESLint' + - script: 'yarn run lint --quiet' + displayName: 'Run ESLint' - - script: 'yarn run stylelint' - displayName: 'Run Stylelint' + - script: 'yarn run stylelint' + displayName: 'Run Stylelint'