diff --git a/.eslintrc.js b/.eslintrc.js index dfb65cb4d4..e5ee2dfe86 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -44,12 +44,12 @@ module.exports = { 'no-restricted-globals': ['error'].concat(restrictedGlobals), 'no-trailing-spaces': ['error'], '@babel/no-unused-expressions': ['error', { 'allowShortCircuit': true, 'allowTernary': true, 'allowTaggedTemplates': true }], - //'no-unused-vars': ['error', { 'vars': 'all', 'args': 'none', 'ignoreRestSiblings': true }], 'one-var': ['error', 'never'], 'padded-blocks': ['error', 'never'], - //'prefer-const': ['error', {'destructuring': 'all'}], + 'prefer-const': ['error', {'destructuring': 'all'}], 'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }], '@babel/semi': ['error'], + 'no-var': ['error'], 'space-before-blocks': ['error'], 'space-infix-ops': 'error', 'yoda': 'error' diff --git a/.gitignore b/.gitignore index 36b843f022..98aa2d974b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ dist web node_modules +# config +config.json + # ide .idea .vscode diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 778d899ef7..1bdf1cd903 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -34,11 +34,13 @@ - [Ryan Hartzell](https://github.com/ryan-hartzell) - [Thibault Nocchi](https://github.com/ThibaultNocchi) - [MrTimscampi](https://github.com/MrTimscampi) + - [ConfusedPolarBear](https://github.com/ConfusedPolarBear) - [Sarab Singh](https://github.com/sarab97) - [GuilhermeHideki](https://github.com/GuilhermeHideki) - [Andrei Oanca](https://github.com/OancaAndrei) - [Cromefire_](https://github.com/cromefire) - [Orry Verducci](https://github.com/orryverducci) + - [Camc314](https://github.com/camc314) # Emby Contributors diff --git a/fedora/jellyfin-web.spec b/fedora/jellyfin-web.spec index 1d85e5ae6b..c35a1caab2 100644 --- a/fedora/jellyfin-web.spec +++ b/fedora/jellyfin-web.spec @@ -11,11 +11,12 @@ Source0: jellyfin-web-%{version}.tar.gz %if 0%{?centos} BuildRequires: yarn -# sadly the yarn RPM at https://dl.yarnpkg.com/rpm/ uses git but doesn't Requires: it -BuildRequires: git %else BuildRequires: nodejs-yarn %endif +# sadly the yarn RPM at https://dl.yarnpkg.com/rpm/ uses git but doesn't Requires: it +# ditto for Fedora's yarn RPM +BuildRequires: git BuildArch: noarch # Disable Automatic Dependency Processing diff --git a/package.json b/package.json index df433ed9b8..59d0a90be8 100644 --- a/package.json +++ b/package.json @@ -5,28 +5,28 @@ "repository": "https://github.com/jellyfin/jellyfin-web", "license": "GPL-2.0-or-later", "devDependencies": { - "@babel/core": "^7.11.6", - "@babel/eslint-parser": "^7.11.5", - "@babel/eslint-plugin": "^7.11.5", + "@babel/core": "^7.12.3", + "@babel/eslint-parser": "^7.12.1", + "@babel/eslint-plugin": "^7.12.1", "@babel/plugin-proposal-class-properties": "^7.10.1", - "@babel/plugin-proposal-private-methods": "^7.10.1", - "@babel/plugin-transform-modules-amd": "^7.10.5", - "@babel/polyfill": "^7.11.5", - "@babel/preset-env": "^7.11.5", + "@babel/plugin-proposal-private-methods": "^7.12.1", + "@babel/plugin-transform-modules-amd": "^7.12.1", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.12.1", "autoprefixer": "^9.8.6", "babel-loader": "^8.0.6", - "browser-sync": "^2.26.12", - "confusing-browser-globals": "^1.0.9", + "browser-sync": "^2.26.13", + "confusing-browser-globals": "^1.0.10", "copy-webpack-plugin": "^5.1.1", - "css-loader": "^4.2.2", + "css-loader": "^5.0.0", "cssnano": "^4.1.10", - "del": "^5.1.0", - "eslint": "^7.8.1", + "del": "^6.0.0", + "eslint": "^7.12.0", "eslint-plugin-compat": "^3.5.1", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-import": "^2.21.2", + "eslint-plugin-import": "^2.22.1", "eslint-plugin-promise": "^4.2.1", - "file-loader": "^6.1.0", + "file-loader": "^6.1.1", "gulp": "^4.0.2", "gulp-babel": "^8.0.0", "gulp-cli": "^2.3.0", @@ -40,17 +40,17 @@ "gulp-sass": "^4.0.2", "gulp-sourcemaps": "^2.6.5", "gulp-terser": "^1.4.0", - "html-webpack-plugin": "^4.4.1", + "html-webpack-plugin": "^4.5.0", "lazypipe": "^1.0.2", "node-sass": "^4.13.1", "postcss-loader": "^3.0.0", "postcss-preset-env": "^6.7.0", - "style-loader": "^1.1.3", - "stylelint": "^13.7.0", + "style-loader": "^2.0.0", + "stylelint": "^13.7.2", "stylelint-config-rational-order": "^0.1.2", "stylelint-no-browser-hacks": "^1.2.1", "stylelint-order": "^4.1.0", - "webpack": "^4.44.1", + "webpack": "^5.2.0", "webpack-merge": "^4.2.2", "webpack-stream": "^6.1.0", "worker-plugin": "^5.0.0" @@ -64,11 +64,11 @@ "epubjs": "^0.3.85", "fast-text-encoding": "^1.0.3", "flv.js": "^1.5.0", - "headroom.js": "^0.11.0", - "hls.js": "^0.14.11", - "howler": "^2.2.0", + "headroom.js": "^0.12.0", + "hls.js": "^0.14.16", + "howler": "^2.2.1", "intersection-observer": "^0.11.0", - "jellyfin-apiclient": "^1.4.1", + "jellyfin-apiclient": "^1.4.2", "jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto", "jquery": "^3.5.1", "jstree": "^3.3.10", @@ -77,11 +77,11 @@ "material-design-icons-iconfont": "^6.1.0", "native-promise-only": "^0.8.0-a", "page": "^1.11.6", - "query-string": "^6.13.1", + "query-string": "^6.13.6", "resize-observer-polyfill": "^1.5.1", "screenfull": "^5.0.2", - "sortablejs": "^1.10.2", - "swiper": "^6.2.0", + "sortablejs": "^1.12.0", + "swiper": "^6.3.4", "webcomponents.js": "^0.7.24", "whatwg-fetch": "^3.4.1" }, @@ -166,6 +166,8 @@ "src/components/playmenu.js", "src/components/pluginManager.js", "src/components/prompt/prompt.js", + "src/components/qualityOptions.js", + "src/components/quickConnectSettings/quickConnectSettings.js", "src/components/recordingcreator/recordingbutton.js", "src/components/recordingcreator/recordingcreator.js", "src/components/recordingcreator/seriesrecordingeditor.js", @@ -173,7 +175,6 @@ "src/components/refreshdialog/refreshdialog.js", "src/components/recordingcreator/recordingeditor.js", "src/components/recordingcreator/recordingfields.js", - "src/components/qualityOptions.js", "src/components/remotecontrol/remotecontrol.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", @@ -213,7 +214,7 @@ "src/components/castSenderApi.js", "src/controllers/session/addServer/index.js", "src/controllers/session/forgotPassword/index.js", - "src/controllers/session/redeemPassword/index.js", + "src/controllers/session/resetPassword/index.js", "src/controllers/session/login/index.js", "src/controllers/session/selectServer/index.js", "src/controllers/dashboard/apikeys.js", @@ -244,6 +245,7 @@ "src/controllers/dashboard/plugins/installed/index.js", "src/controllers/dashboard/plugins/available/index.js", "src/controllers/dashboard/plugins/repositories/index.js", + "src/controllers/dashboard/quickConnect.js", "src/controllers/dashboard/scheduledtasks/scheduledtask.js", "src/controllers/dashboard/scheduledtasks/scheduledtasks.js", "src/controllers/dashboard/serveractivity.js", @@ -292,6 +294,7 @@ "src/controllers/user/menu/index.js", "src/controllers/user/playback/index.js", "src/controllers/user/profile/index.js", + "src/controllers/user/quickConnect/index.js", "src/controllers/user/subtitles/index.js", "src/controllers/wizard/finish/index.js", "src/controllers/wizard/remote/index.js", @@ -329,6 +332,7 @@ "src/plugins/youtubePlayer/plugin.js", "src/scripts/alphanumericshortcuts.js", "src/scripts/autoBackdrops.js", + "src/scripts/autocast.js", "src/scripts/browser.js", "src/scripts/clientUtils.js", "src/scripts/datetime.js", diff --git a/src/assets/css/videoosd.css b/src/assets/css/videoosd.css index 808915e58b..b2446d5d48 100644 --- a/src/assets/css/videoosd.css +++ b/src/assets/css/videoosd.css @@ -6,29 +6,42 @@ -ms-user-select: none; } -.osdPoster img, .videoOsdBottom { bottom: 0; left: 0; right: 0; + position: fixed; + background: linear-gradient(0deg, rgba(16, 16, 16, 0.75) 0%, rgba(16, 16, 16, 0) 100%); + padding-top: 7.5em; + padding-bottom: 1.75em; + display: flex; + flex-direction: row; + justify-content: center; + will-change: opacity; + transition: opacity 0.3s ease-out; + color: #fff; + user-select: none; + -webkit-touch-callout: none; } -.osdHeader { - -webkit-transition: opacity 0.3s ease-out; - -o-transition: opacity 0.3s ease-out; +.skinHeader-withBackground.osdHeader { transition: opacity 0.3s ease-out; position: relative; z-index: 1; - background: rgba(0, 0, 0, 0.7) !important; - -webkit-backdrop-filter: none !important; - backdrop-filter: none !important; - color: #eee !important; + background: linear-gradient(180deg, rgba(16, 16, 16, 0.75) 0%, rgba(16, 16, 16, 0) 100%); + backdrop-filter: none; + color: #eee; + height: 7.5em; } .osdHeader-hidden { opacity: 0; } +.osdHeader .headerTop { + max-height: 3.5em; +} + .osdHeader .headerButton:not(.headerBackButton):not(.headerCastButton):not(.headerSyncButton) { display: none; } @@ -86,34 +99,17 @@ opacity: 0.6; } -.videoOsdBottom { - position: fixed; - background-color: rgba(0, 0, 0, 0.7); - padding: 1%; - display: -webkit-box; - display: -webkit-flex; - display: flex; - -webkit-box-orient: horizontal; - -webkit-box-direction: normal; - -webkit-flex-direction: row; - flex-direction: row; - will-change: opacity; - -webkit-transition: opacity 0.3s ease-out; - -o-transition: opacity 0.3s ease-out; - transition: opacity 0.3s ease-out; - color: #fff; - user-select: none; - -webkit-touch-callout: none; -} - .videoOsdBottom-hidden { opacity: 0; } .osdControls { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; flex-grow: 1; + padding: 0 0.8em; +} + +.layout-desktop .osdControls { + max-width: calc(100vh * 1.77 - 2vh); } .videoOsdBottom .buttons { @@ -145,7 +141,7 @@ } .volumeButtons { - margin: 0 0.5em 0 auto; + margin: 0 1em 0 0.29em; display: flex; -webkit-align-items: center; align-items: center; @@ -153,33 +149,13 @@ .osdTimeText { margin-left: 1em; + margin-right: auto; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } -.osdPoster { - width: 10%; - position: relative; - margin-right: 0.5em; -} - -.osdPoster img { - position: absolute; - height: auto; - width: 100%; - -webkit-box-shadow: 0 0 1.9vh #000; - box-shadow: 0 0 1.9vh #000; - border: 0.08em solid #222; - user-drag: none; - user-select: none; - -moz-user-select: none; - -webkit-user-drag: none; - -webkit-user-select: none; - -ms-user-select: none; -} - .osdTitle, .osdTitleSmall { margin: 0 1em 0 0; diff --git a/src/assets/img/avatar.png b/src/assets/img/avatar.png index 0453f24897..4023d1c5c7 100644 Binary files a/src/assets/img/avatar.png and b/src/assets/img/avatar.png differ diff --git a/src/assets/img/icon-transparent.png b/src/assets/img/icon-transparent.png index 0d71b56067..76ef75baf9 100644 Binary files a/src/assets/img/icon-transparent.png and b/src/assets/img/icon-transparent.png differ diff --git a/src/assets/splash/ipad_splash.png b/src/assets/splash/ipad_splash.png index 0faca927b7..45ed7d398d 100755 Binary files a/src/assets/splash/ipad_splash.png and b/src/assets/splash/ipad_splash.png differ diff --git a/src/assets/splash/ipad_splash_l.png b/src/assets/splash/ipad_splash_l.png index 3ecf2d5adc..baf016e865 100644 Binary files a/src/assets/splash/ipad_splash_l.png and b/src/assets/splash/ipad_splash_l.png differ diff --git a/src/assets/splash/ipadpro1_splash.png b/src/assets/splash/ipadpro1_splash.png index 9e7fdb7f6c..c5afa50986 100755 Binary files a/src/assets/splash/ipadpro1_splash.png and b/src/assets/splash/ipadpro1_splash.png differ diff --git a/src/assets/splash/ipadpro1_splash_l.png b/src/assets/splash/ipadpro1_splash_l.png index cffad337c8..f5ef6f3b04 100644 Binary files a/src/assets/splash/ipadpro1_splash_l.png and b/src/assets/splash/ipadpro1_splash_l.png differ diff --git a/src/assets/splash/ipadpro2_splash.png b/src/assets/splash/ipadpro2_splash.png index a2e9624c65..500cad2b3d 100755 Binary files a/src/assets/splash/ipadpro2_splash.png and b/src/assets/splash/ipadpro2_splash.png differ diff --git a/src/assets/splash/ipadpro2_splash_l.png b/src/assets/splash/ipadpro2_splash_l.png index 588902a2b1..ec17e3e81b 100644 Binary files a/src/assets/splash/ipadpro2_splash_l.png and b/src/assets/splash/ipadpro2_splash_l.png differ diff --git a/src/assets/splash/ipadpro3_splash.png b/src/assets/splash/ipadpro3_splash.png index 89a04afe07..3a1c82e983 100755 Binary files a/src/assets/splash/ipadpro3_splash.png and b/src/assets/splash/ipadpro3_splash.png differ diff --git a/src/assets/splash/ipadpro3_splash_l.png b/src/assets/splash/ipadpro3_splash_l.png index a0b6c56904..df275b3448 100644 Binary files a/src/assets/splash/ipadpro3_splash_l.png and b/src/assets/splash/ipadpro3_splash_l.png differ diff --git a/src/assets/splash/iphone5_splash.png b/src/assets/splash/iphone5_splash.png index 3e073a9e1b..bdbc28ab0d 100755 Binary files a/src/assets/splash/iphone5_splash.png and b/src/assets/splash/iphone5_splash.png differ diff --git a/src/assets/splash/iphone5_splash_l.png b/src/assets/splash/iphone5_splash_l.png index 28fa8838e1..789f50f628 100644 Binary files a/src/assets/splash/iphone5_splash_l.png and b/src/assets/splash/iphone5_splash_l.png differ diff --git a/src/assets/splash/iphone6_splash.png b/src/assets/splash/iphone6_splash.png index afe42fa26a..879d5b716f 100755 Binary files a/src/assets/splash/iphone6_splash.png and b/src/assets/splash/iphone6_splash.png differ diff --git a/src/assets/splash/iphone6_splash_l.png b/src/assets/splash/iphone6_splash_l.png index c7de58510f..396224fcb2 100644 Binary files a/src/assets/splash/iphone6_splash_l.png and b/src/assets/splash/iphone6_splash_l.png differ diff --git a/src/assets/splash/iphoneplus_splash.png b/src/assets/splash/iphoneplus_splash.png index 2cc62163ac..a9e7de01ca 100755 Binary files a/src/assets/splash/iphoneplus_splash.png and b/src/assets/splash/iphoneplus_splash.png differ diff --git a/src/assets/splash/iphoneplus_splash_l.png b/src/assets/splash/iphoneplus_splash_l.png index c989f2237e..f14f0af1ff 100644 Binary files a/src/assets/splash/iphoneplus_splash_l.png and b/src/assets/splash/iphoneplus_splash_l.png differ diff --git a/src/assets/splash/iphonex_splash.png b/src/assets/splash/iphonex_splash.png index 2d9698c287..435bbe07a9 100755 Binary files a/src/assets/splash/iphonex_splash.png and b/src/assets/splash/iphonex_splash.png differ diff --git a/src/assets/splash/iphonex_splash_l.png b/src/assets/splash/iphonex_splash_l.png index 9eb9e037ce..cbadd0a239 100644 Binary files a/src/assets/splash/iphonex_splash_l.png and b/src/assets/splash/iphonex_splash_l.png differ diff --git a/src/assets/splash/iphonexr_splash.png b/src/assets/splash/iphonexr_splash.png index 0f911eb2e8..b6072df329 100755 Binary files a/src/assets/splash/iphonexr_splash.png and b/src/assets/splash/iphonexr_splash.png differ diff --git a/src/assets/splash/iphonexr_splash_l.png b/src/assets/splash/iphonexr_splash_l.png index 1522f372a9..f78e825192 100644 Binary files a/src/assets/splash/iphonexr_splash_l.png and b/src/assets/splash/iphonexr_splash_l.png differ diff --git a/src/assets/splash/iphonexsmax_splash.png b/src/assets/splash/iphonexsmax_splash.png index 3e9aaf56af..b4e9255b31 100755 Binary files a/src/assets/splash/iphonexsmax_splash.png and b/src/assets/splash/iphonexsmax_splash.png differ diff --git a/src/assets/splash/iphonexsmax_splash_l.png b/src/assets/splash/iphonexsmax_splash_l.png index e2961f512e..e94692de0e 100644 Binary files a/src/assets/splash/iphonexsmax_splash_l.png and b/src/assets/splash/iphonexsmax_splash_l.png differ diff --git a/src/bundle.js b/src/bundle.js index 25810f58ee..3d1d600a9f 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -177,7 +177,7 @@ _define('appStorage', function () { }); // libarchive.js -var libarchive = require('libarchive.js'); +const libarchive = require('libarchive.js'); _define('libarchive', function () { return libarchive; }); diff --git a/src/components/appFooter/appFooter.js b/src/components/appFooter/appFooter.js index c60aa1a27c..260aea8280 100644 --- a/src/components/appFooter/appFooter.js +++ b/src/components/appFooter/appFooter.js @@ -27,7 +27,7 @@ class appFooter { }; } destroy() { - var self = this; + const self = this; self.element = null; } diff --git a/src/components/apphost.js b/src/components/apphost.js index 33ca5a0b79..875c7907e6 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -78,7 +78,7 @@ function getDeviceId() { } function getDeviceName() { - var deviceName; + let deviceName; if (browser.tizen) { deviceName = 'Samsung Smart TV'; } else if (browser.web0s) { diff --git a/src/components/displaySettings/displaySettings.js b/src/components/displaySettings/displaySettings.js index 9def27dc8a..efaab16b3f 100644 --- a/src/components/displaySettings/displaySettings.js +++ b/src/components/displaySettings/displaySettings.js @@ -23,7 +23,7 @@ import 'emby-button'; }).join(''); // get default theme - var defaultTheme = themes.find(theme => { + const defaultTheme = themes.find(theme => { return theme.default; }); diff --git a/src/components/filtermenu/filtermenu.js b/src/components/filtermenu/filtermenu.js index be12b04edd..7cef08303d 100644 --- a/src/components/filtermenu/filtermenu.js +++ b/src/components/filtermenu/filtermenu.js @@ -19,7 +19,7 @@ function onSubmit(e) { return false; } function renderOptions(context, selector, cssClass, items, isCheckedFn) { - var elem = context.querySelector(selector); + const elem = context.querySelector(selector); if (items.length) { elem.classList.remove('hide'); @@ -27,12 +27,12 @@ function renderOptions(context, selector, cssClass, items, isCheckedFn) { elem.classList.add('hide'); } - var html = ''; + let html = ''; html += items.map(function (filter) { - var itemHtml = ''; + let itemHtml = ''; - var checkedHtml = isCheckedFn(filter) ? ' checked' : ''; + const checkedHtml = isCheckedFn(filter) ? ' checked' : ''; itemHtml += '