diff --git a/.ci/azure-pipelines-package.yml b/.ci/azure-pipelines-package.yml index bf4234ec97..bb2a09f176 100644 --- a/.ci/azure-pipelines-package.yml +++ b/.ci/azure-pipelines-package.yml @@ -59,7 +59,15 @@ jobs: pool: vmImage: 'ubuntu-latest' + variables: + - name: JellyfinVersion + value: 0.0.0 + steps: + - script: echo "##vso[task.setvariable variable=JellyfinVersion]$( awk -F '/' '{ print $NF }' <<<'$(Build.SourceBranch)' | sed 's/^v//' )" + displayName: Set release version (stable) + condition: startsWith(variables['Build.SourceBranch'], 'refs/tags') + - task: Docker@2 displayName: 'Push Unstable Image' condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/master') @@ -84,7 +92,7 @@ jobs: containerRegistry: Docker Hub tags: | stable-$(Build.BuildNumber) - stable + $(JellyfinVersion) - job: CollectArtifacts displayName: 'Collect Artifacts' diff --git a/.editorconfig b/.editorconfig index 92cf9dc590..84ba694073 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,5 +8,5 @@ trim_trailing_whitespace = true insert_final_newline = true end_of_line = lf -[json] +[*.json] indent_size = 2 diff --git a/.eslintrc.js b/.eslintrc.js index baf6d0e084..ff12e198c3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,7 @@ module.exports = { root: true, plugins: [ + '@babel', 'promise', 'import', 'eslint-comments' @@ -28,7 +29,7 @@ module.exports = { ], rules: { 'block-spacing': ['error'], - 'brace-style': ['error'], + 'brace-style': ['error', '1tbs', { 'allowSingleLine': true }], 'comma-dangle': ['error', 'never'], 'comma-spacing': ['error'], 'eol-last': ['error'], @@ -39,18 +40,22 @@ module.exports = { 'no-multi-spaces': ['error'], 'no-multiple-empty-lines': ['error', { 'max': 1 }], 'no-trailing-spaces': ['error'], + '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'], 'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }], 'semi': ['error'], 'space-before-blocks': ['error'], - 'space-infix-ops': 'error' + 'space-infix-ops': 'error', + 'yoda': 'error' }, overrides: [ { files: [ './src/**/*.js' ], - parser: 'babel-eslint', + parser: '@babel/eslint-parser', env: { node: false, amd: true, @@ -98,9 +103,8 @@ module.exports = { }, rules: { // TODO: Fix warnings and remove these rules - 'no-redeclare': ['warn'], - 'no-unused-vars': ['warn'], - 'no-useless-escape': ['warn'], + 'no-redeclare': ['off'], + 'no-useless-escape': ['off'], // TODO: Remove after ES6 migration is complete 'import/no-unresolved': ['off'] }, diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 73f40aaca1..c51cd6b31f 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -36,6 +36,7 @@ - [MrTimscampi](https://github.com/MrTimscampi) - [Sarab Singh](https://github.com/sarab97) - [Andrei Oanca](https://github.com/OancaAndrei) + - [Cromefire_](https://github.com/cromefire) # Emby Contributors diff --git a/README.md b/README.md index f06e461320..ca42965dd9 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Jellyfin Web is the frontend used for most of the clients available for end user ### Dependencies +- [Node.js](https://nodejs.org/en/download/) - [Yarn 1.22.4](https://classic.yarnpkg.com/en/docs/install) - Gulp-cli diff --git a/build.yaml b/build.yaml index fe1633faec..a73be8ec43 100644 --- a/build.yaml +++ b/build.yaml @@ -1,7 +1,7 @@ --- # We just wrap `build` so this is really it name: "jellyfin-web" -version: "10.6.0" +version: "10.7.0" packages: - debian.all - fedora.all diff --git a/bump_version b/bump_version index bc8288b829..4e6aa6f792 100755 --- a/bump_version +++ b/bump_version @@ -4,6 +4,7 @@ set -o errexit set -o pipefail +set -o xtrace usage() { echo -e "bump_version - increase the shared version and generate changelogs" @@ -23,10 +24,7 @@ build_file="./build.yaml" new_version="$1" # Parse the version from shared version file -old_version="$( - grep "appVersion" ${shared_version_file} | head -1 \ - | sed -E 's/var appVersion = "([0-9\.]+)";/\1/' -)" +old_version="$( grep "appVersion" ${shared_version_file} | head -1 | sed -E "s/var appVersion = '([0-9\.]+)';/\1/" | tr -d '[:space:]' )" echo "Old version in appHost is: $old_version" # Set the shared version to the specified new_version @@ -34,11 +32,8 @@ old_version_sed="$( sed 's/\./\\./g' <<<"${old_version}" )" # Escape the '.' cha new_version_sed="$( cut -f1 -d'-' <<<"${new_version}" )" sed -i "s/${old_version_sed}/${new_version_sed}/g" ${shared_version_file} -old_version="$( - grep "version:" ${build_file} \ - | sed -E 's/version: "([0-9\.]+[-a-z0-9]*)"/\1/' -)" -echo "Old version in ${build_file}: $old_version`" +old_version="$( grep "version:" ${build_file} | sed -E 's/version: "([0-9\.]+[-a-z0-9]*)"/\1/' )" +echo "Old version in ${build_file}: ${old_version}" # Set the build.yaml version to the specified new_version old_version_sed="$( sed 's/\./\\./g' <<<"${old_version}" )" # Escape the '.' chars @@ -54,7 +49,7 @@ fi debian_changelog_file="debian/changelog" debian_changelog_temp="$( mktemp )" # Create new temp file with our changelog -echo -e "jellyfin (${new_version_deb}) unstable; urgency=medium +echo -e "jellyfin-web (${new_version_deb}) unstable; urgency=medium * New upstream version ${new_version}; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v${new_version} @@ -65,15 +60,15 @@ cat ${debian_changelog_file} >> ${debian_changelog_temp} mv ${debian_changelog_temp} ${debian_changelog_file} # Write out a temporary Yum changelog with our new stuff prepended and some templated formatting -fedora_spec_file="fedora/jellyfin.spec" +fedora_spec_file="fedora/jellyfin-web.spec" fedora_changelog_temp="$( mktemp )" fedora_spec_temp_dir="$( mktemp -d )" -fedora_spec_temp="${fedora_spec_temp_dir}/jellyfin.spec.tmp" +fedora_spec_temp="${fedora_spec_temp_dir}/jellyfin-web.spec.tmp" # Make a copy of our spec file for hacking cp ${fedora_spec_file} ${fedora_spec_temp_dir}/ pushd ${fedora_spec_temp_dir} # Split out the stuff before and after changelog -csplit jellyfin.spec "/^%changelog/" # produces xx00 xx01 +csplit jellyfin-web.spec "/^%changelog/" # produces xx00 xx01 # Update the version in xx00 sed -i "s/${old_version_sed}/${new_version_sed}/g" xx00 # Remove the header from xx01 @@ -92,5 +87,5 @@ mv ${fedora_spec_temp} ${fedora_spec_file} rm -rf ${fedora_changelog_temp} ${fedora_spec_temp_dir} # Stage the changed files for commit -git add ${shared_version_file} ${build_file} ${debian_changelog_file} ${fedora_spec_file} Dockerfile* +git add ${shared_version_file} ${build_file} ${debian_changelog_file} ${fedora_spec_file} git status diff --git a/debian/changelog b/debian/changelog index 50966c3a01..ab5e13196d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +jellyfin-web (10.7.0-1) unstable; urgency=medium + + * Forthcoming stable release + + -- Jellyfin Packaging Team Mon, 27 Jul 2020 19:13:31 -0400 + jellyfin-web (10.6.0-1) unstable; urgency=medium * New upstream version 10.6.0; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.6.0 diff --git a/fedora/jellyfin-web.spec b/fedora/jellyfin-web.spec index dcc9d9d2ab..b8c77f2a1f 100644 --- a/fedora/jellyfin-web.spec +++ b/fedora/jellyfin-web.spec @@ -1,7 +1,7 @@ %global debug_package %{nil} Name: jellyfin-web -Version: 10.6.0 +Version: 10.7.0 Release: 1%{?dist} Summary: The Free Software Media System web client License: GPLv3 @@ -39,5 +39,7 @@ mv dist %{buildroot}%{_datadir}/jellyfin-web %{_datadir}/licenses/jellyfin/LICENSE %changelog +* Mon Jul 27 2020 Jellyfin Packaging Team +- Forthcoming stable release * Mon Mar 23 2020 Jellyfin Packaging Team - Forthcoming stable release diff --git a/package.json b/package.json index 088e820a85..8408217bf3 100644 --- a/package.json +++ b/package.json @@ -5,21 +5,22 @@ "repository": "https://github.com/jellyfin/jellyfin-web", "license": "GPL-2.0-or-later", "devDependencies": { - "@babel/core": "^7.10.5", + "@babel/core": "^7.11.0", + "@babel/eslint-parser": "^7.11.0", + "@babel/eslint-plugin": "^7.11.0", "@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.8.7", - "@babel/preset-env": "^7.10.3", - "autoprefixer": "^9.8.5", - "babel-eslint": "^11.0.0-beta.2", + "@babel/preset-env": "^7.11.0", + "autoprefixer": "^9.8.6", "babel-loader": "^8.0.6", - "browser-sync": "^2.26.10", + "browser-sync": "^2.26.12", "copy-webpack-plugin": "^5.1.1", - "css-loader": "^3.6.0", + "css-loader": "^4.2.0", "cssnano": "^4.1.10", "del": "^5.1.0", - "eslint": "^6.8.0", + "eslint": "^7.6.0", "eslint-plugin-compat": "^3.5.1", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-import": "^2.21.2", @@ -37,7 +38,7 @@ "gulp-postcss": "^8.0.0", "gulp-sass": "^4.0.2", "gulp-sourcemaps": "^2.6.5", - "gulp-terser": "^1.2.1", + "gulp-terser": "^1.3.0", "html-webpack-plugin": "^4.3.0", "lazypipe": "^1.0.2", "node-sass": "^4.13.1", @@ -48,7 +49,7 @@ "stylelint-config-rational-order": "^0.1.2", "stylelint-no-browser-hacks": "^1.2.1", "stylelint-order": "^4.1.0", - "webpack": "^4.44.0", + "webpack": "^4.44.1", "webpack-merge": "^4.2.2", "webpack-stream": "^5.2.1" }, @@ -62,7 +63,7 @@ "fast-text-encoding": "^1.0.3", "flv.js": "^1.5.0", "headroom.js": "^0.11.0", - "hls.js": "^0.14.5", + "hls.js": "^0.14.7", "howler": "^2.2.0", "intersection-observer": "^0.11.0", "jellyfin-apiclient": "^1.4.1", @@ -76,7 +77,6 @@ "query-string": "^6.13.1", "resize-observer-polyfill": "^1.5.1", "screenfull": "^5.0.2", - "shaka-player": "^2.5.13", "sortablejs": "^1.10.2", "swiper": "^5.4.5", "webcomponents.js": "^0.7.24", @@ -107,6 +107,7 @@ "src/components/dialogHelper/dialogHelper.js", "src/components/directorybrowser/directorybrowser.js", "src/components/displaySettings/displaySettings.js", + "src/components/favoriteitems.js", "src/components/fetchhelper.js", "src/components/filterdialog/filterdialog.js", "src/components/groupedcards.js", @@ -115,14 +116,18 @@ "src/components/htmlMediaHelper.js", "src/components/imageOptionsEditor/imageOptionsEditor.js", "src/components/images/imageLoader.js", + "src/components/imageDownloader/imageDownloader.js", + "src/components/imageeditor/imageeditor.js", "src/components/imageUploader/imageUploader.js", "src/components/indicators/indicators.js", "src/components/itemContextMenu.js", + "src/components/itemHelper.js", "src/components/itemidentifier/itemidentifier.js", "src/components/itemMediaInfo/itemMediaInfo.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", "src/components/libraryoptionseditor/libraryoptionseditor.js", "src/components/listview/listview.js", + "src/components/loading/loading.js", "src/components/maintabsmanager.js", "src/components/mediainfo/mediainfo.js", "src/components/mediaLibraryCreator/mediaLibraryCreator.js", @@ -135,9 +140,11 @@ "src/components/playback/mediasession.js", "src/components/playback/nowplayinghelper.js", "src/components/playback/playbackorientation.js", + "src/components/playback/playbackmanager.js", "src/components/playback/playerSelectionMenu.js", "src/components/playback/playersettingsmenu.js", "src/components/playback/playmethodhelper.js", + "src/components/playback/playqueuemanager.js", "src/components/playback/remotecontrolautoplay.js", "src/components/playback/volumeosd.js", "src/components/playbackSettings/playbackSettings.js", @@ -145,8 +152,10 @@ "src/components/playlisteditor/playlisteditor.js", "src/components/playmenu.js", "src/components/prompt/prompt.js", + "src/components/refreshdialog/refreshdialog.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", + "src/plugins/htmlVideoPlayer/plugin.js", "src/components/search/searchfields.js", "src/components/search/searchresults.js", "src/components/settingshelper.js", @@ -157,11 +166,12 @@ "src/components/syncPlay/playbackPermissionManager.js", "src/components/syncPlay/syncPlayManager.js", "src/components/syncPlay/timeSyncManager.js", - "src/controllers/auth/addserver.js", - "src/controllers/auth/forgotpassword.js", - "src/controllers/auth/forgotpasswordpin.js", - "src/controllers/auth/login.js", - "src/controllers/auth/selectserver.js", + "src/components/viewContainer.js", + "src/controllers/session/addServer/index.js", + "src/controllers/session/forgotPassword/index.js", + "src/controllers/session/redeemPassword/index.js", + "src/controllers/session/login/index.js", + "src/controllers/session/selectServer/index.js", "src/controllers/dashboard/apikeys.js", "src/controllers/dashboard/dashboard.js", "src/controllers/dashboard/devices/device.js", @@ -173,6 +183,12 @@ "src/controllers/dashboard/general.js", "src/controllers/dashboard/librarydisplay.js", "src/controllers/dashboard/logs.js", + "src/controllers/music/musicalbums.js", + "src/controllers/music/musicartists.js", + "src/controllers/music/musicgenres.js", + "src/controllers/music/musicplaylists.js", + "src/controllers/music/musicrecommended.js", + "src/controllers/music/songs.js", "src/controllers/dashboard/mediaLibrary.js", "src/controllers/dashboard/metadataImages.js", "src/controllers/dashboard/metadatanfo.js", @@ -180,7 +196,7 @@ "src/controllers/dashboard/notifications/notification.js", "src/controllers/dashboard/notifications/notifications.js", "src/controllers/dashboard/playback.js", - "src/controllers/dashboard/plugins/repositories.js", + "src/controllers/dashboard/plugins/repositories/index.js", "src/controllers/dashboard/scheduledtasks/scheduledtask.js", "src/controllers/dashboard/scheduledtasks/scheduledtasks.js", "src/controllers/dashboard/serveractivity.js", @@ -191,9 +207,19 @@ "src/controllers/dashboard/users/userparentalcontrol.js", "src/controllers/dashboard/users/userpasswordpage.js", "src/controllers/dashboard/users/userprofilespage.js", + "src/controllers/edititemmetadata.js", + "src/controllers/favorites.js", + "src/controllers/hometab.js", "src/controllers/playback/nowplaying.js", "src/controllers/playback/videoosd.js", + "src/controllers/itemDetails/index.js", + "src/controllers/playback/queue/index.js", + "src/controllers/playback/video/index.js", "src/controllers/searchpage.js", + "src/controllers/livetvtuner.js", + "src/controllers/livetvstatus.js", + "src/controllers/livetvguideprovider.js", + "src/controllers/livetvsettings.js", "src/controllers/shows/episodes.js", "src/controllers/shows/tvgenres.js", "src/controllers/shows/tvlatest.js", @@ -201,18 +227,17 @@ "src/controllers/shows/tvshows.js", "src/controllers/shows/tvstudios.js", "src/controllers/shows/tvupcoming.js", - "src/controllers/user/display.js", - "src/controllers/user/home.js", - "src/controllers/user/menu.js", - "src/controllers/user/playback.js", - "src/controllers/user/profile.js", - "src/controllers/user/subtitles.js", - "src/controllers/user/subtitles.js", - "src/controllers/wizard/finish.js", - "src/controllers/wizard/remoteaccess.js", - "src/controllers/wizard/settings.js", - "src/controllers/wizard/start.js", - "src/controllers/wizard/user.js", + "src/controllers/user/display/index.js", + "src/controllers/user/home/index.js", + "src/controllers/user/menu/index.js", + "src/controllers/user/playback/index.js", + "src/controllers/user/profile/index.js", + "src/controllers/user/subtitles/index.js", + "src/controllers/wizard/finish/index.js", + "src/controllers/wizard/remote/index.js", + "src/controllers/wizard/settings/index.js", + "src/controllers/wizard/start/index.js", + "src/controllers/wizard/user/index.js", "src/elements/emby-button/emby-button.js", "src/elements/emby-button/paper-icon-button-light.js", "src/elements/emby-checkbox/emby-checkbox.js", @@ -240,6 +265,7 @@ "src/plugins/youtubePlayer/plugin.js", "src/scripts/alphanumericshortcuts.js", "src/scripts/autoBackdrops.js", + "src/scripts/browser.js", "src/scripts/datetime.js", "src/scripts/deleteHelper.js", "src/scripts/dfnshelper.js", @@ -250,8 +276,14 @@ "src/scripts/globalize.js", "src/scripts/imagehelper.js", "src/scripts/inputManager.js", + "src/scripts/autoThemes.js", + "src/scripts/themeManager.js", "src/scripts/keyboardNavigation.js", + "src/scripts/libraryBrowser.js", + "src/scripts/mouseManager.js", + "src/scripts/multiDownload.js", "src/scripts/playlists.js", + "src/scripts/routes.js", "src/scripts/settings/appSettings.js", "src/scripts/settings/userSettings.js", "src/scripts/settings/webSettings.js", @@ -272,7 +304,7 @@ "last 2 Chrome versions", "last 2 ChromeAndroid versions", "last 2 Safari versions", - "last 2 iOS versions", + "iOS > 10", "last 2 Edge versions", "Chrome 27", "Chrome 38", @@ -280,6 +312,7 @@ "Chrome 53", "Chrome 56", "Chrome 63", + "Edge 18", "Firefox ESR" ], "scripts": { diff --git a/src/assets/css/librarybrowser.css b/src/assets/css/librarybrowser.css index 61815a590f..047ae0a1c6 100644 --- a/src/assets/css/librarybrowser.css +++ b/src/assets/css/librarybrowser.css @@ -646,7 +646,7 @@ .layout-desktop .detailRibbon, .layout-tv .detailRibbon { margin-top: -7.2em; - height: 7.18em; + height: 7.2em; } .layout-desktop .noBackdrop .detailRibbon, diff --git a/src/assets/css/site.css b/src/assets/css/site.css index f6326f4c9e..38e056df89 100644 --- a/src/assets/css/site.css +++ b/src/assets/css/site.css @@ -133,3 +133,13 @@ div[data-role=page] { .w-100 { width: 100%; } + +.margin-auto-x { + margin-left: auto; + margin-right: auto; +} + +.margin-auto-y { + margin-top: auto; + margin-bottom: auto; +} diff --git a/src/assets/img/devices/edgechromium.svg b/src/assets/img/devices/edgechromium.svg new file mode 100644 index 0000000000..14d68a5d48 --- /dev/null +++ b/src/assets/img/devices/edgechromium.svg @@ -0,0 +1 @@ +Microsoft Edge icon diff --git a/src/bundle.js b/src/bundle.js index dd1ff6548b..ae2a59f0d5 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -78,12 +78,6 @@ _define('webcomponents', function() { return webcomponents; }); -// shaka -var shaka = require('shaka-player'); -_define('shaka', function() { - return shaka; -}); - // libass-wasm var libassWasm = require('libass-wasm'); _define('JavascriptSubtitlesOctopus', function() { diff --git a/src/components/accessSchedule/accessSchedule.js b/src/components/accessSchedule/accessSchedule.js index 6b96aad1d4..b513766d0b 100644 --- a/src/components/accessSchedule/accessSchedule.js +++ b/src/components/accessSchedule/accessSchedule.js @@ -49,7 +49,7 @@ import 'formDialogStyle'; }; if (parseFloat(updatedSchedule.StartHour) >= parseFloat(updatedSchedule.EndHour)) { - return void alert(globalize.translate('ErrorMessageStartHourGreaterThanEnd')); + return void alert(globalize.translate('ErrorStartHourGreaterThanEnd')); } context.submitted = true; diff --git a/src/components/actionSheet/actionSheet.js b/src/components/actionSheet/actionSheet.js index a68d6a6acd..937cd2afe5 100644 --- a/src/components/actionSheet/actionSheet.js +++ b/src/components/actionSheet/actionSheet.js @@ -9,7 +9,6 @@ import 'scrollStyles'; import 'listViewStyle'; function getOffsets(elems) { - let results = []; if (!document) { @@ -31,7 +30,6 @@ function getOffsets(elems) { } function getPosition(options, dlg) { - const windowSize = dom.getWindowSize(); const windowHeight = windowSize.innerHeight; const windowWidth = windowSize.innerWidth; @@ -80,7 +78,6 @@ function centerFocus(elem, horiz, on) { } export function show(options) { - // items // positionTo // showCancel @@ -98,7 +95,6 @@ export function show(options) { isFullscreen = true; dialogOptions.autoFocus = true; } else { - dialogOptions.modal = false; dialogOptions.entryAnimation = options.entryAnimation; dialogOptions.exitAnimation = options.exitAnimation; @@ -136,7 +132,6 @@ export function show(options) { let icons = []; let itemIcon; for (const item of options.items) { - itemIcon = item.icon || (item.selected ? 'check' : null); if (itemIcon) { @@ -161,7 +156,6 @@ export function show(options) { } if (options.title) { - html += '

' + options.title + '

'; } if (options.text) { @@ -197,7 +191,6 @@ export function show(options) { const item = options.items[i]; if (item.divider) { - html += '
'; continue; } @@ -255,8 +248,6 @@ export function show(options) { }); } - // Seeing an issue in some non-chrome browsers where this is requiring a double click - //var eventName = browser.firefox ? 'mousedown' : 'click'; let selectedId; let timeout; @@ -267,26 +258,20 @@ export function show(options) { } return new Promise(function (resolve, reject) { - let isResolved; dlg.addEventListener('click', function (e) { - const actionSheetMenuItem = dom.parentWithClass(e.target, 'actionSheetMenuItem'); if (actionSheetMenuItem) { selectedId = actionSheetMenuItem.getAttribute('data-id'); if (options.resolveOnClick) { - if (options.resolveOnClick.indexOf) { - if (options.resolveOnClick.indexOf(selectedId) !== -1) { - resolve(selectedId); isResolved = true; } - } else { resolve(selectedId); isResolved = true; @@ -295,11 +280,9 @@ export function show(options) { dialogHelper.close(dlg); } - }); dlg.addEventListener('close', function () { - if (layoutManager.tv) { centerFocus(dlg.querySelector('.actionSheetScroller'), false, false); } diff --git a/src/components/activitylog.js b/src/components/activitylog.js index 2d5a21756f..ab489a3f31 100644 --- a/src/components/activitylog.js +++ b/src/components/activitylog.js @@ -3,7 +3,6 @@ import globalize from 'globalize'; import dom from 'dom'; import * as datefns from 'date-fns'; import dfnshelper from 'dfnshelper'; -import userSettings from 'userSettings'; import serverNotifications from 'serverNotifications'; import connectionManager from 'connectionManager'; import 'emby-button'; @@ -17,7 +16,7 @@ import 'listViewStyle'; let color = '#00a4dc'; let icon = 'notifications'; - if ('Error' == entry.Severity || 'Fatal' == entry.Severity || 'Warn' == entry.Severity) { + if (entry.Severity == 'Error' || entry.Severity == 'Fatal' || entry.Severity == 'Warn') { color = '#cc0000'; icon = 'notification_important'; } @@ -61,14 +60,15 @@ import 'listViewStyle'; } function reloadData(instance, elem, apiClient, startIndex, limit) { - if (null == startIndex) { + if (startIndex == null) { startIndex = parseInt(elem.getAttribute('data-activitystartindex') || '0'); } limit = limit || parseInt(elem.getAttribute('data-activitylimit') || '7'); const minDate = new Date(); - const hasUserId = 'false' !== elem.getAttribute('data-useractivity'); + const hasUserId = elem.getAttribute('data-useractivity') !== 'false'; + // TODO: Use date-fns if (hasUserId) { minDate.setTime(minDate.getTime() - 24 * 60 * 60 * 1000); // one day back } else { diff --git a/src/components/alert.js b/src/components/alert.js index 5d396e3a62..1420c7f428 100644 --- a/src/components/alert.js +++ b/src/components/alert.js @@ -10,7 +10,6 @@ import globalize from 'globalize'; } export default function (text, title) { - let options; if (typeof text === 'string') { options = { diff --git a/src/components/alphaPicker/alphaPicker.js b/src/components/alphaPicker/alphaPicker.js index 4bc8af56f0..95b5881677 100644 --- a/src/components/alphaPicker/alphaPicker.js +++ b/src/components/alphaPicker/alphaPicker.js @@ -26,7 +26,6 @@ import 'material-icons'; } function getAlphaPickerButtonClassName(vertical) { - let alphaPickerButtonClassName = 'alphaPickerButton'; if (layoutManager.tv) { @@ -45,14 +44,12 @@ import 'material-icons'; } function mapLetters(letters, vertical) { - return letters.map(l => { return getLetterButton(l, vertical); }); } function render(element, options) { - element.classList.add('alphaPicker'); if (layoutManager.tv) { @@ -137,7 +134,6 @@ import 'material-icons'; } function onAlphaPickerInKeyboardModeClick(e) { - const alphaPickerButton = dom.parentWithClass(e.target, 'alphaPickerButton'); if (alphaPickerButton) { @@ -153,7 +149,6 @@ import 'material-icons'; } function onAlphaPickerClick(e) { - const alphaPickerButton = dom.parentWithClass(e.target, 'alphaPickerButton'); if (alphaPickerButton) { @@ -167,7 +162,6 @@ import 'material-icons'; } function onAlphaPickerFocusIn(e) { - if (alphaFocusTimeout) { clearTimeout(alphaFocusTimeout); alphaFocusTimeout = null; @@ -182,13 +176,11 @@ import 'material-icons'; } function onItemsFocusIn(e) { - const item = dom.parentWithClass(e.target, itemClass); if (item) { const prefix = item.getAttribute('data-prefix'); if (prefix && prefix.length) { - itemFocusValue = prefix[0]; if (itemFocusTimeout) { clearTimeout(itemFocusTimeout); @@ -199,9 +191,7 @@ import 'material-icons'; } this.enabled = function (enabled) { - if (enabled) { - if (itemsContainer) { itemsContainer.addEventListener('focus', onItemsFocusIn, true); } @@ -215,9 +205,7 @@ import 'material-icons'; } else { element.addEventListener('click', onAlphaPickerClick.bind(this)); } - } else { - if (itemsContainer) { itemsContainer.removeEventListener('focus', onItemsFocusIn, true); } @@ -235,14 +223,12 @@ import 'material-icons'; } value(value, applyValue) { - const element = this.options.element; let btn; let selected; if (value !== undefined) { if (value != null) { - value = value.toUpperCase(); this._currentValue = value; @@ -295,33 +281,27 @@ import 'material-icons'; } visible(visible) { - const element = this.options.element; element.style.visibility = visible ? 'visible' : 'hidden'; } values() { - const element = this.options.element; const elems = element.querySelectorAll('.alphaPickerButton'); const values = []; for (let i = 0, length = elems.length; i < length; i++) { - values.push(elems[i].getAttribute('data-value')); - } return values; } focus() { - const element = this.options.element; focusManager.autoFocus(element, true); } destroy() { - const element = this.options.element; this.enabled(false); element.classList.remove('focuscontainer-x'); diff --git a/src/components/appFooter/appFooter.js b/src/components/appFooter/appFooter.js index af50ef7bf9..c60aa1a27c 100644 --- a/src/components/appFooter/appFooter.js +++ b/src/components/appFooter/appFooter.js @@ -1,4 +1,3 @@ -import browser from 'browser'; import 'css!./appFooter'; function render(options) { diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 8054279c92..da3b08317c 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -1,6 +1,9 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdrop', 'browser', 'page', 'appSettings', 'apphost', 'connectionManager'], function (loading, globalize, events, viewManager, skinManager, backdrop, browser, page, appSettings, appHost, connectionManager) { 'use strict'; + browser = browser.default || browser; + loading = loading.default || loading; + var appRouter = { showLocalLogin: function (serverId, manualLogin) { var pageName = manualLogin ? 'manuallogin' : 'login'; @@ -16,7 +19,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro show('/settings/settings.html'); }, showNowPlaying: function () { - show('/nowplaying.html'); + show('queue'); } }; @@ -34,7 +37,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro switch (result.State) { case 'SignedIn': loading.hide(); - skinManager.loadUserSkin(); + Emby.Page.goHome(); break; case 'ServerSignIn': result.ApiClient.getPublicUsers().then(function (users) { @@ -147,26 +150,19 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro if (typeof route.path === 'string') { loadContentUrl(ctx, next, route, currentRequest); } else { - // ? TODO next(); } }; if (!isBackNav) { - // Don't force a new view for home due to the back menu - //if (route.type !== 'home') { onNewViewNeeded(); return; - //} } viewManager.tryRestoreView(currentRequest, function () { - - // done currentRouteInfo = { route: route, path: ctx.path }; - }).catch(function (result) { if (!result || !result.cancelled) { onNewViewNeeded(); @@ -197,12 +193,10 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro } function onRequestFail(e, data) { - var apiClient = this; if (data.status === 403) { if (data.errorCode === 'ParentalControl') { - var isCurrentAllowed = currentRouteInfo ? (currentRouteInfo.route.anonymous || currentRouteInfo.route.startup) : true; // Bounce to the login screen, but not if a password entry fails, obviously @@ -210,7 +204,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro showForcedLogoutMessage(globalize.translate('AccessRestrictedTryAgainLater')); appRouter.showLocalLogin(apiClient.serverId()); } - } } } @@ -237,12 +230,10 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro if (navigator.connection) { var max = navigator.connection.downlinkMax; if (max && max > 0 && max < Number.POSITIVE_INFINITY) { - max /= 8; max *= 1000000; max *= 0.7; - max = parseInt(max); - return max; + return parseInt(max, 10); } } /* eslint-enable compat/compat */ @@ -255,7 +246,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro } function onApiClientCreated(e, newApiClient) { - newApiClient.normalizeImageOptions = normalizeImageOptions; if (browser.iOS) { @@ -269,12 +259,10 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro } function initApiClient(apiClient) { - onApiClientCreated({}, apiClient); } function initApiClients() { - connectionManager.getApiClients().forEach(initApiClient); events.on(connectionManager, 'apiclientcreated', onApiClientCreated); @@ -290,7 +278,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro var firstConnectionResult; function start(options) { - loading.show(); initApiClients(); @@ -300,55 +287,28 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro connectionManager.connect({ enableAutoLogin: appSettings.enableAutoLogin() - }).then(function (result) { - firstConnectionResult = result; - options = options || {}; - page({ click: options.click !== false, - hashbang: options.hashbang !== false, - enableHistory: enableHistory() + hashbang: options.hashbang !== false }); }).catch().then(function() { loading.hide(); }); } - function enableHistory() { - - //if (browser.edgeUwp) { - // return false; - //} - - // shows status bar on navigation - if (browser.xboxOne) { - return false; - } - - // Does not support history - if (browser.orsay) { - return false; - } - - return true; - } - function enableNativeHistory() { return false; } function authenticate(ctx, route, callback) { - var firstResult = firstConnectionResult; if (firstResult) { - firstConnectionResult = null; if (firstResult.State !== 'SignedIn' && !route.anonymous) { - handleConnectionResult(firstResult); return; } @@ -377,19 +337,15 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro } if (apiClient && apiClient.isLoggedIn()) { - console.debug('appRouter - user is authenticated'); if (route.isDefaultRoute) { console.debug('appRouter - loading skin home page'); - loadUserSkinWithOptions(ctx); + Emby.Page.goHome(); return; } else if (route.roles) { - validateRoles(apiClient, route.roles).then(function () { - callback(); - }, beginConnectionWizard); return; } @@ -399,15 +355,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro callback(); } - function loadUserSkinWithOptions(ctx) { - require(['queryString'], function (queryString) { - var params = queryString.parse(ctx.querystring); - skinManager.loadUserSkin({ - start: params.start - }); - }); - } - function validateRoles(apiClient, roles) { return Promise.all(roles.split(',').map(function (role) { return validateRole(apiClient, role); @@ -431,7 +378,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro var isDummyBackToHome; function loadContent(ctx, route, html, request) { - html = globalize.translateHtml(html, route.dictionary); request.view = html; @@ -491,7 +437,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro } function getWindowLocationSearch(win) { - var currentPath = currentRouteInfo ? (currentRouteInfo.path || '') : ''; var index = currentPath.indexOf('?'); @@ -535,9 +480,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro if (!document.querySelector('.dialogContainer') && startPages.indexOf(curr.type) !== -1) { return false; } - if (enableHistory()) { - return history.length > 1; - } + return (page.len || 0) > 0; } @@ -644,7 +587,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro function pushState(state, title, url) { state.navigate = false; history.pushState(state, title, url); - } function setBaseRoute() { diff --git a/src/components/apphost.js b/src/components/apphost.js index f200b9a642..3ed590b546 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -1,6 +1,8 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'globalize'], function (appSettings, browser, events, htmlMediaHelper, webSettings, globalize) { 'use strict'; + browser = browser.default || browser; + function getBaseProfileOptions(item) { var disableHlsVideoAudioCodecs = []; @@ -47,7 +49,7 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g profile = window.NativeShell.AppHost.getDeviceProfile(profileBuilder); } else { var builderOpts = getBaseProfileOptions(item); - builderOpts.enableSsaRender = (item && !options.isRetry && 'allcomplexformats' !== appSettings.get('subtitleburnin')); + builderOpts.enableSsaRender = (item && !options.isRetry && appSettings.get('subtitleburnin') !== 'allcomplexformats'); profile = profileBuilder(builderOpts); } @@ -105,6 +107,8 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g deviceName = 'Sony PS4'; } else if (browser.chrome) { deviceName = 'Chrome'; + } else if (browser.edgeChromium) { + deviceName = 'Edge Chromium'; } else if (browser.edge) { deviceName = 'Edge'; } else if (browser.firefox) { @@ -257,12 +261,6 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g features.push('fullscreenchange'); } - if (browser.chrome || browser.edge && !browser.slow) { - if (!browser.noAnimation && !browser.edgeUwp && !browser.xboxOne) { - features.push('imageanalysis'); - } - } - if (browser.tv || browser.xboxOne || browser.ps4 || browser.mobile) { features.push('physicalvolumecontrol'); } @@ -281,7 +279,7 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g features.push('targetblank'); features.push('screensaver'); - webSettings.enableMultiServer().then(enabled => { + webSettings.getMultiServer().then(enabled => { if (enabled) features.push('multiserver'); }); @@ -297,7 +295,7 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g features.push('fileinput'); } - if (browser.chrome) { + if (browser.chrome || browser.edgeChromium) { features.push('chromecast'); } @@ -353,7 +351,7 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g var deviceId; var deviceName; var appName = 'Jellyfin Web'; - var appVersion = '10.6.0'; + var appVersion = '10.7.0'; var appHost = { getWindowState: function () { @@ -374,7 +372,7 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g return window.NativeShell.AppHost.supports(command); } - return -1 !== supportedFeatures.indexOf(command.toLowerCase()); + return supportedFeatures.indexOf(command.toLowerCase()) !== -1; }, preferVisualCards: browser.android || browser.chrome, getSyncProfile: getSyncProfile, @@ -411,13 +409,6 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g getPushTokenInfo: function () { return {}; }, - setThemeColor: function (color) { - var metaThemeColor = document.querySelector('meta[name=theme-color]'); - - if (metaThemeColor) { - metaThemeColor.setAttribute('content', color); - } - }, setUserScalable: function (scalable) { if (!browser.tv) { var att = scalable ? 'width=device-width, initial-scale=1, minimum-scale=1, user-scalable=yes' : 'width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no'; diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index a6d0b10662..4a37331ef4 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -277,7 +277,7 @@ import 'programStyles'; */ function getImageWidth(shape, screenWidth, isOrientationLandscape) { const imagesPerRow = getPostersPerRow(shape, screenWidth, isOrientationLandscape); - return Math.round(screenWidth / imagesPerRow) * 2; + return Math.round(screenWidth / imagesPerRow); } /** @@ -291,12 +291,10 @@ import 'programStyles'; const primaryImageAspectRatio = imageLoader.getPrimaryImageAspectRatio(items); if (['auto', 'autohome', 'autooverflow', 'autoVertical'].includes(options.shape)) { - const requestedShape = options.shape; options.shape = null; if (primaryImageAspectRatio) { - if (primaryImageAspectRatio >= 3) { options.shape = 'banner'; options.coverImage = true; @@ -394,7 +392,6 @@ import 'programStyles'; } if (newIndexValue !== currentIndexValue) { - if (hasOpenRow) { html += ''; hasOpenRow = false; @@ -402,7 +399,6 @@ import 'programStyles'; } if (hasOpenSection) { - html += ''; if (isVertical) { @@ -426,7 +422,6 @@ import 'programStyles'; } if (options.rows && itemsInRow === 0) { - if (hasOpenRow) { html += ''; hasOpenRow = false; @@ -686,7 +681,6 @@ import 'programStyles'; let valid = 0; for (let i = 0; i < lines.length; i++) { - let currentCssClass = cssClass; let text = lines[i]; @@ -713,7 +707,6 @@ import 'programStyles'; } if (forceLines) { - let linesLength = maxLines || Math.min(lines.length, maxLines || lines.length); while (valid < linesLength) { @@ -745,7 +738,6 @@ import 'programStyles'; let airTimeText = ''; if (item.StartDate) { - try { let date = datetime.parseISO8601Date(item.StartDate); @@ -792,7 +784,6 @@ import 'programStyles'; const showOtherText = isOuterFooter ? !overlayText : overlayText; if (isOuterFooter && options.cardLayout && layoutManager.mobile) { - if (options.cardFooterAside !== 'none') { html += ''; } @@ -807,9 +798,7 @@ import 'programStyles'; if (showOtherText) { if ((options.showParentTitle || options.showParentTitleOrTitle) && !parentTitleUnderneath) { - if (isOuterFooter && item.Type === 'Episode' && item.SeriesName) { - if (item.SeriesId) { lines.push(getTextActionButton({ Id: item.SeriesId, @@ -822,15 +811,12 @@ import 'programStyles'; lines.push(item.SeriesName); } } else { - if (isUsingLiveTvNaming(item)) { - lines.push(item.Name); if (!item.EpisodeTitle) { titleAdded = true; } - } else { const parentTitle = item.SeriesName || item.Series || item.Album || item.AlbumArtist || ''; @@ -848,7 +834,6 @@ import 'programStyles'; } if (showMediaTitle) { - const name = options.showTitle === 'auto' && !item.IsFolder && item.MediaType === 'Photo' ? '' : itemHelper.getDisplayName(item, { includeParentInfo: options.includeParentInfoInTitle }); @@ -865,7 +850,6 @@ import 'programStyles'; if (showOtherText) { if (options.showParentTitle && parentTitleUnderneath) { - if (isOuterFooter && item.AlbumArtists && item.AlbumArtists.length) { item.AlbumArtists[0].Type = 'MusicArtist'; item.AlbumArtists[0].IsFolder = true; @@ -899,7 +883,6 @@ import 'programStyles'; } if (options.showPremiereDate) { - if (item.PremiereDate) { try { lines.push(datetime.toLocaleDateString( @@ -908,7 +891,6 @@ import 'programStyles'; )); } catch (err) { lines.push(''); - } } else { lines.push(''); @@ -916,14 +898,10 @@ import 'programStyles'; } if (options.showYear || options.showSeriesYear) { - if (item.Type === 'Series') { if (item.Status === 'Continuing') { - lines.push(globalize.translate('SeriesYearToPresent', item.ProductionYear || '')); - } else { - if (item.EndDate && item.ProductionYear) { const endYear = datetime.parseISO8601Date(item.EndDate).getFullYear(); lines.push(item.ProductionYear + ((endYear === item.ProductionYear) ? '' : (' - ' + endYear))); @@ -937,9 +915,7 @@ import 'programStyles'; } if (options.showRuntime) { - if (item.RunTimeTicks) { - lines.push(datetime.getDisplayRunningTime(item.RunTimeTicks)); } else { lines.push(''); @@ -947,14 +923,11 @@ import 'programStyles'; } if (options.showAirTime) { - lines.push(getAirTimeText(item, options.showAirDateTime, options.showAirEndTime) || ''); } if (options.showChannelName) { - if (item.ChannelId) { - lines.push(getTextActionButton({ Id: item.ChannelId, @@ -971,7 +944,6 @@ import 'programStyles'; } if (options.showCurrentProgram && item.Type === 'TvChannel') { - if (item.CurrentProgram) { lines.push(item.CurrentProgram.Name); } else { @@ -980,7 +952,6 @@ import 'programStyles'; } if (options.showCurrentProgramTime && item.Type === 'TvChannel') { - if (item.CurrentProgram) { lines.push(getAirTimeText(item.CurrentProgram, false, true) || ''); } else { @@ -990,7 +961,6 @@ import 'programStyles'; if (options.showSeriesTimerTime) { if (item.RecordAnyTime) { - lines.push(globalize.translate('Anytime')); } else { lines.push(datetime.getDisplayTime(item.StartDate)); @@ -1025,7 +995,6 @@ import 'programStyles'; } if (html) { - if (!isOuterFooter || logoUrl || options.cardLayout) { html = '
' + html; @@ -1071,27 +1040,21 @@ import 'programStyles'; let childText; if (item.Type === 'Playlist') { - childText = ''; if (item.RunTimeTicks) { - let minutes = item.RunTimeTicks / 600000000; minutes = minutes || 1; childText += globalize.translate('ValueMinutes', Math.round(minutes)); - } else { childText += globalize.translate('ValueMinutes', 0); } counts.push(childText); - } else if (item.Type === 'Genre' || item.Type === 'Studio') { - if (item.MovieCount) { - childText = item.MovieCount === 1 ? globalize.translate('ValueOneMovie') : globalize.translate('ValueMovieCount', item.MovieCount); @@ -1100,7 +1063,6 @@ import 'programStyles'; } if (item.SeriesCount) { - childText = item.SeriesCount === 1 ? globalize.translate('ValueOneSeries') : globalize.translate('ValueSeriesCount', item.SeriesCount); @@ -1108,18 +1070,14 @@ import 'programStyles'; counts.push(childText); } if (item.EpisodeCount) { - childText = item.EpisodeCount === 1 ? globalize.translate('ValueOneEpisode') : globalize.translate('ValueEpisodeCount', item.EpisodeCount); counts.push(childText); } - } else if (item.Type === 'MusicGenre' || options.context === 'MusicArtist') { - if (item.AlbumCount) { - childText = item.AlbumCount === 1 ? globalize.translate('ValueOneAlbum') : globalize.translate('ValueAlbumCount', item.AlbumCount); @@ -1127,7 +1085,6 @@ import 'programStyles'; counts.push(childText); } if (item.SongCount) { - childText = item.SongCount === 1 ? globalize.translate('ValueOneSong') : globalize.translate('ValueSongCount', item.SongCount); @@ -1135,16 +1092,13 @@ import 'programStyles'; counts.push(childText); } if (item.MusicVideoCount) { - childText = item.MusicVideoCount === 1 ? globalize.translate('ValueOneMusicVideo') : globalize.translate('ValueMusicVideoCount', item.MusicVideoCount); counts.push(childText); } - } else if (item.Type === 'Series') { - childText = item.RecursiveItemCount === 1 ? globalize.translate('ValueOneEpisode') : globalize.translate('ValueEpisodeCount', item.RecursiveItemCount); @@ -1163,6 +1117,7 @@ import 'programStyles'; function importRefreshIndicator() { if (!refreshIndicatorLoaded) { refreshIndicatorLoaded = true; + /* eslint-disable-next-line no-unused-expressions */ import('emby-itemrefreshindicator'); } } @@ -1197,13 +1152,11 @@ import 'programStyles'; let shape = options.shape; if (shape === 'mixed') { - shape = null; const primaryImageAspectRatio = item.PrimaryImageAspectRatio; if (primaryImageAspectRatio) { - if (primaryImageAspectRatio >= 1.33) { shape = 'mixedBackdrop'; } else if (primaryImageAspectRatio > 0.71) { @@ -1295,7 +1248,6 @@ import 'programStyles'; } if (overlayText) { - logoUrl = null; footerCssClass = progressHtml ? 'innerCardFooter fullInnerCardFooter' : 'innerCardFooter'; @@ -1404,7 +1356,6 @@ import 'programStyles'; indicatorsHtml += indicators.getTypeIndicator(item); if (options.showGroupCount) { - indicatorsHtml += indicators.getChildCountIndicatorHtml(item, { minCount: 1 }); @@ -1498,14 +1449,15 @@ import 'programStyles'; const userData = item.UserData || {}; if (itemHelper.canMarkPlayed(item)) { + /* eslint-disable-next-line no-unused-expressions */ import('emby-playstatebutton'); html += ''; } if (itemHelper.canRate(item)) { - const likes = userData.Likes == null ? '' : userData.Likes; + /* eslint-disable-next-line no-unused-expressions */ import('emby-ratingbutton'); html += ''; } @@ -1583,7 +1535,6 @@ import 'programStyles'; const html = buildCardsHtmlInternal(items, options); if (html) { - if (options.itemsContainer.cardBuilderHtml !== html) { options.itemsContainer.innerHTML = html; @@ -1596,7 +1547,6 @@ import 'programStyles'; imageLoader.lazyChildren(options.itemsContainer); } else { - options.itemsContainer.innerHTML = html; options.itemsContainer.cardBuilderHtml = null; } @@ -1620,7 +1570,6 @@ import 'programStyles'; indicatorsElem = card.querySelector('.cardIndicators'); if (!indicatorsElem) { - const cardImageContainer = card.querySelector('.cardImageContainer'); indicatorsElem = document.createElement('div'); indicatorsElem.classList.add('cardIndicators'); @@ -1644,11 +1593,9 @@ import 'programStyles'; let itemProgressBar = null; if (userData.Played) { - playedIndicator = card.querySelector('.playedIndicator'); if (!playedIndicator) { - playedIndicator = document.createElement('div'); playedIndicator.classList.add('playedIndicator'); playedIndicator.classList.add('indicator'); @@ -1657,10 +1604,8 @@ import 'programStyles'; } playedIndicator.innerHTML = ''; } else { - playedIndicator = card.querySelector('.playedIndicator'); if (playedIndicator) { - playedIndicator.parentNode.removeChild(playedIndicator); } } @@ -1668,7 +1613,6 @@ import 'programStyles'; countIndicator = card.querySelector('.countIndicator'); if (!countIndicator) { - countIndicator = document.createElement('div'); countIndicator.classList.add('countIndicator'); indicatorsElem = ensureIndicators(card, indicatorsElem); @@ -1676,10 +1620,8 @@ import 'programStyles'; } countIndicator.innerHTML = userData.UnplayedItemCount; } else if (enableCountIndicator) { - countIndicator = card.querySelector('.countIndicator'); if (countIndicator) { - countIndicator.parentNode.removeChild(countIndicator); } } @@ -1691,7 +1633,6 @@ import 'programStyles'; }); if (progressHtml) { - itemProgressBar = card.querySelector('.itemProgressBar'); if (!itemProgressBar) { @@ -1710,7 +1651,6 @@ import 'programStyles'; itemProgressBar.innerHTML = progressHtml; } else { - itemProgressBar = card.querySelector('.itemProgressBar'); if (itemProgressBar) { itemProgressBar.parentNode.removeChild(itemProgressBar); diff --git a/src/components/cardbuilder/chaptercardbuilder.js b/src/components/cardbuilder/chaptercardbuilder.js index c6ee9ba3c5..642a87db2a 100644 --- a/src/components/cardbuilder/chaptercardbuilder.js +++ b/src/components/cardbuilder/chaptercardbuilder.js @@ -14,7 +14,6 @@ import browser from 'browser'; const enableFocusTransform = !browser.slow && !browser.edge; function buildChapterCardsHtml(item, chapters, options) { - // TODO move card creation code to Card component let className = 'card itemAction chapterCard'; @@ -35,7 +34,6 @@ import browser from 'browser'; let shape = (options.backdropShape || 'backdrop'); if (videoStream.Width && videoStream.Height) { - if ((videoStream.Width / videoStream.Height) <= 1.2) { shape = (options.squareShape || 'square'); } @@ -53,7 +51,6 @@ import browser from 'browser'; const apiClient = connectionManager.getApiClient(item.ServerId); for (let i = 0, length = chapters.length; i < length; i++) { - if (options.rows && itemsInRow === 0) { html += '
'; } @@ -73,12 +70,10 @@ import browser from 'browser'; } function getImgUrl({Id}, {ImageTag}, index, maxWidth, apiClient) { - if (ImageTag) { - return apiClient.getScaledImageUrl(Id, { - maxWidth: maxWidth * 2, + maxWidth: maxWidth, tag: ImageTag, type: 'Chapter', index @@ -89,7 +84,6 @@ import browser from 'browser'; } function buildChapterCard(item, apiClient, chapter, index, {width, coverImage}, className, shape) { - const imgUrl = getImgUrl(item, chapter, index, width || 400, apiClient); let cardImageContainerClass = 'cardContent cardContent-shadow cardImageContainer chapterCardImageContainer'; @@ -110,13 +104,10 @@ import browser from 'browser'; const cardBoxCssClass = 'cardBox'; const cardScalableClass = 'cardScalable'; - const html = `
`; - - return html; + return `
`; } export function buildChapterCards(item, chapters, options) { - if (options.parentContainer) { // Abort if the container has been disposed if (!document.body.contains(options.parentContainer)) { diff --git a/src/components/cardbuilder/peoplecardbuilder.js b/src/components/cardbuilder/peoplecardbuilder.js index 3b9a26a704..5fc9e8ade5 100644 --- a/src/components/cardbuilder/peoplecardbuilder.js +++ b/src/components/cardbuilder/peoplecardbuilder.js @@ -8,7 +8,6 @@ import cardBuilder from 'cardBuilder'; export function buildPeopleCards(items, options) { - options = Object.assign(options || {}, { cardLayout: false, centerText: true, diff --git a/src/components/collectionEditor/collectionEditor.js b/src/components/collectionEditor/collectionEditor.js index 18cc0d311f..a115b86a8f 100644 --- a/src/components/collectionEditor/collectionEditor.js +++ b/src/components/collectionEditor/collectionEditor.js @@ -1,7 +1,6 @@ import dom from 'dom'; import dialogHelper from 'dialogHelper'; import loading from 'loading'; -import appHost from 'apphost'; import layoutManager from 'layoutManager'; import connectionManager from 'connectionManager'; import appRouter from 'appRouter'; @@ -39,7 +38,6 @@ import 'flexStyles'; } function createCollection(apiClient, dlg) { - const url = apiClient.getUrl('Collections', { Name: dlg.querySelector('#txtNewCollectionName').value, @@ -53,7 +51,6 @@ import 'flexStyles'; dataType: 'json' }).then(result => { - loading.hide(); const id = result.Id; @@ -61,17 +58,14 @@ import 'flexStyles'; dlg.submitted = true; dialogHelper.close(dlg); redirectToCollection(apiClient, id); - }); } function redirectToCollection(apiClient, id) { - appRouter.showItem(id, apiClient.serverId()); } function addToCollection(apiClient, dlg, id) { - const url = apiClient.getUrl(`Collections/${id}/Items`, { Ids: dlg.querySelector('.fldSelectedItemIds').value || '' @@ -82,7 +76,6 @@ import 'flexStyles'; url: url }).then(() => { - loading.hide(); dlg.submitted = true; @@ -99,7 +92,6 @@ import 'flexStyles'; } function populateCollections(panel) { - loading.show(); const select = panel.querySelector('#selectCollectionToAddTo'); @@ -116,13 +108,11 @@ import 'flexStyles'; const apiClient = connectionManager.getApiClient(currentServerId); apiClient.getItems(apiClient.getCurrentUserId(), options).then(result => { - let html = ''; html += ``; html += result.Items.map(i => { - return ``; }); @@ -135,7 +125,6 @@ import 'flexStyles'; } function getEditorHtml() { - let html = ''; html += '
'; @@ -183,7 +172,6 @@ import 'flexStyles'; } function initEditor(content, items) { - content.querySelector('#selectCollectionToAddTo').addEventListener('change', function () { if (this.value) { content.querySelector('.newCollectionInfo').classList.add('hide'); @@ -220,7 +208,6 @@ import 'flexStyles'; export class showEditor { constructor(options) { - const items = options.items || {}; currentServerId = options.serverId; @@ -248,10 +235,6 @@ import 'flexStyles'; html += title; html += ''; - if (appHost.supports('externallinks')) { - html += `${globalize.translate('Help')}`; - } - html += '
'; html += getEditorHtml(); @@ -261,7 +244,6 @@ import 'flexStyles'; initEditor(dlg, items); dlg.querySelector('.btnCancel').addEventListener('click', () => { - dialogHelper.close(dlg); }); @@ -270,7 +252,6 @@ import 'flexStyles'; } return dialogHelper.open(dlg).then(() => { - if (layoutManager.tv) { centerFocus(dlg.querySelector('.formDialogContent'), false, false); } diff --git a/src/components/confirm/confirm.js b/src/components/confirm/confirm.js index 2d5cfdb55c..0670816a53 100644 --- a/src/components/confirm/confirm.js +++ b/src/components/confirm/confirm.js @@ -4,7 +4,6 @@ import globalize from 'globalize'; /* eslint-disable indent */ export default (() => { - function replaceAll(str, find, replace) { return str.split(find).join(replace); } diff --git a/src/components/dialog/dialog.js b/src/components/dialog/dialog.js index 937e96d297..1b13900d85 100644 --- a/src/components/dialog/dialog.js +++ b/src/components/dialog/dialog.js @@ -13,7 +13,6 @@ import 'flexStyles'; /* eslint-disable indent */ function showDialog(options, template) { - const dialogOptions = { removeOnClose: true, scrollY: false @@ -45,10 +44,6 @@ import 'flexStyles'; dlg.classList.add('dialog-fullscreen-lowres'); } - //dlg.querySelector('.btnCancel').addEventListener('click', function (e) { - // dialogHelper.close(dlg); - //}); - if (options.title) { dlg.querySelector('.formDialogHeaderTitle').innerHTML = options.title || ''; } else { @@ -68,7 +63,6 @@ import 'flexStyles'; let hasDescriptions = false; for (i = 0, length = options.buttons.length; i < length; i++) { - const item = options.buttons[i]; const autoFocus = i === 0 ? ' autofocus' : ''; @@ -111,7 +105,6 @@ import 'flexStyles'; } return dialogHelper.open(dlg).then(() => { - if (enableTvLayout) { scrollHelper.centerFocus.off(dlg.querySelector('.formDialogContent'), false); } @@ -125,7 +118,6 @@ import 'flexStyles'; } export async function show(text, title) { - let options; if (typeof text === 'string') { options = { diff --git a/src/components/dialogHelper/dialogHelper.js b/src/components/dialogHelper/dialogHelper.js index ca7c94a416..1f11d8a195 100644 --- a/src/components/dialogHelper/dialogHelper.js +++ b/src/components/dialogHelper/dialogHelper.js @@ -12,7 +12,6 @@ import 'scrollStyles'; let globalOnOpenCallback; function enableAnimation() { - // too slow if (browser.tv) { return false; @@ -22,7 +21,6 @@ import 'scrollStyles'; } function removeCenterFocus(dlg) { - if (layoutManager.tv) { if (dlg.classList.contains('scrollX')) { centerFocus(dlg, true, false); @@ -35,7 +33,6 @@ import 'scrollStyles'; function tryRemoveElement(elem) { const parentNode = elem.parentNode; if (parentNode) { - // Seeing crashes in edge webview try { parentNode.removeChild(elem); @@ -46,14 +43,12 @@ import 'scrollStyles'; } function DialogHashHandler(dlg, hash, resolve) { - const self = this; self.originalUrl = window.location.href; const activeElement = document.activeElement; let removeScrollLockOnClose = false; function onHashChange(e) { - const isBack = self.originalUrl === window.location.href; if (isBack || !isOpened(dlg)) { @@ -67,7 +62,6 @@ import 'scrollStyles'; } function onBackCommand(e) { - if (e.detail.command === 'back') { self.closedByBack = true; e.preventDefault(); @@ -77,7 +71,6 @@ import 'scrollStyles'; } function onDialogClosed() { - if (!isHistoryEnabled(dlg)) { inputManager.off(dlg, onBackCommand); } @@ -158,7 +151,6 @@ import 'scrollStyles'; } function addBackdropOverlay(dlg) { - const backdrop = document.createElement('div'); backdrop.classList.add('dialogBackdrop'); @@ -193,7 +185,6 @@ import 'scrollStyles'; } export function open(dlg) { - if (globalOnOpenCallback) { globalOnOpenCallback(dlg); } @@ -210,19 +201,16 @@ import 'scrollStyles'; document.body.appendChild(dialogContainer); return new Promise((resolve, reject) => { - new DialogHashHandler(dlg, `dlg${new Date().getTime()}`, resolve); }); } function isOpened(dlg) { - //return dlg.opened; return !dlg.classList.contains('hide'); } export function close(dlg) { - if (isOpened(dlg)) { if (isHistoryEnabled(dlg)) { history.back(); @@ -233,9 +221,7 @@ import 'scrollStyles'; } function closeDialog(dlg) { - if (!dlg.classList.contains('hide')) { - dlg.dispatchEvent(new CustomEvent('closing', { bubbles: false, cancelable: false @@ -256,7 +242,6 @@ import 'scrollStyles'; } function animateDialogOpen(dlg) { - const onAnimationFinish = () => { focusManager.pushScope(dlg); @@ -271,7 +256,6 @@ import 'scrollStyles'; }; if (enableAnimation()) { - const onFinish = () => { dom.removeEventListener(dlg, dom.whichAnimationEvent(), onFinish, { once: true @@ -288,13 +272,10 @@ import 'scrollStyles'; } function animateDialogClose(dlg, onAnimationFinish) { - if (enableAnimation()) { - let animated = true; switch (dlg.animationConfig.exit.name) { - case 'fadeout': dlg.style.animation = `fadeout ${dlg.animationConfig.exit.timing.duration}ms ease-out normal both`; break; @@ -329,7 +310,6 @@ import 'scrollStyles'; const supportsOverscrollBehavior = 'overscroll-behavior-y' in document.body.style; function shouldLockDocumentScroll(options) { - if (supportsOverscrollBehavior && (options.size || !browser.touch)) { return false; } @@ -350,7 +330,6 @@ import 'scrollStyles'; } function removeBackdrop(dlg) { - const backdrop = dlg.backdrop; if (!backdrop) { @@ -364,7 +343,6 @@ import 'scrollStyles'; }; if (enableAnimation()) { - backdrop.classList.remove('dialogBackdropOpened'); // this is not firing animatonend @@ -383,7 +361,6 @@ import 'scrollStyles'; } export function createDialog(options) { - options = options || {}; // If there's no native dialog support, use a plain div @@ -473,9 +450,7 @@ import 'scrollStyles'; } if (enableAnimation()) { - switch (dlg.animationConfig.entry.name) { - case 'fadein': dlg.style.animation = `fadein ${entryAnimationDuration}ms ease-out normal`; break; diff --git a/src/components/displaySettings/displaySettings.js b/src/components/displaySettings/displaySettings.js index 4e24a3b730..ae7647f98b 100644 --- a/src/components/displaySettings/displaySettings.js +++ b/src/components/displaySettings/displaySettings.js @@ -1,6 +1,5 @@ import browser from 'browser'; import layoutManager from 'layoutManager'; -import appSettings from 'appSettings'; import pluginManager from 'pluginManager'; import appHost from 'apphost'; import focusManager from 'focusManager'; @@ -16,17 +15,22 @@ import 'emby-button'; /* eslint-disable indent */ - function fillThemes(select, isDashboard) { - select.innerHTML = skinManager.getThemes().map(t => { - let value = t.id; - if (t.isDefault && !isDashboard) { - value = ''; - } else if (t.isDefaultServerDashboard && isDashboard) { - value = ''; - } + function fillThemes(context, userSettings) { + const select = context.querySelector('#selectTheme'); - return ``; - }).join(''); + skinManager.getThemes().then(themes => { + select.innerHTML = themes.map(t => { + return ``; + }).join(''); + + // get default theme + var defaultTheme = themes.find(theme => { + return theme.default; + }); + + // set the current theme + select.value = userSettings.theme() || defaultTheme.id; + }); } function loadScreensavers(context, userSettings) { @@ -46,6 +50,7 @@ import 'emby-button'; selectScreensaver.innerHTML = options.map(o => { return ``; }).join(''); + selectScreensaver.value = userSettings.screensaver(); if (!selectScreensaver.value) { @@ -54,61 +59,7 @@ import 'emby-button'; } } - function loadSoundEffects(context, userSettings) { - - const selectSoundEffects = context.querySelector('.selectSoundEffects'); - const options = pluginManager.ofType('soundeffects').map(plugin => { - return { - name: plugin.name, - value: plugin.id - }; - }); - - options.unshift({ - name: globalize.translate('None'), - value: 'none' - }); - - selectSoundEffects.innerHTML = options.map(o => { - return ``; - }).join(''); - selectSoundEffects.value = userSettings.soundEffects(); - - if (!selectSoundEffects.value) { - // TODO: set the default instead of none - selectSoundEffects.value = 'none'; - } - } - - function loadSkins(context, userSettings) { - - const selectSkin = context.querySelector('.selectSkin'); - - const options = pluginManager.ofType('skin').map(plugin => { - return { - name: plugin.name, - value: plugin.id - }; - }); - - selectSkin.innerHTML = options.map(o => { - return ``; - }).join(''); - selectSkin.value = userSettings.skin(); - - if (!selectSkin.value && options.length) { - selectSkin.value = options[0].value; - } - - if (options.length > 1 && appHost.supports('skins')) { - context.querySelector('.selectSkinContainer').classList.remove('hide'); - } else { - context.querySelector('.selectSkinContainer').classList.add('hide'); - } - } - function showOrHideMissingEpisodesField(context) { - if (browser.tizen || browser.web0s) { context.querySelector('.fldDisplayMissingEpisodes').classList.add('hide'); return; @@ -118,13 +69,6 @@ import 'emby-button'; } function loadForm(context, user, userSettings) { - - if (user.Policy.IsAdministrator) { - context.querySelector('.selectDashboardThemeContainer').classList.remove('hide'); - } else { - context.querySelector('.selectDashboardThemeContainer').classList.add('hide'); - } - if (appHost.supports('displaylanguage')) { context.querySelector('.languageSection').classList.remove('hide'); } else { @@ -143,18 +87,6 @@ import 'emby-button'; context.querySelector('.learnHowToContributeContainer').classList.add('hide'); } - if (appHost.supports('runatstartup')) { - context.querySelector('.fldAutorun').classList.remove('hide'); - } else { - context.querySelector('.fldAutorun').classList.add('hide'); - } - - if (appHost.supports('soundeffects')) { - context.querySelector('.fldSoundEffects').classList.remove('hide'); - } else { - context.querySelector('.fldSoundEffects').classList.add('hide'); - } - if (appHost.supports('screensaver')) { context.querySelector('.selectScreensaverContainer').classList.remove('hide'); } else { @@ -177,16 +109,8 @@ import 'emby-button'; context.querySelector('.fldThemeVideo').classList.add('hide'); } - context.querySelector('.chkRunAtStartup').checked = appSettings.runAtStartup(); - - const selectTheme = context.querySelector('#selectTheme'); - const selectDashboardTheme = context.querySelector('#selectDashboardTheme'); - - fillThemes(selectTheme); - fillThemes(selectDashboardTheme, true); + fillThemes(context, userSettings); loadScreensavers(context, userSettings); - loadSoundEffects(context, userSettings); - loadSkins(context, userSettings); context.querySelector('.chkDisplayMissingEpisodes').checked = user.Configuration.DisplayMissingEpisodes || false; @@ -202,9 +126,6 @@ import 'emby-button'; context.querySelector('#txtLibraryPageSize').value = userSettings.libraryPageSize(); - selectDashboardTheme.value = userSettings.dashboardTheme() || ''; - selectTheme.value = userSettings.theme() || ''; - context.querySelector('.selectLayout').value = layoutManager.getSavedLayout() || ''; showOrHideMissingEpisodesField(context); @@ -213,9 +134,6 @@ import 'emby-button'; } function saveUser(context, user, userSettingsInstance, apiClient) { - - appSettings.runAtStartup(context.querySelector('.chkRunAtStartup').checked); - user.Configuration.DisplayMissingEpisodes = context.querySelector('.chkDisplayMissingEpisodes').checked; if (appHost.supports('displaylanguage')) { @@ -226,15 +144,11 @@ import 'emby-button'; userSettingsInstance.enableThemeSongs(context.querySelector('#chkThemeSong').checked); userSettingsInstance.enableThemeVideos(context.querySelector('#chkThemeVideo').checked); - userSettingsInstance.dashboardTheme(context.querySelector('#selectDashboardTheme').value); userSettingsInstance.theme(context.querySelector('#selectTheme').value); - userSettingsInstance.soundEffects(context.querySelector('.selectSoundEffects').value); userSettingsInstance.screensaver(context.querySelector('.selectScreensaver').value); userSettingsInstance.libraryPageSize(context.querySelector('#txtLibraryPageSize').value); - userSettingsInstance.skin(context.querySelector('.selectSkin').value); - userSettingsInstance.enableFastFadein(context.querySelector('#chkFadein').checked); userSettingsInstance.enableBlurhash(context.querySelector('#chkBlurhash').checked); userSettingsInstance.enableBackdrops(context.querySelector('#chkBackdrops').checked); diff --git a/src/components/displaySettings/displaySettings.template.html b/src/components/displaySettings/displaySettings.template.html index ab01b4b6ae..fdaf8d70f1 100644 --- a/src/components/displaySettings/displaySettings.template.html +++ b/src/components/displaySettings/displaySettings.template.html @@ -1,5 +1,4 @@
-

${Display}

@@ -123,26 +122,14 @@
${LabelPleaseRestart}
-
- -
-
-
- -
-
-
- -
-
${LabelLibraryPageSizeHelp}
@@ -159,9 +146,9 @@
-
${EnableBlurhashHelp}
+
${EnableBlurHashHelp}
@@ -196,13 +183,6 @@
${EnableThemeVideosHelp}
-
- -
-
'; + html += ''; + html += '
'; + html += ''; - return html; - } + return html; +} - function centerFocus(elem, horiz, on) { - require(['scrollHelper'], function (scrollHelper) { - var fn = on ? 'on' : 'off'; - scrollHelper.centerFocus[fn](elem, horiz); +function centerFocus(elem, horiz, on) { + import('scrollHelper').then(({default: scrollHelper}) => { + const fn = on ? 'on' : 'off'; + scrollHelper.centerFocus[fn](elem, horiz); + }); +} + +function onSubmit(e) { + loading.show(); + + const instance = this; + const dlg = dom.parentWithClass(e.target, 'dialog'); + const options = instance.options; + + const apiClient = connectionManager.getApiClient(options.serverId); + + const replaceAllMetadata = dlg.querySelector('#selectMetadataRefreshMode').value === 'all'; + + const mode = dlg.querySelector('#selectMetadataRefreshMode').value === 'scan' ? 'Default' : 'FullRefresh'; + const replaceAllImages = mode === 'FullRefresh' && dlg.querySelector('.chkReplaceImages').checked; + + options.itemIds.forEach(function (itemId) { + apiClient.refreshItem(itemId, { + + Recursive: true, + ImageRefreshMode: mode, + MetadataRefreshMode: mode, + ReplaceAllImages: replaceAllImages, + ReplaceAllMetadata: replaceAllMetadata }); - } + }); - function onSubmit(e) { + dialogHelper.close(dlg); - loading.show(); + import('toast').then(({default: toast}) => { + toast(globalize.translate('RefreshQueued')); + }); - var instance = this; - var dlg = dom.parentWithClass(e.target, 'dialog'); - var options = instance.options; + loading.hide(); - var apiClient = connectionManager.getApiClient(options.serverId); + e.preventDefault(); + return false; +} - var replaceAllMetadata = dlg.querySelector('#selectMetadataRefreshMode').value === 'all'; - - var mode = dlg.querySelector('#selectMetadataRefreshMode').value === 'scan' ? 'Default' : 'FullRefresh'; - var replaceAllImages = mode === 'FullRefresh' && dlg.querySelector('.chkReplaceImages').checked; - - options.itemIds.forEach(function (itemId) { - apiClient.refreshItem(itemId, { - - Recursive: true, - ImageRefreshMode: mode, - MetadataRefreshMode: mode, - ReplaceAllImages: replaceAllImages, - ReplaceAllMetadata: replaceAllMetadata - }); - }); - - dialogHelper.close(dlg); - - require(['toast'], function (toast) { - toast(globalize.translate('RefreshQueued')); - }); - - loading.hide(); - - e.preventDefault(); - return false; - } - - function RefreshDialog(options) { +class RefreshDialog { + constructor(options) { this.options = options; } - RefreshDialog.prototype.show = function () { - - var dialogOptions = { + show() { + const dialogOptions = { removeOnClose: true, scrollY: false }; @@ -102,12 +113,12 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionM dialogOptions.size = 'small'; } - var dlg = dialogHelper.createDialog(dialogOptions); + const dlg = dialogHelper.createDialog(dialogOptions); dlg.classList.add('formDialog'); - var html = ''; - var title = globalize.translate('RefreshMetadata'); + let html = ''; + const title = globalize.translate('RefreshMetadata'); html += '
'; html += ''; @@ -124,7 +135,6 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionM dlg.querySelector('form').addEventListener('submit', onSubmit.bind(this)); dlg.querySelector('#selectMetadataRefreshMode').addEventListener('change', function () { - if (this.value === 'scan') { dlg.querySelector('.fldReplaceExistingImages').classList.add('hide'); } else { @@ -139,7 +149,6 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionM dlg.querySelector('#selectMetadataRefreshMode').dispatchEvent(new CustomEvent('change')); dlg.querySelector('.btnCancel').addEventListener('click', function () { - dialogHelper.close(dlg); }); @@ -148,7 +157,6 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionM } return new Promise(function (resolve, reject) { - if (layoutManager.tv) { centerFocus(dlg.querySelector('.formDialogContent'), false, false); } @@ -156,7 +164,7 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionM dlg.addEventListener('close', resolve); dialogHelper.open(dlg); }); - }; + } +} - return RefreshDialog; -}); +export default RefreshDialog; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 874137155c..b5ac4c9a8b 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -1,5 +1,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageLoader', 'playbackManager', 'nowPlayingHelper', 'events', 'connectionManager', 'apphost', 'globalize', 'layoutManager', 'userSettings', 'cardBuilder', 'itemContextMenu', 'cardStyle', 'emby-itemscontainer', 'css!./remotecontrol.css', 'emby-ratingbutton'], function (browser, datetime, backdrop, libraryBrowser, listView, imageLoader, playbackManager, nowPlayingHelper, events, connectionManager, appHost, globalize, layoutManager, userSettings, cardBuilder, itemContextMenu) { 'use strict'; + + playbackManager = playbackManager.default || playbackManager; + var showMuteButton = true; var showVolumeSlider = true; @@ -48,7 +51,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL menuItems.unshift({ id: -1, name: globalize.translate('ButtonOff'), - selected: null == currentIndex + selected: currentIndex == null }); require(['actionsheet'], function (actionsheet) { @@ -69,18 +72,18 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } function seriesImageUrl(item, options) { - if ('Episode' !== item.Type) { + if (item.Type !== 'Episode') { return null; } options = options || {}; options.type = options.type || 'Primary'; - if ('Primary' === options.type && item.SeriesPrimaryImageTag) { + if (options.type === 'Primary' && item.SeriesPrimaryImageTag) { options.tag = item.SeriesPrimaryImageTag; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); } - if ('Thumb' === options.type) { + if (options.type === 'Thumb') { if (item.SeriesThumbImageTag) { options.tag = item.SeriesThumbImageTag; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); @@ -119,9 +122,9 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL var nowPlayingServerId = (item.ServerId || serverId); if (item.Type == 'Audio' || item.MediaStreams[0].Type == 'Audio') { var songName = item.Name; - if (item.Album != null && item.Artists != null) { - var artistsSeries = ''; - var albumName = item.Album; + var artistsSeries = ''; + var albumName = ''; + if (item.Artists != null) { if (item.ArtistItems != null) { for (const artist of item.ArtistItems) { let artistName = artist.Name; @@ -142,9 +145,12 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } } } - context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries; - context.querySelector('.nowPlayingAlbum').innerHTML = '${albumName}`; } + if (item.Album != null) { + albumName = '` + item.Album + ''; + } + context.querySelector('.nowPlayingAlbum').innerHTML = albumName; + context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries; context.querySelector('.nowPlayingSongName').innerHTML = songName; } else if (item.Type == 'Episode') { if (item.SeasonName != null) { @@ -171,9 +177,9 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } var url = item ? seriesImageUrl(item, { - maxHeight: 300 * 2 + maxHeight: 300 }) || imageUrl(item, { - maxHeight: 300 * 2 + maxHeight: 300 }) : null; let contextButton = context.querySelector('.btnToggleContextMenu'); @@ -210,7 +216,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL backdrop.setBackdrops([item]); apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (fullItem) { var userData = fullItem.UserData || {}; - var likes = null == userData.Likes ? '' : userData.Likes; + var likes = userData.Likes == null ? '' : userData.Likes; context.querySelector('.nowPlayingPageUserDataButtonsTitle').innerHTML = ''; context.querySelector('.nowPlayingPageUserDataButtons').innerHTML = ''; }); @@ -222,7 +228,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } function setImageUrl(context, state, url) { - currentImgUrl = url; var item = state.NowPlayingItem; var imgContainer = context.querySelector('.nowPlayingPageImageContainer'); @@ -252,12 +257,11 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL var all = context.querySelectorAll('.btnCommand'); for (var i = 0, length = all.length; i < length; i++) { - var enableButton = -1 !== commands.indexOf(all[i].getAttribute('data-command')); + var enableButton = commands.indexOf(all[i].getAttribute('data-command')) !== -1; all[i].disabled = !enableButton; } } - var currentImgUrl; return function () { function toggleRepeat() { switch (playbackManager.getRepeatMode()) { @@ -280,7 +284,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL currentPlayerSupportedCommands = supportedCommands; var playState = state.PlayState || {}; var isSupportedCommands = supportedCommands.includes('DisplayMessage') || supportedCommands.includes('SendString') || supportedCommands.includes('Select'); - buttonVisible(context.querySelector('.btnToggleFullscreen'), item && 'Video' == item.MediaType && supportedCommands.includes('ToggleFullscreen')); + buttonVisible(context.querySelector('.btnToggleFullscreen'), item && item.MediaType == 'Video' && supportedCommands.includes('ToggleFullscreen')); updateAudioTracksDisplay(player, context); updateSubtitleTracksDisplay(player, context); @@ -308,15 +312,15 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL context.querySelector('.remoteControlSection').classList.add('hide'); } - buttonVisible(context.querySelector('.btnStop'), null != item); - buttonVisible(context.querySelector('.btnNextTrack'), null != item); - buttonVisible(context.querySelector('.btnPreviousTrack'), null != item); + buttonVisible(context.querySelector('.btnStop'), item != null); + buttonVisible(context.querySelector('.btnNextTrack'), item != null); + buttonVisible(context.querySelector('.btnPreviousTrack'), item != null); if (layoutManager.mobile) { buttonVisible(context.querySelector('.btnRewind'), false); buttonVisible(context.querySelector('.btnFastForward'), false); } else { - buttonVisible(context.querySelector('.btnRewind'), null != item); - buttonVisible(context.querySelector('.btnFastForward'), null != item); + buttonVisible(context.querySelector('.btnRewind'), item != null); + buttonVisible(context.querySelector('.btnFastForward'), item != null); } var positionSlider = context.querySelector('.nowPlayingPositionSlider'); @@ -327,15 +331,15 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (positionSlider && !positionSlider.dragging) { positionSlider.disabled = !playState.CanSeek; - var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks; + var isProgressClear = state.MediaSource && state.MediaSource.RunTimeTicks == null; positionSlider.setIsClear(isProgressClear); } - updatePlayPauseState(playState.IsPaused, null != item); + updatePlayPauseState(playState.IsPaused, item != null); updateTimeDisplay(playState.PositionTicks, item ? item.RunTimeTicks : null); updatePlayerVolumeState(context, playState.IsMuted, playState.VolumeLevel); - if (item && 'Video' == item.MediaType) { + if (item && item.MediaType == 'Video') { context.classList.remove('hideVideoButtons'); } else { context.classList.add('hideVideoButtons'); @@ -348,12 +352,12 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function updateAudioTracksDisplay(player, context) { var supportedCommands = currentPlayerSupportedCommands; - buttonVisible(context.querySelector('.btnAudioTracks'), playbackManager.audioTracks(player).length > 1 && -1 != supportedCommands.indexOf('SetAudioStreamIndex')); + buttonVisible(context.querySelector('.btnAudioTracks'), playbackManager.audioTracks(player).length > 1 && supportedCommands.indexOf('SetAudioStreamIndex') != -1); } function updateSubtitleTracksDisplay(player, context) { var supportedCommands = currentPlayerSupportedCommands; - buttonVisible(context.querySelector('.btnSubtitles'), playbackManager.subtitleTracks(player).length && -1 != supportedCommands.indexOf('SetSubtitleStreamIndex')); + buttonVisible(context.querySelector('.btnSubtitles'), playbackManager.subtitleTracks(player).length && supportedCommands.indexOf('SetSubtitleStreamIndex') != -1); } function updateRepeatModeDisplay(repeatMode) { @@ -385,11 +389,11 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL var view = context; var supportedCommands = currentPlayerSupportedCommands; - if (-1 === supportedCommands.indexOf('Mute')) { + if (supportedCommands.indexOf('Mute') === -1) { showMuteButton = false; } - if (-1 === supportedCommands.indexOf('SetVolume')) { + if (supportedCommands.indexOf('SetVolume') === -1) { showVolumeSlider = false; } @@ -420,7 +424,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL var nowPlayingVolumeSliderContainer = context.querySelector('.nowPlayingVolumeSliderContainer'); if (nowPlayingVolumeSlider) { - nowPlayingVolumeSliderContainer.classList.toggle('hide', !showVolumeSlider); if (!nowPlayingVolumeSlider.dragging) { @@ -455,8 +458,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } } - context.querySelector('.positionTime').innerHTML = null == positionTicks ? '--:--' : datetime.getDisplayRunningTime(positionTicks); - context.querySelector('.runtime').innerHTML = null != runtimeTicks ? datetime.getDisplayRunningTime(runtimeTicks) : '--:--'; + context.querySelector('.positionTime').innerHTML = positionTicks == null ? '--:--' : datetime.getDisplayRunningTime(positionTicks); + context.querySelector('.runtime').innerHTML = runtimeTicks != null ? datetime.getDisplayRunningTime(runtimeTicks) : '--:--'; } function getPlaylistItems(player) { @@ -909,7 +912,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } function onShow(context, tab) { - currentImgUrl = null; bindToPlayer(context, playbackManager.getCurrentPlayer()); } diff --git a/src/components/require/requirecss.js b/src/components/require/requirecss.js index 78e5af2a08..8aaa04d689 100644 --- a/src/components/require/requirecss.js +++ b/src/components/require/requirecss.js @@ -18,7 +18,6 @@ define(function () { } function removeFromLoadHistory(url) { - url = url.toLowerCase(); importedCss = importedCss.filter(function (c) { @@ -27,7 +26,6 @@ define(function () { } requireCss.load = function (cssId, req, load, config) { - // Somehow if the url starts with /css, require will get all screwed up since this extension is also called css var srch = 'components/require/requirecss'; var index = cssId.indexOf(srch); @@ -65,7 +63,6 @@ define(function () { window.requireCss = { removeStylesheet: function (stylesheet) { - stylesheet.parentNode.removeChild(stylesheet); removeFromLoadHistory(stylesheet.href); } diff --git a/src/components/require/requiretext.js b/src/components/require/requiretext.js index ac508f95be..8c68daed92 100644 --- a/src/components/require/requiretext.js +++ b/src/components/require/requiretext.js @@ -7,7 +7,6 @@ define(function () { return { load: function (url, req, load, config) { - if (url.indexOf('://') === -1) { url = config.baseUrl + url; } diff --git a/src/components/sanitizeFilename.js b/src/components/sanitizeFilename.js index de7b1a0782..ffea2a0a6c 100644 --- a/src/components/sanitizeFilename.js +++ b/src/components/sanitizeFilename.js @@ -1,3 +1,4 @@ +// TODO: Check if needed and move to external dependency // From https://github.com/parshap/node-sanitize-filename const illegalRe = /[\/\?<>\\:\*\|":]/g; diff --git a/src/components/scrollManager.js b/src/components/scrollManager.js index 3b01cf1ad1..4ee31a6275 100644 --- a/src/components/scrollManager.js +++ b/src/components/scrollManager.js @@ -376,7 +376,6 @@ import layoutManager from 'layoutManager'; * @param {number} scrollY - Vertical coordinate. */ function animateScroll(xScroller, scrollX, yScroller, scrollY) { - const ox = xScroller.scrollLeft; const oy = yScroller.scrollTop; const dx = scrollX - ox; @@ -389,7 +388,6 @@ import layoutManager from 'layoutManager'; let start; function scrollAnim(currentTimestamp) { - start = start || currentTimestamp; let k = Math.min(1, (currentTimestamp - start) / ScrollTime); @@ -423,7 +421,6 @@ import layoutManager from 'layoutManager'; * @param {boolean} smooth - Smooth scrolling. */ function doScroll(xScroller, scrollX, yScroller, scrollY, smooth) { - resetScrollTimer(); if (smooth && useAnimatedScroll()) { @@ -437,7 +434,6 @@ import layoutManager from 'layoutManager'; * Returns true if smooth scroll must be used. */ function useSmoothScroll() { - if (browser.tizen) { return true; } @@ -469,7 +465,6 @@ import layoutManager from 'layoutManager'; * @param {boolean} [smooth=false] - Smooth scrolling. */ export function scrollTo(scrollX, scrollY, smooth) { - smooth = !!smooth; // Scroller is document itself by default @@ -491,7 +486,6 @@ import layoutManager from 'layoutManager'; * @param {boolean} [smooth=false] - Smooth scrolling. */ export function scrollToElement(element, smooth) { - smooth = !!smooth; let scrollCenterX = true; diff --git a/src/components/search/searchfields.js b/src/components/search/searchfields.js index 5cc38eda9a..b3cb3cf4c4 100644 --- a/src/components/search/searchfields.js +++ b/src/components/search/searchfields.js @@ -11,7 +11,6 @@ import 'css!./searchfields'; /* eslint-disable indent */ function onSearchTimeout() { - const instance = this; let value = instance.nextSearchValue; @@ -20,7 +19,6 @@ import 'css!./searchfields'; } function triggerSearch(instance, value) { - if (instance.searchTimeout) { clearTimeout(instance.searchTimeout); } @@ -30,17 +28,14 @@ import 'css!./searchfields'; } function onAlphaValueClicked(e) { - const value = e.detail.value; const searchFieldsInstance = this; const txtSearch = searchFieldsInstance.options.element.querySelector('.searchfields-txtSearch'); if (value === 'backspace') { - const val = txtSearch.value; txtSearch.value = val.length ? val.substring(0, val.length - 1) : ''; - } else { txtSearch.value += value; } @@ -51,7 +46,6 @@ import 'css!./searchfields'; } function initAlphaPicker(alphaPickerElement, instance) { - instance.alphaPicker = new AlphaPicker({ element: alphaPickerElement, mode: 'keyboard' @@ -61,16 +55,13 @@ import 'css!./searchfields'; } function onSearchInput(e) { - const value = e.target.value; const searchFieldsInstance = this; triggerSearch(searchFieldsInstance, value); } function embed(elem, instance, options) { - import('text!./searchfields.template.html').then(({default: template}) => { - let html = globalize.translateHtml(template, 'core'); if (browser.tizen || browser.orsay) { @@ -98,16 +89,13 @@ import 'css!./searchfields'; class SearchFields { constructor(options) { - this.options = options; embed(options.element, this, options); } focus() { - this.options.element.querySelector('.searchfields-txtSearch').focus(); } destroy() { - const options = this.options; if (options) { options.element.classList.remove('searchFields'); diff --git a/src/components/search/searchresults.js b/src/components/search/searchresults.js index e16b6a1cd4..64be0e3e87 100644 --- a/src/components/search/searchresults.js +++ b/src/components/search/searchresults.js @@ -1,7 +1,5 @@ import layoutManager from 'layoutManager'; import globalize from 'globalize'; -import require from 'require'; -import events from 'events'; import connectionManager from 'connectionManager'; import cardBuilder from 'cardBuilder'; import appRouter from 'appRouter'; @@ -12,7 +10,6 @@ import 'emby-button'; /* eslint-disable indent */ function loadSuggestions(instance, context, apiClient) { - const options = { SortBy: 'IsFavoriteOrLiked,Random', @@ -26,20 +23,17 @@ import 'emby-button'; }; apiClient.getItems(apiClient.getCurrentUserId(), options).then(function (result) { - if (instance.mode !== 'suggestions') { result.Items = []; } const html = result.Items.map(function (i) { - const href = appRouter.getRouteUrl(i); let itemHtml = '
'; itemHtml += i.Name; itemHtml += '
'; return itemHtml; - }).join(''); const searchSuggestions = context.querySelector('.searchSuggestions'); @@ -52,7 +46,6 @@ import 'emby-button'; } function getSearchHints(instance, apiClient, query) { - if (!query.searchTerm) { return Promise.resolve({ SearchHints: [] @@ -131,7 +124,6 @@ import 'emby-button'; // Convert the search hint query to a regular item query if (apiClient.isMinServerVersion('3.4.1.31')) { - query.Fields = 'PrimaryImageAspectRatio,CanDelete,BasicSyncInfo,MediaSourceCount'; query.Recursive = true; query.EnableTotalRecordCount = false; @@ -142,7 +134,6 @@ import 'emby-button'; if (!query.IncludeMedia) { if (query.IncludePeople) { methodName = 'getPeople'; - } else if (query.IncludeArtists) { methodName = 'getArtists'; } @@ -157,7 +148,6 @@ import 'emby-button'; } function search(instance, apiClient, context, value) { - if (value || layoutManager.tv) { instance.mode = 'search'; context.querySelector('.searchSuggestions').classList.add('hide'); @@ -167,7 +157,6 @@ import 'emby-button'; } if (instance.options.collectionType === 'livetv') { - searchType(instance, apiClient, { searchTerm: value, IncludePeople: false, @@ -196,7 +185,6 @@ import 'emby-button'; showChannelName: true }); } else { - searchType(instance, apiClient, { searchTerm: value, IncludePeople: false, @@ -233,7 +221,6 @@ import 'emby-button'; }); if (instance.options.collectionType === 'livetv') { - searchType(instance, apiClient, { searchTerm: value, IncludePeople: false, @@ -262,9 +249,7 @@ import 'emby-button'; showAirDateTime: true, showChannelName: true }); - } else { - searchType(instance, apiClient, { searchTerm: value, IncludePeople: false, @@ -562,18 +547,15 @@ import 'emby-button'; } function searchType(instance, apiClient, query, context, section, cardOptions) { - query.Limit = enableScrollX() ? 24 : 16; query.ParentId = instance.options.parentId; getSearchHints(instance, apiClient, query).then(function (result) { - populateResults(result, context, section, cardOptions); }); } function populateResults(result, context, section, cardOptions) { - section = context.querySelector(section); const items = result.Items || result.SearchHints; @@ -603,9 +585,7 @@ import 'emby-button'; } function embed(elem, instance, options) { - import('text!./searchresults.template.html').then(({default: template}) => { - if (!enableScrollX()) { template = replaceAll(template, 'data-horizontal="true"', 'data-horizontal="false"'); template = replaceAll(template, 'itemsContainer scrollSlider', 'itemsContainer scrollSlider vertical-wrap'); @@ -622,24 +602,20 @@ import 'emby-button'; class SearchResults { constructor(options) { - this.options = options; embed(options.element, this, options); } search(value) { - const apiClient = connectionManager.getApiClient(this.options.serverId); search(this, apiClient, this.options.element, value); } destroy() { - const options = this.options; if (options) { options.element.classList.remove('searchFields'); } this.options = null; - } } diff --git a/src/components/shortcuts.js b/src/components/shortcuts.js index f105d6c599..5bd65ae1d9 100644 --- a/src/components/shortcuts.js +++ b/src/components/shortcuts.js @@ -14,7 +14,6 @@ import dom from 'dom'; import recordingHelper from 'recordingHelper'; function playAllFromHere(card, serverId, queue) { - const parent = card.parentNode; const className = card.classList.length ? (`.${card.classList[0]}`) : ''; const cards = parent.querySelectorAll(`${className}[data-id]`); @@ -36,17 +35,14 @@ import recordingHelper from 'recordingHelper'; const itemsContainer = dom.parentWithClass(card, 'itemsContainer'); if (itemsContainer && itemsContainer.fetchData) { - const queryOptions = queue ? { StartIndex: startIndex } : {}; return itemsContainer.fetchData(queryOptions).then(result => { - if (queue) { return playbackManager.queue({ items: result.Items }); } else { - return playbackManager.play({ items: result.Items, startIndex: startIndex @@ -65,7 +61,6 @@ import recordingHelper from 'recordingHelper'; serverId: serverId }); } else { - return playbackManager.play({ ids: ids, serverId: serverId, @@ -75,15 +70,12 @@ import recordingHelper from 'recordingHelper'; } function showProgramDialog(item) { - import('recordingCreator').then(({default:recordingCreator}) => { - recordingCreator.show(item.Id, item.ServerId); }); } function getItem(button) { - button = dom.parentWithAttribute(button, 'data-id'); const serverId = button.getAttribute('data-serverid'); const id = button.getAttribute('data-id'); @@ -101,7 +93,6 @@ import recordingHelper from 'recordingHelper'; } function notifyRefreshNeeded(childElement, itemsContainer) { - itemsContainer = itemsContainer || dom.parentWithAttribute(childElement, 'is', 'emby-itemscontainer'); if (itemsContainer) { @@ -110,9 +101,7 @@ import recordingHelper from 'recordingHelper'; } function showContextMenu(card, options) { - getItem(card).then(item => { - const playlistId = card.getAttribute('data-playlistid'); const collectionId = card.getAttribute('data-collectionid'); @@ -122,7 +111,6 @@ import recordingHelper from 'recordingHelper'; } import('itemContextMenu').then(({default: itemContextMenu}) => { - connectionManager.getApiClient(item.ServerId).getCurrentUser().then(user => { itemContextMenu.show(Object.assign({ item: item, @@ -135,7 +123,6 @@ import recordingHelper from 'recordingHelper'; user: user }, options || {})).then(result => { - if (result.command === 'playallfromhere' || result.command === 'queueallfromhere') { executeAction(card, options.positionTo, result.command); } else if (result.updated || result.deleted) { @@ -148,7 +135,6 @@ import recordingHelper from 'recordingHelper'; } function getItemInfoFromCard(card) { - return { Type: card.getAttribute('data-type'), Id: card.getAttribute('data-id'), @@ -166,11 +152,9 @@ import recordingHelper from 'recordingHelper'; } function showPlayMenu(card, target) { - const item = getItemInfoFromCard(card); import('playMenu').then(({default: playMenu}) => { - playMenu.show({ item: item, @@ -186,7 +170,6 @@ import recordingHelper from 'recordingHelper'; } function executeAction(card, target, action) { - target = target || card; let id = card.getAttribute('data-id'); @@ -208,13 +191,11 @@ import recordingHelper from 'recordingHelper'; } if (action === 'link') { - appRouter.showItem(item, { context: card.getAttribute('data-context'), parentId: card.getAttribute('data-parentid') }); } else if (action === 'programdialog') { - showProgramDialog(item); } else if (action === 'instantmix') { playbackManager.instantMix({ @@ -222,7 +203,6 @@ import recordingHelper from 'recordingHelper'; ServerId: serverId }); } else if (action === 'play' || action === 'resume') { - const startPositionTicks = parseInt(card.getAttribute('data-positionticks') || '0'); playbackManager.play({ @@ -231,7 +211,6 @@ import recordingHelper from 'recordingHelper'; serverId: serverId }); } else if (action === 'queue') { - if (playbackManager.isPlaying()) { playbackManager.queue({ ids: [playableItemId], @@ -253,7 +232,6 @@ import recordingHelper from 'recordingHelper'; } else if (action === 'record') { onRecordCommand(serverId, id, type, card.getAttribute('data-timerid'), card.getAttribute('data-seriestimerid')); } else if (action === 'menu') { - const options = target.getAttribute('data-playoptions') === 'false' ? { shuffle: false, @@ -279,7 +257,6 @@ import recordingHelper from 'recordingHelper'; } else if (action === 'addtoplaylist') { getItem(target).then(addToPlaylist); } else if (action === 'custom') { - const customAction = target.getAttribute('data-customaction'); card.dispatchEvent(new CustomEvent(`action-${customAction}`, { @@ -294,7 +271,6 @@ import recordingHelper from 'recordingHelper'; function addToPlaylist(item) { import('playlistEditor').then(({default: playlistEditor}) => { - new playlistEditor().show({ items: [item.Id], serverId: item.ServerId @@ -304,7 +280,6 @@ import recordingHelper from 'recordingHelper'; } function playTrailer(item) { - const apiClient = connectionManager.getApiClient(item.ServerId); apiClient.getLocalTrailers(apiClient.getCurrentUserId(), item.Id).then(trailers => { @@ -313,28 +288,23 @@ import recordingHelper from 'recordingHelper'; } function editItem(item, serverId) { - const apiClient = connectionManager.getApiClient(serverId); return new Promise((resolve, reject) => { - const serverId = apiClient.serverInfo().Id; if (item.Type === 'Timer') { if (item.ProgramId) { import('recordingCreator').then(({default: recordingCreator}) => { - recordingCreator.show(item.ProgramId, serverId).then(resolve, reject); }); } else { import('recordingEditor').then(({default: recordingEditor}) => { - recordingEditor.show(item.Id, serverId).then(resolve, reject); }); } } else { import('metadataEditor').then(({default: metadataEditor}) => { - metadataEditor.show(item.Id, serverId).then(resolve, reject); }); } @@ -342,20 +312,16 @@ import recordingHelper from 'recordingHelper'; } function onRecordCommand(serverId, id, type, timerId, seriesTimerId) { - if (type === 'Program' || timerId || seriesTimerId) { - const programId = type === 'Program' ? id : null; recordingHelper.toggleRecording(serverId, programId, timerId, seriesTimerId); } } export function onClick(e) { - const card = dom.parentWithClass(e.target, 'itemAction'); if (card) { - let actionElement = card; let action = actionElement.getAttribute('data-action'); @@ -377,11 +343,9 @@ import recordingHelper from 'recordingHelper'; } function onCommand(e) { - const cmd = e.detail.command; if (cmd === 'play' || cmd === 'resume' || cmd === 'record' || cmd === 'menu' || cmd === 'info') { - const target = e.target; const card = dom.parentWithClass(target, 'itemAction') || dom.parentWithAttribute(target, 'data-id'); @@ -394,7 +358,6 @@ import recordingHelper from 'recordingHelper'; } export function on(context, options) { - options = options || {}; if (options.click !== false) { @@ -417,7 +380,6 @@ import recordingHelper from 'recordingHelper'; } export function getShortcutAttributesHtml(item, serverId) { - let html = `data-id="${item.Id}" data-serverid="${serverId || item.ServerId}" data-type="${item.Type}" data-mediatype="${item.MediaType}" data-channelid="${item.ChannelId}" data-isfolder="${item.IsFolder}"`; const collectionType = item.CollectionType; diff --git a/src/components/skinManager.js b/src/components/skinManager.js deleted file mode 100644 index faa1a1f306..0000000000 --- a/src/components/skinManager.js +++ /dev/null @@ -1,184 +0,0 @@ -define(['apphost', 'userSettings', 'browser', 'events', 'backdrop', 'globalize', 'require', 'appSettings'], function (appHost, userSettings, browser, events, backdrop, globalize, require, appSettings) { - 'use strict'; - - var themeStyleElement; - var currentThemeId; - - function unloadTheme() { - var elem = themeStyleElement; - if (elem) { - elem.parentNode.removeChild(elem); - themeStyleElement = null; - currentThemeId = null; - } - } - - function loadUserSkin(options) { - options = options || {}; - if (options.start) { - Emby.Page.invokeShortcut(options.start); - } else { - Emby.Page.goHome(); - } - } - - function getThemes() { - return [{ - name: 'Apple TV', - id: 'appletv' - }, { - name: 'Blue Radiance', - id: 'blueradiance' - }, { - name: 'Dark', - id: 'dark', - isDefault: true, - isDefaultServerDashboard: true - }, { - name: 'Light', - id: 'light' - }, { - name: 'Purple Haze', - id: 'purplehaze' - }, { - name: 'Windows Media Center', - id: 'wmc' - }]; - } - - var skinManager = { - getThemes: getThemes, - loadUserSkin: loadUserSkin - }; - - function getThemeStylesheetInfo(id, isDefaultProperty) { - var themes = skinManager.getThemes(); - var defaultTheme; - var selectedTheme; - - for (var i = 0, length = themes.length; i < length; i++) { - var theme = themes[i]; - if (theme[isDefaultProperty]) { - defaultTheme = theme; - } - if (id === theme.id) { - selectedTheme = theme; - } - } - - selectedTheme = selectedTheme || defaultTheme; - return { - stylesheetPath: require.toUrl('themes/' + selectedTheme.id + '/theme.css'), - themeId: selectedTheme.id - }; - } - - var themeResources = {}; - var lastSound = 0; - var currentSound; - - function loadThemeResources(id) { - lastSound = 0; - if (currentSound) { - currentSound.stop(); - currentSound = null; - } - - backdrop.clearBackdrop(); - } - - function onThemeLoaded() { - document.documentElement.classList.remove('preload'); - try { - var color = getComputedStyle(document.querySelector('.skinHeader')).getPropertyValue('background-color'); - if (color) { - appHost.setThemeColor(color); - } - } catch (err) { - console.error('error setting theme color: ' + err); - } - } - - skinManager.setTheme = function (id, context) { - return new Promise(function (resolve, reject) { - if (currentThemeId && currentThemeId === id) { - resolve(); - return; - } - - var isDefaultProperty = context === 'serverdashboard' ? 'isDefaultServerDashboard' : 'isDefault'; - var info = getThemeStylesheetInfo(id, isDefaultProperty); - if (currentThemeId && currentThemeId === info.themeId) { - resolve(); - return; - } - - var linkUrl = info.stylesheetPath; - unloadTheme(); - - var link = document.createElement('link'); - link.setAttribute('rel', 'stylesheet'); - link.setAttribute('type', 'text/css'); - link.onload = function () { - onThemeLoaded(); - resolve(); - }; - - link.setAttribute('href', linkUrl); - document.head.appendChild(link); - themeStyleElement = link; - currentThemeId = info.themeId; - loadThemeResources(info.themeId); - - onViewBeforeShow({}); - }); - }; - - function onViewBeforeShow(e) { - if (e.detail && e.detail.type === 'video-osd') { - // This removes the space that the scrollbar takes while playing a video - document.body.classList.remove('force-scroll'); - return; - } - - if (themeResources.backdrop) { - backdrop.setBackdrop(themeResources.backdrop); - } - - if (!browser.mobile && userSettings.enableThemeSongs()) { - if (lastSound === 0) { - if (themeResources.themeSong) { - playSound(themeResources.themeSong); - } - } else if ((new Date().getTime() - lastSound) > 30000) { - if (themeResources.effect) { - playSound(themeResources.effect); - } - } - } - // This keeps the scrollbar always present in all pages, so we avoid clipping while switching between pages - // that need the scrollbar and pages that don't. - document.body.classList.add('force-scroll'); - } - - document.addEventListener('viewshow', onViewBeforeShow); - - function playSound(path, volume) { - lastSound = new Date().getTime(); - require(['howler'], function (howler) { - /* globals Howl */ - try { - var sound = new Howl({ - src: [path], - volume: volume || 0.1 - }); - sound.play(); - currentSound = sound; - } catch (err) { - console.error('error playing sound: ' + err); - } - }); - } - - return skinManager; -}); diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index f7026a007e..60c458e234 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -5,6 +5,8 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'focusManager', 'browser', 'apphost', 'dom', 'css!./style', 'material-icons', 'paper-icon-button-light'], function (dialogHelper, inputManager, connectionManager, layoutManager, focusManager, browser, appHost, dom) { 'use strict'; + browser = browser.default || browser; + /** * Name of transition event. */ @@ -38,7 +40,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f if (options.type === 'Primary') { if (item.AlbumId && item.AlbumPrimaryImageTag) { - options.tag = item.AlbumPrimaryImageTag; return apiClient.getScaledImageUrl(item.AlbumId, options); } @@ -64,7 +65,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f } if (item.BackdropImageTags && item.BackdropImageTags.length) { - options.tag = item.BackdropImageTags[0]; return apiClient.getScaledImageUrl(item.Id, options); } @@ -130,11 +130,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f var hideTimeout; /** Last coordinates of the mouse pointer. */ var lastMouseMoveData; - /** Visibility status of the OSD. */ - var _osdOpen = false; - - // Use autoplay on Chromecast since it is non-interactive. - if (browser.chromecast) options.interactive = false; /** * Creates the HTML markup for the dialog and the OSD. @@ -189,7 +184,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f html += '
'; } - } else { html += '

'; } @@ -363,8 +357,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f function getSwiperSlideHtmlFromItem(item) { return getSwiperSlideHtmlFromSlide({ originalImage: getImgUrl(item, currentOptions.user), - //title: item.Name, - //description: item.Overview Id: item.Id, ServerId: item.ServerId }); @@ -545,7 +537,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f return; } - _osdOpen = true; element.classList.remove('hide'); var onFinish = function () { @@ -578,7 +569,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f var onFinish = function () { element.classList.add('hide'); - _osdOpen = false; }; if (!element.animate) { diff --git a/src/components/sortmenu/sortmenu.js b/src/components/sortmenu/sortmenu.js index dbf7ef1a7f..f62e5bb3a4 100644 --- a/src/components/sortmenu/sortmenu.js +++ b/src/components/sortmenu/sortmenu.js @@ -2,13 +2,11 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana 'use strict'; function onSubmit(e) { - e.preventDefault(); return false; } function initEditor(context, settings) { - context.querySelector('form').addEventListener('submit', onSubmit); context.querySelector('.selectSortOrder').value = settings.sortOrder; @@ -26,14 +24,11 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana var selectSortBy = context.querySelector('.selectSortBy'); selectSortBy.innerHTML = options.map(function (o) { - return ''; - }).join(''); } function saveValues(context, settings, settingsKey) { - userSettings.setFilter(settingsKey + '-sortorder', context.querySelector('.selectSortOrder').value); userSettings.setFilter(settingsKey + '-sortby', context.querySelector('.selectSortBy').value); } @@ -43,11 +38,8 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana } SortMenu.prototype.show = function (options) { - return new Promise(function (resolve, reject) { - require(['text!./sortmenu.template.html'], function (template) { - var dialogOptions = { removeOnClose: true, scrollY: false @@ -79,7 +71,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana initEditor(dlg, options.settings); dlg.querySelector('.btnCancel').addEventListener('click', function () { - dialogHelper.close(dlg); }); @@ -90,27 +81,17 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana var submitted; dlg.querySelector('form').addEventListener('change', function () { - submitted = true; - //if (options.onChange) { - // saveValues(dlg, options.settings, options.settingsKey); - // options.onChange(); - //} - }, true); dialogHelper.open(dlg).then(function () { - if (layoutManager.tv) { centerFocus(dlg.querySelector('.formDialogContent'), false, false); } if (submitted) { - - //if (!options.onChange) { saveValues(dlg, options.settings, options.settingsKey); resolve(); - //} return; } diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js index 9c0992c53c..7df24b5da8 100644 --- a/src/components/subtitleeditor/subtitleeditor.js +++ b/src/components/subtitleeditor/subtitleeditor.js @@ -1,48 +1,12 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', 'connectionManager', 'loading', 'focusManager', 'dom', 'apphost', 'emby-select', 'listViewStyle', 'paper-icon-button-light', 'css!./../formdialog', 'material-icons', 'css!./subtitleeditor', 'emby-button', 'flexStyles'], function (dialogHelper, require, layoutManager, globalize, userSettings, connectionManager, loading, focusManager, dom, appHost) { 'use strict'; + loading = loading.default || loading; + var currentItem; var hasChanges; - function showLocalSubtitles(context, index) { - - loading.show(); - - var subtitleContent = context.querySelector('.subtitleContent'); - subtitleContent.innerHTML = ''; - - var apiClient = connectionManager.getApiClient(currentItem.ServerId); - var url = 'Videos/' + currentItem.Id + '/Subtitles/' + index; - - apiClient.ajax({ - - type: 'GET', - url: url - - }).then(function (result) { - - subtitleContent.innerHTML = result; - - loading.hide(); - }); - } - - function showRemoteSubtitles(context, id) { - - loading.show(); - - var url = 'Providers/Subtitles/Subtitles/' + id; - - ApiClient.get(ApiClient.getUrl(url)).then(function (result) { - - // show result - - loading.hide(); - }); - } - function downloadRemoteSubtitles(context, id) { - var url = 'Items/' + currentItem.Id + '/RemoteSearch/Subtitles/' + id; var apiClient = connectionManager.getApiClient(currentItem.ServerId); @@ -52,7 +16,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', url: apiClient.getUrl(url) }).then(function () { - hasChanges = true; require(['toast'], function (toast) { @@ -64,11 +27,9 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', } function deleteLocalSubtitle(context, index) { - var msg = globalize.translate('MessageAreYouSureDeleteSubtitles'); require(['confirm'], function (confirm) { - confirm.default({ title: globalize.translate('ConfirmDeletion'), @@ -77,7 +38,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', primary: 'delete' }).then(function () { - loading.show(); var itemId = currentItem.Id; @@ -91,34 +51,28 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', url: apiClient.getUrl(url) }).then(function () { - hasChanges = true; reload(context, apiClient, itemId); - }); }); }); } function fillSubtitleList(context, item) { - var streams = item.MediaStreams || []; var subs = streams.filter(function (s) { - return s.Type === 'Subtitle'; }); var html = ''; if (subs.length) { - html += '

' + globalize.translate('MySubtitles') + '

'; html += '
'; html += subs.map(function (s) { - var itemHtml = ''; var tagName = layoutManager.tv ? 'button' : 'div'; @@ -156,7 +110,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', itemHtml += ''; return itemHtml; - }).join(''); html += '
'; @@ -170,22 +123,12 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', elem.classList.add('hide'); } elem.innerHTML = html; - - //('.btnViewSubtitles', elem).on('click', function () { - - // var index = this.getAttribute('data-index'); - - // showLocalSubtitles(context, index); - - //}); } function fillLanguages(context, apiClient, languages) { - var selectLanguage = context.querySelector('#selectLanguage'); selectLanguage.innerHTML = languages.map(function (l) { - return ''; }); @@ -193,9 +136,7 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', if (lastLanguage) { selectLanguage.value = lastLanguage; } else { - apiClient.getCurrentUser().then(function (user) { - var lang = user.Configuration.SubtitleLanguagePreference; if (lang) { @@ -206,12 +147,10 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', } function renderSearchResults(context, results) { - var lastProvider = ''; var html = ''; if (!results.length) { - context.querySelector('.noSearchResults').classList.remove('hide'); context.querySelector('.subtitleResults').innerHTML = ''; loading.hide(); @@ -221,13 +160,11 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', context.querySelector('.noSearchResults').classList.add('hide'); for (var i = 0, length = results.length; i < length; i++) { - var result = results[i]; var provider = result.ProviderName; if (provider !== lastProvider) { - if (i > 0) { html += ''; } @@ -250,8 +187,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', html += '
'; - //html += ''; - html += '
' + (result.Name) + '
'; html += '
'; if (!layoutManager.tv) { @@ -290,17 +223,10 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', var elem = context.querySelector('.subtitleResults'); elem.innerHTML = html; - //('.btnViewSubtitle', elem).on('click', function () { - - // var id = this.getAttribute('data-subid'); - // showRemoteSubtitles(context, id); - //}); - loading.hide(); } function searchForSubtitles(context, language) { - userSettings.set('subtitleeditor-language', language); loading.show(); @@ -309,17 +235,14 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', var url = apiClient.getUrl('Items/' + currentItem.Id + '/RemoteSearch/Subtitles/' + language); apiClient.getJSON(url).then(function (results) { - renderSearchResults(context, results); }); } function reload(context, apiClient, itemId) { - context.querySelector('.noSearchResults').classList.add('hide'); function onGetItem(item) { - currentItem = item; fillSubtitleList(context, item); @@ -359,7 +282,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', } function onSubtitleListClick(e) { - var btnDelete = dom.parentWithClass(e.target, 'btnDelete'); if (btnDelete) { var index = btnDelete.getAttribute('data-index'); @@ -369,11 +291,10 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', } function onSubtitleResultsClick(e) { - - var btnOptions = dom.parentWithClass(e.target, 'btnOptions'); var subtitleId; var context; + var btnOptions = dom.parentWithClass(e.target, 'btnOptions'); if (btnOptions) { subtitleId = btnOptions.getAttribute('data-subid'); context = dom.parentWithClass(btnOptions, 'subtitleEditorDialog'); @@ -389,7 +310,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', } function showDownloadOptions(button, context, subtitleId) { - var items = []; items.push({ @@ -398,15 +318,12 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', }); require(['actionsheet'], function (actionsheet) { - actionsheet.show({ items: items, positionTo: button }).then(function (id) { - switch (id) { - case 'download': downloadRemoteSubtitles(context, subtitleId); break; @@ -414,7 +331,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', break; } }); - }); } @@ -426,12 +342,10 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', } function showEditorInternal(itemId, serverId, template) { - hasChanges = false; var apiClient = connectionManager.getApiClient(serverId); return apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) { - var dialogOptions = { removeOnClose: true, scrollY: false @@ -469,19 +383,15 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', dlg.querySelector('.subtitleResults').addEventListener('click', onSubtitleResultsClick); apiClient.getCultures().then(function (languages) { - fillLanguages(editorContent, apiClient, languages); }); dlg.querySelector('.btnCancel').addEventListener('click', function () { - dialogHelper.close(dlg); }); return new Promise(function (resolve, reject) { - dlg.addEventListener('close', function () { - if (layoutManager.tv) { centerFocus(dlg.querySelector('.formDialogContent'), false, false); } @@ -501,17 +411,13 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', } function showEditor(itemId, serverId) { - loading.show(); return new Promise(function (resolve, reject) { - require(['text!./subtitleeditor.template.html'], function (template) { - showEditorInternal(itemId, serverId, template).then(resolve, reject); }); }); - } return { diff --git a/src/components/subtitlesettings/subtitleappearancehelper.js b/src/components/subtitlesettings/subtitleappearancehelper.js index f710751376..7e3e2de7ac 100644 --- a/src/components/subtitlesettings/subtitleappearancehelper.js +++ b/src/components/subtitlesettings/subtitleappearancehelper.js @@ -4,12 +4,10 @@ */ function getTextStyles(settings, isCue) { - let list = []; if (isCue) { switch (settings.textSize || '') { - case 'smaller': list.push({ name: 'font-size', value: '.5em' }); break; @@ -31,7 +29,6 @@ function getTextStyles(settings, isCue) { } } else { switch (settings.textSize || '') { - case 'smaller': list.push({ name: 'font-size', value: '.8em' }); break; @@ -55,7 +52,6 @@ function getTextStyles(settings, isCue) { } switch (settings.dropShadow || '') { - case 'raised': list.push({ name: 'text-shadow', value: '-1px -1px white, 0px -1px white, -1px 0px white, 1px 1px black, 0px 1px black, 1px 0px black' }); break; @@ -85,7 +81,6 @@ function getTextStyles(settings, isCue) { } switch (settings.font || '') { - case 'typewriter': list.push({ name: 'font-family', value: '"Courier New",monospace' }); list.push({ name: 'font-variant', value: 'none' }); @@ -120,7 +115,6 @@ function getTextStyles(settings, isCue) { } export function getStyles(settings, isCue) { - return { text: getTextStyles(settings, isCue), window: [] @@ -128,9 +122,7 @@ export function getStyles(settings, isCue) { } function applyStyleList(styles, elem) { - for (let i = 0, length = styles.length; i < length; i++) { - let style = styles[i]; elem.style[style.name] = style.value; @@ -138,7 +130,6 @@ function applyStyleList(styles, elem) { } export function applyStyles(elements, appearanceSettings) { - let styles = getStyles(appearanceSettings); if (elements.text) { diff --git a/src/components/subtitlesettings/subtitlesettings.js b/src/components/subtitlesettings/subtitlesettings.js index d2ae852bd5..79fa289ab0 100644 --- a/src/components/subtitlesettings/subtitlesettings.js +++ b/src/components/subtitlesettings/subtitlesettings.js @@ -1,4 +1,3 @@ -import require from 'require'; import globalize from 'globalize'; import appHost from 'apphost'; import appSettings from 'appSettings'; @@ -33,9 +32,7 @@ function getSubtitleAppearanceObject(context) { } function loadForm(context, user, userSettings, appearanceSettings, apiClient) { - apiClient.getCultures().then(function (allCultures) { - if (appHost.supports('subtitleburnsettings') && user.Policy.EnableVideoPlaybackTranscoding) { context.querySelector('.fldBurnIn').classList.remove('hide'); } @@ -66,7 +63,6 @@ function loadForm(context, user, userSettings, appearanceSettings, apiClient) { } function saveUser(context, user, userSettingsInstance, appearanceKey, apiClient) { - let appearanceSettings = userSettingsInstance.getSubtitleAppearanceSettings(appearanceKey); appearanceSettings = Object.assign(appearanceSettings, getSubtitleAppearanceObject(context)); @@ -79,15 +75,12 @@ function saveUser(context, user, userSettingsInstance, appearanceKey, apiClient) } function save(instance, context, userId, userSettings, apiClient, enableSaveConfirmation) { - loading.show(); appSettings.set('subtitleburnin', context.querySelector('#selectSubtitleBurnIn').value); apiClient.getUser(userId).then(function (user) { - saveUser(context, user, userSettings, instance.appearanceKey, apiClient).then(function () { - loading.hide(); if (enableSaveConfirmation) { import('toast').then(({default: toast}) => { @@ -96,7 +89,6 @@ function save(instance, context, userId, userSettings, apiClient, enableSaveConf } events.trigger(instance, 'saved'); - }, function () { loading.hide(); }); @@ -104,7 +96,6 @@ function save(instance, context, userId, userSettings, apiClient, enableSaveConf } function onSubtitleModeChange(e) { - let view = dom.parentWithClass(e.target, 'subtitlesettings'); let subtitlesHelp = view.querySelectorAll('.subtitlesHelp'); @@ -115,7 +106,6 @@ function onSubtitleModeChange(e) { } function onAppearanceFieldChange(e) { - let view = dom.parentWithClass(e.target, 'subtitlesettings'); let appearanceSettings = getSubtitleAppearanceObject(view); @@ -129,9 +119,7 @@ function onAppearanceFieldChange(e) { } function embed(options, self) { - import('text!./subtitlesettings.template.html').then(({default: template}) => { - options.element.classList.add('subtitlesettings'); options.element.innerHTML = globalize.translateHtml(template, 'core'); @@ -161,9 +149,7 @@ function embed(options, self) { } export class SubtitleSettings { - constructor(options) { - this.options = options; embed(options, this); @@ -205,7 +191,6 @@ export class SubtitleSettings { let userSettings = self.options.userSettings; userSettings.setUserInfo(userId, apiClient).then(function () { - let enableSaveConfirmation = self.options.enableSaveConfirmation; save(self, self.options.element, userId, userSettings, apiClient, enableSaveConfirmation); }); diff --git a/src/components/subtitlesync/subtitlesync.js b/src/components/subtitlesync/subtitlesync.js index a3e60593e8..203d88535f 100644 --- a/src/components/subtitlesync/subtitlesync.js +++ b/src/components/subtitlesync/subtitlesync.js @@ -1,6 +1,8 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html', 'css!./subtitlesync'], function (playbackManager, layoutManager, template, css) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + var player; var subtitleSyncSlider; var subtitleSyncTextField; @@ -8,7 +10,6 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html', var subtitleSyncContainer; function init(instance) { - var parent = document.createElement('div'); document.body.appendChild(parent); parent.innerHTML = template; @@ -141,7 +142,6 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html', }; SubtitleSync.prototype.toggle = function(action) { - if (player && playbackManager.supportSubtitleOffset(player)) { /* eslint-disable no-fallthrough */ switch (action) { diff --git a/src/components/syncPlay/playbackPermissionManager.js b/src/components/syncPlay/playbackPermissionManager.js index 3c258ad18d..e2d7ef2f4c 100644 --- a/src/components/syncPlay/playbackPermissionManager.js +++ b/src/components/syncPlay/playbackPermissionManager.js @@ -3,7 +3,6 @@ * @returns {HTMLMediaElement} The audio element. */ function createTestMediaElement () { - const elem = document.createElement('audio'); elem.classList.add('testMediaPlayerAudio'); elem.classList.add('hide'); diff --git a/src/components/syncPlay/syncPlayManager.js b/src/components/syncPlay/syncPlayManager.js index c8660b2bc4..2366172a79 100644 --- a/src/components/syncPlay/syncPlayManager.js +++ b/src/components/syncPlay/syncPlayManager.js @@ -554,7 +554,6 @@ class SyncPlayManager { this.syncTimeout = setTimeout(() => { this.syncEnabled = true; }, SyncMethodThreshold / 2); - }, playTimeout); console.debug('Scheduled play in', playTimeout / 1000.0, 'seconds.'); diff --git a/src/components/syncPlay/timeSyncManager.js b/src/components/syncPlay/timeSyncManager.js index d3b59589ee..e219fb0413 100644 --- a/src/components/syncPlay/timeSyncManager.js +++ b/src/components/syncPlay/timeSyncManager.js @@ -140,7 +140,6 @@ class TimeSyncManager { }).finally(() => { this.requestPing(); }); - }, this.pollingInterval); } } diff --git a/src/components/tabbedview/itemstab.js b/src/components/tabbedview/itemstab.js deleted file mode 100644 index d40faef5dc..0000000000 --- a/src/components/tabbedview/itemstab.js +++ /dev/null @@ -1,589 +0,0 @@ -define(['playbackManager', 'userSettings', 'alphaPicker', 'alphaNumericShortcuts', 'connectionManager', 'focusManager', 'loading', 'globalize'], function (playbackManager, userSettings, AlphaPicker, AlphaNumericShortcuts, connectionManager, focusManager, loading, globalize) { - 'use strict'; - - function trySelectValue(instance, scroller, view, value) { - - var card; - - // If it's the symbol just pick the first card - if (value === '#') { - - card = view.querySelector('.card'); - - if (card) { - scroller.toStart(card, false); - return; - } - } - - card = view.querySelector('.card[data-prefix^=\'' + value + '\']'); - - if (card) { - scroller.toStart(card, false); - return; - } - - // go to the previous letter - var values = instance.alphaPicker.values(); - var index = values.indexOf(value); - - if (index < values.length - 2) { - trySelectValue(instance, scroller, view, values[index + 1]); - } else { - var all = view.querySelectorAll('.card'); - card = all.length ? all[all.length - 1] : null; - - if (card) { - scroller.toStart(card, false); - } - } - } - - function onAlphaValueChanged() { - - var value = this.alphaPicker.value(); - var scroller = this.scroller; - - trySelectValue(this, scroller, this.itemsContainer, value); - } - - function initAlphaPicker(instance, view) { - - instance.itemsContainer = view.querySelector('.itemsContainer'); - - instance.alphaPicker = new AlphaPicker.default({ - element: instance.alphaPickerElement, - itemsContainer: instance.itemsContainer, - itemClass: 'card' - }); - - instance.alphaPicker.on('alphavaluechanged', onAlphaValueChanged.bind(instance)); - } - - function showFilterMenu() { - - var instance = this; - - require(['filterMenu'], function (FilterMenu) { - - new FilterMenu().show({ - - settingsKey: instance.getSettingsKey(), - settings: instance.getFilters(), - visibleSettings: instance.getVisibleFilters(), - onChange: instance.itemsContainer.refreshItems.bind(instance.itemsContainer), - parentId: instance.params.parentId, - itemTypes: instance.getItemTypes ? instance.getItemTypes() : [], - serverId: instance.apiClient.serverId(), - filterMenuOptions: instance.getFilterMenuOptions() - - }).then(function () { - - instance.itemsContainer.refreshItems(); - }); - }); - } - - function updateAlphaPickerState(instance) { - - if (!instance.alphaPicker) { - return; - } - - var alphaPicker = instance.alphaPickerElement; - if (!alphaPicker) { - return; - } - var values = instance.getSortValues(); - - if (values.sortBy === 'SortName' && values.sortOrder === 'Ascending') { - alphaPicker.classList.remove('hide'); - } else { - alphaPicker.classList.add('hide'); - } - } - - function showSortMenu() { - var instance = this; - require(['sortMenu'], function (SortMenu) { - new SortMenu().show({ - settingsKey: instance.getSettingsKey(), - settings: instance.getSortValues(), - onChange: instance.itemsContainer.refreshItems.bind(instance.itemsContainer), - serverId: instance.params.serverId, - sortOptions: instance.getSortMenuOptions() - }).then(function () { - updateSortText(instance); - updateAlphaPickerState(instance); - instance.itemsContainer.refreshItems(); - }); - }); - } - - function showViewSettingsMenu() { - - var instance = this; - - require(['viewSettings'], function (ViewSettings) { - - new ViewSettings().show({ - - settingsKey: instance.getSettingsKey(), - settings: instance.getViewSettings(), - visibleSettings: instance.getVisibleViewSettings() - - }).then(function () { - - updateItemsContainerForViewType(instance); - instance.itemsContainer.refreshItems(); - }); - }); - } - - function updateItemsContainerForViewType(instance) { - - var settings = instance.getViewSettings(); - - if (settings.imageType === 'list') { - - instance.itemsContainer.classList.remove('vertical-wrap'); - instance.itemsContainer.classList.add('vertical-list'); - - } else { - instance.itemsContainer.classList.add('vertical-wrap'); - instance.itemsContainer.classList.remove('vertical-list'); - } - } - - function updateSortText(instance) { - - var btnSortText = instance.btnSortText; - if (!btnSortText) { - return; - } - - var options = instance.getSortMenuOptions(); - var values = instance.getSortValues(); - - var sortBy = values.sortBy; - - for (var i = 0, length = options.length; i < length; i++) { - - if (sortBy === options[i].value) { - - btnSortText.innerHTML = globalize.translate('SortByValue', options[i].name); - break; - } - } - - var btnSortIcon = instance.btnSortIcon; - if (!btnSortIcon) { - return; - } - - btnSortIcon.classList.remove('arrow_downward', 'arrow_upward'); - btnSortIcon.classList.add(values.sortOrder === 'Descending' ? 'arrow_downward' : 'arrow_upward'); - } - - function bindAll(elems, eventName, fn) { - for (var i = 0, length = elems.length; i < length; i++) { - - elems[i].addEventListener(eventName, fn); - } - } - - function play() { - - this.fetchData().then(function (result) { - playbackManager.play({ - items: result.Items || result - }); - }); - } - - function shuffle() { - - this.fetchData().then(function (result) { - playbackManager.play({ - items: result.Items || result - }); - }); - } - - function hideOrShowAll(elems, hide) { - - for (var i = 0, length = elems.length; i < length; i++) { - - if (hide) { - elems[i].classList.add('hide'); - } else { - elems[i].classList.remove('hide'); - } - } - } - - function ItemsTab(view, params) { - this.view = view; - this.params = params; - - if (params.serverId) { - this.apiClient = connectionManager.getApiClient(params.serverId); - } - - this.itemsContainer = view.querySelector('.itemsContainer'); - this.scroller = view.querySelector('.scrollFrameY'); - - this.itemsContainer.fetchData = this.fetchData.bind(this); - this.itemsContainer.getItemsHtml = this.getItemsHtml.bind(this); - - if (params.parentId) { - this.itemsContainer.setAttribute('data-parentid', params.parentId); - } - - var i; - var length; - - var btnViewSettings = view.querySelectorAll('.btnViewSettings'); - for (i = 0, length = btnViewSettings.length; i < length; i++) { - - btnViewSettings[i].addEventListener('click', showViewSettingsMenu.bind(this)); - } - - var filterButtons = view.querySelectorAll('.btnFilter'); - this.filterButtons = filterButtons; - var hasVisibleFilters = this.getVisibleFilters().length; - for (i = 0, length = filterButtons.length; i < length; i++) { - - var btnFilter = filterButtons[i]; - btnFilter.addEventListener('click', showFilterMenu.bind(this)); - - if (hasVisibleFilters) { - btnFilter.classList.remove('hide'); - } else { - btnFilter.classList.add('hide'); - } - } - - var sortButtons = view.querySelectorAll('.btnSort'); - this.sortButtons = sortButtons; - for (i = 0, length = sortButtons.length; i < length; i++) { - - var sortButton = sortButtons[i]; - sortButton.addEventListener('click', showSortMenu.bind(this)); - - if (params.type !== 'nextup') { - sortButton.classList.remove('hide'); - } - } - this.btnSortText = view.querySelector('.btnSortText'); - this.btnSortIcon = view.querySelector('.btnSortIcon'); - - this.alphaPickerElement = view.querySelector('.alphaPicker'); - - hideOrShowAll(view.querySelectorAll('.btnShuffle'), true); - - bindAll(view.querySelectorAll('.btnPlay'), 'click', play.bind(this)); - bindAll(view.querySelectorAll('.btnShuffle'), 'click', shuffle.bind(this)); - } - - function getSettingValue(key, defaultValue) { - } - - ItemsTab.prototype.getViewSettings = function () { - - var basekey = this.getSettingsKey(); - - return { - showTitle: userSettings.get(basekey + '-showTitle') !== 'false', - showYear: userSettings.get(basekey + '-showYear') !== 'false', - imageType: userSettings.get(basekey + '-imageType') || this.getDefaultImageType() - }; - }; - - ItemsTab.prototype.getDefaultImageType = function () { - - return 'primary'; - }; - - ItemsTab.prototype.getSettingsKey = function () { - - return this.params.parentId + '-1'; - }; - - ItemsTab.prototype.onResume = function (options) { - - if (options && options.refresh) { - updateSortText(this); - updateItemsContainerForViewType(this); - loading.show(); - } - - var view = this.view; - - var scroller = this.scroller; - if (scroller && scroller.resume) { - scroller.resume(); - } - - if (this.enableAlphaPicker && !this.alphaPicker) { - initAlphaPicker(this, view); - updateAlphaPickerState(this); - } - - if (this.enableAlphaNumericShortcuts !== false) { - this.alphaNumericShortcuts = new AlphaNumericShortcuts.default({ - itemsContainer: this.itemsContainer - }); - } - - var instance = this; - var autoFocus = options.autoFocus; - - this.itemsContainer.resume(options).then(function (result) { - - loading.hide(); - - if (autoFocus) { - focusManager.autoFocus(instance.itemsContainer); - } - }); - }; - - ItemsTab.prototype.getVisibleViewSettings = function () { - - return [ - 'showTitle', - 'showYear', - 'imageType' - ]; - }; - - ItemsTab.prototype.getFilters = function () { - - var basekey = this.getSettingsKey(); - - return { - IsPlayed: userSettings.getFilter(basekey + '-filter-IsPlayed') === 'true', - IsUnplayed: userSettings.getFilter(basekey + '-filter-IsUnplayed') === 'true', - IsFavorite: userSettings.getFilter(basekey + '-filter-IsFavorite') === 'true', - IsResumable: userSettings.getFilter(basekey + '-filter-IsResumable') === 'true', - Is4K: userSettings.getFilter(basekey + '-filter-Is4K') === 'true', - IsHD: userSettings.getFilter(basekey + '-filter-IsHD') === 'true', - IsSD: userSettings.getFilter(basekey + '-filter-IsSD') === 'true', - Is3D: userSettings.getFilter(basekey + '-filter-Is3D') === 'true', - VideoTypes: userSettings.getFilter(basekey + '-filter-VideoTypes'), - SeriesStatus: userSettings.getFilter(basekey + '-filter-SeriesStatus'), - HasSubtitles: userSettings.getFilter(basekey + '-filter-HasSubtitles'), - HasTrailer: userSettings.getFilter(basekey + '-filter-HasTrailer'), - HasSpecialFeature: userSettings.getFilter(basekey + '-filter-HasSpecialFeature'), - HasThemeSong: userSettings.getFilter(basekey + '-filter-HasThemeSong'), - HasThemeVideo: userSettings.getFilter(basekey + '-filter-HasThemeVideo'), - GenreIds: userSettings.getFilter(basekey + '-filter-GenreIds') - }; - }; - - ItemsTab.prototype.getSortValues = function () { - - var basekey = this.getSettingsKey(); - - return { - sortBy: userSettings.getFilter(basekey + '-sortby') || this.getSortMenuOptions()[0].value, - sortOrder: userSettings.getFilter(basekey + '-sortorder') === 'Descending' ? 'Descending' : 'Ascending' - }; - }; - - ItemsTab.prototype.getVisibleFilters = function () { - - return [ - 'IsUnplayed', - 'IsPlayed', - 'IsFavorite', - 'IsResumable', - 'VideoType', - 'HasSubtitles', - 'HasTrailer', - 'HasSpecialFeature', - 'HasThemeSong', - 'HasThemeVideo' - ]; - }; - - ItemsTab.prototype.getDefaultSortBy = function () { - - return 'SortName'; - }; - - ItemsTab.prototype.getSortMenuOptions = function () { - - var sortBy = []; - - var option = this.getNameSortOption(); - if (option) { - sortBy.push(option); - } - - option = this.getCommunityRatingSortOption(); - if (option) { - sortBy.push(option); - } - - option = this.getCriticRatingSortOption(); - - if (option) { - sortBy.push(option); - } - - sortBy.push({ - name: globalize.translate('DateAdded'), - value: 'DateCreated,SortName' - }); - - option = this.getDatePlayedSortOption(); - if (option) { - sortBy.push(option); - } - - sortBy.push({ - name: globalize.translate('ParentalRating'), - value: 'OfficialRating,SortName' - }); - - option = this.getPlayCountSortOption(); - if (option) { - sortBy.push(option); - } - - sortBy.push({ - name: globalize.translate('ReleaseDate'), - value: 'PremiereDate,ProductionYear,SortName' - }); - - sortBy.push({ - name: globalize.translate('Runtime'), - value: 'Runtime,SortName' - }); - - return sortBy; - }; - - ItemsTab.prototype.getNameSortOption = function () { - - return { - name: globalize.translate('Name'), - value: 'SortName' - }; - }; - - ItemsTab.prototype.getPlayCountSortOption = function () { - - return { - name: globalize.translate('PlayCount'), - value: 'PlayCount,SortName' - }; - }; - - ItemsTab.prototype.getDatePlayedSortOption = function () { - - return { - name: globalize.translate('DatePlayed'), - value: 'DatePlayed,SortName' - }; - }; - - ItemsTab.prototype.getCriticRatingSortOption = function () { - - return { - name: globalize.translate('CriticRating'), - value: 'CriticRating,SortName' - }; - }; - - ItemsTab.prototype.getCommunityRatingSortOption = function () { - - return { - name: globalize.translate('CommunityRating'), - value: 'CommunityRating,SortName' - }; - }; - - ItemsTab.prototype.getFilterMenuOptions = function () { - - var params = this.params; - - return { - - }; - }; - - ItemsTab.prototype.getItemTypes = function () { - - return []; - }; - - ItemsTab.prototype.setFilterStatus = function (hasFilters) { - - this.hasFilters = hasFilters; - - var filterButtons = this.filterButtons; - if (!filterButtons.length) { - return; - } - - for (var i = 0, length = filterButtons.length; i < length; i++) { - - var btnFilter = filterButtons[i]; - - var bubble = btnFilter.querySelector('.filterButtonBubble'); - if (!bubble) { - - if (!hasFilters) { - continue; - } - - btnFilter.insertAdjacentHTML('afterbegin', '
!
'); - btnFilter.classList.add('btnFilterWithBubble'); - bubble = btnFilter.querySelector('.filterButtonBubble'); - } - - if (hasFilters) { - bubble.classList.remove('hide'); - } else { - bubble.classList.add('hide'); - } - } - }; - - ItemsTab.prototype.onPause = function () { - var scroller = this.scroller; - if (scroller && scroller.pause) { - scroller.pause(); - } - - var alphaNumericShortcuts = this.alphaNumericShortcuts; - if (alphaNumericShortcuts) { - alphaNumericShortcuts.default.destroy(); - this.alphaNumericShortcuts = null; - } - }; - - ItemsTab.prototype.destroy = function () { - this.view = null; - this.itemsContainer = null; - this.params = null; - this.apiClient = null; - this.scroller = null; - this.filterButtons = null; - - if (this.alphaPicker) { - this.alphaPicker.destroy(); - this.alphaPicker = null; - } - - this.sortButtons = null; - this.btnSortText = null; - this.btnSortIcon = null; - this.alphaPickerElement = null; - }; - - return ItemsTab; -}); diff --git a/src/components/tabbedview/tabbedview.js b/src/components/tabbedview/tabbedview.js index 4fec69f619..8bd3afd372 100644 --- a/src/components/tabbedview/tabbedview.js +++ b/src/components/tabbedview/tabbedview.js @@ -2,7 +2,6 @@ define(['backdrop', 'mainTabsManager', 'layoutManager', 'emby-tabs'], function ( 'use strict'; function onViewDestroy(e) { - var tabControllers = this.tabControllers; if (tabControllers) { @@ -26,7 +25,6 @@ define(['backdrop', 'mainTabsManager', 'layoutManager', 'emby-tabs'], function ( } function TabbedView(view, params) { - this.tabControllers = []; this.view = view; this.params = params; @@ -37,15 +35,12 @@ define(['backdrop', 'mainTabsManager', 'layoutManager', 'emby-tabs'], function ( this.initialTabIndex = currentTabIndex; function validateTabLoad(index) { - return self.validateTabLoad ? self.validateTabLoad(index) : Promise.resolve(); } function loadTab(index, previousIndex) { - validateTabLoad(index).then(function () { self.getTabController(index).then(function (controller) { - var refresh = !controller.refreshed; controller.onResume({ @@ -80,12 +75,10 @@ define(['backdrop', 'mainTabsManager', 'layoutManager', 'emby-tabs'], function ( view.addEventListener('viewbeforehide', this.onPause.bind(this)); view.addEventListener('viewbeforeshow', function (e) { - mainTabsManager.setTabs(view, currentTabIndex, self.getTabs, getTabContainers, onBeforeTabChange, onTabChange, false); }); view.addEventListener('viewshow', function (e) { - self.onResume(e.detail); }); @@ -93,7 +86,6 @@ define(['backdrop', 'mainTabsManager', 'layoutManager', 'emby-tabs'], function ( } TabbedView.prototype.onResume = function (options) { - this.setTitle(); backdrop.clearBackdrop(); @@ -107,7 +99,6 @@ define(['backdrop', 'mainTabsManager', 'layoutManager', 'emby-tabs'], function ( }; TabbedView.prototype.onPause = function () { - var currentTabController = this.currentTabController; if (currentTabController && currentTabController.onPause) { diff --git a/src/components/themeMediaPlayer.js b/src/components/themeMediaPlayer.js index 94012ba823..60f0986884 100644 --- a/src/components/themeMediaPlayer.js +++ b/src/components/themeMediaPlayer.js @@ -1,17 +1,17 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playbackManager, userSettings, connectionManager) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + var currentOwnerId; var currentThemeIds = []; function playThemeMedia(items, ownerId) { - var currentThemeItems = items.filter(function (i) { return enabled(i.MediaType); }); if (currentThemeItems.length) { - // Stop if a theme song from another ownerId // Leave it alone if anything else (e.g user playing a movie) if (!currentOwnerId && playbackManager.isPlaying()) { @@ -29,7 +29,6 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playb }).then(function () { currentOwnerId = ownerId; }); - } else { stopIfPlaying(); } @@ -44,7 +43,6 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playb } function enabled(mediaType) { - if (mediaType === 'Video') { return userSettings.enableThemeVideos(); } @@ -55,7 +53,6 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playb var excludeTypes = ['CollectionFolder', 'UserView', 'Program', 'SeriesTimer', 'Person', 'TvChannel', 'Channel']; function loadThemeMedia(item) { - if (item.CollectionType) { stopIfPlaying(); return; @@ -68,11 +65,9 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playb var apiClient = connectionManager.getApiClient(item.ServerId); apiClient.getThemeMedia(apiClient.getCurrentUserId(), item.Id, true).then(function (themeMediaResult) { - var ownerId = themeMediaResult.ThemeVideosResult.Items.length ? themeMediaResult.ThemeVideosResult.OwnerId : themeMediaResult.ThemeSongsResult.OwnerId; if (ownerId !== currentOwnerId) { - var items = themeMediaResult.ThemeVideosResult.Items.length ? themeMediaResult.ThemeVideosResult.Items : themeMediaResult.ThemeSongsResult.Items; playThemeMedia(items, ownerId); @@ -81,7 +76,6 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playb } document.addEventListener('viewshow', function (e) { - var state = e.detail.state || {}; var item = state.item; @@ -97,15 +91,13 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playb } else { playThemeMedia([], null); } - }, true); - //Events.on(playbackManager, 'playbackstart', function (e, player) { - // var item = playbackManager.currentItem(player); - // // User played something manually - // if (currentThemeIds.indexOf(item.Id) == -1) { - // currentOwnerId = null; - // } - //}); - + Events.on(playbackManager, 'playbackstart', function (e, player) { + var item = playbackManager.currentItem(player); + // User played something manually + if (currentThemeIds.indexOf(item.Id) == -1) { + currentOwnerId = null; + } + }); }); diff --git a/src/components/toast/toast.js b/src/components/toast/toast.js index 7b8e49e4d2..d14abffce4 100644 --- a/src/components/toast/toast.js +++ b/src/components/toast/toast.js @@ -2,24 +2,19 @@ define(['css!./toast'], function () { 'use strict'; function remove(elem) { - setTimeout(function () { elem.parentNode.removeChild(elem); }, 300); } function animateRemove(elem) { - setTimeout(function () { - elem.classList.remove('toastVisible'); remove(elem); - }, 3300); } return function (options) { - if (typeof options === 'string') { options = { text: options @@ -36,7 +31,6 @@ define(['css!./toast'], function () { elem.classList.add('toastVisible'); animateRemove(elem); - }, 300); }; }); diff --git a/src/components/tunerPicker.js b/src/components/tunerPicker.js index e7c92851a4..5bc9386053 100644 --- a/src/components/tunerPicker.js +++ b/src/components/tunerPicker.js @@ -1,6 +1,9 @@ define(['dialogHelper', 'dom', 'layoutManager', 'connectionManager', 'globalize', 'loading', 'browser', 'focusManager', 'scrollHelper', 'material-icons', 'formDialogStyle', 'emby-button', 'emby-itemscontainer', 'cardStyle'], function (dialogHelper, dom, layoutManager, connectionManager, globalize, loading, browser, focusManager, scrollHelper) { 'use strict'; + browser = browser.default || browser; + loading = loading.default || loading; + var enableFocusTransform = !browser.slow && !browser.edge; function getEditorHtml() { diff --git a/src/components/tvproviders/schedulesdirect.js b/src/components/tvproviders/schedulesdirect.js index be1cdf575b..a0c29f48b8 100644 --- a/src/components/tvproviders/schedulesdirect.js +++ b/src/components/tvproviders/schedulesdirect.js @@ -1,6 +1,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'listViewStyle', 'emby-input', 'emby-select', 'emby-button', 'flexStyles'], function ($, loading, globalize) { 'use strict'; + loading = loading.default || loading; + return function (page, providerId, options) { function reload() { loading.show(); @@ -42,7 +44,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'listViewStyle', 'emb for (var region in result) { var countries = result[region]; - if (countries.length && 'ZZZ' !== region) { + if (countries.length && region !== 'ZZZ') { for (i = 0, length = countries.length; i < length; i++) { countryList.push({ name: countries[i].fullName, @@ -237,7 +239,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'listViewStyle', 'emb var device = devices[i]; html += '
'; var enabledTuners = providerInfo.EnabledTuners || []; - var isChecked = providerInfo.EnableAllTuners || -1 !== enabledTuners.indexOf(device.Id); + var isChecked = providerInfo.EnableAllTuners || enabledTuners.indexOf(device.Id) !== -1; var checkedAttribute = isChecked ? ' checked' : ''; html += ''; html += '
'; diff --git a/src/components/tvproviders/xmltv.js b/src/components/tvproviders/xmltv.js index 054c5b640d..2203bc1fea 100644 --- a/src/components/tvproviders/xmltv.js +++ b/src/components/tvproviders/xmltv.js @@ -1,6 +1,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'emby-input', 'listViewStyle', 'paper-icon-button-light'], function ($, loading, globalize) { 'use strict'; + loading = loading.default || loading; + return function (page, providerId, options) { function getListingProvider(config, id) { if (config && id) { @@ -84,7 +86,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'emby-input', 'listVi }).then(function (result) { loading.hide(); - if (false !== options.showConfirmation) { + if (options.showConfirmation !== false) { Dashboard.processServerConfigurationUpdateResult(); } @@ -118,7 +120,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'emby-input', 'listVi var device = devices[i]; html += '
'; var enabledTuners = providerInfo.EnabledTuners || []; - var isChecked = providerInfo.EnableAllTuners || -1 !== enabledTuners.indexOf(device.Id); + var isChecked = providerInfo.EnableAllTuners || enabledTuners.indexOf(device.Id) !== -1; var checkedAttribute = isChecked ? ' checked' : ''; html += ''; html += '
'; diff --git a/src/components/upnextdialog/upnextdialog.js b/src/components/upnextdialog/upnextdialog.js index 3e9c9f9c5e..5eb2a2ffcc 100644 --- a/src/components/upnextdialog/upnextdialog.js +++ b/src/components/upnextdialog/upnextdialog.js @@ -1,10 +1,11 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'layoutManager', 'focusManager', 'globalize', 'itemHelper', 'css!./upnextdialog', 'emby-button', 'flexStyles'], function (dom, playbackManager, connectionManager, events, mediaInfo, layoutManager, focusManager, globalize, itemHelper) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + var transitionEndEventName = dom.whichTransitionEvent(); function seriesImageUrl(item, options) { - if (item.Type !== 'Episode') { return null; } @@ -13,9 +14,7 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l options.type = options.type || 'Primary'; if (options.type === 'Primary') { - if (item.SeriesPrimaryImageTag) { - options.tag = item.SeriesPrimaryImageTag; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); @@ -23,15 +22,12 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } if (options.type === 'Thumb') { - if (item.SeriesThumbImageTag) { - options.tag = item.SeriesThumbImageTag; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); } if (item.ParentThumbImageTag) { - options.tag = item.ParentThumbImageTag; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.ParentThumbItemId, options); @@ -42,19 +38,16 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function imageUrl(item, options) { - options = options || {}; options.type = options.type || 'Primary'; if (item.ImageTags && item.ImageTags[options.type]) { - options.tag = item.ImageTags[options.type]; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.PrimaryImageItemId || item.Id, options); } if (options.type === 'Primary') { if (item.AlbumId && item.AlbumPrimaryImageTag) { - options.tag = item.AlbumPrimaryImageTag; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.AlbumId, options); } @@ -64,9 +57,7 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function setPoster(osdPoster, item, secondaryItem) { - if (item) { - var imgUrl = seriesImageUrl(item, { type: 'Primary' }) || seriesImageUrl(item, { type: 'Thumb' }) || imageUrl(item, { type: 'Primary' }); @@ -87,7 +78,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function getHtml() { - var html = ''; html += '
'; @@ -124,7 +114,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function setNextVideoText() { - var instance = this; var elem = instance.options.parent; @@ -143,7 +132,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function fillItem(item) { - var instance = this; var elem = instance.options.parent; @@ -175,11 +163,9 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function onStartNowClick() { - var options = this.options; if (options) { - var player = options.player; this.hide(); @@ -189,7 +175,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function init(instance, options) { - options.parent.innerHTML = getHtml(); options.parent.classList.add('hide'); @@ -203,7 +188,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function clearHideAnimationEventListeners(instance, elem) { - var fn = instance._onHideAnimationComplete; if (fn) { @@ -214,7 +198,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function onHideAnimationComplete(e) { - var instance = this; var elem = e.target; @@ -225,7 +208,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function hideComingUpNext() { - var instance = this; clearCountdownTextTimeout(this); @@ -259,10 +241,8 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function getTimeRemainingMs(instance) { - var options = instance.options; if (options) { - var runtimeTicks = playbackManager.duration(options.player); if (runtimeTicks) { @@ -276,7 +256,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function startComingUpNextHideTimer(instance) { - var timeRemainingMs = getTimeRemainingMs(instance); if (timeRemainingMs <= 0) { @@ -290,14 +269,12 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function UpNextDialog(options) { - this.options = options; init(this, options); } UpNextDialog.prototype.show = function () { - var elem = this.options.parent; clearHideAnimationEventListeners(this, elem); @@ -319,12 +296,10 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l }; UpNextDialog.prototype.hide = function () { - hideComingUpNext.call(this); }; UpNextDialog.prototype.destroy = function () { - hideComingUpNext.call(this); this.options = null; diff --git a/src/components/userdatabuttons/userdatabuttons.js b/src/components/userdatabuttons/userdatabuttons.js index 86b9902133..e3a7b9e06b 100644 --- a/src/components/userdatabuttons/userdatabuttons.js +++ b/src/components/userdatabuttons/userdatabuttons.js @@ -9,7 +9,6 @@ define(['connectionManager', 'globalize', 'dom', 'itemHelper', 'paper-icon-butto }; function getUserDataButtonHtml(method, itemId, serverId, buttonCssClass, iconCssClass, icon, tooltip, style) { - if (style === 'fab-mini') { style = 'fab'; buttonCssClass = buttonCssClass ? (buttonCssClass + ' mini') : 'mini'; @@ -34,7 +33,6 @@ define(['connectionManager', 'globalize', 'dom', 'itemHelper', 'paper-icon-butto } function onContainerClick(e) { - var btnUserData = dom.parentWithClass(e.target, 'btnUserData'); if (!btnUserData) { @@ -46,7 +44,6 @@ define(['connectionManager', 'globalize', 'dom', 'itemHelper', 'paper-icon-butto } function fill(options) { - var html = getIconsHtml(options); if (options.fillMode === 'insertAdjacent') { @@ -65,7 +62,6 @@ define(['connectionManager', 'globalize', 'dom', 'itemHelper', 'paper-icon-butto } function destroy(options) { - options.element.innerHTML = ''; dom.removeEventListener(options.element, 'click', onContainerClick, { @@ -74,7 +70,6 @@ define(['connectionManager', 'globalize', 'dom', 'itemHelper', 'paper-icon-butto } function getIconsHtml(options) { - var item = options.item; var includePlayed = options.includePlayed; var cssClass = options.cssClass; @@ -112,25 +107,8 @@ define(['connectionManager', 'globalize', 'dom', 'itemHelper', 'paper-icon-butto } } - //var tooltipLike = globalize.translate('Like'); - //var tooltipDislike = globalize.translate('Dislike'); - - //if (typeof userData.Likes == "undefined") { - // html += getUserDataButtonHtml('markDislike', itemId, serverId, btnCssClass + ' btnUserData btnDislike', 'thumb-down', tooltipDislike); - // html += getUserDataButtonHtml('markLike', itemId, serverId, btnCssClass + ' btnUserData btnLike', 'thumb-up', tooltipLike); - //} - //else if (userData.Likes) { - // html += getUserDataButtonHtml('markDislike', itemId, serverId, btnCssClass + ' btnUserData btnDislike', 'thumb-down', tooltipDislike); - // html += getUserDataButtonHtml('markLike', itemId, serverId, btnCssClass + ' btnUserData btnLike btnUserDataOn', 'thumb-up', tooltipLike); - //} - //else { - // html += getUserDataButtonHtml('markDislike', itemId, serverId, btnCssClass + ' btnUserData btnDislike btnUserDataOn', 'thumb-down', tooltipDislike); - // html += getUserDataButtonHtml('markLike', itemId, serverId, btnCssClass + ' btnUserData btnLike', 'thumb-up', tooltipLike); - //} - var tooltipFavorite = globalize.translate('Favorite'); if (userData.IsFavorite) { - html += getUserDataButtonHtml('markFavorite', itemId, serverId, btnCssClass + ' btnUserData btnUserDataOn', iconCssClass, 'favorite', tooltipFavorite, style); } else { html += getUserDataButtonHtml('markFavorite', itemId, serverId, btnCssClass + ' btnUserData', iconCssClass, 'favorite', tooltipFavorite, style); @@ -140,7 +118,6 @@ define(['connectionManager', 'globalize', 'dom', 'itemHelper', 'paper-icon-butto } function markFavorite(link) { - var id = link.getAttribute('data-itemid'); var serverId = link.getAttribute('data-serverid'); @@ -156,18 +133,14 @@ define(['connectionManager', 'globalize', 'dom', 'itemHelper', 'paper-icon-butto } function markLike(link) { - var id = link.getAttribute('data-itemid'); var serverId = link.getAttribute('data-serverid'); if (!link.classList.contains('btnUserDataOn')) { - likes(id, serverId, true); link.classList.add('btnUserDataOn'); - } else { - clearLike(id, serverId); link.classList.remove('btnUserDataOn'); @@ -177,18 +150,14 @@ define(['connectionManager', 'globalize', 'dom', 'itemHelper', 'paper-icon-butto } function markDislike(link) { - var id = link.getAttribute('data-itemid'); var serverId = link.getAttribute('data-serverid'); if (!link.classList.contains('btnUserDataOn')) { - likes(id, serverId, false); link.classList.add('btnUserDataOn'); - } else { - clearLike(id, serverId); link.classList.remove('btnUserDataOn'); @@ -198,18 +167,14 @@ define(['connectionManager', 'globalize', 'dom', 'itemHelper', 'paper-icon-butto } function markPlayed(link) { - var id = link.getAttribute('data-itemid'); var serverId = link.getAttribute('data-serverid'); if (!link.classList.contains('btnUserDataOn')) { - played(id, serverId, true); link.classList.add('btnUserDataOn'); - } else { - played(id, serverId, false); link.classList.remove('btnUserDataOn'); @@ -236,7 +201,6 @@ define(['connectionManager', 'globalize', 'dom', 'itemHelper', 'paper-icon-butto } function clearLike(id, serverId) { - var apiClient = connectionManager.getApiClient(serverId); return apiClient.clearUserItemRating(apiClient.getCurrentUserId(), id); @@ -247,5 +211,4 @@ define(['connectionManager', 'globalize', 'dom', 'itemHelper', 'paper-icon-butto destroy: destroy, getIconsHtml: getIconsHtml }; - }); diff --git a/src/components/viewContainer.js b/src/components/viewContainer.js index dbc493bc91..9d64130cdb 100644 --- a/src/components/viewContainer.js +++ b/src/components/viewContainer.js @@ -1,20 +1,20 @@ -define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewContainer'], function (browser, dom, layoutManager) { - 'use strict'; +import 'css!components/viewManager/viewContainer'; +/* eslint-disable indent */ function setControllerClass(view, options) { if (options.controllerFactory) { return Promise.resolve(); } - var controllerUrl = view.getAttribute('data-controller'); + let controllerUrl = view.getAttribute('data-controller'); if (controllerUrl) { - if (0 === controllerUrl.indexOf('__plugin/')) { + if (controllerUrl.indexOf('__plugin/') === 0) { controllerUrl = controllerUrl.substring('__plugin/'.length); } controllerUrl = Dashboard.getConfigurationResourceUrl(controllerUrl); - return getRequirePromise([controllerUrl]).then(function (ControllerFactory) { + return import(controllerUrl).then((ControllerFactory) => { options.controllerFactory = ControllerFactory; }); } @@ -22,94 +22,85 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta return Promise.resolve(); } - function getRequirePromise(deps) { - return new Promise(function (resolve, reject) { - require(deps, resolve); - }); - } - - function loadView(options) { + export function loadView(options) { if (!options.cancel) { - var selected = selectedPageIndex; - var previousAnimatable = -1 === selected ? null : allPages[selected]; - var pageIndex = selected + 1; + const selected = selectedPageIndex; + const previousAnimatable = selected === -1 ? null : allPages[selected]; + let pageIndex = selected + 1; if (pageIndex >= pageContainerCount) { pageIndex = 0; } - var isPluginpage = -1 !== options.url.toLowerCase().indexOf('/configurationpage'); - var newViewInfo = normalizeNewView(options, isPluginpage); - var newView = newViewInfo.elem; - var modulesToLoad = []; + const isPluginpage = options.url.toLowerCase().indexOf('/configurationpage') !== -1; + const newViewInfo = normalizeNewView(options, isPluginpage); + const newView = newViewInfo.elem; - return new Promise(function (resolve) { - require(modulesToLoad, function () { - var currentPage = allPages[pageIndex]; + return new Promise((resolve) => { + const currentPage = allPages[pageIndex]; - if (currentPage) { - triggerDestroy(currentPage); - } + if (currentPage) { + triggerDestroy(currentPage); + } - var view = newView; + let view = newView; - if ('string' == typeof view) { - view = document.createElement('div'); - view.innerHTML = newView; - } + if (typeof view == 'string') { + view = document.createElement('div'); + view.innerHTML = newView; + } - view.classList.add('mainAnimatedPage'); + view.classList.add('mainAnimatedPage'); - if (currentPage) { - if (newViewInfo.hasScript && window.$) { - view = $(view).appendTo(mainAnimatedPages)[0]; - mainAnimatedPages.removeChild(currentPage); - } else { - mainAnimatedPages.replaceChild(view, currentPage); - } + if (currentPage) { + if (newViewInfo.hasScript && window.$) { + mainAnimatedPages.removeChild(currentPage); + view = $(view).appendTo(mainAnimatedPages)[0]; } else { - if (newViewInfo.hasScript && window.$) { - view = $(view).appendTo(mainAnimatedPages)[0]; - } else { - mainAnimatedPages.appendChild(view); - } + mainAnimatedPages.replaceChild(view, currentPage); + } + } else { + if (newViewInfo.hasScript && window.$) { + view = $(view).appendTo(mainAnimatedPages)[0]; + } else { + mainAnimatedPages.appendChild(view); + } + } + + if (options.type) { + view.setAttribute('data-type', options.type); + } + + const properties = []; + + if (options.fullscreen) { + properties.push('fullscreen'); + } + + if (properties.length) { + view.setAttribute('data-properties', properties.join(',')); + } + + allPages[pageIndex] = view; + setControllerClass(view, options).then(() => { + if (onBeforeChange) { + onBeforeChange(view, false, options); } - if (options.type) { - view.setAttribute('data-type', options.type); + beforeAnimate(allPages, pageIndex, selected); + selectedPageIndex = pageIndex; + currentUrls[pageIndex] = options.url; + + if (!options.cancel && previousAnimatable) { + afterAnimate(allPages, pageIndex); } - var properties = []; - - if (options.fullscreen) { - properties.push('fullscreen'); + if (window.$) { + $.mobile = $.mobile || {}; + $.mobile.activePage = view; } - if (properties.length) { - view.setAttribute('data-properties', properties.join(',')); - } - - allPages[pageIndex] = view; - setControllerClass(view, options).then(function () { - if (onBeforeChange) { - onBeforeChange(view, false, options); - } - - beforeAnimate(allPages, pageIndex, selected); - selectedPageIndex = pageIndex; - currentUrls[pageIndex] = options.url; - - if (!options.cancel && previousAnimatable) { - afterAnimate(allPages, pageIndex); - } - - if (window.$) { - $.mobile = $.mobile || {}; - $.mobile.activePage = view; - } - - resolve(view); - }); + resolve(view); }); }); } @@ -125,33 +116,33 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta html = replaceAll(html, '<\/script>--\x3e', '<\/script>'); } - var wrapper = document.createElement('div'); + const wrapper = document.createElement('div'); wrapper.innerHTML = html; return wrapper.querySelector('div[data-role="page"]'); } function normalizeNewView(options, isPluginpage) { - var viewHtml = options.view; + const viewHtml = options.view; - if (-1 === viewHtml.indexOf('data-role="page"')) { + if (viewHtml.indexOf('data-role="page"') === -1) { return viewHtml; } - var hasScript = -1 !== viewHtml.indexOf(' { if (onBeforeChange) { onBeforeChange(view, true, options); } @@ -228,25 +219,28 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta view.dispatchEvent(new CustomEvent('viewdestroy', {})); } - function reset() { + export function reset() { allPages = []; currentUrls = []; mainAnimatedPages.innerHTML = ''; selectedPageIndex = -1; } - var onBeforeChange; - var mainAnimatedPages = document.querySelector('.mainAnimatedPages'); - var allPages = []; - var currentUrls = []; - var pageContainerCount = 3; - var selectedPageIndex = -1; + let onBeforeChange; + const mainAnimatedPages = document.querySelector('.mainAnimatedPages'); + let allPages = []; + let currentUrls = []; + const pageContainerCount = 3; + let selectedPageIndex = -1; reset(); mainAnimatedPages.classList.remove('hide'); - return { - loadView: loadView, - tryRestoreView: tryRestoreView, - reset: reset, - setOnBeforeChange: setOnBeforeChange - }; -}); + +/* eslint-enable indent */ + +export default { + loadView: loadView, + tryRestoreView: tryRestoreView, + reset: reset, + setOnBeforeChange: setOnBeforeChange +}; + diff --git a/src/components/viewManager/viewManager.js b/src/components/viewManager/viewManager.js index 8e17264f9f..058ba4ebb2 100644 --- a/src/components/viewManager/viewManager.js +++ b/src/components/viewManager/viewManager.js @@ -5,10 +5,8 @@ define(['viewContainer', 'focusManager', 'queryString', 'layoutManager'], functi var dispatchPageEvents; viewContainer.setOnBeforeChange(function (newView, isRestored, options) { - var lastView = currentView; if (lastView) { - var beforeHideResult = dispatchViewEvent(lastView, null, 'viewbeforehide', true); if (!beforeHideResult) { @@ -21,11 +19,10 @@ define(['viewContainer', 'focusManager', 'queryString', 'layoutManager'], functi if (!newView.initComplete) { newView.initComplete = true; - var controller; if (typeof options.controllerFactory === 'function') { - controller = new options.controllerFactory(newView, eventDetail.detail.params); + new options.controllerFactory(newView, eventDetail.detail.params); } else if (options.controllerFactory && typeof options.controllerFactory.default === 'function') { - controller = new options.controllerFactory.default(newView, eventDetail.detail.params); + new options.controllerFactory.default(newView, eventDetail.detail.params); } if (!options.controllerFactory || dispatchPageEvents) { @@ -37,7 +34,6 @@ define(['viewContainer', 'focusManager', 'queryString', 'layoutManager'], functi }); function onViewChange(view, options, isRestore) { - var lastView = currentView; if (lastView) { dispatchViewEvent(lastView, null, 'viewhide'); @@ -77,7 +73,6 @@ define(['viewContainer', 'focusManager', 'queryString', 'layoutManager'], functi } function dispatchViewEvent(view, eventInfo, eventName, isCancellable) { - if (!eventInfo) { eventInfo = { detail: { @@ -102,7 +97,6 @@ define(['viewContainer', 'focusManager', 'queryString', 'layoutManager'], functi } function getViewEventDetail(view, options, isRestore) { - var url = options.url; var index = url.indexOf('?'); var params = index === -1 ? {} : queryString.parse(url.substring(index + 1)); @@ -134,7 +128,6 @@ define(['viewContainer', 'focusManager', 'queryString', 'layoutManager'], functi } ViewManager.prototype.loadView = function (options) { - var lastView = currentView; // Record the element that has focus @@ -147,13 +140,11 @@ define(['viewContainer', 'focusManager', 'queryString', 'layoutManager'], functi } viewContainer.loadView(options).then(function (view) { - onViewChange(view, options); }); }; ViewManager.prototype.tryRestoreView = function (options, onViewChanging) { - if (options.cancel) { return Promise.reject({ cancelled: true }); } @@ -164,10 +155,8 @@ define(['viewContainer', 'focusManager', 'queryString', 'layoutManager'], functi } return viewContainer.tryRestoreView(options).then(function (view) { - onViewChanging(); onViewChange(view, options, true); - }); }; diff --git a/src/components/viewSettings/viewSettings.js b/src/components/viewSettings/viewSettings.js index 28a9854c34..67abc25a9c 100644 --- a/src/components/viewSettings/viewSettings.js +++ b/src/components/viewSettings/viewSettings.js @@ -2,19 +2,16 @@ define(['require', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'conne 'use strict'; function onSubmit(e) { - e.preventDefault(); return false; } function initEditor(context, settings) { - context.querySelector('form').addEventListener('submit', onSubmit); var elems = context.querySelectorAll('.viewSetting-checkboxContainer'); for (var i = 0, length = elems.length; i < length; i++) { - elems[i].querySelector('input').checked = settings[elems[i].getAttribute('data-settingname')] || false; } @@ -22,7 +19,6 @@ define(['require', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'conne } function saveValues(context, settings, settingsKey) { - var elems = context.querySelectorAll('.viewSetting-checkboxContainer'); for (var i = 0, length = elems.length; i < length; i++) { userSettings.set(settingsKey + '-' + elems[i].getAttribute('data-settingname'), elems[i].querySelector('input').checked); @@ -39,7 +35,6 @@ define(['require', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'conne } function showIfAllowed(context, selector, visible) { - var elem = context.querySelector(selector); if (visible && !elem.classList.contains('hiddenFromViewSettings')) { @@ -54,11 +49,8 @@ define(['require', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'conne } ViewSettings.prototype.show = function (options) { - return new Promise(function (resolve, reject) { - require(['text!./viewSettings.template.html'], function (template) { - var dialogOptions = { removeOnClose: true, scrollY: false @@ -100,13 +92,11 @@ define(['require', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'conne initEditor(dlg, options.settings); dlg.querySelector('.selectImageType').addEventListener('change', function () { - showIfAllowed(dlg, '.chkTitleContainer', this.value !== 'list'); showIfAllowed(dlg, '.chkYearContainer', this.value !== 'list'); }); dlg.querySelector('.btnCancel').addEventListener('click', function () { - dialogHelper.close(dlg); }); @@ -119,13 +109,10 @@ define(['require', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'conne dlg.querySelector('.selectImageType').dispatchEvent(new CustomEvent('change', {})); dlg.querySelector('form').addEventListener('change', function () { - submitted = true; - }, true); dialogHelper.open(dlg).then(function () { - if (layoutManager.tv) { centerFocus(dlg.querySelector('.formDialogContent'), false, false); } diff --git a/src/config.template.json b/src/config.template.json index 4b22a699d6..9d98e8b6f7 100644 --- a/src/config.template.json +++ b/src/config.template.json @@ -1,3 +1,38 @@ { - "multiserver": false + "multiserver": false, + "themes": [ + { + "name": "Apple TV", + "id": "appletv" + }, { + "name": "Blue Radiance", + "id": "blueradiance" + }, { + "name": "Dark", + "id": "dark", + "default": true + }, { + "name": "Light", + "id": "light" + }, { + "name": "Purple Haze", + "id": "purplehaze" + }, { + "name": "WMC", + "id": "wmc" + } + ], + "plugins": [ + "plugins/playAccessValidation/plugin", + "plugins/experimentalWarnings/plugin", + "plugins/htmlAudioPlayer/plugin", + "plugins/htmlVideoPlayer/plugin", + "plugins/photoPlayer/plugin", + "plugins/bookPlayer/plugin", + "plugins/youtubePlayer/plugin", + "plugins/backdropScreensaver/plugin", + "plugins/logoScreensaver/plugin", + "plugins/sessionPlayer/plugin", + "plugins/chromecastPlayer/plugin" + ] } diff --git a/src/controllers/dashboard/apikeys.js b/src/controllers/dashboard/apikeys.js index 0e122c486d..2b526aa8cc 100644 --- a/src/controllers/dashboard/apikeys.js +++ b/src/controllers/dashboard/apikeys.js @@ -1,6 +1,5 @@ import datetime from 'datetime'; import loading from 'loading'; -import libraryMenu from 'libraryMenu'; import dom from 'dom'; import globalize from 'globalize'; import 'emby-button'; diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index b9405c2da9..61fc345382 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -313,7 +313,7 @@ import 'emby-itemscontainer'; btnCssClass = session.TranscodingInfo && session.TranscodingInfo.TranscodeReasons && session.TranscodingInfo.TranscodeReasons.length ? '' : ' hide'; html += ''; - btnCssClass = session.ServerId && -1 !== session.SupportedCommands.indexOf('DisplayMessage') && session.DeviceId !== connectionManager.deviceId() ? '' : ' hide'; + btnCssClass = session.ServerId && session.SupportedCommands.indexOf('DisplayMessage') !== -1 && session.DeviceId !== connectionManager.deviceId() ? '' : ' hide'; html += ''; html += '
'; @@ -346,7 +346,7 @@ import 'emby-itemscontainer'; function renderRunningTasks(view, tasks) { let html = ''; tasks = tasks.filter(function (task) { - if ('Idle' != task.State) { + if (task.State != 'Idle') { return !task.IsHidden; } @@ -551,7 +551,7 @@ import 'emby-itemscontainer'; row.classList.remove('playingSession'); } - if (session.ServerId && -1 !== session.SupportedCommands.indexOf('DisplayMessage') && session.DeviceId !== connectionManager.deviceId()) { + if (session.ServerId && session.SupportedCommands.indexOf('DisplayMessage') !== -1 && session.DeviceId !== connectionManager.deviceId()) { row.querySelector('.btnSessionSendMessage').classList.remove('hide'); } else { row.querySelector('.btnSessionSendMessage').classList.add('hide'); diff --git a/src/controllers/dashboard/devices/device.js b/src/controllers/dashboard/devices/device.js index 7faaee2494..17e28b9bdb 100644 --- a/src/controllers/dashboard/devices/device.js +++ b/src/controllers/dashboard/devices/device.js @@ -1,5 +1,4 @@ import loading from 'loading'; -import libraryMenu from 'libraryMenu'; import dom from 'dom'; import 'emby-input'; import 'emby-button'; diff --git a/src/controllers/dashboard/devices/devices.js b/src/controllers/dashboard/devices/devices.js index 9f05d84713..93ae62c43f 100644 --- a/src/controllers/dashboard/devices/devices.js +++ b/src/controllers/dashboard/devices/devices.js @@ -1,6 +1,5 @@ import loading from 'loading'; import dom from 'dom'; -import libraryMenu from 'libraryMenu'; import globalize from 'globalize'; import imageHelper from 'scripts/imagehelper'; import * as datefns from 'date-fns'; diff --git a/src/controllers/dashboard/dlna/profile.js b/src/controllers/dashboard/dlna/profile.js index 69098ac506..17dc9f78cb 100644 --- a/src/controllers/dashboard/dlna/profile.js +++ b/src/controllers/dashboard/dlna/profile.js @@ -29,7 +29,7 @@ import 'listViewStyle'; function renderProfile(page, profile, users) { $('#txtName', page).val(profile.Name); $('.chkMediaType', page).each(function () { - this.checked = -1 != (profile.SupportedMediaTypes || '').split(',').indexOf(this.getAttribute('data-value')); + this.checked = (profile.SupportedMediaTypes || '').split(',').indexOf(this.getAttribute('data-value')) != -1; }); $('#chkEnableAlbumArtInDidl', page).prop('checked', profile.EnableAlbumArtInDidl); $('#chkEnableSingleImageLimit', page).prop('checked', profile.EnableSingleAlbumArtLimit); @@ -111,7 +111,7 @@ import 'listViewStyle'; } function editIdentificationHeader(page, header) { - isSubProfileNew = null == header; + isSubProfileNew = header == null; header = header || {}; currentSubProfile = header; const popup = $('#identificationHeaderPopup', page); @@ -156,7 +156,7 @@ import 'listViewStyle'; } function editXmlDocumentAttribute(page, attribute) { - isSubProfileNew = null == attribute; + isSubProfileNew = attribute == null; attribute = attribute || {}; currentSubProfile = attribute; const popup = $('#xmlAttributePopup', page); @@ -204,7 +204,7 @@ import 'listViewStyle'; } function editSubtitleProfile(page, profile) { - isSubProfileNew = null == profile; + isSubProfileNew = profile == null; profile = profile || {}; currentSubProfile = profile; const popup = $('#subtitleProfilePopup', page); @@ -257,7 +257,6 @@ import 'listViewStyle'; let currentType; for (const [index, profile] of profiles.entries()) { - if (profile.Type !== currentType) { html += '
  • ' + profile.Type + '
  • '; currentType = profile.Type; @@ -267,11 +266,11 @@ import 'listViewStyle'; html += ''; html += '

    ' + globalize.translate('ValueContainer', profile.Container || allText) + '

    '; - if ('Video' == profile.Type) { + if (profile.Type == 'Video') { html += '

    ' + globalize.translate('ValueVideoCodec', profile.VideoCodec || allText) + '

    '; html += '

    ' + globalize.translate('ValueAudioCodec', profile.AudioCodec || allText) + '

    '; } else { - if ('Audio' == profile.Type) { + if (profile.Type == 'Audio') { html += '

    ' + globalize.translate('ValueCodec', profile.AudioCodec || allText) + '

    '; } } @@ -299,7 +298,7 @@ import 'listViewStyle'; } function editDirectPlayProfile(page, directPlayProfile) { - isSubProfileNew = null == directPlayProfile; + isSubProfileNew = directPlayProfile == null; directPlayProfile = directPlayProfile || {}; currentSubProfile = directPlayProfile; const popup = $('#popupEditDirectPlayProfile', page); @@ -328,11 +327,11 @@ import 'listViewStyle'; html += '

    Protocol: ' + (profile.Protocol || 'Http') + '

    '; html += '

    ' + globalize.translate('ValueContainer', profile.Container || allText) + '

    '; - if ('Video' == profile.Type) { + if (profile.Type == 'Video') { html += '

    ' + globalize.translate('ValueVideoCodec', profile.VideoCodec || allText) + '

    '; html += '

    ' + globalize.translate('ValueAudioCodec', profile.AudioCodec || allText) + '

    '; } else { - if ('Audio' == profile.Type) { + if (profile.Type == 'Audio') { html += '

    ' + globalize.translate('ValueCodec', profile.AudioCodec || allText) + '

    '; } } @@ -355,7 +354,7 @@ import 'listViewStyle'; } function editTranscodingProfile(page, transcodingProfile) { - isSubProfileNew = null == transcodingProfile; + isSubProfileNew = transcodingProfile == null; transcodingProfile = transcodingProfile || {}; currentSubProfile = transcodingProfile; const popup = $('#transcodingProfilePopup', page); @@ -366,7 +365,7 @@ import 'listViewStyle'; $('#selectTranscodingProtocol', popup).val(transcodingProfile.Protocol || 'Http'); $('#chkEnableMpegtsM2TsMode', popup).prop('checked', transcodingProfile.EnableMpegtsM2TsMode || false); $('#chkEstimateContentLength', popup).prop('checked', transcodingProfile.EstimateContentLength || false); - $('#chkReportByteRangeRequests', popup).prop('checked', 'Bytes' == transcodingProfile.TranscodeSeekInfo); + $('#chkReportByteRangeRequests', popup).prop('checked', transcodingProfile.TranscodeSeekInfo == 'Bytes'); $('.radioTabButton:first', popup).trigger('click'); openPopup(popup[0]); } @@ -444,7 +443,7 @@ import 'listViewStyle'; } function editContainerProfile(page, containerProfile) { - isSubProfileNew = null == containerProfile; + isSubProfileNew = containerProfile == null; containerProfile = containerProfile || {}; currentSubProfile = containerProfile; const popup = $('#containerProfilePopup', page); @@ -516,7 +515,7 @@ import 'listViewStyle'; } function editCodecProfile(page, codecProfile) { - isSubProfileNew = null == codecProfile; + isSubProfileNew = codecProfile == null; codecProfile = codecProfile || {}; currentSubProfile = codecProfile; const popup = $('#codecProfilePopup', page); @@ -556,11 +555,11 @@ import 'listViewStyle'; html += '
    '; html += '

    ' + globalize.translate('ValueContainer', profile.Container || allText) + '

    '; - if ('Video' == profile.Type) { + if (profile.Type == 'Video') { html += '

    ' + globalize.translate('ValueVideoCodec', profile.VideoCodec || allText) + '

    '; html += '

    ' + globalize.translate('ValueAudioCodec', profile.AudioCodec || allText) + '

    '; } else { - if ('Audio' == profile.Type) { + if (profile.Type == 'Audio') { html += '

    ' + globalize.translate('ValueCodec', profile.AudioCodec || allText) + '

    '; } } @@ -596,7 +595,7 @@ import 'listViewStyle'; } function editResponseProfile(page, responseProfile) { - isSubProfileNew = null == responseProfile; + isSubProfileNew = responseProfile == null; responseProfile = responseProfile || {}; currentSubProfile = responseProfile; const popup = $('#responseProfilePopup', page); @@ -704,26 +703,26 @@ import 'listViewStyle'; $('.radioTabButton', page).on('click', function () { $(this).siblings().removeClass('ui-btn-active'); $(this).addClass('ui-btn-active'); - const value = 'A' == this.tagName ? this.getAttribute('data-value') : this.value; + const value = this.tagName == 'A' ? this.getAttribute('data-value') : this.value; const elem = $('.' + value, page); elem.siblings('.tabContent').hide(); elem.show(); }); $('#selectDirectPlayProfileType', page).on('change', function () { - if ('Video' == this.value) { + if (this.value == 'Video') { $('#fldDirectPlayVideoCodec', page).show(); } else { $('#fldDirectPlayVideoCodec', page).hide(); } - if ('Photo' == this.value) { + if (this.value == 'Photo') { $('#fldDirectPlayAudioCodec', page).hide(); } else { $('#fldDirectPlayAudioCodec', page).show(); } }); $('#selectTranscodingProfileType', page).on('change', function () { - if ('Video' == this.value) { + if (this.value == 'Video') { $('#fldTranscodingVideoCodec', page).show(); $('#fldTranscodingProtocol', page).show(); $('#fldEnableMpegtsM2TsMode', page).show(); @@ -733,7 +732,7 @@ import 'listViewStyle'; $('#fldEnableMpegtsM2TsMode', page).hide(); } - if ('Photo' == this.value) { + if (this.value == 'Photo') { $('#fldTranscodingAudioCodec', page).hide(); $('#fldEstimateContentLength', page).hide(); $('#fldReportByteRangeRequests', page).hide(); @@ -744,13 +743,13 @@ import 'listViewStyle'; } }); $('#selectResponseProfileType', page).on('change', function () { - if ('Video' == this.value) { + if (this.value == 'Video') { $('#fldResponseProfileVideoCodec', page).show(); } else { $('#fldResponseProfileVideoCodec', page).hide(); } - if ('Photo' == this.value) { + if (this.value == 'Photo') { $('#fldResponseProfileAudioCodec', page).hide(); } else { $('#fldResponseProfileAudioCodec', page).show(); diff --git a/src/controllers/dashboard/dlna/profiles.js b/src/controllers/dashboard/dlna/profiles.js index 510128be4b..7fd3bdb525 100644 --- a/src/controllers/dashboard/dlna/profiles.js +++ b/src/controllers/dashboard/dlna/profiles.js @@ -18,13 +18,13 @@ import 'emby-button'; function renderUserProfiles(page, profiles) { renderProfiles(page, page.querySelector('.customProfiles'), profiles.filter(function (p) { - return 'User' == p.Type; + return p.Type == 'User'; })); } function renderSystemProfiles(page, profiles) { renderProfiles(page, page.querySelector('.systemProfiles'), profiles.filter(function (p) { - return 'System' == p.Type; + return p.Type == 'System'; })); } @@ -45,7 +45,7 @@ import 'emby-button'; html += '
    '; html += '
    '; - if ('User' == profile.Type) { + if (profile.Type == 'User') { html += ''; } diff --git a/src/controllers/dashboard/encodingsettings.js b/src/controllers/dashboard/encodingsettings.js index aac18360ac..3a0ad24430 100644 --- a/src/controllers/dashboard/encodingsettings.js +++ b/src/controllers/dashboard/encodingsettings.js @@ -8,7 +8,7 @@ import libraryMenu from 'libraryMenu'; function loadPage(page, config, systemInfo) { Array.prototype.forEach.call(page.querySelectorAll('.chkDecodeCodec'), function (c) { - c.checked = -1 !== (config.HardwareDecodingCodecs || []).indexOf(c.getAttribute('data-codec')); + c.checked = (config.HardwareDecodingCodecs || []).indexOf(c.getAttribute('data-codec')) !== -1; }); page.querySelector('#chkDecodingColorDepth10Hevc').checked = config.EnableDecodingColorDepth10Hevc; page.querySelector('#chkDecodingColorDepth10Vp9').checked = config.EnableDecodingColorDepth10Vp9; @@ -81,7 +81,7 @@ import libraryMenu from 'libraryMenu'; updateEncoder(form); }, function () { import('alert').then(({default: alert}) => { - alert(globalize.translate('DefaultErrorMessage')); + alert(globalize.translate('ErrorDefault')); }); Dashboard.processServerConfigurationUpdateResult(); @@ -107,7 +107,7 @@ import libraryMenu from 'libraryMenu'; value = value || ''; let any; Array.prototype.forEach.call(context.querySelectorAll('.chkDecodeCodec'), function (c) { - if (-1 === c.getAttribute('data-types').split(',').indexOf(value)) { + if (c.getAttribute('data-types').split(',').indexOf(value) === -1) { dom.parentWithTag(c, 'LABEL').classList.add('hide'); } else { dom.parentWithTag(c, 'LABEL').classList.remove('hide'); @@ -138,7 +138,7 @@ import libraryMenu from 'libraryMenu'; $(document).on('pageinit', '#encodingSettingsPage', function () { const page = this; page.querySelector('#selectVideoDecoder').addEventListener('change', function () { - if ('vaapi' == this.value) { + if (this.value == 'vaapi') { page.querySelector('.fldVaapiDevice').classList.remove('hide'); page.querySelector('#txtVaapiDevice').setAttribute('required', 'required'); } else { diff --git a/src/controllers/dashboard/general.js b/src/controllers/dashboard/general.js index 8e30749aba..eb819dc415 100644 --- a/src/controllers/dashboard/general.js +++ b/src/controllers/dashboard/general.js @@ -52,7 +52,7 @@ import 'emby-button'; }); }, function () { import('alert').then(({default: alert}) => { - alert(globalize.translate('DefaultErrorMessage')); + alert(globalize.translate('ErrorDefault')); }); Dashboard.processServerConfigurationUpdateResult(); diff --git a/src/controllers/dashboard/librarydisplay.js b/src/controllers/dashboard/librarydisplay.js index 2269e19c44..bbc7e633d1 100644 --- a/src/controllers/dashboard/librarydisplay.js +++ b/src/controllers/dashboard/librarydisplay.js @@ -48,7 +48,7 @@ import 'emby-button'; ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult); }); ApiClient.getNamedConfiguration('metadata').then(function(config) { - config.UseFileCreationTimeForDateAdded = '1' === $('#selectDateAdded', form).val(); + config.UseFileCreationTimeForDateAdded = $('#selectDateAdded', form).val() === '1'; ApiClient.updateNamedConfiguration('metadata', config); }); @@ -61,7 +61,7 @@ import 'emby-button'; libraryMenu.setTabs('librarysetup', 1, getTabs); loadData(); ApiClient.getSystemInfo().then(function(info) { - if ('Windows' === info.OperatingSystem) { + if (info.OperatingSystem === 'Windows') { view.querySelector('.fldSaveMetadataHidden').classList.remove('hide'); } else { view.querySelector('.fldSaveMetadataHidden').classList.add('hide'); diff --git a/src/controllers/dashboard/mediaLibrary.js b/src/controllers/dashboard/mediaLibrary.js index b958e69d22..4fee65e674 100644 --- a/src/controllers/dashboard/mediaLibrary.js +++ b/src/controllers/dashboard/mediaLibrary.js @@ -1,11 +1,9 @@ import $ from 'jQuery'; -import appHost from 'apphost'; import taskButton from 'scripts/taskbutton'; import loading from 'loading'; import libraryMenu from 'libraryMenu'; import globalize from 'globalize'; import dom from 'dom'; -import indicators from 'indicators'; import imageHelper from 'scripts/imagehelper'; import 'cardStyle'; import 'emby-itemrefreshindicator'; @@ -158,7 +156,7 @@ import 'emby-itemrefreshindicator'; } function shouldRefreshLibraryAfterChanges(page) { - return 'mediaLibraryPage' === page.id; + return page.id === 'mediaLibraryPage'; } function reloadVirtualFolders(page, virtualFolders) { @@ -288,7 +286,7 @@ import 'emby-itemrefreshindicator'; if (hasCardImageContainer) { html += '
    '; - html += '
    '; + html += '
    '; html += '
    '; html += '
    '; } @@ -395,7 +393,6 @@ import 'emby-itemrefreshindicator'; }); }); pageIdOn('pagebeforehide', 'mediaLibraryPage', function () { - const page = this; taskButton({ mode: 'off', diff --git a/src/controllers/dashboard/metadataImages.js b/src/controllers/dashboard/metadataImages.js index cbfe05419c..02e01736ea 100644 --- a/src/controllers/dashboard/metadataImages.js +++ b/src/controllers/dashboard/metadataImages.js @@ -1,5 +1,4 @@ import $ from 'jQuery'; -import dom from 'dom'; import loading from 'loading'; import libraryMenu from 'libraryMenu'; import globalize from 'globalize'; diff --git a/src/controllers/dashboard/networking.js b/src/controllers/dashboard/networking.js index 367ab8335c..a7f3076056 100644 --- a/src/controllers/dashboard/networking.js +++ b/src/controllers/dashboard/networking.js @@ -1,5 +1,4 @@ import loading from 'loading'; -import libraryMenu from 'libraryMenu'; import globalize from 'globalize'; import 'emby-checkbox'; import 'emby-select'; @@ -31,7 +30,7 @@ import 'emby-select'; }).filter(function (s) { return s.length > 0; }); - config.IsRemoteIPFilterBlacklist = 'blacklist' === form.querySelector('#selectExternalAddressFilterMode').value; + config.IsRemoteIPFilterBlacklist = form.querySelector('#selectExternalAddressFilterMode').value === 'blacklist'; config.PublicPort = form.querySelector('#txtPublicPort').value; config.PublicHttpsPort = form.querySelector('#txtPublicHttpsPort').value; config.HttpServerPortNumber = form.querySelector('#txtPortNumber').value; @@ -111,7 +110,7 @@ import 'emby-select'; page.querySelector('#txtLanNetworks').value = (config.LocalNetworkSubnets || []).join(', '); page.querySelector('#txtExternalAddressFilter').value = (config.RemoteIPFilter || []).join(', '); page.querySelector('#selectExternalAddressFilterMode').value = config.IsRemoteIPFilterBlacklist ? 'blacklist' : 'whitelist'; - page.querySelector('#chkRemoteAccess').checked = null == config.EnableRemoteAccess || config.EnableRemoteAccess; + page.querySelector('#chkRemoteAccess').checked = config.EnableRemoteAccess == null || config.EnableRemoteAccess; page.querySelector('#txtHttpsPort').value = config.HttpsPortNumber; page.querySelector('#chkEnableHttps').checked = config.EnableHttps; page.querySelector('#chkRequireHttps').checked = config.RequireHttps; diff --git a/src/notificationsetting.html b/src/controllers/dashboard/notifications/notification/index.html similarity index 100% rename from src/notificationsetting.html rename to src/controllers/dashboard/notifications/notification/index.html diff --git a/src/controllers/dashboard/notifications/notification.js b/src/controllers/dashboard/notifications/notification/index.js similarity index 99% rename from src/controllers/dashboard/notifications/notification.js rename to src/controllers/dashboard/notifications/notification/index.js index 013e505f36..2ab3720ccb 100644 --- a/src/controllers/dashboard/notifications/notification.js +++ b/src/controllers/dashboard/notifications/notification/index.js @@ -106,7 +106,7 @@ const notificationsConfigurationKey = 'notifications'; $(document).on('pageinit', '#notificationSettingPage', function () { const page = this; $('#selectUsers', page).on('change', function () { - if ('Custom' == this.value) { + if (this.value == 'Custom') { $('.selectCustomUsers', page).show(); } else { $('.selectCustomUsers', page).hide(); diff --git a/src/notificationsettings.html b/src/controllers/dashboard/notifications/notifications/index.html similarity index 100% rename from src/notificationsettings.html rename to src/controllers/dashboard/notifications/notifications/index.html diff --git a/src/controllers/dashboard/notifications/notifications.js b/src/controllers/dashboard/notifications/notifications/index.js similarity index 100% rename from src/controllers/dashboard/notifications/notifications.js rename to src/controllers/dashboard/notifications/notifications/index.js diff --git a/src/addplugin.html b/src/controllers/dashboard/plugins/add/index.html similarity index 100% rename from src/addplugin.html rename to src/controllers/dashboard/plugins/add/index.html diff --git a/src/controllers/dashboard/plugins/add.js b/src/controllers/dashboard/plugins/add/index.js similarity index 89% rename from src/controllers/dashboard/plugins/add.js rename to src/controllers/dashboard/plugins/add/index.js index 375a0c0ec7..6c666b4646 100644 --- a/src/controllers/dashboard/plugins/add.js +++ b/src/controllers/dashboard/plugins/add/index.js @@ -1,6 +1,8 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'emby-button'], function ($, loading, libraryMenu, globalize, connectionManager) { 'use strict'; + loading = loading.default || loading; + function populateHistory(packageInfo, page) { var html = ''; var length = Math.min(packageInfo.versions.length, 10); @@ -66,7 +68,7 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'e } function alertText(options) { - require(['alert'], function (alert) { + require(['alert'], function ({default: alert}) { alert(options); }); } @@ -79,7 +81,7 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'e page.querySelector('#btnInstall').disabled = true; ApiClient.installPlugin(name, guid, version).then(function () { loading.hide(); - alertText(globalize.translate('PluginInstalledMessage')); + alertText(globalize.translate('MessagePluginInstalled')); }); }; @@ -114,14 +116,12 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'e })[0]; var version = $('#selectVersion', page).val(); - if (installedPlugin) { - if (installedPlugin.Version === version) { - loading.hide(); - Dashboard.alert({ - message: globalize.translate('MessageAlreadyInstalled'), - title: globalize.translate('HeaderPluginInstallation') - }); - } + if (installedPlugin && installedPlugin.Version === version) { + loading.hide(); + Dashboard.alert({ + message: globalize.translate('MessageAlreadyInstalled'), + title: globalize.translate('HeaderPluginInstallation') + }); } else { performInstallation(page, name, guid, version); } diff --git a/src/availableplugins.html b/src/controllers/dashboard/plugins/available/index.html similarity index 100% rename from src/availableplugins.html rename to src/controllers/dashboard/plugins/available/index.html diff --git a/src/controllers/dashboard/plugins/available.js b/src/controllers/dashboard/plugins/available/index.js similarity index 95% rename from src/controllers/dashboard/plugins/available.js rename to src/controllers/dashboard/plugins/available/index.js index 37df8801b5..e38365ef55 100644 --- a/src/controllers/dashboard/plugins/available.js +++ b/src/controllers/dashboard/plugins/available/index.js @@ -1,6 +1,8 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby-checkbox', 'emby-select'], function (loading, libraryMenu, globalize) { 'use strict'; + loading = loading.default || loading; + function reloadList(page) { loading.show(); var promise1 = ApiClient.getAvailablePlugins(); @@ -17,13 +19,13 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby function getHeaderText(category) { category = category.replace(' ', ''); - if ('Channel' === category) { + if (category === 'Channel') { category = 'Channels'; - } else if ('Theme' === category) { + } else if (category === 'Theme') { category = 'Themes'; - } else if ('LiveTV' === category) { + } else if (category === 'LiveTV') { category = 'HeaderLiveTV'; - } else if ('ScreenSaver' === category) { + } else if (category === 'ScreenSaver') { category = 'HeaderScreenSavers'; } @@ -34,7 +36,6 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby var availablePlugins = options.availablePlugins; var installedPlugins = options.installedPlugins; - var categories = []; availablePlugins.forEach(function (plugin, index, array) { plugin.category = plugin.category || 'General'; plugin.categoryDisplayName = getHeaderText(plugin.category); diff --git a/src/installedplugins.html b/src/controllers/dashboard/plugins/installed/index.html similarity index 100% rename from src/installedplugins.html rename to src/controllers/dashboard/plugins/installed/index.html diff --git a/src/controllers/dashboard/plugins/installed.js b/src/controllers/dashboard/plugins/installed/index.js similarity index 95% rename from src/controllers/dashboard/plugins/installed.js rename to src/controllers/dashboard/plugins/installed/index.js index d28a04cb2b..80577d227b 100644 --- a/src/controllers/dashboard/plugins/installed.js +++ b/src/controllers/dashboard/plugins/installed/index.js @@ -1,15 +1,17 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'], function (loading, libraryMenu, dom, globalize) { 'use strict'; + loading = loading.default || loading; + function deletePlugin(page, uniqueid, name) { var msg = globalize.translate('UninstallPluginConfirmation', name); require(['confirm'], function (confirm) { confirm.default({ - title: globalize.translate('UninstallPluginHeader'), + title: globalize.translate('HeaderUninstallPlugin'), text: msg, primary: 'delete', - confirmText: globalize.translate('UninstallPluginHeader') + confirmText: globalize.translate('HeaderUninstallPlugin') }).then(function () { loading.show(); ApiClient.uninstallPlugin(uniqueid).then(function () { @@ -21,7 +23,7 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button' function showNoConfigurationMessage() { Dashboard.alert({ - message: globalize.translate('NoPluginConfigurationMessage') + message: globalize.translate('MessageNoPluginConfiguration') }); } @@ -95,7 +97,7 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button' html += '
    '; html += '

    ' + globalize.translate('MessageNoPluginsInstalled') + '

    '; html += '

    '; - html += globalize.translate('BrowsePluginCatalogMessage'); + html += globalize.translate('MessageBrowsePluginCatalog'); html += '

    '; html += '
    '; } diff --git a/src/repositories.html b/src/controllers/dashboard/plugins/repositories/index.html similarity index 100% rename from src/repositories.html rename to src/controllers/dashboard/plugins/repositories/index.html diff --git a/src/controllers/dashboard/plugins/repositories.js b/src/controllers/dashboard/plugins/repositories/index.js similarity index 100% rename from src/controllers/dashboard/plugins/repositories.js rename to src/controllers/dashboard/plugins/repositories/index.js diff --git a/src/controllers/dashboard/scheduledtasks/scheduledtask.js b/src/controllers/dashboard/scheduledtasks/scheduledtask.js index fe214fef63..7944eb8a60 100644 --- a/src/controllers/dashboard/scheduledtasks/scheduledtask.js +++ b/src/controllers/dashboard/scheduledtasks/scheduledtask.js @@ -10,7 +10,6 @@ import 'emby-select'; /* eslint-disable indent */ function fillTimeOfDay(select) { - const options = []; for (let i = 0; i < 86400000; i += 900000) { @@ -85,21 +84,20 @@ import 'emby-select'; }, // TODO: Replace this mess with date-fns and remove datetime completely getTriggerFriendlyName: function (trigger) { - if ('DailyTrigger' == trigger.Type) { + if (trigger.Type == 'DailyTrigger') { return globalize.translate('DailyAt', ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks)); } - if ('WeeklyTrigger' == trigger.Type) { + if (trigger.Type == 'WeeklyTrigger') { // TODO: The day of week isn't localised as well return globalize.translate('WeeklyAt', trigger.DayOfWeek, ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks)); } - if ('SystemEventTrigger' == trigger.Type && 'WakeFromSleep' == trigger.SystemEvent) { + if (trigger.Type == 'SystemEventTrigger' && trigger.SystemEvent == 'WakeFromSleep') { return globalize.translate('OnWakeFromSleep'); } if (trigger.Type == 'IntervalTrigger') { - const hours = trigger.IntervalTicks / 36e9; if (hours == 0.25) { @@ -138,7 +136,7 @@ import 'emby-select'; }, confirmDeleteTrigger: function (view, index) { import('confirm').then(({default: confirm}) => { - confirm.default(globalize.translate('MessageDeleteTaskTrigger'), globalize.translate('HeaderDeleteTaskTrigger')).then(function () { + confirm(globalize.translate('MessageDeleteTaskTrigger'), globalize.translate('HeaderDeleteTaskTrigger')).then(function () { ScheduledTaskPage.deleteTrigger(view, index); }); }); diff --git a/src/controllers/dashboard/users/useredit.js b/src/controllers/dashboard/users/useredit.js index 866e940e54..796b70c704 100644 --- a/src/controllers/dashboard/users/useredit.js +++ b/src/controllers/dashboard/users/useredit.js @@ -14,13 +14,13 @@ import globalize from 'globalize'; let html = ''; for (const folder of mediaFolders) { - isChecked = user.Policy.EnableContentDeletion || -1 != user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id); + isChecked = user.Policy.EnableContentDeletion || user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id) != -1; checkedAttribute = isChecked ? ' checked="checked"' : ''; html += ''; } for (const folder of channelsResult.Items) { - isChecked = user.Policy.EnableContentDeletion || -1 != user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id); + isChecked = user.Policy.EnableContentDeletion || user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id) != -1; checkedAttribute = isChecked ? ' checked="checked"' : ''; html += ''; } @@ -96,7 +96,7 @@ import globalize from 'globalize'; $('#chkEnableVideoPlaybackTranscoding', page).prop('checked', user.Policy.EnableVideoPlaybackTranscoding); $('#chkEnableVideoPlaybackRemuxing', page).prop('checked', user.Policy.EnablePlaybackRemuxing); $('#chkForceRemoteSourceTranscoding', page).prop('checked', user.Policy.ForceRemoteSourceTranscoding); - $('#chkRemoteAccess', page).prop('checked', null == user.Policy.EnableRemoteAccess || user.Policy.EnableRemoteAccess); + $('#chkRemoteAccess', page).prop('checked', user.Policy.EnableRemoteAccess == null || user.Policy.EnableRemoteAccess); $('#chkEnableSyncTranscoding', page).prop('checked', user.Policy.EnableSyncTranscoding); $('#chkEnableConversion', page).prop('checked', user.Policy.EnableMediaConversion || false); $('#chkEnableSharing', page).prop('checked', user.Policy.EnablePublicSharing); diff --git a/src/controllers/dashboard/users/userlibraryaccess.js b/src/controllers/dashboard/users/userlibraryaccess.js index df42733f0c..d32c7312b7 100644 --- a/src/controllers/dashboard/users/userlibraryaccess.js +++ b/src/controllers/dashboard/users/userlibraryaccess.js @@ -18,7 +18,7 @@ import globalize from 'globalize'; for (let i = 0, length = mediaFolders.length; i < length; i++) { const folder = mediaFolders[i]; - const isChecked = user.Policy.EnableAllFolders || -1 != user.Policy.EnabledFolders.indexOf(folder.Id); + const isChecked = user.Policy.EnableAllFolders || user.Policy.EnabledFolders.indexOf(folder.Id) != -1; const checkedAttribute = isChecked ? ' checked="checked"' : ''; html += ''; } @@ -37,7 +37,7 @@ import globalize from 'globalize'; for (let i = 0, length = channels.length; i < length; i++) { const folder = channels[i]; - const isChecked = user.Policy.EnableAllChannels || -1 != user.Policy.EnabledChannels.indexOf(folder.Id); + const isChecked = user.Policy.EnableAllChannels || user.Policy.EnabledChannels.indexOf(folder.Id) != -1; const checkedAttribute = isChecked ? ' checked="checked"' : ''; html += ''; } @@ -61,7 +61,7 @@ import globalize from 'globalize'; for (let i = 0, length = devices.length; i < length; i++) { const device = devices[i]; - const checkedAttribute = user.Policy.EnableAllDevices || -1 != user.Policy.EnabledDevices.indexOf(device.Id) ? ' checked="checked"' : ''; + const checkedAttribute = user.Policy.EnableAllDevices || user.Policy.EnabledDevices.indexOf(device.Id) != -1 ? ' checked="checked"' : ''; html += ''; } diff --git a/src/controllers/dashboard/users/usernew.js b/src/controllers/dashboard/users/usernew.js index f45cbf8ca8..d3ff449d02 100644 --- a/src/controllers/dashboard/users/usernew.js +++ b/src/controllers/dashboard/users/usernew.js @@ -89,7 +89,7 @@ import 'emby-checkbox'; }); }, function (response) { import('toast').then(({default: toast}) => { - toast(globalize.translate('DefaultErrorMessage')); + toast(globalize.translate('ErrorDefault')); }); loading.hide(); diff --git a/src/controllers/dashboard/users/userparentalcontrol.js b/src/controllers/dashboard/users/userparentalcontrol.js index 3fba3fc2b2..0c74c2c018 100644 --- a/src/controllers/dashboard/users/userparentalcontrol.js +++ b/src/controllers/dashboard/users/userparentalcontrol.js @@ -67,7 +67,7 @@ import 'paper-icon-button-light'; for (let i = 0, length = items.length; i < length; i++) { const item = items[i]; - const checkedAttribute = -1 != user.Policy.BlockUnratedItems.indexOf(item.value) ? ' checked="checked"' : ''; + const checkedAttribute = user.Policy.BlockUnratedItems.indexOf(item.value) != -1 ? ' checked="checked"' : ''; html += ''; } @@ -201,7 +201,7 @@ import 'paper-icon-button-light'; }).then(function (updatedSchedule) { const schedules = getSchedulesFromPage(page); - if (-1 == index) { + if (index == -1) { index = schedules.length; } @@ -228,14 +228,13 @@ import 'paper-icon-button-light'; } function showBlockedTagPopup(page) { - import('prompt').then(({default: prompt}) => { prompt({ label: globalize.translate('LabelTag') }).then(function (value) { const tags = getBlockedTagsFromPage(page); - if (-1 == tags.indexOf(value)) { + if (tags.indexOf(value) == -1) { tags.push(value); loadBlockedTags(page, tags); } diff --git a/src/controllers/dashboard/users/userpasswordpage.js b/src/controllers/dashboard/users/userpasswordpage.js index d694bb2c5d..d399804d3e 100644 --- a/src/controllers/dashboard/users/userpasswordpage.js +++ b/src/controllers/dashboard/users/userpasswordpage.js @@ -14,7 +14,7 @@ import 'emby-button'; let showPasswordSection = true; let showLocalAccessSection = false; - if ('Guest' == user.ConnectLinkType) { + if (user.ConnectLinkType == 'Guest') { page.querySelector('.localAccessSection').classList.add('hide'); showPasswordSection = false; } else if (user.HasConfiguredPassword) { @@ -145,14 +145,14 @@ import 'emby-button'; function resetPassword() { const msg = globalize.translate('PasswordResetConfirmation'); import('confirm').then(({default: confirm}) => { - confirm(msg, globalize.translate('PasswordResetHeader')).then(function () { + confirm(msg, globalize.translate('HeaderResetPassword')).then(function () { const userId = params.userId; loading.show(); ApiClient.resetUserPassword(userId).then(function () { loading.hide(); Dashboard.alert({ message: globalize.translate('PasswordResetComplete'), - title: globalize.translate('PasswordResetHeader') + title: globalize.translate('HeaderResetPassword') }); loadUser(view, params); }); diff --git a/src/controllers/dashboard/users/userprofilespage.js b/src/controllers/dashboard/users/userprofilespage.js index dbdec4f752..add90d0a0b 100644 --- a/src/controllers/dashboard/users/userprofilespage.js +++ b/src/controllers/dashboard/users/userprofilespage.js @@ -129,7 +129,7 @@ import 'flexStyles'; html += '
    '; html += '
    '; const lastSeen = getLastSeenText(user.LastActivityDate); - html += '' != lastSeen ? lastSeen : ' '; + html += lastSeen != '' ? lastSeen : ' '; html += '
    '; html += '
    '; html += '
    '; @@ -155,102 +155,12 @@ import 'flexStyles'; page.querySelector('.localUsers').innerHTML = getUserSectionHtml(users, true); } - function showPendingUserMenu(elem) { - const menuItems = []; - menuItems.push({ - name: globalize.translate('ButtonCancel'), - id: 'delete', - icon: 'delete' - }); - - import('actionsheet').then(({default: actionsheet}) => { - const card = dom.parentWithClass(elem, 'card'); - const page = dom.parentWithClass(card, 'page'); - const id = card.getAttribute('data-id'); - actionsheet.show({ - items: menuItems, - positionTo: card, - callback: function (menuItemId) { - switch (menuItemId) { - case 'delete': - cancelAuthorization(page, id); - } - } - }); - }); - } - - function getPendingUserHtml(user) { - let html = ''; - html += "
    "; - html += '
    '; - html += ''; - html += '
    '; - html += '
    '; - html += ''; - html += '
    '; - html += '
    '; - html += user.UserName; - html += '
    '; - html += '
    '; - html += '
    '; - return html + '
    '; - } - - function renderPendingGuests(page, users) { - if (users.length) { - page.querySelector('.sectionPendingGuests').classList.remove('hide'); - } else { - page.querySelector('.sectionPendingGuests').classList.add('hide'); - } - - page.querySelector('.pending').innerHTML = users.map(getPendingUserHtml).join(''); - } - - // TODO cvium: maybe reuse for invitation system - function cancelAuthorization(page, id) { - loading.show(); - ApiClient.ajax({ - type: 'DELETE', - url: ApiClient.getUrl('Connect/Pending', { - Id: id - }) - }).then(function () { - loadData(page); - }); - } - function loadData(page) { loading.show(); ApiClient.getUsers().then(function (users) { renderUsers(page, users); loading.hide(); }); - // TODO cvium - renderPendingGuests(page, []); - // ApiClient.getJSON(ApiClient.getUrl("Connect/Pending")).then(function (pending) { - // - // }); - } - - function showInvitePopup(page) { - import('components/guestinviter/guestinviter').then(({default: guestinviter}) => { - guestinviter.show().then(function () { - loadData(page); - }); - }); } pageIdOn('pageinit', 'userProfilesPage', function () { @@ -265,14 +175,8 @@ import 'flexStyles'; showUserMenu(btnUserMenu); } }); - page.querySelector('.pending').addEventListener('click', function (e__r) { - const btnUserMenu = dom.parentWithClass(e__r.target, 'btnUserMenu'); - - if (btnUserMenu) { - showPendingUserMenu(btnUserMenu); - } - }); }); + pageIdOn('pagebeforeshow', 'userProfilesPage', function () { loadData(this); }); diff --git a/src/controllers/edititemmetadata.js b/src/controllers/edititemmetadata.js index 1a3647a758..57c72dda28 100644 --- a/src/controllers/edititemmetadata.js +++ b/src/controllers/edititemmetadata.js @@ -1,31 +1,30 @@ -define(['loading', 'scripts/editorsidebar'], function (loading) { - 'use strict'; +import loading from 'loading'; +import 'scripts/editorsidebar'; - function reload(context, itemId) { - loading.show(); +function reload(context, itemId) { + loading.show(); - if (itemId) { - require(['metadataEditor'], function ({default: metadataEditor}) { - metadataEditor.embed(context.querySelector('.editPageInnerContent'), itemId, ApiClient.serverInfo().Id); - }); - } else { - context.querySelector('.editPageInnerContent').innerHTML = ''; - loading.hide(); - } + if (itemId) { + import('metadataEditor').then(({ default: metadataEditor }) => { + metadataEditor.embed(context.querySelector('.editPageInnerContent'), itemId, ApiClient.serverInfo().Id); + }); + } else { + context.querySelector('.editPageInnerContent').innerHTML = ''; + loading.hide(); } +} - return function (view, params) { - view.addEventListener('viewshow', function () { - reload(this, MetadataEditor.getCurrentItemId()); - }); - MetadataEditor.setCurrentItemId(null); - view.querySelector('.libraryTree').addEventListener('itemclicked', function (event) { - var data = event.detail; +export default function (view, params) { + view.addEventListener('viewshow', function () { + reload(this, MetadataEditor.getCurrentItemId()); + }); + MetadataEditor.setCurrentItemId(null); + view.querySelector('.libraryTree').addEventListener('itemclicked', function (event) { + var data = event.detail; - if (data.id != MetadataEditor.getCurrentItemId()) { - MetadataEditor.setCurrentItemId(data.id); - reload(view, data.id); - } - }); - }; -}); + if (data.id != MetadataEditor.getCurrentItemId()) { + MetadataEditor.setCurrentItemId(data.id); + reload(view, data.id); + } + }); +} diff --git a/src/controllers/favorites.js b/src/controllers/favorites.js index b4c7936239..7e316df118 100644 --- a/src/controllers/favorites.js +++ b/src/controllers/favorites.js @@ -1,5 +1,15 @@ -define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'apphost', 'layoutManager', 'focusManager', 'emby-itemscontainer', 'emby-scroller'], function (appRouter, cardBuilder, dom, globalize, connectionManager, appHost, layoutManager, focusManager) { - 'use strict'; +import appRouter from 'appRouter'; +import cardBuilder from 'cardBuilder'; +import dom from 'dom'; +import globalize from 'globalize'; +import connectionManager from 'connectionManager'; +import appHost from 'apphost'; +import layoutManager from 'layoutManager'; +import focusManager from 'focusManager'; +import 'emby-itemscontainer'; +import 'emby-scroller'; + +/* eslint-disable indent */ function enableScrollX() { return true; @@ -133,8 +143,8 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap function getFetchDataFn(section) { return function () { - var apiClient = this.apiClient; - var options = { + const apiClient = this.apiClient; + const options = { SortBy: (section.types, 'SeriesName,SortName'), SortOrder: 'Ascending', Filters: 'IsFavorite', @@ -145,13 +155,13 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap EnableTotalRecordCount: false }; options.Limit = 20; - var userId = apiClient.getCurrentUserId(); + const userId = apiClient.getCurrentUserId(); - if ('MusicArtist' === section.types) { + if (section.types === 'MusicArtist') { return apiClient.getArtists(userId, options); } - if ('Person' === section.types) { + if (section.types === 'Person') { return apiClient.getPeople(userId, options); } @@ -170,17 +180,16 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap function getItemsHtmlFn(section) { return function (items) { - var supportsImageAnalysis = appHost.supports('imageanalysis'); - var cardLayout = (appHost.preferVisualCards || supportsImageAnalysis) && section.autoCardLayout && section.showTitle; + let cardLayout = appHost.preferVisualCards && section.autoCardLayout && section.showTitle; cardLayout = false; - var serverId = this.apiClient.serverId(); - var leadingButtons = layoutManager.tv ? [{ + const serverId = this.apiClient.serverId(); + const leadingButtons = layoutManager.tv ? [{ name: globalize.translate('All'), id: 'more', icon: 'favorite', routeUrl: getRouteUrl(section, serverId) }] : null; - var lines = 0; + let lines = 0; if (section.showTitle) { lines++; @@ -199,7 +208,7 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap preferThumb: section.preferThumb, shape: section.shape, centerText: section.centerText && !cardLayout, - overlayText: false !== section.overlayText, + overlayText: section.overlayText !== false, showTitle: section.showTitle, showYear: section.showYear, showParentTitle: section.showParentTitle, @@ -216,23 +225,12 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap }; } - function FavoritesTab(view, params) { - this.view = view; - this.params = params; - this.apiClient = connectionManager.currentApiClient(); - this.sectionsContainer = view.querySelector('.sections'); - createSections(this, this.sectionsContainer, this.apiClient); - } - function createSections(instance, elem, apiClient) { - var i; - var length; - var sections = getSections(); - var html = ''; + const sections = getSections(); + let html = ''; - for (i = 0, length = sections.length; i < length; i++) { - var section = sections[i]; - var sectionClass = 'verticalSection'; + for (const section of sections) { + let sectionClass = 'verticalSection'; if (!section.showTitle) { sectionClass += ' verticalSection-extrabottompadding'; @@ -258,23 +256,32 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap } elem.innerHTML = html; - var elems = elem.querySelectorAll('.itemsContainer'); + const elems = elem.querySelectorAll('.itemsContainer'); - for (i = 0, length = elems.length; i < length; i++) { - var itemsContainer = elems[i]; + for (let i = 0, length = elems.length; i < length; i++) { + const itemsContainer = elems[i]; itemsContainer.fetchData = getFetchDataFn(sections[i]).bind(instance); itemsContainer.getItemsHtml = getItemsHtmlFn(sections[i]).bind(instance); itemsContainer.parentContainer = dom.parentWithClass(itemsContainer, 'verticalSection'); } } - FavoritesTab.prototype.onResume = function (options) { - var promises = (this.apiClient, []); - var view = this.view; - var elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); +class FavoritesTab { + constructor(view, params) { + this.view = view; + this.params = params; + this.apiClient = connectionManager.currentApiClient(); + this.sectionsContainer = view.querySelector('.sections'); + createSections(this, this.sectionsContainer, this.apiClient); + } - for (var i = 0, length = elems.length; i < length; i++) { - promises.push(elems[i].resume(options)); + onResume(options) { + const promises = (this.apiClient, []); + const view = this.view; + const elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); + + for (const elem of elems) { + promises.push(elem.resume(options)); } Promise.all(promises).then(function () { @@ -282,30 +289,32 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap focusManager.autoFocus(view); } }); - }; + } - FavoritesTab.prototype.onPause = function () { - var elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); + onPause() { + const elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); - for (var i = 0, length = elems.length; i < length; i++) { - elems[i].pause(); + for (const elem of elems) { + elem.pause(); } - }; + } - FavoritesTab.prototype.destroy = function () { + destroy() { this.view = null; this.params = null; this.apiClient = null; - var elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); + const elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); - for (var i = 0, length = elems.length; i < length; i++) { - elems[i].fetchData = null; - elems[i].getItemsHtml = null; - elems[i].parentContainer = null; + for (const elem of elems) { + elem.fetchData = null; + elem.getItemsHtml = null; + elem.parentContainer = null; } this.sectionsContainer = null; - }; + } +} - return FavoritesTab; -}); +export default FavoritesTab; + +/* eslint-enable indent */ diff --git a/src/controllers/home.js b/src/controllers/home.js index 9a4cea2227..b615b3609d 100644 --- a/src/controllers/home.js +++ b/src/controllers/home.js @@ -20,7 +20,7 @@ define(['tabbedView', 'globalize', 'require', 'emby-tabs', 'emby-button', 'emby- } function getTabController(index) { - if (null == index) { + if (index == null) { throw new Error('index cannot be null'); } @@ -40,7 +40,7 @@ define(['tabbedView', 'globalize', 'require', 'emby-tabs', 'emby-button', 'emby- var controller = instance.tabControllers[index]; if (!controller) { - controller = new controllerFactory(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params); + controller = new controllerFactory.default(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params); instance.tabControllers[index] = controller; } diff --git a/src/controllers/hometab.js b/src/controllers/hometab.js index 8e2a1f92e7..d834e3e233 100644 --- a/src/controllers/hometab.js +++ b/src/controllers/hometab.js @@ -1,27 +1,21 @@ -define(['userSettings', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'focusManager', 'homeSections', 'emby-itemscontainer'], function (userSettings, loading, connectionManager, appHost, layoutManager, focusManager, homeSections) { - 'use strict'; +import * as userSettings from 'userSettings'; +import loading from 'loading'; +import connectionManager from 'connectionManager'; +import focusManager from 'focusManager'; +import homeSections from 'homeSections'; +import 'emby-itemscontainer'; - function HomeTab(view, params) { +class HomeTab { + constructor(view, params) { this.view = view; this.params = params; this.apiClient = connectionManager.currentApiClient(); this.sectionsContainer = view.querySelector('.sections'); view.querySelector('.sections').addEventListener('settingschange', onHomeScreenSettingsChanged.bind(this)); } - - function onHomeScreenSettingsChanged() { - this.sectionsRendered = false; - - if (!this.paused) { - this.onResume({ - refresh: true - }); - } - } - - HomeTab.prototype.onResume = function (options) { + onResume(options) { if (this.sectionsRendered) { - var sectionsContainer = this.sectionsContainer; + const sectionsContainer = this.sectionsContainer; if (sectionsContainer) { return homeSections.resume(sectionsContainer, options); @@ -31,8 +25,8 @@ define(['userSettings', 'loading', 'connectionManager', 'apphost', 'layoutManage } loading.show(); - var view = this.view; - var apiClient = this.apiClient; + const view = this.view; + const apiClient = this.apiClient; this.destroyHomeSections(); this.sectionsRendered = true; return apiClient.getCurrentUser().then(function (user) { @@ -44,31 +38,38 @@ define(['userSettings', 'loading', 'connectionManager', 'apphost', 'layoutManage loading.hide(); }); }); - }; - - HomeTab.prototype.onPause = function () { - var sectionsContainer = this.sectionsContainer; + } + onPause() { + const sectionsContainer = this.sectionsContainer; if (sectionsContainer) { homeSections.pause(sectionsContainer); } - }; - - HomeTab.prototype.destroy = function () { + } + destroy() { this.view = null; this.params = null; this.apiClient = null; this.destroyHomeSections(); this.sectionsContainer = null; - }; - - HomeTab.prototype.destroyHomeSections = function () { - var sectionsContainer = this.sectionsContainer; + } + destroyHomeSections() { + const sectionsContainer = this.sectionsContainer; if (sectionsContainer) { homeSections.destroySections(sectionsContainer); } - }; + } +} - return HomeTab; -}); +function onHomeScreenSettingsChanged() { + this.sectionsRendered = false; + + if (!this.paused) { + this.onResume({ + refresh: true + }); + } +} + +export default HomeTab; diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index 011bc4ac92..df2855d69a 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -1,8 +1,36 @@ -define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSettings', 'cardBuilder', 'datetime', 'mediaInfo', 'backdrop', 'listView', 'itemContextMenu', 'itemHelper', 'dom', 'indicators', 'imageLoader', 'libraryMenu', 'globalize', 'browser', 'events', 'playbackManager', 'scrollStyles', 'emby-itemscontainer', 'emby-checkbox', 'emby-button', 'emby-playstatebutton', 'emby-ratingbutton', 'emby-scroller', 'emby-select'], function (loading, appRouter, layoutManager, connectionManager, userSettings, cardBuilder, datetime, mediaInfo, backdrop, listView, itemContextMenu, itemHelper, dom, indicators, imageLoader, libraryMenu, globalize, browser, events, playbackManager) { - 'use strict'; +import loading from 'loading'; +import appRouter from 'appRouter'; +import layoutManager from 'layoutManager'; +import connectionManager from 'connectionManager'; +import * as userSettings from 'userSettings'; +import cardBuilder from 'cardBuilder'; +import datetime from 'datetime'; +import mediaInfo from 'mediaInfo'; +import backdrop from 'backdrop'; +import listView from 'listView'; +import itemContextMenu from 'itemContextMenu'; +import itemHelper from 'itemHelper'; +import dom from 'dom'; +import indicators from 'indicators'; +import imageLoader from 'imageLoader'; +import libraryMenu from 'libraryMenu'; +import globalize from 'globalize'; +import browser from 'browser'; +import events from 'events'; +import playbackManager from 'playbackManager'; +import 'scrollStyles'; +import 'emby-itemscontainer'; +import 'emby-checkbox'; +import 'emby-button'; +import 'emby-playstatebutton'; +import 'emby-ratingbutton'; +import 'emby-scroller'; +import 'emby-select'; + +/* eslint-disable indent */ function getPromise(apiClient, params) { - var id = params.id; + const id = params.id; if (id) { return apiClient.getItem(apiClient.getCurrentUserId(), id); @@ -38,7 +66,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function getContextMenuOptions(item, user, button) { - var options = { + return { item: item, open: false, play: false, @@ -53,12 +81,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti user: user, share: true }; - - return options; } function getProgramScheduleHtml(items) { - var html = ''; + let html = ''; html += '
    '; html += listView.getListViewHtml({ @@ -94,15 +120,15 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti result.Items = []; } - var html = getProgramScheduleHtml(result.Items); - var scheduleTab = page.querySelector('.seriesTimerSchedule'); + const html = getProgramScheduleHtml(result.Items); + const scheduleTab = page.querySelector('.seriesTimerSchedule'); scheduleTab.innerHTML = html; imageLoader.lazyChildren(scheduleTab); }); } function renderTimerEditor(page, item, apiClient, user) { - if ('Recording' !== item.Type || !user.Policy.EnableLiveTvManagement || !item.TimerId || 'InProgress' !== item.Status) { + if (item.Type !== 'Recording' || !user.Policy.EnableLiveTvManagement || !item.TimerId || item.Status !== 'InProgress') { return void hideAll(page, 'btnCancelTimer'); } @@ -110,12 +136,12 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderSeriesTimerEditor(page, item, apiClient, user) { - if ('SeriesTimer' !== item.Type) { + if (item.Type !== 'SeriesTimer') { return void hideAll(page, 'btnCancelSeriesTimer'); } if (user.Policy.EnableLiveTvManagement) { - require(['seriesRecordingEditor'], function (seriesRecordingEditor) { + import('seriesRecordingEditor').then(({default: seriesRecordingEditor}) => { seriesRecordingEditor.embed(item, apiClient.serverId(), { context: page.querySelector('.seriesRecordingEditor') }); @@ -131,9 +157,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderTrackSelections(page, instance, item, forceReload) { - var select = page.querySelector('.selectSource'); + const select = page.querySelector('.selectSource'); - if (!item.MediaSources || !itemHelper.supportsMediaSourceSelection(item) || -1 === playbackManager.getSupportedCommands().indexOf('PlayMediaSource') || !playbackManager.canPlay(item)) { + if (!item.MediaSources || !itemHelper.supportsMediaSourceSelection(item) || playbackManager.getSupportedCommands().indexOf('PlayMediaSource') === -1 || !playbackManager.canPlay(item)) { page.querySelector('.trackSelections').classList.add('hide'); select.innerHTML = ''; page.querySelector('.selectVideo').innerHTML = ''; @@ -142,17 +168,17 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti return; } - var mediaSources = item.MediaSources; + const mediaSources = item.MediaSources; instance._currentPlaybackMediaSources = mediaSources; page.querySelector('.trackSelections').classList.remove('hide'); select.setLabel(globalize.translate('LabelVersion')); - var currentValue = select.value; + const currentValue = select.value; - var selectedId = mediaSources[0].Id; + const selectedId = mediaSources[0].Id; select.innerHTML = mediaSources.map(function (v) { - var selected = v.Id === selectedId ? ' selected' : ''; + const selected = v.Id === selectedId ? ' selected' : ''; return ''; }).join(''); @@ -170,22 +196,22 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderVideoSelections(page, mediaSources) { - var mediaSourceId = page.querySelector('.selectSource').value; - var mediaSource = mediaSources.filter(function (m) { + const mediaSourceId = page.querySelector('.selectSource').value; + const mediaSource = mediaSources.filter(function (m) { return m.Id === mediaSourceId; })[0]; - var tracks = mediaSource.MediaStreams.filter(function (m) { + const tracks = mediaSource.MediaStreams.filter(function (m) { return m.Type === 'Video'; }); - var select = page.querySelector('.selectVideo'); + const select = page.querySelector('.selectVideo'); select.setLabel(globalize.translate('LabelVideo')); - var selectedId = tracks.length ? tracks[0].Index : -1; + const selectedId = tracks.length ? tracks[0].Index : -1; select.innerHTML = tracks.map(function (v) { - var selected = v.Index === selectedId ? ' selected' : ''; - var titleParts = []; - var resolutionText = mediaInfo.getResolutionText(v); + const selected = v.Index === selectedId ? ' selected' : ''; + const titleParts = []; + const resolutionText = mediaInfo.getResolutionText(v); if (resolutionText) { titleParts.push(resolutionText); @@ -207,18 +233,18 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderAudioSelections(page, mediaSources) { - var mediaSourceId = page.querySelector('.selectSource').value; - var mediaSource = mediaSources.filter(function (m) { + const mediaSourceId = page.querySelector('.selectSource').value; + const mediaSource = mediaSources.filter(function (m) { return m.Id === mediaSourceId; })[0]; - var tracks = mediaSource.MediaStreams.filter(function (m) { - return 'Audio' === m.Type; + const tracks = mediaSource.MediaStreams.filter(function (m) { + return m.Type === 'Audio'; }); - var select = page.querySelector('.selectAudio'); + const select = page.querySelector('.selectAudio'); select.setLabel(globalize.translate('LabelAudio')); - var selectedId = mediaSource.DefaultAudioStreamIndex; + const selectedId = mediaSource.DefaultAudioStreamIndex; select.innerHTML = tracks.map(function (v) { - var selected = v.Index === selectedId ? ' selected' : ''; + const selected = v.Index === selectedId ? ' selected' : ''; return ''; }).join(''); @@ -236,24 +262,24 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderSubtitleSelections(page, mediaSources) { - var mediaSourceId = page.querySelector('.selectSource').value; - var mediaSource = mediaSources.filter(function (m) { + const mediaSourceId = page.querySelector('.selectSource').value; + const mediaSource = mediaSources.filter(function (m) { return m.Id === mediaSourceId; })[0]; - var tracks = mediaSource.MediaStreams.filter(function (m) { - return 'Subtitle' === m.Type; + const tracks = mediaSource.MediaStreams.filter(function (m) { + return m.Type === 'Subtitle'; }); - var select = page.querySelector('.selectSubtitles'); + const select = page.querySelector('.selectSubtitles'); select.setLabel(globalize.translate('LabelSubtitles')); - var selectedId = null == mediaSource.DefaultSubtitleStreamIndex ? -1 : mediaSource.DefaultSubtitleStreamIndex; + const selectedId = mediaSource.DefaultSubtitleStreamIndex == null ? -1 : mediaSource.DefaultSubtitleStreamIndex; - var videoTracks = mediaSource.MediaStreams.filter(function (m) { - return 'Video' === m.Type; + const videoTracks = mediaSource.MediaStreams.filter(function (m) { + return m.Type === 'Video'; }); // This only makes sense on Video items if (videoTracks.length) { - var selected = -1 === selectedId ? ' selected' : ''; + let selected = selectedId === -1 ? ' selected' : ''; select.innerHTML = '' + tracks.map(function (v) { selected = v.Index === selectedId ? ' selected' : ''; return ''; @@ -273,10 +299,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function reloadPlayButtons(page, item) { - var canPlay = false; + let canPlay = false; - if ('Program' == item.Type) { - var now = new Date(); + if (item.Type == 'Program') { + const now = new Date(); if (now >= datetime.parseISO8601Date(item.StartDate, true) && now < datetime.parseISO8601Date(item.EndDate, true)) { hideAll(page, 'btnPlay', true); @@ -290,9 +316,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti hideAll(page, 'btnShuffle'); } else if (playbackManager.canPlay(item)) { hideAll(page, 'btnPlay', true); - var enableInstantMix = -1 !== ['Audio', 'MusicAlbum', 'MusicGenre', 'MusicArtist'].indexOf(item.Type); + const enableInstantMix = ['Audio', 'MusicAlbum', 'MusicGenre', 'MusicArtist'].indexOf(item.Type) !== -1; hideAll(page, 'btnInstantMix', enableInstantMix); - var enableShuffle = item.IsFolder || -1 !== ['MusicAlbum', 'MusicGenre', 'MusicArtist'].indexOf(item.Type); + const enableShuffle = item.IsFolder || ['MusicAlbum', 'MusicGenre', 'MusicArtist'].indexOf(item.Type) !== -1; hideAll(page, 'btnShuffle', enableShuffle); canPlay = true; @@ -315,12 +341,12 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function reloadUserDataButtons(page, item) { - var i; - var length; - var btnPlaystates = page.querySelectorAll('.btnPlaystate'); + let i; + let length; + const btnPlaystates = page.querySelectorAll('.btnPlaystate'); for (i = 0, length = btnPlaystates.length; i < length; i++) { - var btnPlaystate = btnPlaystates[i]; + const btnPlaystate = btnPlaystates[i]; if (itemHelper.canMarkPlayed(item)) { btnPlaystate.classList.remove('hide'); @@ -331,10 +357,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } } - var btnUserRatings = page.querySelectorAll('.btnUserRating'); + const btnUserRatings = page.querySelectorAll('.btnUserRating'); for (i = 0, length = btnUserRatings.length; i < length; i++) { - var btnUserRating = btnUserRatings[i]; + const btnUserRating = btnUserRatings[i]; if (itemHelper.canRate(item)) { btnUserRating.classList.remove('hide'); @@ -347,19 +373,18 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function getArtistLinksHtml(artists, serverId, context) { - var html = []; + let html = []; for (const artist of artists) { - var href = appRouter.getRouteUrl(artist, { + const href = appRouter.getRouteUrl(artist, { context: context, itemType: 'MusicArtist', serverId: serverId }); html.push('' + artist.Name + ''); } - html = html.join(' / '); - return html; + return html.join(' / '); } /** @@ -369,17 +394,17 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti * @param {Object} context - Application context. */ function renderName(item, container, context) { - var parentRoute; - var parentNameHtml = []; - var parentNameLast = false; + let parentRoute; + const parentNameHtml = []; + let parentNameLast = false; if (item.AlbumArtists) { parentNameHtml.push(getArtistLinksHtml(item.AlbumArtists, item.ServerId, context)); parentNameLast = true; - } else if (item.ArtistItems && item.ArtistItems.length && 'MusicVideo' === item.Type) { + } else if (item.ArtistItems && item.ArtistItems.length && item.Type === 'MusicVideo') { parentNameHtml.push(getArtistLinksHtml(item.ArtistItems, item.ServerId, context)); parentNameLast = true; - } else if (item.SeriesName && 'Episode' === item.Type) { + } else if (item.SeriesName && item.Type === 'Episode') { parentRoute = appRouter.getRouteUrl({ Id: item.SeriesId, Name: item.SeriesName, @@ -394,7 +419,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti parentNameHtml.push(item.Name); } - if (item.SeriesName && 'Season' === item.Type) { + if (item.SeriesName && item.Type === 'Season') { parentRoute = appRouter.getRouteUrl({ Id: item.SeriesId, Name: item.SeriesName, @@ -405,7 +430,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti context: context }); parentNameHtml.push('' + item.SeriesName + ''); - } else if (null != item.ParentIndexNumber && 'Episode' === item.Type) { + } else if (item.ParentIndexNumber != null && item.Type === 'Episode') { parentRoute = appRouter.getRouteUrl({ Id: item.SeasonId, Name: item.SeasonName, @@ -416,9 +441,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti context: context }); parentNameHtml.push('' + item.SeasonName + ''); - } else if (null != item.ParentIndexNumber && item.IsSeries) { + } else if (item.ParentIndexNumber != null && item.IsSeries) { parentNameHtml.push(item.SeasonName || 'S' + item.ParentIndexNumber); - } else if (item.Album && item.AlbumId && ('MusicVideo' === item.Type || 'Audio' === item.Type)) { + } else if (item.Album && item.AlbumId && (item.Type === 'MusicVideo' || item.Type === 'Audio')) { parentRoute = appRouter.getRouteUrl({ Id: item.AlbumId, Name: item.Album, @@ -434,9 +459,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } // FIXME: This whole section needs some refactoring, so it becames easier to scale across all form factors. See GH #1022 - var html = ''; - var tvShowHtml = parentNameHtml[0]; - var tvSeasonHtml = parentNameHtml[1]; + let html = ''; + const tvShowHtml = parentNameHtml[0]; + const tvSeasonHtml = parentNameHtml[1]; if (parentNameHtml.length) { if (parentNameLast) { @@ -451,7 +476,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } } - var name = itemHelper.getDisplayName(item, { + const name = itemHelper.getDisplayName(item, { includeParentInfo: false }); @@ -481,7 +506,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function setTrailerButtonVisibility(page, item) { - if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf('PlayTrailers')) { + if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && playbackManager.getSupportedCommands().indexOf('PlayTrailers') !== -1) { hideAll(page, 'btnPlayTrailer', true); } else { hideAll(page, 'btnPlayTrailer'); @@ -497,9 +522,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderDetailPageBackdrop(page, item, apiClient) { - var imgUrl; - var hasbackdrop = false; - var itemBackdropElement = page.querySelector('#itemBackdrop'); + let imgUrl; + let hasbackdrop = false; + const itemBackdropElement = page.querySelector('#itemBackdrop'); if (!layoutManager.mobile && !userSettings.detailsBanner()) { return false; @@ -523,6 +548,14 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti }); imageLoader.lazyImage(itemBackdropElement, imgUrl); hasbackdrop = true; + } else if (item.ImageTags && item.ImageTags.Primary) { + imgUrl = apiClient.getScaledImageUrl(item.Id, { + type: 'Primary', + maxWidth: dom.getScreenWidth(), + tag: item.ImageTags.Primary + }); + imageLoader.lazyImage(itemBackdropElement, imgUrl); + hasbackdrop = true; } else { itemBackdropElement.style.backgroundImage = ''; } @@ -550,9 +583,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti renderSeriesTimerEditor(page, item, apiClient, user); renderTimerEditor(page, item, apiClient, user); setInitialCollapsibleState(page, item, apiClient, params.context, user); - var canPlay = reloadPlayButtons(page, item); + const canPlay = reloadPlayButtons(page, item); - if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf('PlayTrailers')) { + if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && playbackManager.getSupportedCommands().indexOf('PlayTrailers') !== -1) { hideAll(page, 'btnPlayTrailer', true); } else { hideAll(page, 'btnPlayTrailer'); @@ -560,15 +593,15 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti setTrailerButtonVisibility(page, item); - if ('Program' !== item.Type || canPlay) { + if (item.Type !== 'Program' || canPlay) { hideAll(page, 'mainDetailButtons', true); } else { hideAll(page, 'mainDetailButtons'); } showRecordingFields(instance, page, item, user); - var groupedVersions = (item.MediaSources || []).filter(function (g) { - return 'Grouping' == g.Type; + const groupedVersions = (item.MediaSources || []).filter(function (g) { + return g.Type == 'Grouping'; }); if (user.Policy.IsAdministrator && groupedVersions.length) { @@ -583,11 +616,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti hideAll(page, 'btnMoreCommands'); } - var itemBirthday = page.querySelector('#itemBirthday'); + const itemBirthday = page.querySelector('#itemBirthday'); - if ('Person' == item.Type && item.PremiereDate) { + if (item.Type == 'Person' && item.PremiereDate) { try { - var birthday = datetime.parseISO8601Date(item.PremiereDate, true).toDateString(); + const birthday = datetime.parseISO8601Date(item.PremiereDate, true).toDateString(); itemBirthday.classList.remove('hide'); itemBirthday.innerHTML = globalize.translate('BirthDateValue', birthday); } catch (err) { @@ -597,11 +630,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti itemBirthday.classList.add('hide'); } - var itemDeathDate = page.querySelector('#itemDeathDate'); + const itemDeathDate = page.querySelector('#itemDeathDate'); - if ('Person' == item.Type && item.EndDate) { + if (item.Type == 'Person' && item.EndDate) { try { - var deathday = datetime.parseISO8601Date(item.EndDate, true).toDateString(); + const deathday = datetime.parseISO8601Date(item.EndDate, true).toDateString(); itemDeathDate.classList.remove('hide'); itemDeathDate.innerHTML = globalize.translate('DeathDateValue', deathday); } catch (err) { @@ -611,10 +644,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti itemDeathDate.classList.add('hide'); } - var itemBirthLocation = page.querySelector('#itemBirthLocation'); + const itemBirthLocation = page.querySelector('#itemBirthLocation'); - if ('Person' == item.Type && item.ProductionLocations && item.ProductionLocations.length) { - var gmap = '' + item.ProductionLocations[0] + ''; + if (item.Type == 'Person' && item.ProductionLocations && item.ProductionLocations.length) { + const gmap = '' + item.ProductionLocations[0] + ''; itemBirthLocation.classList.remove('hide'); itemBirthLocation.innerHTML = globalize.translate('BirthPlaceValue', gmap); } else { @@ -628,7 +661,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti hideAll(page, 'btnDownload', true); } - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(page); }); } @@ -651,9 +684,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderLogo(page, item, apiClient) { - var detailLogo = page.querySelector('.detailLogo'); + const detailLogo = page.querySelector('.detailLogo'); - var url = logoImageUrl(item, apiClient, {}); + const url = logoImageUrl(item, apiClient, {}); if (!layoutManager.mobile && !userSettings.enableBackdrops()) { detailLogo.classList.add('hide'); @@ -667,10 +700,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti function showRecordingFields(instance, page, item, user) { if (!instance.currentRecordingFields) { - var recordingFieldsElement = page.querySelector('.recordingFields'); + const recordingFieldsElement = page.querySelector('.recordingFields'); - if ('Program' == item.Type && user.Policy.EnableLiveTvManagement) { - require(['recordingFields'], function (recordingFields) { + if (item.Type == 'Program' && user.Policy.EnableLiveTvManagement) { + import('recordingFields').then(({default: recordingFields}) => { instance.currentRecordingFields = new recordingFields({ parent: recordingFieldsElement, programId: item.Id, @@ -686,9 +719,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderLinks(page, item) { - var externalLinksElem = page.querySelector('.itemExternalLinks'); + const externalLinksElem = page.querySelector('.itemExternalLinks'); - var links = []; + const links = []; if (!layoutManager.tv && item.HomePageUrl) { links.push(`${globalize.translate('ButtonWebsite')}`); @@ -700,7 +733,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } } - var html = []; + const html = []; if (links.length) { html.push(links.join(', ')); } @@ -726,7 +759,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti disableIndicators: true, disableHoverMenu: true, overlayPlayButton: true, - width: dom.getWindowSize().innerWidth * 0.5 + width: dom.getWindowSize().innerWidth * 0.25 }); elem.innerHTML = cardHtml; @@ -750,7 +783,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function setPeopleHeader(page, item) { - if ('Audio' == item.MediaType || 'MusicAlbum' == item.Type || 'Book' == item.MediaType || 'Photo' == item.MediaType) { + if (item.MediaType == 'Audio' || item.Type == 'MusicAlbum' || item.MediaType == 'Book' || item.MediaType == 'Photo') { page.querySelector('#peopleHeader').innerHTML = globalize.translate('HeaderPeople'); } else { page.querySelector('#peopleHeader').innerHTML = globalize.translate('HeaderCastAndCrew'); @@ -758,9 +791,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderNextUp(page, item, user) { - var section = page.querySelector('.nextUpSection'); + const section = page.querySelector('.nextUpSection'); - if ('Series' != item.Type) { + if (item.Type != 'Series') { return void section.classList.add('hide'); } @@ -774,16 +807,16 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti section.classList.add('hide'); } - var html = cardBuilder.getCardsHtml({ + const html = cardBuilder.getCardsHtml({ items: result.Items, shape: 'overflowBackdrop', showTitle: true, - displayAsSpecial: 'Season' == item.Type && item.IndexNumber, + displayAsSpecial: item.Type == 'Season' && item.IndexNumber, overlayText: false, centerText: true, overlayPlayButton: true }); - var itemsContainer = section.querySelector('.nextUpItems'); + const itemsContainer = section.querySelector('.nextUpItems'); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); }); @@ -792,14 +825,14 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti function setInitialCollapsibleState(page, item, apiClient, context, user) { page.querySelector('.collectionItems').innerHTML = ''; - if ('Playlist' == item.Type) { + if (item.Type == 'Playlist') { page.querySelector('#childrenCollapsible').classList.remove('hide'); renderPlaylistItems(page, item); - } else if ('Studio' == item.Type || 'Person' == item.Type || 'Genre' == item.Type || 'MusicGenre' == item.Type || 'MusicArtist' == item.Type) { + } else if (item.Type == 'Studio' || item.Type == 'Person' || item.Type == 'Genre' || item.Type == 'MusicGenre' || item.Type == 'MusicArtist') { page.querySelector('#childrenCollapsible').classList.remove('hide'); renderItemsByName(page, item); } else if (item.IsFolder) { - if ('BoxSet' == item.Type) { + if (item.Type == 'BoxSet') { page.querySelector('#childrenCollapsible').classList.add('hide'); } @@ -808,7 +841,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti page.querySelector('#childrenCollapsible').classList.add('hide'); } - if ('Series' == item.Type) { + if (item.Type == 'Series') { renderSeriesSchedule(page, item); renderNextUp(page, item, user); } else { @@ -817,7 +850,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti renderScenes(page, item); - if (item.SpecialFeatureCount && 0 != item.SpecialFeatureCount && 'Series' != item.Type) { + if (item.SpecialFeatureCount && item.SpecialFeatureCount != 0 && item.Type != 'Series') { page.querySelector('#specialsCollapsible').classList.remove('hide'); renderSpecials(page, item, user); } else { @@ -833,7 +866,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti page.querySelector('#additionalPartsCollapsible').classList.add('hide'); } - if ('MusicAlbum' == item.Type) { + if (item.Type == 'MusicAlbum') { renderMusicVideos(page, item, user); } else { page.querySelector('#musicVideosCollapsible').classList.add('hide'); @@ -841,8 +874,8 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function toggleLineClamp(clampTarget, e) { - var expandButton = e.target; - var clampClassName = 'detail-clamp-text'; + const expandButton = e.target; + const clampClassName = 'detail-clamp-text'; if (clampTarget.classList.contains(clampClassName)) { clampTarget.classList.remove(clampClassName); @@ -855,7 +888,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti function renderOverview(page, item) { for (const overviewElemnt of page.querySelectorAll('.overview')) { - var overview = item.Overview || ''; + const overview = item.Overview || ''; if (overview) { overviewElemnt.innerHTML = overview; @@ -863,7 +896,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti overviewElemnt.classList.add('detail-clamp-text'); // Grab the sibling element to control the expand state - var expandButton = overviewElemnt.parentElement.querySelector('.overview-expand'); + const expandButton = overviewElemnt.parentElement.querySelector('.overview-expand'); // Detect if we have overflow of text. Based on this StackOverflow answer // https://stackoverflow.com/a/35157976 @@ -886,10 +919,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderGenres(page, item, context = inferContext(item)) { - var genres = item.GenreItems || []; - var type = context === 'music' ? 'MusicGenre' : 'Genre'; + const genres = item.GenreItems || []; + const type = context === 'music' ? 'MusicGenre' : 'Genre'; - var html = genres.map(function (p) { + const html = genres.map(function (p) { return '' + p.Name + ''; }).join(', '); - var genresLabel = page.querySelector('.genresLabel'); + const genresLabel = page.querySelector('.genresLabel'); genresLabel.innerHTML = globalize.translate(genres.length > 1 ? 'Genres' : 'Genre'); - var genresValue = page.querySelector('.genres'); + const genresValue = page.querySelector('.genres'); genresValue.innerHTML = html; - var genresGroup = page.querySelector('.genresGroup'); + const genresGroup = page.querySelector('.genresGroup'); if (genres.length) { genresGroup.classList.remove('hide'); } else { @@ -914,11 +947,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderWriter(page, item, context) { - var writers = (item.People || []).filter(function (person) { + const writers = (item.People || []).filter(function (person) { return person.Type === 'Writer'; }); - var html = writers.map(function (person) { + const html = writers.map(function (person) { return '' + person.Name + ''; }).join(', '); - var writersLabel = page.querySelector('.writersLabel'); + const writersLabel = page.querySelector('.writersLabel'); writersLabel.innerHTML = globalize.translate(writers.length > 1 ? 'Writers' : 'Writer'); - var writersValue = page.querySelector('.writers'); + const writersValue = page.querySelector('.writers'); writersValue.innerHTML = html; - var writersGroup = page.querySelector('.writersGroup'); + const writersGroup = page.querySelector('.writersGroup'); if (writers.length) { writersGroup.classList.remove('hide'); } else { @@ -943,11 +976,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderDirector(page, item, context) { - var directors = (item.People || []).filter(function (person) { + const directors = (item.People || []).filter(function (person) { return person.Type === 'Director'; }); - var html = directors.map(function (person) { + const html = directors.map(function (person) { return '' + person.Name + ''; }).join(', '); - var directorsLabel = page.querySelector('.directorsLabel'); + const directorsLabel = page.querySelector('.directorsLabel'); directorsLabel.innerHTML = globalize.translate(directors.length > 1 ? 'Directors' : 'Director'); - var directorsValue = page.querySelector('.directors'); + const directorsValue = page.querySelector('.directors'); directorsValue.innerHTML = html; - var directorsGroup = page.querySelector('.directorsGroup'); + const directorsGroup = page.querySelector('.directorsGroup'); if (directors.length) { directorsGroup.classList.remove('hide'); } else { @@ -981,7 +1014,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti subtitles: false }); - if (miscInfo.innerHTML && 'SeriesTimer' !== item.Type) { + if (miscInfo.innerHTML && item.Type !== 'SeriesTimer') { miscInfo.classList.remove('hide'); } else { miscInfo.classList.add('hide'); @@ -995,7 +1028,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti interactive: true }); - if (miscInfo.innerHTML && 'SeriesTimer' !== item.Type) { + if (miscInfo.innerHTML && item.Type !== 'SeriesTimer') { miscInfo.classList.remove('hide'); } else { miscInfo.classList.add('hide'); @@ -1004,7 +1037,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderTagline(page, item) { - var taglineElement = page.querySelector('.tagline'); + const taglineElement = page.querySelector('.tagline'); if (item.Taglines && item.Taglines.length) { taglineElement.classList.remove('hide'); @@ -1036,7 +1069,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function getPortraitShape(scrollX) { - if (null == scrollX) { + if (scrollX == null) { scrollX = enableScrollX(); } @@ -1044,7 +1077,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function getSquareShape(scrollX) { - if (null == scrollX) { + if (scrollX == null) { scrollX = enableScrollX(); } @@ -1052,14 +1085,14 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderMoreFromSeason(view, item, apiClient) { - var section = view.querySelector('.moreFromSeasonSection'); + const section = view.querySelector('.moreFromSeasonSection'); if (section) { - if ('Episode' !== item.Type || !item.SeasonId || !item.SeriesId) { + if (item.Type !== 'Episode' || !item.SeasonId || !item.SeriesId) { return void section.classList.add('hide'); } - var userId = apiClient.getCurrentUserId(); + const userId = apiClient.getCurrentUserId(); apiClient.getEpisodes(item.SeriesId, { SeasonId: item.SeasonId, UserId: userId, @@ -1071,7 +1104,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti section.classList.remove('hide'); section.querySelector('h2').innerHTML = globalize.translate('MoreFromValue', item.SeasonName); - var itemsContainer = section.querySelector('.itemsContainer'); + const itemsContainer = section.querySelector('.itemsContainer'); cardBuilder.buildCards(result.Items, { parentContainer: section, itemsContainer: itemsContainer, @@ -1084,7 +1117,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti includeParentInfoInTitle: false, allowBottomPadding: false }); - var card = itemsContainer.querySelector('.card[data-id="' + item.Id + '"]'); + const card = itemsContainer.querySelector('.card[data-id="' + item.Id + '"]'); if (card) { setTimeout(function () { @@ -1096,18 +1129,18 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderMoreFromArtist(view, item, apiClient) { - var section = view.querySelector('.moreFromArtistSection'); + const section = view.querySelector('.moreFromArtistSection'); if (section) { - if ('MusicArtist' === item.Type) { + if (item.Type === 'MusicArtist') { if (!apiClient.isMinServerVersion('3.4.1.19')) { return void section.classList.add('hide'); } - } else if ('MusicAlbum' !== item.Type || !item.AlbumArtists || !item.AlbumArtists.length) { + } else if (item.Type !== 'MusicAlbum' || !item.AlbumArtists || !item.AlbumArtists.length) { return void section.classList.add('hide'); } - var query = { + const query = { IncludeItemTypes: 'MusicAlbum', Recursive: true, ExcludeItemIds: item.Id, @@ -1115,7 +1148,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti SortOrder: 'Descending' }; - if ('MusicArtist' === item.Type) { + if (item.Type === 'MusicArtist') { query.ContributingArtistIds = item.Id; } else if (apiClient.isMinServerVersion('3.4.1.18')) { query.AlbumArtistIds = item.AlbumArtists[0].Id; @@ -1130,7 +1163,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti section.classList.remove('hide'); - if ('MusicArtist' === item.Type) { + if (item.Type === 'MusicArtist') { section.querySelector('h2').innerHTML = globalize.translate('HeaderAppearsOn'); } else { section.querySelector('h2').innerHTML = globalize.translate('MoreFromValue', item.AlbumArtists[0].Name); @@ -1142,7 +1175,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti shape: 'autooverflow', sectionTitleTagName: 'h2', scalable: true, - coverImage: 'MusicArtist' === item.Type || 'MusicAlbum' === item.Type, + coverImage: item.Type === 'MusicArtist' || item.Type === 'MusicAlbum', showTitle: true, showParentTitle: false, centerText: true, @@ -1155,22 +1188,22 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderSimilarItems(page, item, context) { - var similarCollapsible = page.querySelector('#similarCollapsible'); + const similarCollapsible = page.querySelector('#similarCollapsible'); if (similarCollapsible) { - if ('Movie' != item.Type && 'Trailer' != item.Type && 'Series' != item.Type && 'Program' != item.Type && 'Recording' != item.Type && 'MusicAlbum' != item.Type && 'MusicArtist' != item.Type && 'Playlist' != item.Type) { + if (item.Type != 'Movie' && item.Type != 'Trailer' && item.Type != 'Series' && item.Type != 'Program' && item.Type != 'Recording' && item.Type != 'MusicAlbum' && item.Type != 'MusicArtist' && item.Type != 'Playlist') { return void similarCollapsible.classList.add('hide'); } similarCollapsible.classList.remove('hide'); - var apiClient = connectionManager.getApiClient(item.ServerId); - var options = { + const apiClient = connectionManager.getApiClient(item.ServerId); + const options = { userId: apiClient.getCurrentUserId(), limit: 12, fields: 'PrimaryImageAspectRatio,UserData,CanDelete' }; - if ('MusicAlbum' == item.Type && item.AlbumArtists && item.AlbumArtists.length) { + if (item.Type == 'MusicAlbum' && item.AlbumArtists && item.AlbumArtists.length) { options.ExcludeArtistIds = item.AlbumArtists[0].Id; } @@ -1180,22 +1213,22 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } similarCollapsible.classList.remove('hide'); - var html = ''; + let html = ''; html += cardBuilder.getCardsHtml({ items: result.Items, shape: 'autooverflow', - showParentTitle: 'MusicAlbum' == item.Type, + showParentTitle: item.Type == 'MusicAlbum', centerText: true, showTitle: true, context: context, lazy: true, showDetailsMenu: true, - coverImage: 'MusicAlbum' == item.Type || 'MusicArtist' == item.Type, + coverImage: item.Type == 'MusicAlbum' || item.Type == 'MusicArtist', overlayPlayButton: true, overlayText: false, - showYear: 'Movie' === item.Type || 'Trailer' === item.Type || 'Series' === item.Type + showYear: item.Type === 'Movie' || item.Type === 'Trailer' || item.Type === 'Series' }); - var similarContent = similarCollapsible.querySelector('.similarContent'); + const similarContent = similarCollapsible.querySelector('.similarContent'); similarContent.innerHTML = html; imageLoader.lazyChildren(similarContent); }); @@ -1203,14 +1236,14 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderSeriesAirTime(page, item, isStatic) { - var seriesAirTime = page.querySelector('#seriesAirTime'); - if ('Series' != item.Type) { + const seriesAirTime = page.querySelector('#seriesAirTime'); + if (item.Type != 'Series') { seriesAirTime.classList.add('hide'); return; } - var html = ''; + let html = ''; if (item.AirDays && item.AirDays.length) { - if (7 == item.AirDays.length) { + if (item.AirDays.length == 7) { html += 'daily'; } else { html += item.AirDays.map(function (a) { @@ -1225,8 +1258,8 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti if (isStatic) { html += ' on ' + item.Studios[0].Name; } else { - var context = inferContext(item); - var href = appRouter.getRouteUrl(item.Studios[0], { + const context = inferContext(item); + const href = appRouter.getRouteUrl(item.Studios[0], { context: context, itemType: 'Studio', serverId: item.ServerId @@ -1235,7 +1268,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } } if (html) { - html = ('Ended' == item.Status ? 'Aired ' : 'Airs ') + html; + html = (item.Status == 'Ended' ? 'Aired ' : 'Airs ') + html; seriesAirTime.innerHTML = html; seriesAirTime.classList.remove('hide'); } else { @@ -1244,15 +1277,15 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderTags(page, item) { - var itemTags = page.querySelector('.itemTags'); - var tagElements = []; - var tags = item.Tags || []; + const itemTags = page.querySelector('.itemTags'); + const tagElements = []; + let tags = item.Tags || []; - if ('Program' === item.Type) { + if (item.Type === 'Program') { tags = []; } - for (var i = 0, length = tags.length; i < length; i++) { + for (let i = 0, length = tags.length; i < length; i++) { tagElements.push(tags[i]); } @@ -1266,44 +1299,44 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderChildren(page, item) { - var fields = 'ItemCounts,PrimaryImageAspectRatio,BasicSyncInfo,CanDelete,MediaSourceCount'; - var query = { + let fields = 'ItemCounts,PrimaryImageAspectRatio,BasicSyncInfo,CanDelete,MediaSourceCount'; + const query = { ParentId: item.Id, Fields: fields }; - if ('BoxSet' !== item.Type) { + if (item.Type !== 'BoxSet') { query.SortBy = 'SortName'; } - var promise; - var apiClient = connectionManager.getApiClient(item.ServerId); - var userId = apiClient.getCurrentUserId(); + let promise; + const apiClient = connectionManager.getApiClient(item.ServerId); + const userId = apiClient.getCurrentUserId(); - if ('Series' == item.Type) { + if (item.Type == 'Series') { promise = apiClient.getSeasons(item.Id, { userId: userId, Fields: fields }); - } else if ('Season' == item.Type) { + } else if (item.Type == 'Season') { fields += ',Overview'; promise = apiClient.getEpisodes(item.SeriesId, { seasonId: item.Id, userId: userId, Fields: fields }); - } else if ('MusicArtist' == item.Type) { + } else if (item.Type == 'MusicArtist') { query.SortBy = 'ProductionYear,SortName'; } promise = promise || apiClient.getItems(apiClient.getCurrentUserId(), query); promise.then(function (result) { - var html = ''; - var scrollX = false; - var isList = false; - var childrenItemsContainer = page.querySelector('.childrenItemsContainer'); + let html = ''; + let scrollX = false; + let isList = false; + const childrenItemsContainer = page.querySelector('.childrenItemsContainer'); - if ('MusicAlbum' == item.Type) { + if (item.Type == 'MusicAlbum') { html = listView.getListViewHtml({ items: result.Items, smallIcon: true, @@ -1317,7 +1350,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti containerAlbumArtists: item.AlbumArtists }); isList = true; - } else if ('Series' == item.Type) { + } else if (item.Type == 'Series') { scrollX = enableScrollX(); html = cardBuilder.getCardsHtml({ items: result.Items, @@ -1328,21 +1361,21 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti overlayPlayButton: true, allowBottomPadding: !scrollX }); - } else if ('Season' == item.Type || 'Episode' == item.Type) { - if ('Episode' !== item.Type) { + } else if (item.Type == 'Season' || item.Type == 'Episode') { + if (item.Type !== 'Episode') { isList = true; } - scrollX = 'Episode' == item.Type; - if (result.Items.length < 2 && 'Episode' === item.Type) { + scrollX = item.Type == 'Episode'; + if (result.Items.length < 2 && item.Type === 'Episode') { return; } - if ('Episode' === item.Type) { + if (item.Type === 'Episode') { html = cardBuilder.getCardsHtml({ items: result.Items, shape: 'overflowBackdrop', showTitle: true, - displayAsSpecial: 'Season' == item.Type && item.IndexNumber, + displayAsSpecial: item.Type == 'Season' && item.IndexNumber, playFromHere: true, overlayText: true, lazy: true, @@ -1351,7 +1384,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti allowBottomPadding: !scrollX, includeParentInfoInTitle: false }); - } else if ('Season' === item.Type) { + } else if (item.Type === 'Season') { html = listView.getListViewHtml({ items: result.Items, showIndexNumber: false, @@ -1368,7 +1401,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } } - if ('BoxSet' !== item.Type) { + if (item.Type !== 'BoxSet') { page.querySelector('#childrenCollapsible').classList.remove('hide'); } if (scrollX) { @@ -1393,8 +1426,8 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } childrenItemsContainer.innerHTML = html; imageLoader.lazyChildren(childrenItemsContainer); - if ('BoxSet' == item.Type) { - var collectionItemTypes = [{ + if (item.Type == 'BoxSet') { + const collectionItemTypes = [{ name: globalize.translate('HeaderVideos'), mediaType: 'Video' }, { @@ -1411,17 +1444,17 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } }); - if ('Season' == item.Type) { + if (item.Type == 'Season') { page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderEpisodes'); - } else if ('Series' == item.Type) { + } else if (item.Type == 'Series') { page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderSeasons'); - } else if ('MusicAlbum' == item.Type) { + } else if (item.Type == 'MusicAlbum') { page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderTracks'); } else { page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderItems'); } - if ('MusicAlbum' == item.Type || 'Season' == item.Type) { + if (item.Type == 'MusicAlbum' || item.Type == 'Season') { page.querySelector('.childrenSectionHeader').classList.add('hide'); page.querySelector('#childrenCollapsible').classList.add('verticalSection-extrabottompadding'); } else { @@ -1430,25 +1463,25 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderItemsByName(page, item) { - require('scripts/itembynamedetailpage'.split(','), function () { + import('scripts/itembynamedetailpage').then(() => { window.ItemsByName.renderItems(page, item); }); } function renderPlaylistItems(page, item) { - require('scripts/playlistedit'.split(','), function () { + import('scripts/playlistedit').then(() => { PlaylistViewer.render(page, item); }); } function renderProgramsForChannel(page, result) { - var html = ''; - var currentItems = []; - var currentStartDate = null; + let html = ''; + let currentItems = []; + let currentStartDate = null; - for (var i = 0, length = result.Items.length; i < length; i++) { - var item = result.Items[i]; - var itemStartDate = datetime.parseISO8601Date(item.StartDate); + for (let i = 0, length = result.Items.length; i < length; i++) { + const item = result.Items[i]; + const itemStartDate = datetime.parseISO8601Date(item.StartDate); if (!(currentStartDate && currentStartDate.toDateString() === itemStartDate.toDateString())) { if (currentItems.length) { @@ -1498,7 +1531,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderChannelGuide(page, apiClient, item) { - if ('TvChannel' === item.Type) { + if (item.Type === 'TvChannel') { page.querySelector('.programGuideSection').classList.remove('hide'); apiClient.getLiveTvPrograms({ ChannelIds: item.Id, @@ -1516,7 +1549,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderSeriesSchedule(page, item) { - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); apiClient.getLiveTvPrograms({ UserId: apiClient.getCurrentUserId(), HasAired: false, @@ -1550,19 +1583,19 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function inferContext(item) { - if ('Movie' === item.Type || 'BoxSet' === item.Type) { + if (item.Type === 'Movie' || item.Type === 'BoxSet') { return 'movies'; } - if ('Series' === item.Type || 'Season' === item.Type || 'Episode' === item.Type) { + if (item.Type === 'Series' || item.Type === 'Season' || item.Type === 'Episode') { return 'tvshows'; } - if ('MusicArtist' === item.Type || 'MusicAlbum' === item.Type || 'Audio' === item.Type || 'AudioBook' === item.Type) { + if (item.Type === 'MusicArtist' || item.Type === 'MusicAlbum' || item.Type === 'Audio' || item.Type === 'AudioBook') { return 'music'; } - if ('Program' === item.Type) { + if (item.Type === 'Program') { return 'livetv'; } @@ -1580,9 +1613,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function canPlaySomeItemInCollection(items) { - var i = 0; + let i = 0; - for (var length = items.length; i < length; i++) { + for (let length = items.length; i < length; i++) { if (playbackManager.canPlay(items[i])) { return true; } @@ -1596,17 +1629,17 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti page.querySelector('.collectionItems').innerHTML = ''; for (const type of types) { - var typeItems = filterItemsByCollectionItemType(items, type); + const typeItems = filterItemsByCollectionItemType(items, type); if (typeItems.length) { renderCollectionItemType(page, parentItem, type, typeItems); } } - var otherType = { + const otherType = { name: globalize.translate('HeaderOtherItems') }; - var otherTypeItems = items.filter(function (curr) { + const otherTypeItems = items.filter(function (curr) { return !types.filter(function (t) { return filterItemsByCollectionItemType([curr], t).length > 0; }).length; @@ -1622,9 +1655,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti }, items); } - var containers = page.querySelectorAll('.collectionItemsContainer'); + const containers = page.querySelectorAll('.collectionItemsContainer'); - var notifyRefreshNeeded = function () { + const notifyRefreshNeeded = function () { renderChildren(page, parentItem); }; @@ -1640,27 +1673,26 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti // HACK: Call autoFocuser again because btnPlay may be hidden, but focused by reloadFromItem // FIXME: Sometimes focus does not move until all (?) sections are loaded - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(page); }); } function renderCollectionItemType(page, parentItem, type, items) { - var html = ''; + let html = ''; html += '
    '; html += '
    '; html += '

    '; html += '' + type.name + ''; html += '

    '; - html += ''; html += '
    '; html += '
    '; - var shape = 'MusicAlbum' == type.type ? getSquareShape(false) : getPortraitShape(false); + const shape = type.type == 'MusicAlbum' ? getSquareShape(false) : getPortraitShape(false); html += cardBuilder.getCardsHtml({ items: items, shape: shape, showTitle: true, - showYear: 'Video' === type.mediaType || 'Series' === type.type, + showYear: type.mediaType === 'Video' || type.type === 'Series', centerText: true, lazy: true, showDetailsMenu: true, @@ -1671,17 +1703,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti }); html += '
    '; html += '
    '; - var collectionItems = page.querySelector('.collectionItems'); + const collectionItems = page.querySelector('.collectionItems'); collectionItems.insertAdjacentHTML('beforeend', html); imageLoader.lazyChildren(collectionItems); - collectionItems.querySelector('.btnAddToCollection').addEventListener('click', function () { - require(['alert'], function (alert) { - alert.default({ - text: globalize.translate('AddItemToCollectionHelp'), - html: globalize.translate('AddItemToCollectionHelp') + '

    ' + globalize.translate('ButtonLearnMore') + '' - }); - }); - }); } function renderMusicVideos(page, item, user) { @@ -1695,7 +1719,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti }).then(function (result) { if (result.Items.length) { page.querySelector('#musicVideosCollapsible').classList.remove('hide'); - var musicVideosContent = page.querySelector('.musicVideosContent'); + const musicVideosContent = page.querySelector('.musicVideosContent'); musicVideosContent.innerHTML = getVideosHtml(result.Items); imageLoader.lazyChildren(musicVideosContent); } else { @@ -1708,7 +1732,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti connectionManager.getApiClient(item.ServerId).getAdditionalVideoParts(user.Id, item.Id).then(function (result) { if (result.Items.length) { page.querySelector('#additionalPartsCollapsible').classList.remove('hide'); - var additionalPartsContent = page.querySelector('#additionalPartsContent'); + const additionalPartsContent = page.querySelector('#additionalPartsContent'); additionalPartsContent.innerHTML = getVideosHtml(result.Items); imageLoader.lazyChildren(additionalPartsContent); } else { @@ -1718,13 +1742,13 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderScenes(page, item) { - var chapters = item.Chapters || []; + let chapters = item.Chapters || []; if (chapters.length && !chapters[0].ImageTag && (chapters = []), chapters.length) { page.querySelector('#scenesCollapsible').classList.remove('hide'); - var scenesContent = page.querySelector('#scenesContent'); + const scenesContent = page.querySelector('#scenesContent'); - require(['chaptercardbuilder'], function (chaptercardbuilder) { + import('chaptercardbuilder').then(({default: chaptercardbuilder}) => { chaptercardbuilder.buildChapterCards(item, chapters, { itemsContainer: scenesContent, backdropShape: 'overflowBackdrop', @@ -1738,7 +1762,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function getVideosHtml(items) { - var html = cardBuilder.getCardsHtml({ + return cardBuilder.getCardsHtml({ items: items, shape: 'autooverflow', showTitle: true, @@ -1747,20 +1771,18 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti centerText: true, showRuntime: true }); - - return html; } function renderSpecials(page, item, user) { connectionManager.getApiClient(item.ServerId).getSpecialFeatures(user.Id, item.Id).then(function (specials) { - var specialsContent = page.querySelector('#specialsContent'); + const specialsContent = page.querySelector('#specialsContent'); specialsContent.innerHTML = getVideosHtml(specials); imageLoader.lazyChildren(specialsContent); }); } function renderCast(page, item) { - var people = (item.People || []).filter(function (p) { + const people = (item.People || []).filter(function (p) { return p.Type === 'Actor'; }); @@ -1769,9 +1791,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } page.querySelector('#castCollapsible').classList.remove('hide'); - var castContent = page.querySelector('#castContent'); + const castContent = page.querySelector('#castContent'); - require(['peoplecardbuilder'], function (peoplecardbuilder) { + import('peoplecardbuilder').then(({default: peoplecardbuilder}) => { peoplecardbuilder.buildPeopleCards(people, { itemsContainer: castContent, coverImage: true, @@ -1783,14 +1805,14 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function itemDetailPage() { - var self = this; + const self = this; self.setInitialCollapsibleState = setInitialCollapsibleState; self.renderDetails = renderDetails; self.renderCast = renderCast; } function bindAll(view, selector, eventName, fn) { - var elems = view.querySelectorAll(selector); + const elems = view.querySelectorAll(selector); for (const elem of elems) { elem.addEventListener(eventName, fn); @@ -1803,11 +1825,12 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } window.ItemDetailPage = new itemDetailPage(); - return function (view, params) { + + export default function (view, params) { function reload(instance, page, params) { loading.show(); - var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient; + const apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient; Promise.all([getPromise(apiClient, params), apiClient.getCurrentUser()]).then(([item, user]) => { currentItem = item; @@ -1818,8 +1841,8 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function splitVersions(instance, page, apiClient, params) { - require(['confirm'], function (confirm) { - confirm.default('Are you sure you wish to split the media sources into separate items?', 'Split Media Apart').then(function () { + import('confirm').then(({default: confirm}) => { + confirm('Are you sure you wish to split the media sources into separate items?', 'Split Media Apart').then(function () { loading.show(); apiClient.ajax({ type: 'DELETE', @@ -1833,7 +1856,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function getPlayOptions(startPosition) { - var audioStreamIndex = view.querySelector('.selectAudio').value || null; + const audioStreamIndex = view.querySelector('.selectAudio').value || null; return { startPositionTicks: startPosition, mediaSourceId: view.querySelector('.selectSource').value, @@ -1843,7 +1866,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function playItem(item, startPosition) { - var playOptions = getPlayOptions(startPosition); + const playOptions = getPlayOptions(startPosition); playOptions.items = [item]; playbackManager.play(playOptions); } @@ -1853,10 +1876,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function playCurrentItem(button, mode) { - var item = currentItem; + const item = currentItem; - if ('Program' === item.Type) { - var apiClient = connectionManager.getApiClient(item.ServerId); + if (item.Type === 'Program') { + const apiClient = connectionManager.getApiClient(item.ServerId); return void apiClient.getLiveTvChannel(item.ChannelId, apiClient.getCurrentUserId()).then(function (channel) { playbackManager.play({ items: [channel] @@ -1880,7 +1903,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function onCancelSeriesTimerClick() { - require(['recordingHelper'], function (recordingHelper) { + import('recordingHelper').then(({default: recordingHelper}) => { recordingHelper.cancelSeriesTimerWithConfirmation(currentItem.Id, currentItem.ServerId).then(function () { Dashboard.navigate('livetv.html'); }); @@ -1888,7 +1911,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function onCancelTimerClick() { - require(['recordingHelper'], function (recordingHelper) { + import('recordingHelper').then(({default: recordingHelper}) => { recordingHelper.cancelTimer(connectionManager.getApiClient(currentItem.ServerId), currentItem.TimerId).then(function () { reload(self, view, params); }); @@ -1900,8 +1923,8 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function onDownloadClick() { - require(['fileDownloader'], function (fileDownloader) { - var downloadHref = apiClient.getItemDownloadUrl(currentItem.Id); + import('fileDownloader').then(({default: fileDownloader}) => { + const downloadHref = apiClient.getItemDownloadUrl(currentItem.Id); fileDownloader.download([{ url: downloadHref, itemId: currentItem.Id, @@ -1911,7 +1934,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function onMoreCommandsClick() { - var button = this; + const button = this; apiClient.getCurrentUser().then(function (user) { itemContextMenu.show(getContextMenuOptions(currentItem, user, button)).then(function (result) { if (result.deleted) { @@ -1929,11 +1952,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function onWebSocketMessage(e, data) { - var msg = data; + const msg = data; - if ('UserDataChanged' === msg.MessageType && currentItem && msg.Data.UserId == apiClient.getCurrentUserId()) { - var key = currentItem.UserData.Key; - var userData = msg.Data.UserDataList.filter(function (u) { + if (msg.MessageType === 'UserDataChanged' && currentItem && msg.Data.UserId == apiClient.getCurrentUserId()) { + const key = currentItem.UserData.Key; + const userData = msg.Data.UserDataList.filter(function (u) { return u.Key == key; })[0]; @@ -1945,9 +1968,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } } - var currentItem; - var self = this; - var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient; + let currentItem; + const self = this; + const apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient; view.querySelectorAll('.btnPlay'); bindAll(view, '.btnPlay', 'click', onPlayClick); bindAll(view, '.btnResume', 'click', onPlayClick); @@ -1968,7 +1991,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti renderSubtitleSelections(view, self._currentPlaybackMediaSources); }); view.addEventListener('viewshow', function (e) { - var page = this; + const page = this; libraryMenu.setTransparentMenu(true); @@ -1994,5 +2017,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti self._currentPlaybackMediaSources = null; self.currentRecordingFields = null; }); - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/list.js b/src/controllers/list.js index e550b535f4..68e81f05dd 100644 --- a/src/controllers/list.js +++ b/src/controllers/list.js @@ -1,6 +1,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager', 'cardBuilder', 'loading', 'connectionManager', 'alphaNumericShortcuts', 'scroller', 'playbackManager', 'alphaPicker', 'emby-itemscontainer', 'emby-scroller'], function (globalize, listView, layoutManager, userSettings, focusManager, cardBuilder, loading, connectionManager, AlphaNumericShortcuts, scroller, playbackManager, AlphaPicker) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + loading = loading.default || loading; + function getInitialLiveTvQuery(instance, params) { var query = { UserId: connectionManager.getApiClient(params.serverId).getCurrentUserId(), @@ -9,7 +12,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' Limit: 300 }; - if ('Recordings' === params.type) { + if (params.type === 'Recordings') { query.IsInProgress = false; } else { query.HasAired = false; @@ -19,39 +22,39 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' query.GenreIds = params.genreId; } - if ('true' === params.IsMovie) { + if (params.IsMovie === 'true') { query.IsMovie = true; - } else if ('false' === params.IsMovie) { + } else if (params.IsMovie === 'false') { query.IsMovie = false; } - if ('true' === params.IsSeries) { + if (params.IsSeries === 'true') { query.IsSeries = true; - } else if ('false' === params.IsSeries) { + } else if (params.IsSeries === 'false') { query.IsSeries = false; } - if ('true' === params.IsNews) { + if (params.IsNews === 'true') { query.IsNews = true; - } else if ('false' === params.IsNews) { + } else if (params.IsNews === 'false') { query.IsNews = false; } - if ('true' === params.IsSports) { + if (params.IsSports === 'true') { query.IsSports = true; - } else if ('false' === params.IsSports) { + } else if (params.IsSports === 'false') { query.IsSports = false; } - if ('true' === params.IsKids) { + if (params.IsKids === 'true') { query.IsKids = true; - } else if ('false' === params.IsKids) { + } else if (params.IsKids === 'false') { query.IsKids = false; } - if ('true' === params.IsAiring) { + if (params.IsAiring === 'true') { query.IsAiring = true; - } else if ('false' === params.IsAiring) { + } else if (params.IsAiring === 'false') { query.IsAiring = false; } @@ -181,13 +184,13 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' var btnSortIcon = instance.btnSortIcon; if (btnSortIcon) { - setSortButtonIcon(btnSortIcon, 'Descending' === values.sortOrder ? 'arrow_downward' : 'arrow_upward'); + setSortButtonIcon(btnSortIcon, values.sortOrder === 'Descending' ? 'arrow_downward' : 'arrow_upward'); } } } function updateItemsContainerForViewType(instance) { - if ('list' === instance.getViewSettings().imageType) { + if (instance.getViewSettings().imageType === 'list') { instance.itemsContainer.classList.remove('vertical-wrap'); instance.itemsContainer.classList.add('vertical-list'); } else { @@ -203,11 +206,11 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' if (alphaPicker) { var values = instance.getSortValues(); - if (null == numItems) { + if (numItems == null) { numItems = 100; } - if ('SortName' === values.sortBy && 'Ascending' === values.sortOrder && numItems > 40) { + if (values.sortBy === 'SortName' && values.sortOrder === 'Ascending' && numItems > 40) { alphaPicker.classList.remove('hide'); instance.itemsContainer.parentNode.classList.add('padded-right-withalphapicker'); } else { @@ -222,19 +225,19 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' var apiClient = connectionManager.getApiClient(params.serverId); instance.queryRecursive = false; - if ('Recordings' === params.type) { + if (params.type === 'Recordings') { return apiClient.getLiveTvRecordings(getInitialLiveTvQuery(instance, params)); } - if ('Programs' === params.type) { - if ('true' === params.IsAiring) { + if (params.type === 'Programs') { + if (params.IsAiring === 'true') { return apiClient.getLiveTvRecommendedPrograms(getInitialLiveTvQuery(instance, params)); } return apiClient.getLiveTvPrograms(getInitialLiveTvQuery(instance, params)); } - if ('nextup' === params.type) { + if (params.type === 'nextup') { return apiClient.getNextUpEpisodes(modifyQueryWithFilters(instance, { Limit: limit, Fields: 'PrimaryImageAspectRatio,SeriesInfo,DateCreated,BasicSyncInfo', @@ -250,9 +253,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' instance.queryRecursive = true; var method = 'getItems'; - if ('MusicArtist' === params.type) { + if (params.type === 'MusicArtist') { method = 'getArtists'; - } else if ('Person' === params.type) { + } else if (params.type === 'Person') { method = 'getPeople'; } @@ -261,15 +264,15 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' Limit: limit, Fields: 'PrimaryImageAspectRatio,SortName', ImageTypeLimit: 1, - IncludeItemTypes: 'MusicArtist' === params.type || 'Person' === params.type ? null : params.type, + IncludeItemTypes: params.type === 'MusicArtist' || params.type === 'Person' ? null : params.type, Recursive: true, - IsFavorite: 'true' === params.IsFavorite || null, + IsFavorite: params.IsFavorite === 'true' || null, ArtistIds: params.artistId || null, SortBy: sortBy })); } - if ('Genre' === item.Type || 'MusicGenre' === item.Type || 'Studio' === item.Type || 'Person' === item.Type) { + if (item.Type === 'Genre' || item.Type === 'MusicGenre' || item.Type === 'Studio' || item.Type === 'Person') { instance.queryRecursive = true; var query = { StartIndex: startIndex, @@ -280,25 +283,25 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' SortBy: sortBy }; - if ('Studio' === item.Type) { + if (item.Type === 'Studio') { query.StudioIds = item.Id; - } else if ('Genre' === item.Type || 'MusicGenre' === item.Type) { + } else if (item.Type === 'Genre' || item.Type === 'MusicGenre') { query.GenreIds = item.Id; - } else if ('Person' === item.Type) { + } else if (item.Type === 'Person') { query.PersonIds = item.Id; } - if ('MusicGenre' === item.Type) { + if (item.Type === 'MusicGenre') { query.IncludeItemTypes = 'MusicAlbum'; - } else if ('GameGenre' === item.Type) { + } else if (item.Type === 'GameGenre') { query.IncludeItemTypes = 'Game'; - } else if ('movies' === item.CollectionType) { + } else if (item.CollectionType === 'movies') { query.IncludeItemTypes = 'Movie'; - } else if ('tvshows' === item.CollectionType) { + } else if (item.CollectionType === 'tvshows') { query.IncludeItemTypes = 'Series'; - } else if ('Genre' === item.Type) { + } else if (item.Type === 'Genre') { query.IncludeItemTypes = 'Movie,Series,Video'; - } else if ('Person' === item.Type) { + } else if (item.Type === 'Person') { query.IncludeItemTypes = params.type; } @@ -316,7 +319,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function getItem(params) { - if ('Recordings' === params.type || 'Programs' === params.type || 'nextup' === params.type) { + if (params.type === 'Recordings' || params.type === 'Programs' || params.type === 'nextup') { return Promise.resolve(null); } @@ -412,7 +415,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' function ItemsView(view, params) { function fetchData() { return getItems(self, params, self.currentItem).then(function (result) { - if (null == self.totalItemCount) { + if (self.totalItemCount == null) { self.totalItemCount = result.Items ? result.Items.length : result.length; } @@ -424,7 +427,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' function getItemsHtml(items) { var settings = self.getViewSettings(); - if ('list' === settings.imageType) { + if (settings.imageType === 'list') { return listView.getListViewHtml({ items: items }); @@ -438,24 +441,24 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' var item = self.currentItem; var lines = settings.showTitle ? 2 : 0; - if ('banner' === settings.imageType) { + if (settings.imageType === 'banner') { shape = 'banner'; - } else if ('disc' === settings.imageType) { + } else if (settings.imageType === 'disc') { shape = 'square'; preferDisc = true; - } else if ('logo' === settings.imageType) { + } else if (settings.imageType === 'logo') { shape = 'backdrop'; preferLogo = true; - } else if ('thumb' === settings.imageType) { + } else if (settings.imageType === 'thumb') { shape = 'backdrop'; preferThumb = true; - } else if ('nextup' === params.type) { + } else if (params.type === 'nextup') { shape = 'backdrop'; - preferThumb = 'thumb' === settings.imageType; - } else if ('Programs' === params.type || 'Recordings' === params.type) { - shape = 'true' === params.IsMovie ? 'portrait' : 'autoVertical'; - preferThumb = 'true' !== params.IsMovie ? 'auto' : false; - defaultShape = 'true' === params.IsMovie ? 'portrait' : 'backdrop'; + preferThumb = settings.imageType === 'thumb'; + } else if (params.type === 'Programs' || params.type === 'Recordings') { + shape = params.IsMovie === 'true' ? 'portrait' : 'autoVertical'; + preferThumb = params.IsMovie !== 'true' ? 'auto' : false; + defaultShape = params.IsMovie === 'true' ? 'portrait' : 'backdrop'; } else { shape = 'autoVertical'; } @@ -473,46 +476,46 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' overlayMoreButton: true, overlayText: !settings.showTitle, defaultShape: defaultShape, - action: 'Audio' === params.type ? 'playallfromhere' : null + action: params.type === 'Audio' ? 'playallfromhere' : null }; - if ('nextup' === params.type) { + if (params.type === 'nextup') { posterOptions.showParentTitle = settings.showTitle; - } else if ('Person' === params.type) { + } else if (params.type === 'Person') { posterOptions.showYear = false; posterOptions.showParentTitle = false; lines = 1; - } else if ('Audio' === params.type) { + } else if (params.type === 'Audio') { posterOptions.showParentTitle = settings.showTitle; - } else if ('MusicAlbum' === params.type) { + } else if (params.type === 'MusicAlbum') { posterOptions.showParentTitle = settings.showTitle; - } else if ('Episode' === params.type) { + } else if (params.type === 'Episode') { posterOptions.showParentTitle = settings.showTitle; - } else if ('MusicArtist' === params.type) { + } else if (params.type === 'MusicArtist') { posterOptions.showYear = false; lines = 1; - } else if ('Programs' === params.type) { + } else if (params.type === 'Programs') { lines = settings.showTitle ? 1 : 0; - var showParentTitle = settings.showTitle && 'true' !== params.IsMovie; + var showParentTitle = settings.showTitle && params.IsMovie !== 'true'; if (showParentTitle) { lines++; } - var showAirTime = settings.showTitle && 'Recordings' !== params.type; + var showAirTime = settings.showTitle && params.type !== 'Recordings'; if (showAirTime) { lines++; } - var showYear = settings.showTitle && 'true' === params.IsMovie && 'Recordings' === params.type; + var showYear = settings.showTitle && params.IsMovie === 'true' && params.type === 'Recordings'; if (showYear) { lines++; } posterOptions = Object.assign(posterOptions, { - inheritThumb: 'Recordings' === params.type, + inheritThumb: params.type === 'Recordings', context: 'livetv', showParentTitle: showParentTitle, showAirTime: showAirTime, @@ -529,7 +532,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' posterOptions.lines = lines; posterOptions.items = items; - if (item && 'folders' === item.CollectionType) { + if (item && item.CollectionType === 'folders') { posterOptions.context = 'folders'; } @@ -561,7 +564,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' function setTitle(item) { Emby.Page.setTitle(getTitle(item) || ''); - if (item && 'playlists' === item.CollectionType) { + if (item && item.CollectionType === 'playlists') { hideOrShowAll(view.querySelectorAll('.btnNewItem'), false); } else { hideOrShowAll(view.querySelectorAll('.btnNewItem'), true); @@ -569,43 +572,43 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function getTitle(item) { - if ('Recordings' === params.type) { + if (params.type === 'Recordings') { return globalize.translate('Recordings'); } - if ('Programs' === params.type) { - if ('true' === params.IsMovie) { + if (params.type === 'Programs') { + if (params.IsMovie === 'true') { return globalize.translate('Movies'); } - if ('true' === params.IsSports) { + if (params.IsSports === 'true') { return globalize.translate('Sports'); } - if ('true' === params.IsKids) { + if (params.IsKids === 'true') { return globalize.translate('HeaderForKids'); } - if ('true' === params.IsAiring) { + if (params.IsAiring === 'true') { return globalize.translate('HeaderOnNow'); } - if ('true' === params.IsSeries) { + if (params.IsSeries === 'true') { return globalize.translate('Shows'); } - if ('true' === params.IsNews) { + if (params.IsNews === 'true') { return globalize.translate('News'); } return globalize.translate('Programs'); } - if ('nextup' === params.type) { + if (params.type === 'nextup') { return globalize.translate('NextUp'); } - if ('favoritemovies' === params.type) { + if (params.type === 'favoritemovies') { return globalize.translate('FavoriteMovies'); } @@ -613,35 +616,35 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' return item.Name; } - if ('Movie' === params.type) { + if (params.type === 'Movie') { return globalize.translate('Movies'); } - if ('Series' === params.type) { + if (params.type === 'Series') { return globalize.translate('Shows'); } - if ('Season' === params.type) { + if (params.type === 'Season') { return globalize.translate('Seasons'); } - if ('Episode' === params.type) { + if (params.type === 'Episode') { return globalize.translate('Episodes'); } - if ('MusicArtist' === params.type) { + if (params.type === 'MusicArtist') { return globalize.translate('Artists'); } - if ('MusicAlbum' === params.type) { + if (params.type === 'MusicAlbum') { return globalize.translate('Albums'); } - if ('Audio' === params.type) { + if (params.type === 'Audio') { return globalize.translate('Songs'); } - if ('Video' === params.type) { + if (params.type === 'Video') { return globalize.translate('Videos'); } @@ -700,11 +703,11 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' if (params.parentId) { this.itemsContainer.setAttribute('data-parentid', params.parentId); - } else if ('nextup' === params.type) { + } else if (params.type === 'nextup') { this.itemsContainer.setAttribute('data-monitor', 'videoplayback'); - } else if ('favoritemovies' === params.type) { + } else if (params.type === 'favoritemovies') { this.itemsContainer.setAttribute('data-monitor', 'markfavorite'); - } else if ('Programs' === params.type) { + } else if (params.type === 'Programs') { this.itemsContainer.setAttribute('data-refreshinterval', '300000'); } @@ -737,7 +740,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' var sortButton = sortButtons[i]; sortButton.addEventListener('click', showSortMenu.bind(this)); - if ('nextup' !== params.type) { + if (params.type !== 'nextup') { sortButton.classList.remove('hide'); } } @@ -772,19 +775,19 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } }); - if (!isRestored && item && 'PhotoAlbum' !== item.Type) { + if (!isRestored && item && item.Type !== 'PhotoAlbum') { initAlphaPicker(); } var itemType = item ? item.Type : null; - if ('MusicGenre' === itemType || 'Programs' !== params.type && 'Channel' !== itemType) { + if (itemType === 'MusicGenre' || params.type !== 'Programs' && itemType !== 'Channel') { hideOrShowAll(view.querySelectorAll('.btnPlay'), false); } else { hideOrShowAll(view.querySelectorAll('.btnPlay'), true); } - if ('MusicGenre' === itemType || 'Programs' !== params.type && 'nextup' !== params.type && 'Channel' !== itemType) { + if (itemType === 'MusicGenre' || params.type !== 'Programs' && params.type !== 'nextup' && itemType !== 'Channel') { hideOrShowAll(view.querySelectorAll('.btnShuffle'), false); } else { hideOrShowAll(view.querySelectorAll('.btnShuffle'), true); @@ -845,14 +848,14 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' ItemsView.prototype.getFilters = function () { var basekey = this.getSettingsKey(); return { - IsPlayed: 'true' === userSettings.getFilter(basekey + '-filter-IsPlayed'), - IsUnplayed: 'true' === userSettings.getFilter(basekey + '-filter-IsUnplayed'), - IsFavorite: 'true' === userSettings.getFilter(basekey + '-filter-IsFavorite'), - IsResumable: 'true' === userSettings.getFilter(basekey + '-filter-IsResumable'), - Is4K: 'true' === userSettings.getFilter(basekey + '-filter-Is4K'), - IsHD: 'true' === userSettings.getFilter(basekey + '-filter-IsHD'), - IsSD: 'true' === userSettings.getFilter(basekey + '-filter-IsSD'), - Is3D: 'true' === userSettings.getFilter(basekey + '-filter-Is3D'), + IsPlayed: userSettings.getFilter(basekey + '-filter-IsPlayed') === 'true', + IsUnplayed: userSettings.getFilter(basekey + '-filter-IsUnplayed') === 'true', + IsFavorite: userSettings.getFilter(basekey + '-filter-IsFavorite') === 'true', + IsResumable: userSettings.getFilter(basekey + '-filter-IsResumable') === 'true', + Is4K: userSettings.getFilter(basekey + '-filter-Is4K') === 'true', + IsHD: userSettings.getFilter(basekey + '-filter-IsHD') === 'true', + IsSD: userSettings.getFilter(basekey + '-filter-IsSD') === 'true', + Is3D: userSettings.getFilter(basekey + '-filter-Is3D') === 'true', VideoTypes: userSettings.getFilter(basekey + '-filter-VideoTypes'), SeriesStatus: userSettings.getFilter(basekey + '-filter-SeriesStatus'), HasSubtitles: userSettings.getFilter(basekey + '-filter-HasSubtitles'), @@ -868,7 +871,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' var basekey = this.getSettingsKey(); return { sortBy: userSettings.getFilter(basekey + '-sortby') || this.getDefaultSortBy(), - sortOrder: 'Descending' === userSettings.getFilter(basekey + '-sortorder') ? 'Descending' : 'Ascending' + sortOrder: userSettings.getFilter(basekey + '-sortorder') === 'Descending' ? 'Descending' : 'Ascending' }; }; @@ -887,7 +890,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' var sortBy = []; var params = this.params; - if ('Programs' === params.type) { + if (params.type === 'Programs') { sortBy.push({ name: globalize.translate('AirDate'), value: 'StartDate,SortName' @@ -912,7 +915,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' sortBy.push(option); } - if ('Programs' !== params.type) { + if (params.type !== 'Programs') { sortBy.push({ name: globalize.translate('DateAdded'), value: 'DateCreated,SortName' @@ -955,7 +958,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' }; ItemsView.prototype.getNameSortOption = function (params) { - if ('Episode' === params.type) { + if (params.type === 'Episode') { return { name: globalize.translate('Name'), value: 'SeriesName,SortName' @@ -969,7 +972,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' }; ItemsView.prototype.getPlayCountSortOption = function () { - if ('Programs' === this.params.type) { + if (this.params.type === 'Programs') { return null; } @@ -980,7 +983,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' }; ItemsView.prototype.getDatePlayedSortOption = function () { - if ('Programs' === this.params.type) { + if (this.params.type === 'Programs') { return null; } @@ -991,7 +994,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' }; ItemsView.prototype.getCriticRatingSortOption = function () { - if ('Programs' === this.params.type) { + if (this.params.type === 'Programs') { return null; } @@ -1012,8 +1015,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' var filters = []; var params = this.params; - if (!('nextup' === params.type)) { - if ('Programs' === params.type) { + if (!(params.type === 'nextup')) { + if (params.type === 'Programs') { filters.push('Genres'); } else { filters.push('IsUnplayed'); @@ -1081,7 +1084,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' var item = (this.params, this.currentItem); var fields = ['showTitle']; - if (!item || 'PhotoAlbum' !== item.Type && 'ChannelFolderItem' !== item.Type) { + if (!item || item.Type !== 'PhotoAlbum' && item.Type !== 'ChannelFolderItem') { fields.push('imageType'); } @@ -1095,25 +1098,25 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' var item = this.currentItem; var showTitle = userSettings.get(basekey + '-showTitle'); - if ('true' === showTitle) { + if (showTitle === 'true') { showTitle = true; - } else if ('false' === showTitle) { + } else if (showTitle === 'false') { showTitle = false; - } else if ('Programs' === params.type || 'Recordings' === params.type || 'Person' === params.type || 'nextup' === params.type || 'Audio' === params.type || 'MusicAlbum' === params.type || 'MusicArtist' === params.type) { + } else if (params.type === 'Programs' || params.type === 'Recordings' || params.type === 'Person' || params.type === 'nextup' || params.type === 'Audio' || params.type === 'MusicAlbum' || params.type === 'MusicArtist') { showTitle = true; - } else if (item && 'PhotoAlbum' !== item.Type) { + } else if (item && item.Type !== 'PhotoAlbum') { showTitle = true; } var imageType = userSettings.get(basekey + '-imageType'); - if (!imageType && 'nextup' === params.type) { + if (!imageType && params.type === 'nextup') { imageType = 'thumb'; } return { showTitle: showTitle, - showYear: 'false' !== userSettings.get(basekey + '-showYear'), + showYear: userSettings.get(basekey + '-showYear') !== 'false', imageType: imageType || 'primary', viewType: userSettings.get(basekey + '-viewType') || 'images' }; @@ -1122,11 +1125,11 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' ItemsView.prototype.getItemTypes = function () { var params = this.params; - if ('nextup' === params.type) { + if (params.type === 'nextup') { return ['Episode']; } - if ('Programs' === params.type) { + if (params.type === 'Programs') { return ['Program']; } diff --git a/src/controllers/livetv/livetvchannels.js b/src/controllers/livetv/livetvchannels.js index 62906d9d21..f5a0abeb38 100644 --- a/src/controllers/livetv/livetvchannels.js +++ b/src/controllers/livetv/livetvchannels.js @@ -1,6 +1,9 @@ define(['cardBuilder', 'imageLoader', 'libraryBrowser', 'loading', 'events', 'userSettings', 'emby-itemscontainer'], function (cardBuilder, imageLoader, libraryBrowser, loading, events, userSettings) { 'use strict'; + loading = loading.default || loading; + libraryBrowser = libraryBrowser.default || libraryBrowser; + return function (view, params, tabContent) { function getPageData() { if (!pageData) { diff --git a/src/controllers/livetv/livetvrecordings.js b/src/controllers/livetv/livetvrecordings.js index d5cfe66672..b0259bc89b 100644 --- a/src/controllers/livetv/livetvrecordings.js +++ b/src/controllers/livetv/livetvrecordings.js @@ -1,6 +1,8 @@ define(['layoutManager', 'loading', 'cardBuilder', 'apphost', 'imageLoader', 'scripts/livetvcomponents', 'listViewStyle', 'emby-itemscontainer'], function (layoutManager, loading, cardBuilder, appHost, imageLoader) { 'use strict'; + loading = loading.default || loading; + function renderRecordings(elem, recordings, cardOptions, scrollX) { if (!elem) { return; @@ -24,7 +26,6 @@ define(['layoutManager', 'loading', 'cardBuilder', 'apphost', 'imageLoader', 'sc recordingItems.classList.add('vertical-wrap'); } - appHost.supports('imageanalysis'); recordingItems.innerHTML = cardBuilder.getCardsHtml(Object.assign({ items: recordings, shape: scrollX ? 'autooverflow' : 'auto', diff --git a/src/controllers/livetv/livetvschedule.js b/src/controllers/livetv/livetvschedule.js index a6f509c6f1..4427bef5d1 100644 --- a/src/controllers/livetv/livetvschedule.js +++ b/src/controllers/livetv/livetvschedule.js @@ -1,6 +1,8 @@ define(['layoutManager', 'cardBuilder', 'apphost', 'imageLoader', 'loading', 'scripts/livetvcomponents', 'emby-button', 'emby-itemscontainer'], function (layoutManager, cardBuilder, appHost, imageLoader, loading) { 'use strict'; + loading = loading.default || loading; + function enableScrollX() { return !layoutManager.desktop; } @@ -30,17 +32,14 @@ define(['layoutManager', 'cardBuilder', 'apphost', 'imageLoader', 'loading', 'sc recordingItems.classList.add('vertical-wrap'); } - var supportsImageAnalysis = appHost.supports('imageanalysis'); - var cardLayout = appHost.preferVisualCards || supportsImageAnalysis; - cardLayout = false; recordingItems.innerHTML = cardBuilder.getCardsHtml(Object.assign({ items: recordings, shape: enableScrollX() ? 'autooverflow' : 'auto', showTitle: true, showParentTitle: true, coverImage: true, - cardLayout: cardLayout, - centerText: !cardLayout, + cardLayout: false, + centerText: true, allowBottomPadding: !enableScrollX(), preferThumb: 'auto' }, cardOptions || {})); diff --git a/src/controllers/livetv/livetvseriestimers.js b/src/controllers/livetv/livetvseriestimers.js index 27daca1983..62f36a1006 100644 --- a/src/controllers/livetv/livetvseriestimers.js +++ b/src/controllers/livetv/livetvseriestimers.js @@ -1,9 +1,10 @@ define(['datetime', 'cardBuilder', 'imageLoader', 'apphost', 'loading', 'paper-icon-button-light', 'emby-button'], function (datetime, cardBuilder, imageLoader, appHost, loading) { 'use strict'; + loading = loading.default || loading; + function renderTimers(context, timers) { var html = ''; - appHost.supports('imageanalysis'); html += cardBuilder.getCardsHtml({ items: timers, shape: 'auto', diff --git a/src/controllers/livetv/livetvsuggested.js b/src/controllers/livetv/livetvsuggested.js index 036eee9fc6..79d9aac6e9 100644 --- a/src/controllers/livetv/livetvsuggested.js +++ b/src/controllers/livetv/livetvsuggested.js @@ -1,6 +1,8 @@ define(['layoutManager', 'userSettings', 'inputManager', 'loading', 'globalize', 'libraryBrowser', 'mainTabsManager', 'cardBuilder', 'apphost', 'imageLoader', 'scrollStyles', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (layoutManager, userSettings, inputManager, loading, globalize, libraryBrowser, mainTabsManager, cardBuilder, appHost, imageLoader) { 'use strict'; + loading = loading.default || loading; + function enableScrollX() { return !layoutManager.desktop; } @@ -142,9 +144,9 @@ define(['layoutManager', 'userSettings', 'inputManager', 'loading', 'globalize', coverImage: true, overlayText: false, lazy: true, - overlayPlayButton: 'play' === overlayButton, - overlayMoreButton: 'more' === overlayButton, - overlayInfoButton: 'info' === overlayButton, + overlayPlayButton: overlayButton === 'play', + overlayMoreButton: overlayButton === 'more', + overlayInfoButton: overlayButton === 'info', allowBottomPadding: !enableScrollX(), showAirTime: true, showAirDateTime: true @@ -261,7 +263,7 @@ define(['layoutManager', 'userSettings', 'inputManager', 'loading', 'globalize', require(depends, function (controllerFactory) { var tabContent; - if (0 == index) { + if (index == 0) { tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); self.tabContent = tabContent; } @@ -271,9 +273,9 @@ define(['layoutManager', 'userSettings', 'inputManager', 'loading', 'globalize', if (!controller) { tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); - if (0 === index) { + if (index === 0) { controller = self; - } else if (6 === index) { + } else if (index === 6) { controller = new controllerFactory(view, tabContent, { collectionType: 'livetv' }); @@ -305,8 +307,8 @@ define(['layoutManager', 'userSettings', 'inputManager', 'loading', 'globalize', getTabController(page, index, function (controller) { initialTabIndex = null; - if (-1 == renderedTabs.indexOf(index)) { - if (1 === index) { + if (renderedTabs.indexOf(index) == -1) { + if (index === 1) { renderedTabs.push(index); } diff --git a/src/controllers/livetvguideprovider.js b/src/controllers/livetvguideprovider.js index 8f8b9f91c7..6ab195a088 100644 --- a/src/controllers/livetvguideprovider.js +++ b/src/controllers/livetvguideprovider.js @@ -1,30 +1,30 @@ -define(['events', 'loading', 'globalize'], function (events, loading, globalize) { - 'use strict'; +import events from 'events'; +import loading from 'loading'; +import globalize from 'globalize'; - function onListingsSubmitted() { - Dashboard.navigate('livetvstatus.html'); - } +function onListingsSubmitted() { + Dashboard.navigate('livetvstatus.html'); +} - function init(page, type, providerId) { - var url = 'components/tvproviders/' + type + '.js'; +function init(page, type, providerId) { + const url = 'components/tvproviders/' + type + '.js'; - require([url], function (factory) { - var instance = new factory(page, providerId, {}); - events.on(instance, 'submitted', onListingsSubmitted); - instance.init(); - }); - } - - function loadTemplate(page, type, providerId) { - require(['text!./components/tvproviders/' + type + '.template.html'], function (html) { - page.querySelector('.providerTemplate').innerHTML = globalize.translateHtml(html); - init(page, type, providerId); - }); - } - - pageIdOn('pageshow', 'liveTvGuideProviderPage', function () { - loading.show(); - var providerId = getParameterByName('id'); - loadTemplate(this, getParameterByName('type'), providerId); + import(url).then(({default: factory}) => { + const instance = new factory(page, providerId, {}); + events.on(instance, 'submitted', onListingsSubmitted); + instance.init(); }); +} + +function loadTemplate(page, type, providerId) { + import('text!./../components/tvproviders/' + type + '.template.html').then(({default: html}) => { + page.querySelector('.providerTemplate').innerHTML = globalize.translateHtml(html); + init(page, type, providerId); + }); +} + +pageIdOn('pageshow', 'liveTvGuideProviderPage', function () { + loading.show(); + const providerId = getParameterByName('id'); + loadTemplate(this, getParameterByName('type'), providerId); }); diff --git a/src/controllers/livetvsettings.js b/src/controllers/livetvsettings.js index 715eb06214..29ec4a10a5 100644 --- a/src/controllers/livetvsettings.js +++ b/src/controllers/livetvsettings.js @@ -1,65 +1,68 @@ -define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, globalize) { - 'use strict'; +import $ from 'jQuery'; +import loading from 'loading'; +import globalize from 'globalize'; +import 'emby-button'; - function loadPage(page, config) { - $('.liveTvSettingsForm', page).show(); - $('.noLiveTvServices', page).hide(); - $('#selectGuideDays', page).val(config.GuideDays || ''); - $('#txtPrePaddingMinutes', page).val(config.PrePaddingSeconds / 60); - $('#txtPostPaddingMinutes', page).val(config.PostPaddingSeconds / 60); - page.querySelector('#txtRecordingPath').value = config.RecordingPath || ''; - page.querySelector('#txtMovieRecordingPath').value = config.MovieRecordingPath || ''; - page.querySelector('#txtSeriesRecordingPath').value = config.SeriesRecordingPath || ''; - page.querySelector('#txtPostProcessor').value = config.RecordingPostProcessor || ''; - page.querySelector('#txtPostProcessorArguments').value = config.RecordingPostProcessorArguments || ''; - loading.hide(); - } +function loadPage(page, config) { + $('.liveTvSettingsForm', page).show(); + $('.noLiveTvServices', page).hide(); + $('#selectGuideDays', page).val(config.GuideDays || ''); + $('#txtPrePaddingMinutes', page).val(config.PrePaddingSeconds / 60); + $('#txtPostPaddingMinutes', page).val(config.PostPaddingSeconds / 60); + page.querySelector('#txtRecordingPath').value = config.RecordingPath || ''; + page.querySelector('#txtMovieRecordingPath').value = config.MovieRecordingPath || ''; + page.querySelector('#txtSeriesRecordingPath').value = config.SeriesRecordingPath || ''; + page.querySelector('#txtPostProcessor').value = config.RecordingPostProcessor || ''; + page.querySelector('#txtPostProcessorArguments').value = config.RecordingPostProcessorArguments || ''; + loading.hide(); +} - function onSubmit() { - loading.show(); - var form = this; - ApiClient.getNamedConfiguration('livetv').then(function (config) { - config.GuideDays = $('#selectGuideDays', form).val() || null; - var recordingPath = form.querySelector('#txtRecordingPath').value || null; - var movieRecordingPath = form.querySelector('#txtMovieRecordingPath').value || null; - var seriesRecordingPath = form.querySelector('#txtSeriesRecordingPath').value || null; - var recordingPathChanged = recordingPath != config.RecordingPath || movieRecordingPath != config.MovieRecordingPath || seriesRecordingPath != config.SeriesRecordingPath; - config.RecordingPath = recordingPath; - config.MovieRecordingPath = movieRecordingPath; - config.SeriesRecordingPath = seriesRecordingPath; - config.RecordingEncodingFormat = 'mkv'; - config.PrePaddingSeconds = 60 * $('#txtPrePaddingMinutes', form).val(); - config.PostPaddingSeconds = 60 * $('#txtPostPaddingMinutes', form).val(); - config.RecordingPostProcessor = $('#txtPostProcessor', form).val(); - config.RecordingPostProcessorArguments = $('#txtPostProcessorArguments', form).val(); - ApiClient.updateNamedConfiguration('livetv', config).then(function () { - Dashboard.processServerConfigurationUpdateResult(); - showSaveMessage(recordingPathChanged); - }); +function onSubmit() { + loading.show(); + const form = this; + ApiClient.getNamedConfiguration('livetv').then(function (config) { + config.GuideDays = $('#selectGuideDays', form).val() || null; + const recordingPath = form.querySelector('#txtRecordingPath').value || null; + const movieRecordingPath = form.querySelector('#txtMovieRecordingPath').value || null; + const seriesRecordingPath = form.querySelector('#txtSeriesRecordingPath').value || null; + const recordingPathChanged = recordingPath != config.RecordingPath || movieRecordingPath != config.MovieRecordingPath || seriesRecordingPath != config.SeriesRecordingPath; + config.RecordingPath = recordingPath; + config.MovieRecordingPath = movieRecordingPath; + config.SeriesRecordingPath = seriesRecordingPath; + config.RecordingEncodingFormat = 'mkv'; + config.PrePaddingSeconds = 60 * $('#txtPrePaddingMinutes', form).val(); + config.PostPaddingSeconds = 60 * $('#txtPostPaddingMinutes', form).val(); + config.RecordingPostProcessor = $('#txtPostProcessor', form).val(); + config.RecordingPostProcessorArguments = $('#txtPostProcessorArguments', form).val(); + ApiClient.updateNamedConfiguration('livetv', config).then(function () { + Dashboard.processServerConfigurationUpdateResult(); + showSaveMessage(recordingPathChanged); }); - return false; + }); + return false; +} + +function showSaveMessage(recordingPathChanged) { + let msg = ''; + + if (recordingPathChanged) { + msg += globalize.translate('MessageChangeRecordingPath'); } - function showSaveMessage(recordingPathChanged) { - var msg = ''; - - if (recordingPathChanged) { - msg += globalize.translate('RecordingPathChangeMessage'); - } - - if (msg) { - require(['alert'], function (alert) { - alert(msg); - }); - } + if (msg) { + import('alert').then(({default: alert}) => { + alert(msg); + }); } +} +export default function () { $(document).on('pageinit', '#liveTvSettingsPage', function () { - var page = this; + const page = this; $('.liveTvSettingsForm').off('submit', onSubmit).on('submit', onSubmit); $('#btnSelectRecordingPath', page).on('click.selectDirectory', function () { - require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser.default(); + import('directorybrowser').then(({default: directoryBrowser}) => { + const picker = new directoryBrowser(); picker.show({ callback: function (path) { if (path) { @@ -73,8 +76,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, }); }); $('#btnSelectMovieRecordingPath', page).on('click.selectDirectory', function () { - require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser.default(); + import('directorybrowser').then(({default: directoryBrowser}) => { + const picker = new directoryBrowser(); picker.show({ callback: function (path) { if (path) { @@ -88,8 +91,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, }); }); $('#btnSelectSeriesRecordingPath', page).on('click.selectDirectory', function () { - require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser.default(); + import('directorybrowser').then(({default: directoryBrowser}) => { + const picker = new directoryBrowser(); picker.show({ callback: function (path) { if (path) { @@ -103,8 +106,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, }); }); $('#btnSelectPostProcessorPath', page).on('click.selectDirectory', function () { - require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser.default(); + import('directorybrowser').then(({default: directoryBrowser}) => { + const picker = new directoryBrowser(); picker.show({ includeFiles: true, callback: function (path) { @@ -119,9 +122,9 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, }); }).on('pageshow', '#liveTvSettingsPage', function () { loading.show(); - var page = this; + const page = this; ApiClient.getNamedConfiguration('livetv').then(function (config) { loadPage(page, config); }); }); -}); +} diff --git a/src/controllers/livetvstatus.js b/src/controllers/livetvstatus.js index 84ea006fd9..f37760808a 100644 --- a/src/controllers/livetvstatus.js +++ b/src/controllers/livetvstatus.js @@ -1,294 +1,305 @@ -define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layoutManager', 'loading', 'browser', 'listViewStyle', 'flexStyles', 'emby-itemscontainer', 'cardStyle', 'material-icons', 'emby-button'], function ($, globalize, taskButton, dom, libraryMenu, layoutManager, loading, browser) { - 'use strict'; +import $ from 'jQuery'; +import globalize from 'globalize'; +import taskButton from 'scripts/taskbutton'; +import dom from 'dom'; +import layoutManager from 'layoutManager'; +import loading from 'loading'; +import browser from 'browser'; +import 'listViewStyle'; +import 'flexStyles'; +import 'emby-itemscontainer'; +import 'cardStyle'; +import 'material-icons'; +import 'emby-button'; - var enableFocusTransform = !browser.slow && !browser.edge; +const enableFocusTransform = !browser.slow && !browser.edge; - function getDeviceHtml(device) { - var padderClass; - var html = ''; - var cssClass = 'card scalableCard'; - var cardBoxCssClass = 'cardBox visualCardBox'; - cssClass += ' backdropCard backdropCard-scalable'; - padderClass = 'cardPadder-backdrop'; +function getDeviceHtml(device) { + let padderClass; + let html = ''; + let cssClass = 'card scalableCard'; + let cardBoxCssClass = 'cardBox visualCardBox'; + cssClass += ' backdropCard backdropCard-scalable'; + padderClass = 'cardPadder-backdrop'; - // TODO move card creation code to Card component + // TODO move card creation code to Card component - if (layoutManager.tv) { - cssClass += ' show-focus'; + if (layoutManager.tv) { + cssClass += ' show-focus'; - if (enableFocusTransform) { - cssClass += ' show-animation'; - } + if (enableFocusTransform) { + cssClass += ' show-animation'; } - - html += '
    '; - html += '
    '; - html += '
    '; - html += '
    '; - html += '
    '; - html += '
    '; - html += '
    '; - html += '
    '; - html += '
    '; - html += ''; - html += '
    ' + (device.FriendlyName || getTunerName(device.Type)) + '
    '; - html += '
    '; - html += device.Url || ' '; - html += '
    '; - html += '
    '; - html += '
    '; - return html += '
    '; } - function renderDevices(page, devices) { - var html = devices.map(getDeviceHtml).join(''); - page.querySelector('.devicesList').innerHTML = html; - } + html += '
    '; + html += '
    '; + html += '
    '; + html += '
    '; + html += '
    '; + html += '
    '; + html += '
    '; + html += '
    '; + html += '
    '; + html += ''; + html += '
    ' + (device.FriendlyName || getTunerName(device.Type)) + '
    '; + html += '
    '; + html += device.Url || ' '; + html += '
    '; + html += '
    '; + html += '
    '; + return html += '
    '; +} - function deleteDevice(page, id) { - var message = globalize.translate('MessageConfirmDeleteTunerDevice'); +function renderDevices(page, devices) { + page.querySelector('.devicesList').innerHTML = devices.map(getDeviceHtml).join(''); +} - require(['confirm'], function (confirm) { - confirm.default(message, globalize.translate('HeaderDeleteDevice')).then(function () { - loading.show(); - ApiClient.ajax({ - type: 'DELETE', - url: ApiClient.getUrl('LiveTv/TunerHosts', { - Id: id - }) - }).then(function () { - reload(page); - }); +function deleteDevice(page, id) { + const message = globalize.translate('MessageConfirmDeleteTunerDevice'); + + import('confirm').then(({default: confirm}) => { + confirm(message, globalize.translate('HeaderDeleteDevice')).then(function () { + loading.show(); + ApiClient.ajax({ + type: 'DELETE', + url: ApiClient.getUrl('LiveTv/TunerHosts', { + Id: id + }) + }).then(function () { + reload(page); }); }); - } + }); +} - function reload(page) { - loading.show(); - ApiClient.getNamedConfiguration('livetv').then(function (config) { - renderDevices(page, config.TunerHosts); - renderProviders(page, config.ListingProviders); +function reload(page) { + loading.show(); + ApiClient.getNamedConfiguration('livetv').then(function (config) { + renderDevices(page, config.TunerHosts); + renderProviders(page, config.ListingProviders); + }); + loading.hide(); +} + +function submitAddDeviceForm(page) { + page.querySelector('.dlgAddDevice').close(); + loading.show(); + ApiClient.ajax({ + type: 'POST', + url: ApiClient.getUrl('LiveTv/TunerHosts'), + data: JSON.stringify({ + Type: $('#selectTunerDeviceType', page).val(), + Url: $('#txtDevicePath', page).val() + }), + contentType: 'application/json' + }).then(function () { + reload(page); + }, function () { + Dashboard.alert({ + message: globalize.translate('ErrorAddingTunerDevice') }); - loading.hide(); - } + }); +} - function submitAddDeviceForm(page) { - page.querySelector('.dlgAddDevice').close(); - loading.show(); - ApiClient.ajax({ - type: 'POST', - url: ApiClient.getUrl('LiveTv/TunerHosts'), - data: JSON.stringify({ - Type: $('#selectTunerDeviceType', page).val(), - Url: $('#txtDevicePath', page).val() - }), - contentType: 'application/json' - }).then(function () { - reload(page); - }, function () { - Dashboard.alert({ - message: globalize.translate('ErrorAddingTunerDevice') - }); - }); - } +function renderProviders(page, providers) { + let html = ''; - function renderProviders(page, providers) { - var html = ''; - - if (providers.length) { - html += '
    '; - - for (var i = 0, length = providers.length; i < length; i++) { - var provider = providers[i]; - html += ''; - } + if (providers.length) { + html += '
    '; + for (let i = 0, length = providers.length; i < length; i++) { + const provider = providers[i]; + html += ''; } - var elem = $('.providerList', page).html(html); - $('.btnOptions', elem).on('click', function () { - var id = this.getAttribute('data-id'); - showProviderOptions(page, id, this); - }); + html += '
    '; } - function showProviderOptions(page, providerId, button) { - var items = []; - items.push({ - name: globalize.translate('ButtonDelete'), - id: 'delete' - }); - items.push({ - name: globalize.translate('MapChannels'), - id: 'map' - }); + const elem = $('.providerList', page).html(html); + $('.btnOptions', elem).on('click', function () { + const id = this.getAttribute('data-id'); + showProviderOptions(page, id, this); + }); +} - require(['actionsheet'], function (actionsheet) { - actionsheet.show({ - items: items, - positionTo: button - }).then(function (id) { - switch (id) { - case 'delete': - deleteProvider(page, providerId); - break; +function showProviderOptions(page, providerId, button) { + const items = []; + items.push({ + name: globalize.translate('ButtonDelete'), + id: 'delete' + }); + items.push({ + name: globalize.translate('MapChannels'), + id: 'map' + }); - case 'map': - mapChannels(page, providerId); - } - }); - }); - } + import('actionsheet').then(({default: actionsheet}) => { + actionsheet.show({ + items: items, + positionTo: button + }).then(function (id) { + switch (id) { + case 'delete': + deleteProvider(page, providerId); + break; - function mapChannels(page, providerId) { - require(['components/channelMapper/channelMapper'], function (channelMapper) { - new channelMapper.default({ - serverId: ApiClient.serverInfo().Id, - providerId: providerId - }).show(); - }); - } - - function deleteProvider(page, id) { - var message = globalize.translate('MessageConfirmDeleteGuideProvider'); - - require(['confirm'], function (confirm) { - confirm.default(message, globalize.translate('HeaderDeleteProvider')).then(function () { - loading.show(); - ApiClient.ajax({ - type: 'DELETE', - url: ApiClient.getUrl('LiveTv/ListingProviders', { - Id: id - }) - }).then(function () { - reload(page); - }, function () { - reload(page); - }); - }); - }); - } - - function getTunerName(providerId) { - switch (providerId = providerId.toLowerCase()) { - case 'm3u': - return 'M3U'; - case 'hdhomerun': - return 'HDHomeRun'; - case 'hauppauge': - return 'Hauppauge'; - case 'satip': - return 'DVB'; - default: - return 'Unknown'; - } - } - - function getProviderName(providerId) { - switch (providerId = providerId.toLowerCase()) { - case 'schedulesdirect': - return 'Schedules Direct'; - case 'xmltv': - return 'XMLTV'; - default: - return 'Unknown'; - } - } - - function getProviderConfigurationUrl(providerId) { - switch (providerId = providerId.toLowerCase()) { - case 'xmltv': - return 'livetvguideprovider.html?type=xmltv'; - case 'schedulesdirect': - return 'livetvguideprovider.html?type=schedulesdirect'; - } - } - - function addProvider(button) { - var menuItems = []; - menuItems.push({ - name: 'Schedules Direct', - id: 'SchedulesDirect' - }); - menuItems.push({ - name: 'XMLTV', - id: 'xmltv' - }); - - require(['actionsheet'], function (actionsheet) { - actionsheet.show({ - items: menuItems, - positionTo: button, - callback: function (id) { - Dashboard.navigate(getProviderConfigurationUrl(id)); - } - }); - }); - } - - function addDevice(button) { - Dashboard.navigate('livetvtuner.html'); - } - - function showDeviceMenu(button, tunerDeviceId) { - var items = []; - items.push({ - name: globalize.translate('ButtonDelete'), - id: 'delete' - }); - items.push({ - name: globalize.translate('ButtonEdit'), - id: 'edit' - }); - - require(['actionsheet'], function (actionsheet) { - actionsheet.show({ - items: items, - positionTo: button - }).then(function (id) { - switch (id) { - case 'delete': - deleteDevice(dom.parentWithClass(button, 'page'), tunerDeviceId); - break; - - case 'edit': - Dashboard.navigate('livetvtuner.html?id=' + tunerDeviceId); - } - }); - }); - } - - function onDevicesListClick(e) { - var card = dom.parentWithClass(e.target, 'card'); - - if (card) { - var id = card.getAttribute('data-id'); - var btnCardOptions = dom.parentWithClass(e.target, 'btnCardOptions'); - - if (btnCardOptions) { - showDeviceMenu(btnCardOptions, id); - } else { - Dashboard.navigate('livetvtuner.html?id=' + id); + case 'map': + mapChannels(page, providerId); } + }); + }); +} + +function mapChannels(page, providerId) { + import('components/channelMapper/channelMapper').then(({default: channelMapper}) => { + new channelMapper({ + serverId: ApiClient.serverInfo().Id, + providerId: providerId + }).show(); + }); +} + +function deleteProvider(page, id) { + const message = globalize.translate('MessageConfirmDeleteGuideProvider'); + + import('confirm').then(({default: confirm}) => { + confirm(message, globalize.translate('HeaderDeleteProvider')).then(function () { + loading.show(); + ApiClient.ajax({ + type: 'DELETE', + url: ApiClient.getUrl('LiveTv/ListingProviders', { + Id: id + }) + }).then(function () { + reload(page); + }, function () { + reload(page); + }); + }); + }); +} + +function getTunerName(providerId) { + switch (providerId = providerId.toLowerCase()) { + case 'm3u': + return 'M3U'; + case 'hdhomerun': + return 'HDHomeRun'; + case 'hauppauge': + return 'Hauppauge'; + case 'satip': + return 'DVB'; + default: + return 'Unknown'; + } +} + +function getProviderName(providerId) { + switch (providerId = providerId.toLowerCase()) { + case 'schedulesdirect': + return 'Schedules Direct'; + case 'xmltv': + return 'XMLTV'; + default: + return 'Unknown'; + } +} + +function getProviderConfigurationUrl(providerId) { + switch (providerId = providerId.toLowerCase()) { + case 'xmltv': + return 'livetvguideprovider.html?type=xmltv'; + case 'schedulesdirect': + return 'livetvguideprovider.html?type=schedulesdirect'; + } +} + +function addProvider(button) { + const menuItems = []; + menuItems.push({ + name: 'Schedules Direct', + id: 'SchedulesDirect' + }); + menuItems.push({ + name: 'XMLTV', + id: 'xmltv' + }); + + import('actionsheet').then(({default: actionsheet}) => { + actionsheet.show({ + items: menuItems, + positionTo: button, + callback: function (id) { + Dashboard.navigate(getProviderConfigurationUrl(id)); + } + }); + }); +} + +function addDevice(button) { + Dashboard.navigate('livetvtuner.html'); +} + +function showDeviceMenu(button, tunerDeviceId) { + const items = []; + items.push({ + name: globalize.translate('ButtonDelete'), + id: 'delete' + }); + items.push({ + name: globalize.translate('ButtonEdit'), + id: 'edit' + }); + + import('actionsheet').then(({default: actionsheet}) => { + actionsheet.show({ + items: items, + positionTo: button + }).then(function (id) { + switch (id) { + case 'delete': + deleteDevice(dom.parentWithClass(button, 'page'), tunerDeviceId); + break; + + case 'edit': + Dashboard.navigate('livetvtuner.html?id=' + tunerDeviceId); + } + }); + }); +} + +function onDevicesListClick(e) { + const card = dom.parentWithClass(e.target, 'card'); + + if (card) { + const id = card.getAttribute('data-id'); + const btnCardOptions = dom.parentWithClass(e.target, 'btnCardOptions'); + + if (btnCardOptions) { + showDeviceMenu(btnCardOptions, id); + } else { + Dashboard.navigate('livetvtuner.html?id=' + id); } } +} +export default function () { $(document).on('pageinit', '#liveTvStatusPage', function () { - var page = this; + const page = this; $('.btnAddDevice', page).on('click', function () { addDevice(this); }); @@ -301,21 +312,21 @@ define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layo }); page.querySelector('.devicesList').addEventListener('click', onDevicesListClick); }).on('pageshow', '#liveTvStatusPage', function () { - var page = this; + const page = this; reload(page); - taskButton.default({ + taskButton({ mode: 'on', progressElem: page.querySelector('.refreshGuideProgress'), taskKey: 'RefreshGuide', button: page.querySelector('.btnRefresh') }); }).on('pagehide', '#liveTvStatusPage', function () { - var page = this; - taskButton.default({ + const page = this; + taskButton({ mode: 'off', progressElem: page.querySelector('.refreshGuideProgress'), taskKey: 'RefreshGuide', button: page.querySelector('.btnRefresh') }); }); -}); +} diff --git a/src/controllers/livetvtuner.js b/src/controllers/livetvtuner.js index 92f705c02f..0e3b2b689e 100644 --- a/src/controllers/livetvtuner.js +++ b/src/controllers/livetvtuner.js @@ -1,232 +1,228 @@ -define(['globalize', 'loading', 'libraryMenu', 'dom', 'emby-input', 'emby-button', 'emby-checkbox', 'emby-select'], function (globalize, loading, libraryMenu, dom) { - 'use strict'; +import globalize from 'globalize'; +import loading from 'loading'; +import dom from 'dom'; +import 'emby-input'; +import 'emby-button'; +import 'emby-checkbox'; +import 'emby-select'; - function isM3uVariant(type) { - return ['nextpvr'].indexOf(type || '') !== -1; - } +function isM3uVariant(type) { + return ['nextpvr'].indexOf(type || '') !== -1; +} - function fillTypes(view, currentId) { - return ApiClient.getJSON(ApiClient.getUrl('LiveTv/TunerHosts/Types')).then(function (types) { - var selectType = view.querySelector('.selectType'); - var html = ''; - html += types.map(function (tuner) { - return ''; - }).join(''); - html += ''; - selectType.innerHTML = html; - selectType.disabled = null != currentId; - selectType.value = ''; - onTypeChange.call(selectType); - }); - } - - function reload(view, providerId) { - view.querySelector('.txtDevicePath').value = ''; - view.querySelector('.chkFavorite').checked = false; - view.querySelector('.txtDevicePath').value = ''; - - if (providerId) { - ApiClient.getNamedConfiguration('livetv').then(function (config) { - var info = config.TunerHosts.filter(function (i) { - return i.Id === providerId; - })[0]; - fillTunerHostInfo(view, info); - }); - } - } - - function fillTunerHostInfo(view, info) { - var selectType = view.querySelector('.selectType'); - var type = info.Type || ''; - - if (info.Source && isM3uVariant(info.Source)) { - type = info.Source; - } - - selectType.value = type; +function fillTypes(view, currentId) { + return ApiClient.getJSON(ApiClient.getUrl('LiveTv/TunerHosts/Types')).then(function (types) { + const selectType = view.querySelector('.selectType'); + let html = ''; + html += types.map(function (tuner) { + return ''; + }).join(''); + html += ''; + selectType.innerHTML = html; + selectType.disabled = currentId != null; + selectType.value = ''; onTypeChange.call(selectType); - view.querySelector('.txtDevicePath').value = info.Url || ''; - view.querySelector('.txtFriendlyName').value = info.FriendlyName || ''; - view.querySelector('.txtUserAgent').value = info.UserAgent || ''; - view.querySelector('.fldDeviceId').value = info.DeviceId || ''; - view.querySelector('.chkFavorite').checked = info.ImportFavoritesOnly; - view.querySelector('.chkTranscode').checked = info.AllowHWTranscoding; - view.querySelector('.chkStreamLoop').checked = info.EnableStreamLooping; - view.querySelector('.txtTunerCount').value = info.TunerCount || '0'; - } + }); +} - function submitForm(page) { - loading.show(); - var info = { - Type: page.querySelector('.selectType').value, - Url: page.querySelector('.txtDevicePath').value || null, - UserAgent: page.querySelector('.txtUserAgent').value || null, - FriendlyName: page.querySelector('.txtFriendlyName').value || null, - DeviceId: page.querySelector('.fldDeviceId').value || null, - TunerCount: page.querySelector('.txtTunerCount').value || 0, - ImportFavoritesOnly: page.querySelector('.chkFavorite').checked, - AllowHWTranscoding: page.querySelector('.chkTranscode').checked, - EnableStreamLooping: page.querySelector('.chkStreamLoop').checked - }; +function reload(view, providerId) { + view.querySelector('.txtDevicePath').value = ''; + view.querySelector('.chkFavorite').checked = false; + view.querySelector('.txtDevicePath').value = ''; - if (isM3uVariant(info.Type)) { - info.Source = info.Type; - info.Type = 'm3u'; - } - - var id = getParameterByName('id'); - - if (id) { - info.Id = id; - } - - ApiClient.ajax({ - type: 'POST', - url: ApiClient.getUrl('LiveTv/TunerHosts'), - data: JSON.stringify(info), - contentType: 'application/json' - }).then(function (result) { - Dashboard.processServerConfigurationUpdateResult(); - Dashboard.navigate('livetvstatus.html'); - }, function () { - loading.hide(); - Dashboard.alert({ - message: globalize.translate('ErrorSavingTvProvider') - }); + if (providerId) { + ApiClient.getNamedConfiguration('livetv').then(function (config) { + const info = config.TunerHosts.filter(function (i) { + return i.Id === providerId; + })[0]; + fillTunerHostInfo(view, info); }); } +} - function getRequirePromise(deps) { - return new Promise(function (resolve, reject) { - require(deps, resolve); - }); +function fillTunerHostInfo(view, info) { + const selectType = view.querySelector('.selectType'); + let type = info.Type || ''; + + if (info.Source && isM3uVariant(info.Source)) { + type = info.Source; } - function getDetectedDevice() { - return getRequirePromise(['tunerPicker']).then(function (tunerPicker) { - return new tunerPicker().show({ - serverId: ApiClient.serverId() - }); - }); - } + selectType.value = type; + onTypeChange.call(selectType); + view.querySelector('.txtDevicePath').value = info.Url || ''; + view.querySelector('.txtFriendlyName').value = info.FriendlyName || ''; + view.querySelector('.txtUserAgent').value = info.UserAgent || ''; + view.querySelector('.fldDeviceId').value = info.DeviceId || ''; + view.querySelector('.chkFavorite').checked = info.ImportFavoritesOnly; + view.querySelector('.chkTranscode').checked = info.AllowHWTranscoding; + view.querySelector('.chkStreamLoop').checked = info.EnableStreamLooping; + view.querySelector('.txtTunerCount').value = info.TunerCount || '0'; +} - function onTypeChange() { - var value = this.value; - var view = dom.parentWithClass(this, 'page'); - var mayIncludeUnsupportedDrmChannels = 'hdhomerun' === value; - var supportsTranscoding = 'hdhomerun' === value; - var supportsFavorites = 'hdhomerun' === value; - var supportsTunerIpAddress = 'hdhomerun' === value; - var supportsTunerFileOrUrl = 'm3u' === value; - var supportsStreamLooping = 'm3u' === value; - var supportsTunerCount = 'm3u' === value; - var supportsUserAgent = 'm3u' === value; - var suppportsSubmit = 'other' !== value; - var supportsSelectablePath = supportsTunerFileOrUrl; - var txtDevicePath = view.querySelector('.txtDevicePath'); - - if (supportsTunerIpAddress) { - txtDevicePath.label(globalize.translate('LabelTunerIpAddress')); - view.querySelector('.fldPath').classList.remove('hide'); - } else if (supportsTunerFileOrUrl) { - txtDevicePath.label(globalize.translate('LabelFileOrUrl')); - view.querySelector('.fldPath').classList.remove('hide'); - } else { - view.querySelector('.fldPath').classList.add('hide'); - } - - if (supportsSelectablePath) { - view.querySelector('.btnSelectPath').classList.remove('hide'); - view.querySelector('.txtDevicePath').setAttribute('required', 'required'); - } else { - view.querySelector('.btnSelectPath').classList.add('hide'); - view.querySelector('.txtDevicePath').removeAttribute('required'); - } - - if (supportsUserAgent) { - view.querySelector('.fldUserAgent').classList.remove('hide'); - } else { - view.querySelector('.fldUserAgent').classList.add('hide'); - } - - if (supportsFavorites) { - view.querySelector('.fldFavorites').classList.remove('hide'); - } else { - view.querySelector('.fldFavorites').classList.add('hide'); - } - - if (supportsTranscoding) { - view.querySelector('.fldTranscode').classList.remove('hide'); - } else { - view.querySelector('.fldTranscode').classList.add('hide'); - } - - if (supportsStreamLooping) { - view.querySelector('.fldStreamLoop').classList.remove('hide'); - } else { - view.querySelector('.fldStreamLoop').classList.add('hide'); - } - - if (supportsTunerCount) { - view.querySelector('.fldTunerCount').classList.remove('hide'); - view.querySelector('.txtTunerCount').setAttribute('required', 'required'); - } else { - view.querySelector('.fldTunerCount').classList.add('hide'); - view.querySelector('.txtTunerCount').removeAttribute('required'); - } - - if (mayIncludeUnsupportedDrmChannels) { - view.querySelector('.drmMessage').classList.remove('hide'); - } else { - view.querySelector('.drmMessage').classList.add('hide'); - } - - if (suppportsSubmit) { - view.querySelector('.button-submit').classList.remove('hide'); - } else { - view.querySelector('.button-submit').classList.add('hide'); - } - } - - return function (view, params) { - if (!params.id) { - view.querySelector('.btnDetect').classList.remove('hide'); - } - - view.addEventListener('viewshow', function () { - var currentId = params.id; - fillTypes(view, currentId).then(function () { - reload(view, currentId); - }); - }); - view.querySelector('form').addEventListener('submit', function (e) { - submitForm(view); - e.preventDefault(); - e.stopPropagation(); - return false; - }); - view.querySelector('.selectType').addEventListener('change', onTypeChange); - view.querySelector('.btnDetect').addEventListener('click', function () { - getDetectedDevice().then(function (info) { - fillTunerHostInfo(view, info); - }); - }); - view.querySelector('.btnSelectPath').addEventListener('click', function () { - require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser.default(); - picker.show({ - includeFiles: true, - callback: function (path) { - if (path) { - view.querySelector('.txtDevicePath').value = path; - } - - picker.close(); - } - }); - }); - }); +function submitForm(page) { + loading.show(); + const info = { + Type: page.querySelector('.selectType').value, + Url: page.querySelector('.txtDevicePath').value || null, + UserAgent: page.querySelector('.txtUserAgent').value || null, + FriendlyName: page.querySelector('.txtFriendlyName').value || null, + DeviceId: page.querySelector('.fldDeviceId').value || null, + TunerCount: page.querySelector('.txtTunerCount').value || 0, + ImportFavoritesOnly: page.querySelector('.chkFavorite').checked, + AllowHWTranscoding: page.querySelector('.chkTranscode').checked, + EnableStreamLooping: page.querySelector('.chkStreamLoop').checked }; -}); + + if (isM3uVariant(info.Type)) { + info.Source = info.Type; + info.Type = 'm3u'; + } + + if (getParameterByName('id')) { + info.Id = getParameterByName('id'); + } + + ApiClient.ajax({ + type: 'POST', + url: ApiClient.getUrl('LiveTv/TunerHosts'), + data: JSON.stringify(info), + contentType: 'application/json' + }).then(function (result) { + Dashboard.processServerConfigurationUpdateResult(); + Dashboard.navigate('livetvstatus.html'); + }, function () { + loading.hide(); + Dashboard.alert({ + message: globalize.translate('ErrorSavingTvProvider') + }); + }); +} + +function getDetectedDevice() { + return import('tunerPicker').then(({default: tunerPicker}) => { + return new tunerPicker().show({ + serverId: ApiClient.serverId() + }); + }); +} + +function onTypeChange() { + const value = this.value; + const view = dom.parentWithClass(this, 'page'); + const mayIncludeUnsupportedDrmChannels = value === 'hdhomerun'; + const supportsTranscoding = value === 'hdhomerun'; + const supportsFavorites = value === 'hdhomerun'; + const supportsTunerIpAddress = value === 'hdhomerun'; + const supportsTunerFileOrUrl = value === 'm3u'; + const supportsStreamLooping = value === 'm3u'; + const supportsTunerCount = value === 'm3u'; + const supportsUserAgent = value === 'm3u'; + const suppportsSubmit = value !== 'other'; + const supportsSelectablePath = supportsTunerFileOrUrl; + const txtDevicePath = view.querySelector('.txtDevicePath'); + + if (supportsTunerIpAddress) { + txtDevicePath.label(globalize.translate('LabelTunerIpAddress')); + view.querySelector('.fldPath').classList.remove('hide'); + } else if (supportsTunerFileOrUrl) { + txtDevicePath.label(globalize.translate('LabelFileOrUrl')); + view.querySelector('.fldPath').classList.remove('hide'); + } else { + view.querySelector('.fldPath').classList.add('hide'); + } + + if (supportsSelectablePath) { + view.querySelector('.btnSelectPath').classList.remove('hide'); + view.querySelector('.txtDevicePath').setAttribute('required', 'required'); + } else { + view.querySelector('.btnSelectPath').classList.add('hide'); + view.querySelector('.txtDevicePath').removeAttribute('required'); + } + + if (supportsUserAgent) { + view.querySelector('.fldUserAgent').classList.remove('hide'); + } else { + view.querySelector('.fldUserAgent').classList.add('hide'); + } + + if (supportsFavorites) { + view.querySelector('.fldFavorites').classList.remove('hide'); + } else { + view.querySelector('.fldFavorites').classList.add('hide'); + } + + if (supportsTranscoding) { + view.querySelector('.fldTranscode').classList.remove('hide'); + } else { + view.querySelector('.fldTranscode').classList.add('hide'); + } + + if (supportsStreamLooping) { + view.querySelector('.fldStreamLoop').classList.remove('hide'); + } else { + view.querySelector('.fldStreamLoop').classList.add('hide'); + } + + if (supportsTunerCount) { + view.querySelector('.fldTunerCount').classList.remove('hide'); + view.querySelector('.txtTunerCount').setAttribute('required', 'required'); + } else { + view.querySelector('.fldTunerCount').classList.add('hide'); + view.querySelector('.txtTunerCount').removeAttribute('required'); + } + + if (mayIncludeUnsupportedDrmChannels) { + view.querySelector('.drmMessage').classList.remove('hide'); + } else { + view.querySelector('.drmMessage').classList.add('hide'); + } + + if (suppportsSubmit) { + view.querySelector('.button-submit').classList.remove('hide'); + } else { + view.querySelector('.button-submit').classList.add('hide'); + } +} + +export default function (view, params) { + if (!params.id) { + view.querySelector('.btnDetect').classList.remove('hide'); + } + + view.addEventListener('viewshow', function () { + const currentId = params.id; + fillTypes(view, currentId).then(function () { + reload(view, currentId); + }); + }); + view.querySelector('form').addEventListener('submit', function (e) { + submitForm(view); + e.preventDefault(); + e.stopPropagation(); + return false; + }); + view.querySelector('.selectType').addEventListener('change', onTypeChange); + view.querySelector('.btnDetect').addEventListener('click', function () { + getDetectedDevice().then(function (info) { + fillTunerHostInfo(view, info); + }); + }); + view.querySelector('.btnSelectPath').addEventListener('click', function () { + import('directorybrowser').then(({default: directorybrowser}) => { + const picker = new directorybrowser(); + picker.show({ + includeFiles: true, + callback: function (path) { + if (path) { + view.querySelector('.txtDevicePath').value = path; + } + + picker.close(); + } + }); + }); + }); +} diff --git a/src/controllers/movies/moviecollections.js b/src/controllers/movies/moviecollections.js index 65abca46e0..7c1a5156d9 100644 --- a/src/controllers/movies/moviecollections.js +++ b/src/controllers/movies/moviecollections.js @@ -1,6 +1,9 @@ define(['loading', 'events', 'libraryBrowser', 'imageLoader', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, userSettings, globalize) { 'use strict'; + loading = loading.default || loading; + libraryBrowser = libraryBrowser.default || libraryBrowser; + return function (view, params, tabContent) { function getPageData(context) { var key = getSavedQueryKey(context); @@ -48,7 +51,7 @@ define(['loading', 'events', 'libraryBrowser', 'imageLoader', 'listView', 'cardB var viewStyle = self.getCurrentViewStyle(); var itemsContainer = tabContent.querySelector('.itemsContainer'); - if ('List' == viewStyle) { + if (viewStyle == 'List') { itemsContainer.classList.add('vertical-list'); itemsContainer.classList.remove('vertical-wrap'); } else { diff --git a/src/controllers/movies/moviegenres.js b/src/controllers/movies/moviegenres.js index ab410c1bd4..82ab4d4d4b 100644 --- a/src/controllers/movies/moviegenres.js +++ b/src/controllers/movies/moviegenres.js @@ -1,6 +1,9 @@ define(['layoutManager', 'loading', 'libraryBrowser', 'cardBuilder', 'lazyLoader', 'apphost', 'globalize', 'appRouter', 'dom', 'emby-button'], function (layoutManager, loading, libraryBrowser, cardBuilder, lazyLoader, appHost, globalize, appRouter, dom) { 'use strict'; + loading = loading.default || loading; + libraryBrowser = libraryBrowser.default || libraryBrowser; + return function (view, params, tabContent) { function getPageData() { var key = getSavedQueryKey(); @@ -54,13 +57,13 @@ define(['layoutManager', 'loading', 'libraryBrowser', 'cardBuilder', 'lazyLoader var elem = entry.target; var id = elem.getAttribute('data-id'); var viewStyle = self.getCurrentViewStyle(); - var limit = 'Thumb' == viewStyle || 'ThumbCard' == viewStyle ? 5 : 9; + var limit = viewStyle == 'Thumb' || viewStyle == 'ThumbCard' ? 5 : 9; if (enableScrollX()) { limit = 10; } - var enableImageTypes = 'Thumb' == viewStyle || 'ThumbCard' == viewStyle ? 'Primary,Backdrop,Thumb' : 'Primary'; + var enableImageTypes = viewStyle == 'Thumb' || viewStyle == 'ThumbCard' ? 'Primary,Backdrop,Thumb' : 'Primary'; var query = { SortBy: 'SortName', SortOrder: 'Ascending', @@ -75,8 +78,6 @@ define(['layoutManager', 'loading', 'libraryBrowser', 'cardBuilder', 'lazyLoader ParentId: params.topParentId }; ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) { - var supportsImageAnalysis = appHost.supports('imageanalysis'); - if (viewStyle == 'Thumb') { cardBuilder.buildCards(result.Items, { itemsContainer: elem, diff --git a/src/controllers/movies/movies.js b/src/controllers/movies/movies.js index 82b162e2ad..ade9dc4b89 100644 --- a/src/controllers/movies/movies.js +++ b/src/controllers/movies/movies.js @@ -1,6 +1,9 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser', 'alphaPicker', 'listView', 'cardBuilder', 'globalize', 'emby-itemscontainer'], function (loading, layoutManager, userSettings, events, libraryBrowser, AlphaPicker, listView, cardBuilder, globalize) { 'use strict'; + loading = loading.default || loading; + libraryBrowser = libraryBrowser.default || libraryBrowser; + return function (view, params, tabContent, options) { function onViewStyleChange() { if (self.getCurrentViewStyle() == 'List') { diff --git a/src/controllers/movies/moviesrecommended.js b/src/controllers/movies/moviesrecommended.js index d948c1cef7..a633d654cd 100644 --- a/src/controllers/movies/moviesrecommended.js +++ b/src/controllers/movies/moviesrecommended.js @@ -1,6 +1,8 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu', 'mainTabsManager', 'cardBuilder', 'dom', 'imageLoader', 'playbackManager', 'globalize', 'emby-scroller', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, cardBuilder, dom, imageLoader, playbackManager, globalize) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function enableScrollX() { return !layoutManager.desktop; } @@ -346,8 +348,6 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu' function loadTab(page, index) { currentTabIndex = index; getTabController(page, index, function (controller) { - initialTabIndex = null; - if (renderedTabs.indexOf(index) == -1) { renderedTabs.push(index); controller.renderTab(); @@ -370,10 +370,8 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu' } } - var isViewRestored; var self = this; var currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)); - var initialTabIndex = currentTabIndex; var suggestionsTabIndex = 1; self.initTab = function () { @@ -389,7 +387,8 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu' var tabControllers = []; var renderedTabs = []; view.addEventListener('viewshow', function (e) { - if (isViewRestored = e.detail.isRestored, initTabs(), !view.getAttribute('data-title')) { + initTabs(); + if (!view.getAttribute('data-title')) { var parentId = params.topParentId; if (parentId) { diff --git a/src/controllers/movies/movietrailers.js b/src/controllers/movies/movietrailers.js index a9db0abf49..8d9fe8d090 100644 --- a/src/controllers/movies/movietrailers.js +++ b/src/controllers/movies/movietrailers.js @@ -1,6 +1,9 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (layoutManager, loading, events, libraryBrowser, imageLoader, AlphaPicker, listView, cardBuilder, userSettings, globalize) { 'use strict'; + loading = loading.default || loading; + libraryBrowser = libraryBrowser.default || libraryBrowser; + return function (view, params, tabContent) { function getPageData(context) { var key = getSavedQueryKey(context); diff --git a/src/controllers/music/musicalbums.js b/src/controllers/music/musicalbums.js index 3630e0b9f9..7d03c91073 100644 --- a/src/controllers/music/musicalbums.js +++ b/src/controllers/music/musicalbums.js @@ -1,7 +1,18 @@ -define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (layoutManager, playbackManager, loading, events, libraryBrowser, imageLoader, AlphaPicker, listView, cardBuilder, userSettings, globalize) { - 'use strict'; +import playbackManager from 'playbackManager'; +import loading from 'loading'; +import events from 'events'; +import libraryBrowser from 'libraryBrowser'; +import imageLoader from 'imageLoader'; +import AlphaPicker from 'alphaPicker'; +import listView from 'listView'; +import cardBuilder from 'cardBuilder'; +import * as userSettings from 'userSettings'; +import globalize from 'globalize'; +import 'emby-itemscontainer'; - return function (view, params, tabContent) { +/* eslint-disable indent */ + + export default function (view, params, tabContent) { function playAll() { ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function (item) { playbackManager.play({ @@ -18,7 +29,7 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser } function getPageData() { - var key = getSavedQueryKey(); + const key = getSavedQueryKey(); if (!pageData) { pageData = { @@ -59,10 +70,10 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser } function onViewStyleChange() { - var viewStyle = self.getCurrentViewStyle(); - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const viewStyle = self.getCurrentViewStyle(); + const itemsContainer = tabContent.querySelector('.itemsContainer'); - if ('List' == viewStyle) { + if (viewStyle == 'List') { itemsContainer.classList.add('vertical-list'); itemsContainer.classList.remove('vertical-wrap'); } else { @@ -76,7 +87,7 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser function reloadItems(page) { loading.show(); isLoading = true; - var query = getQuery(); + const query = getQuery(); ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) { function onNextPageClick() { if (isLoading) { @@ -102,8 +113,8 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser window.scrollTo(0, 0); updateFilterControls(page); - var html; - var pagingHtml = libraryBrowser.getQueryPagingHtml({ + let html; + const pagingHtml = libraryBrowser.getQueryPagingHtml({ startIndex: query.StartIndex, limit: query.Limit, totalRecordCount: result.TotalRecordCount, @@ -113,7 +124,7 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser sortButton: false, filterButton: false }); - var viewStyle = self.getCurrentViewStyle(); + const viewStyle = self.getCurrentViewStyle(); if (viewStyle == 'List') { html = listView.getListViewHtml({ items: result.Items, @@ -144,50 +155,48 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser overlayPlayButton: true }); } - var i; - var length; - var elems = tabContent.querySelectorAll('.paging'); + let elems = tabContent.querySelectorAll('.paging'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].innerHTML = pagingHtml; } elems = tabContent.querySelectorAll('.btnNextPage'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener('click', onNextPageClick); } elems = tabContent.querySelectorAll('.btnPreviousPage'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener('click', onPreviousPageClick); } - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const itemsContainer = tabContent.querySelector('.itemsContainer'); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(), query); loading.hide(); isLoading = false; - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(tabContent); }); }); } function updateFilterControls(tabContent) { - var query = getQuery(); + const query = getQuery(); self.alphaPicker.value(query.NameStartsWithOrGreater); } - var savedQueryKey; - var pageData; - var self = this; - var isLoading = false; + let savedQueryKey; + let pageData; + const self = this; + let isLoading = false; self.showFilterMenu = function () { - require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) { - var filterDialog = new filterDialogFactory({ + import('components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => { + const filterDialog = new filterDialogFactory({ query: getQuery(), mode: 'albums', serverId: ApiClient.serverId() @@ -205,17 +214,17 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser }; function initPage(tabContent) { - var alphaPickerElement = tabContent.querySelector('.alphaPicker'); - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const alphaPickerElement = tabContent.querySelector('.alphaPicker'); + const itemsContainer = tabContent.querySelector('.itemsContainer'); alphaPickerElement.addEventListener('alphavaluechanged', function (e) { - var newValue = e.detail.value; - var query = getQuery(); + const newValue = e.detail.value; + const query = getQuery(); query.NameStartsWithOrGreater = newValue; query.StartIndex = 0; reloadItems(tabContent); }); - self.alphaPicker = new AlphaPicker.default({ + self.alphaPicker = new AlphaPicker({ element: alphaPickerElement, valueChangeEvent: 'click' }); @@ -259,12 +268,12 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser button: e.target }); }); - var btnSelectView = tabContent.querySelector('.btnSelectView'); + const btnSelectView = tabContent.querySelector('.btnSelectView'); btnSelectView.addEventListener('click', function (e) { libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(',')); }); btnSelectView.addEventListener('layoutchange', function (e) { - var viewStyle = e.detail.viewStyle; + const viewStyle = e.detail.viewStyle; getPageData().view = viewStyle; libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle); getQuery().StartIndex = 0; @@ -284,5 +293,6 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser }; self.destroy = function () {}; - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/music/musicartists.js b/src/controllers/music/musicartists.js index c9a0b06b77..23e0bbd459 100644 --- a/src/controllers/music/musicartists.js +++ b/src/controllers/music/musicartists.js @@ -1,13 +1,22 @@ -define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'apphost', 'userSettings', 'emby-itemscontainer'], function (layoutManager, loading, events, libraryBrowser, imageLoader, AlphaPicker, listView, cardBuilder, appHost, userSettings) { - 'use strict'; +import loading from 'loading'; +import events from 'events'; +import libraryBrowser from 'libraryBrowser'; +import imageLoader from 'imageLoader'; +import AlphaPicker from 'alphaPicker'; +import listView from 'listView'; +import cardBuilder from 'cardBuilder'; +import * as userSettings from 'userSettings'; +import 'emby-itemscontainer'; - return function (view, params, tabContent) { +/* eslint-disable indent */ + + export default function (view, params, tabContent) { function getPageData(context) { - var key = getSavedQueryKey(context); - var pageData = data[key]; + const key = getSavedQueryKey(context); + let pageData = data[key]; if (!pageData) { - var queryValues = { + const queryValues = { SortBy: 'SortName', SortOrder: 'Ascending', Recursive: true, @@ -45,10 +54,10 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' } function onViewStyleChange() { - var viewStyle = self.getCurrentViewStyle(); - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const viewStyle = self.getCurrentViewStyle(); + const itemsContainer = tabContent.querySelector('.itemsContainer'); - if ('List' == viewStyle) { + if (viewStyle == 'List') { itemsContainer.classList.add('vertical-list'); itemsContainer.classList.remove('vertical-wrap'); } else { @@ -62,8 +71,8 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' function reloadItems(page) { loading.show(); isLoading = true; - var query = getQuery(page); - var promise = self.mode == 'albumartists' ? + const query = getQuery(page); + const promise = self.mode == 'albumartists' ? ApiClient.getAlbumArtists(ApiClient.getCurrentUserId(), query) : ApiClient.getArtists(ApiClient.getCurrentUserId(), query); promise.then(function (result) { @@ -91,8 +100,8 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' window.scrollTo(0, 0); updateFilterControls(page); - var html; - var pagingHtml = libraryBrowser.getQueryPagingHtml({ + let html; + const pagingHtml = libraryBrowser.getQueryPagingHtml({ startIndex: query.StartIndex, limit: query.Limit, totalRecordCount: result.TotalRecordCount, @@ -102,7 +111,7 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' sortButton: false, filterButton: false }); - var viewStyle = self.getCurrentViewStyle(); + const viewStyle = self.getCurrentViewStyle(); if (viewStyle == 'List') { html = listView.getListViewHtml({ items: result.Items, @@ -129,49 +138,47 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' overlayPlayButton: true }); } - var i; - var length; - var elems = tabContent.querySelectorAll('.paging'); + let elems = tabContent.querySelectorAll('.paging'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].innerHTML = pagingHtml; } elems = tabContent.querySelectorAll('.btnNextPage'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener('click', onNextPageClick); } elems = tabContent.querySelectorAll('.btnPreviousPage'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener('click', onPreviousPageClick); } - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const itemsContainer = tabContent.querySelector('.itemsContainer'); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(page), query); loading.hide(); isLoading = false; - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(tabContent); }); }); } function updateFilterControls(tabContent) { - var query = getQuery(tabContent); + const query = getQuery(tabContent); self.alphaPicker.value(query.NameStartsWithOrGreater); } - var self = this; - var data = {}; - var isLoading = false; + const self = this; + const data = {}; + let isLoading = false; self.showFilterMenu = function () { - require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) { - var filterDialog = new filterDialogFactory({ + import('components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => { + const filterDialog = new filterDialogFactory({ query: getQuery(tabContent), mode: self.mode, serverId: ApiClient.serverId() @@ -189,17 +196,17 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' }; function initPage(tabContent) { - var alphaPickerElement = tabContent.querySelector('.alphaPicker'); - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const alphaPickerElement = tabContent.querySelector('.alphaPicker'); + const itemsContainer = tabContent.querySelector('.itemsContainer'); alphaPickerElement.addEventListener('alphavaluechanged', function (e) { - var newValue = e.detail.value; - var query = getQuery(tabContent); + const newValue = e.detail.value; + const query = getQuery(tabContent); query.NameStartsWithOrGreater = newValue; query.StartIndex = 0; reloadItems(tabContent); }); - self.alphaPicker = new AlphaPicker.default({ + self.alphaPicker = new AlphaPicker({ element: alphaPickerElement, valueChangeEvent: 'click' }); @@ -211,12 +218,12 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' tabContent.querySelector('.btnFilter').addEventListener('click', function () { self.showFilterMenu(); }); - var btnSelectView = tabContent.querySelector('.btnSelectView'); + const btnSelectView = tabContent.querySelector('.btnSelectView'); btnSelectView.addEventListener('click', function (e) { libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(',')); }); btnSelectView.addEventListener('layoutchange', function (e) { - var viewStyle = e.detail.viewStyle; + const viewStyle = e.detail.viewStyle; getPageData(tabContent).view = viewStyle; libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle); getQuery(tabContent).StartIndex = 0; @@ -234,5 +241,6 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' }; self.destroy = function () {}; - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/music/musicgenres.js b/src/controllers/music/musicgenres.js index 82f2eba574..29e0d888e4 100644 --- a/src/controllers/music/musicgenres.js +++ b/src/controllers/music/musicgenres.js @@ -1,10 +1,14 @@ -define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], function (libraryBrowser, cardBuilder, appHost, imageLoader, loading) { - 'use strict'; +import libraryBrowser from 'libraryBrowser'; +import cardBuilder from 'cardBuilder'; +import imageLoader from 'imageLoader'; +import loading from 'loading'; - return function (view, params, tabContent) { +/* eslint-disable indent */ + + export default function (view, params, tabContent) { function getPageData() { - var key = getSavedQueryKey(); - var pageData = data[key]; + const key = getSavedQueryKey(); + let pageData = data[key]; if (!pageData) { pageData = data[key] = { @@ -34,15 +38,15 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f function getPromise() { loading.show(); - var query = getQuery(); + const query = getQuery(); return ApiClient.getGenres(ApiClient.getCurrentUserId(), query); } function reloadItems(context, promise) { - var query = getQuery(); + const query = getQuery(); promise.then(function (result) { - var html = ''; - var viewStyle = self.getCurrentViewStyle(); + let html = ''; + const viewStyle = self.getCurrentViewStyle(); if (viewStyle == 'Thumb') { html = cardBuilder.getCardsHtml({ @@ -82,13 +86,13 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f }); } - var elem = context.querySelector('#items'); + const elem = context.querySelector('#items'); elem.innerHTML = html; imageLoader.lazyChildren(elem); libraryBrowser.saveQueryValues(getSavedQueryKey(), query); loading.hide(); - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(context); }); }); @@ -99,8 +103,8 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f self.renderTab(); } - var self = this; - var data = {}; + const self = this; + const data = {}; self.getViewStyles = function () { return 'Poster,PosterCard,Thumb,ThumbCard'.split(','); @@ -117,7 +121,7 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f }; self.enableViewSelection = true; - var promise; + let promise; self.preRender = function () { promise = getPromise(); @@ -126,5 +130,6 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f self.renderTab = function () { reloadItems(tabContent, promise); }; - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/music/musicplaylists.js b/src/controllers/music/musicplaylists.js index f508489216..befeafcf4c 100644 --- a/src/controllers/music/musicplaylists.js +++ b/src/controllers/music/musicplaylists.js @@ -1,10 +1,14 @@ -define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], function (libraryBrowser, cardBuilder, appHost, imageLoader, loading) { - 'use strict'; +import libraryBrowser from 'libraryBrowser'; +import cardBuilder from 'cardBuilder'; +import imageLoader from 'imageLoader'; +import loading from 'loading'; - return function (view, params, tabContent) { +/* eslint-disable indent */ + + export default function (view, params, tabContent) { function getPageData() { - var key = getSavedQueryKey(); - var pageData = data[key]; + const key = getSavedQueryKey(); + let pageData = data[key]; if (!pageData) { pageData = data[key] = { @@ -35,14 +39,14 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f function getPromise() { loading.show(); - var query = getQuery(); + const query = getQuery(); return ApiClient.getItems(ApiClient.getCurrentUserId(), query); } function reloadItems(context, promise) { - var query = getQuery(); + const query = getQuery(); promise.then(function (result) { - var html = ''; + let html = ''; html = cardBuilder.getCardsHtml({ items: result.Items, shape: 'square', @@ -53,26 +57,26 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f allowBottomPadding: true, cardLayout: false }); - var elem = context.querySelector('#items'); + const elem = context.querySelector('#items'); elem.innerHTML = html; imageLoader.lazyChildren(elem); libraryBrowser.saveQueryValues(getSavedQueryKey(), query); loading.hide(); - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(context); }); }); } - var self = this; - var data = {}; + const self = this; + const data = {}; self.getCurrentViewStyle = function () { return getPageData().view; }; - var promise; + let promise; self.preRender = function () { promise = getPromise(); @@ -81,5 +85,6 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f self.renderTab = function () { reloadItems(tabContent, promise); }; - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/music/musicrecommended.js b/src/controllers/music/musicrecommended.js index 3f025799f6..db7dac9547 100644 --- a/src/controllers/music/musicrecommended.js +++ b/src/controllers/music/musicrecommended.js @@ -1,8 +1,24 @@ -define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', 'cardBuilder', 'dom', 'apphost', 'imageLoader', 'libraryMenu', 'playbackManager', 'mainTabsManager', 'globalize', 'scrollStyles', 'emby-itemscontainer', 'emby-tabs', 'emby-button', 'flexStyles'], function (browser, layoutManager, userSettings, inputManager, loading, cardBuilder, dom, appHost, imageLoader, libraryMenu, playbackManager, mainTabsManager, globalize) { - 'use strict'; +import browser from 'browser'; +import layoutManager from 'layoutManager'; +import * as userSettings from 'userSettings'; +import inputManager from 'inputManager'; +import loading from 'loading'; +import cardBuilder from 'cardBuilder'; +import dom from 'dom'; +import imageLoader from 'imageLoader'; +import libraryMenu from 'libraryMenu'; +import * as mainTabsManager from 'mainTabsManager'; +import globalize from 'globalize'; +import 'scrollStyles'; +import 'emby-itemscontainer'; +import 'emby-tabs'; +import 'emby-button'; +import 'flexStyles'; + +/* eslint-disable indent */ function itemsPerRow() { - var screenWidth = dom.getWindowSize().innerWidth; + const screenWidth = dom.getWindowSize().innerWidth; if (screenWidth >= 1920) { return 9; @@ -29,8 +45,8 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' function loadLatest(page, parentId) { loading.show(); - var userId = ApiClient.getCurrentUserId(); - var options = { + const userId = ApiClient.getCurrentUserId(); + const options = { IncludeItemTypes: 'Audio', Limit: enableScrollX() ? 3 * itemsPerRow() : 2 * itemsPerRow(), Fields: 'PrimaryImageAspectRatio,BasicSyncInfo', @@ -41,8 +57,6 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' }; ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options)).then(function (items) { var elem = page.querySelector('#recentlyAddedSongs'); - var supportsImageAnalysis = appHost.supports('imageanalysis'); - supportsImageAnalysis = false; elem.innerHTML = cardBuilder.getCardsHtml({ items: items, showUnplayedIndicator: false, @@ -51,23 +65,23 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' showTitle: true, showParentTitle: true, lazy: true, - centerText: !supportsImageAnalysis, - overlayPlayButton: !supportsImageAnalysis, + centerText: true, + overlayPlayButton: true, allowBottomPadding: !enableScrollX(), - cardLayout: supportsImageAnalysis, + cardLayout: false, coverImage: true }); imageLoader.lazyChildren(elem); loading.hide(); - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(page); }); }); } function loadRecentlyPlayed(page, parentId) { - var options = { + const options = { SortBy: 'DatePlayed', SortOrder: 'Descending', IncludeItemTypes: 'Audio', @@ -81,7 +95,7 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' EnableTotalRecordCount: false }; ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) { - var elem = page.querySelector('#recentlyPlayed'); + const elem = page.querySelector('#recentlyPlayed'); if (result.Items.length) { elem.classList.remove('hide'); @@ -90,8 +104,7 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' } var itemsContainer = elem.querySelector('.itemsContainer'); - var supportsImageAnalysis = appHost.supports('imageanalysis'); - supportsImageAnalysis = false; + itemsContainer.innerHTML = cardBuilder.getCardsHtml({ items: result.Items, showUnplayedIndicator: false, @@ -100,10 +113,10 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' showParentTitle: true, action: 'instantmix', lazy: true, - centerText: !supportsImageAnalysis, - overlayMoreButton: !supportsImageAnalysis, + centerText: true, + overlayMoreButton: true, allowBottomPadding: !enableScrollX(), - cardLayout: supportsImageAnalysis, + cardLayout: false, coverImage: true }); imageLoader.lazyChildren(itemsContainer); @@ -111,7 +124,7 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' } function loadFrequentlyPlayed(page, parentId) { - var options = { + const options = { SortBy: 'PlayCount', SortOrder: 'Descending', IncludeItemTypes: 'Audio', @@ -125,7 +138,7 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' EnableTotalRecordCount: false }; ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) { - var elem = page.querySelector('#topPlayed'); + const elem = page.querySelector('#topPlayed'); if (result.Items.length) { elem.classList.remove('hide'); @@ -134,8 +147,6 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' } var itemsContainer = elem.querySelector('.itemsContainer'); - var supportsImageAnalysis = appHost.supports('imageanalysis'); - supportsImageAnalysis = false; itemsContainer.innerHTML = cardBuilder.getCardsHtml({ items: result.Items, showUnplayedIndicator: false, @@ -144,10 +155,10 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' showParentTitle: true, action: 'instantmix', lazy: true, - centerText: !supportsImageAnalysis, - overlayMoreButton: !supportsImageAnalysis, + centerText: true, + overlayMoreButton: true, allowBottomPadding: !enableScrollX(), - cardLayout: supportsImageAnalysis, + cardLayout: false, coverImage: true }); imageLoader.lazyChildren(itemsContainer); @@ -160,7 +171,7 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' loadRecentlyPlayed(tabContent, parentId); loadFrequentlyPlayed(tabContent, parentId); - require(['components/favoriteitems'], function (favoriteItems) { + import('components/favoriteitems').then(({default: favoriteItems}) => { favoriteItems.render(tabContent, ApiClient.getCurrentUserId(), parentId, ['favoriteArtists', 'favoriteAlbums', 'favoriteSongs']); }); } @@ -211,10 +222,10 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' } } - return function (view, params) { + export default function (view, params) { function reload() { loading.show(); - var tabContent = view.querySelector(".pageTabContent[data-index='0']"); + const tabContent = view.querySelector(".pageTabContent[data-index='0']"); loadSuggestionsTab(view, tabContent, params.topParentId); } @@ -257,46 +268,48 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' } function getTabController(page, index, callback) { - var depends = []; + let depends; switch (index) { case 0: + depends = 'controllers/music/musicrecommended'; break; case 1: - depends.push('controllers/music/musicalbums'); + depends = 'controllers/music/musicalbums'; break; case 2: case 3: - depends.push('controllers/music/musicartists'); + depends = 'controllers/music/musicartists'; break; case 4: - depends.push('controllers/music/musicplaylists'); + depends = 'controllers/music/musicplaylists'; break; case 5: - depends.push('controllers/music/songs'); + depends = 'controllers/music/songs'; break; case 6: - depends.push('controllers/music/musicgenres'); + depends = 'controllers/music/musicgenres'; break; case 7: - depends.push('scripts/searchtab'); + depends = 'scripts/searchtab'; + break; } - require(depends, function (controllerFactory) { - var tabContent; + import(depends).then(({default: controllerFactory}) => { + let tabContent; - if (0 == index) { + if (index == 0) { tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); self.tabContent = tabContent; } - var controller = tabControllers[index]; + let controller = tabControllers[index]; if (!controller) { tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); @@ -339,8 +352,6 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' function loadTab(page, index) { currentTabIndex = index; getTabController(page, index, function (controller) { - initialTabIndex = null; - if (renderedTabs.indexOf(index) == -1) { renderedTabs.push(index); controller.renderTab(); @@ -356,16 +367,14 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' } } - var isViewRestored; var self = this; var currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)); - var initialTabIndex = currentTabIndex; self.initTab = function () { - var tabContent = view.querySelector(".pageTabContent[data-index='0']"); - var containers = tabContent.querySelectorAll('.itemsContainer'); + const tabContent = view.querySelector(".pageTabContent[data-index='0']"); + const containers = tabContent.querySelectorAll('.itemsContainer'); - for (var i = 0, length = containers.length; i < length; i++) { + for (let i = 0, length = containers.length; i < length; i++) { setScrollClasses(containers[i], enableScrollX()); } }; @@ -374,13 +383,12 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' reload(); }; - var tabControllers = []; - var renderedTabs = []; + const tabControllers = []; + const renderedTabs = []; view.addEventListener('viewshow', function (e) { - isViewRestored = e.detail.isRestored; initTabs(); if (!view.getAttribute('data-title')) { - var parentId = params.topParentId; + const parentId = params.topParentId; if (parentId) { ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function (item) { @@ -405,5 +413,6 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' } }); }); - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/music/songs.js b/src/controllers/music/songs.js index aa63ec51fe..4c4f229e58 100644 --- a/src/controllers/music/songs.js +++ b/src/controllers/music/songs.js @@ -1,10 +1,18 @@ -define(['events', 'libraryBrowser', 'imageLoader', 'listView', 'loading', 'userSettings', 'globalize', 'emby-itemscontainer'], function (events, libraryBrowser, imageLoader, listView, loading, userSettings, globalize) { - 'use strict'; +import events from 'events'; +import libraryBrowser from 'libraryBrowser'; +import imageLoader from 'imageLoader'; +import listView from 'listView'; +import loading from 'loading'; +import * as userSettings from 'userSettings'; +import globalize from 'globalize'; +import 'emby-itemscontainer'; - return function (view, params, tabContent) { +/* eslint-disable indent */ + + export default function (view, params, tabContent) { function getPageData(context) { - var key = getSavedQueryKey(context); - var pageData = data[key]; + const key = getSavedQueryKey(context); + let pageData = data[key]; if (!pageData) { pageData = data[key] = { @@ -46,7 +54,7 @@ define(['events', 'libraryBrowser', 'imageLoader', 'listView', 'loading', 'userS function reloadItems(page) { loading.show(); isLoading = true; - var query = getQuery(page); + const query = getQuery(page); ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) { function onNextPageClick() { if (isLoading) { @@ -71,9 +79,7 @@ define(['events', 'libraryBrowser', 'imageLoader', 'listView', 'loading', 'userS } window.scrollTo(0, 0); - var i; - var length; - var pagingHtml = libraryBrowser.getQueryPagingHtml({ + const pagingHtml = libraryBrowser.getQueryPagingHtml({ startIndex: query.StartIndex, limit: query.Limit, totalRecordCount: result.TotalRecordCount, @@ -83,49 +89,49 @@ define(['events', 'libraryBrowser', 'imageLoader', 'listView', 'loading', 'userS sortButton: false, filterButton: false }); - var html = listView.getListViewHtml({ + const html = listView.getListViewHtml({ items: result.Items, action: 'playallfromhere', smallIcon: true, artist: true, addToListButton: true }); - var elems = tabContent.querySelectorAll('.paging'); + let elems = tabContent.querySelectorAll('.paging'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].innerHTML = pagingHtml; } elems = tabContent.querySelectorAll('.btnNextPage'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener('click', onNextPageClick); } elems = tabContent.querySelectorAll('.btnPreviousPage'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener('click', onPreviousPageClick); } - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const itemsContainer = tabContent.querySelector('.itemsContainer'); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(page), query); loading.hide(); isLoading = false; - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(page); }); }); } - var self = this; - var data = {}; - var isLoading = false; + const self = this; + const data = {}; + let isLoading = false; self.showFilterMenu = function () { - require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) { - var filterDialog = new filterDialogFactory({ + import('components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => { + const filterDialog = new filterDialogFactory({ query: getQuery(tabContent), mode: 'songs', serverId: ApiClient.serverId() @@ -193,5 +199,6 @@ define(['events', 'libraryBrowser', 'imageLoader', 'listView', 'loading', 'userS }; self.destroy = function () {}; - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/nowplaying.html b/src/controllers/playback/queue/index.html similarity index 100% rename from src/nowplaying.html rename to src/controllers/playback/queue/index.html diff --git a/src/controllers/playback/nowplaying.js b/src/controllers/playback/queue/index.js similarity index 100% rename from src/controllers/playback/nowplaying.js rename to src/controllers/playback/queue/index.js diff --git a/src/videoosd.html b/src/controllers/playback/video/index.html similarity index 97% rename from src/videoosd.html rename to src/controllers/playback/video/index.html index 452c8a9af8..cf3d0beff8 100644 --- a/src/videoosd.html +++ b/src/controllers/playback/video/index.html @@ -28,7 +28,7 @@ - @@ -44,7 +44,7 @@ - diff --git a/src/controllers/playback/videoosd.js b/src/controllers/playback/video/index.js similarity index 95% rename from src/controllers/playback/videoosd.js rename to src/controllers/playback/video/index.js index e821c2393e..a8bd0e01f3 100644 --- a/src/controllers/playback/videoosd.js +++ b/src/controllers/playback/video/index.js @@ -1,6 +1,7 @@ import playbackManager from 'playbackManager'; import dom from 'dom'; import inputManager from 'inputManager'; +import mouseManager from 'mouseManager'; import datetime from 'datetime'; import itemHelper from 'itemHelper'; import mediaInfo from 'mediaInfo'; @@ -21,18 +22,18 @@ import 'css!assets/css/videoosd'; /* eslint-disable indent */ function seriesImageUrl(item, options) { - if ('Episode' !== item.Type) { + if (item.Type !== 'Episode') { return null; } options = options || {}; options.type = options.type || 'Primary'; - if ('Primary' === options.type && item.SeriesPrimaryImageTag) { + if (options.type === 'Primary' && item.SeriesPrimaryImageTag) { options.tag = item.SeriesPrimaryImageTag; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); } - if ('Thumb' === options.type) { + if (options.type === 'Thumb') { if (item.SeriesThumbImageTag) { options.tag = item.SeriesThumbImageTag; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); @@ -56,7 +57,7 @@ import 'css!assets/css/videoosd'; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.PrimaryImageItemId || item.Id, options); } - if ('Primary' === options.type && item.AlbumId && item.AlbumPrimaryImageTag) { + if (options.type === 'Primary' && item.AlbumId && item.AlbumPrimaryImageTag) { options.tag = item.AlbumPrimaryImageTag; return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.AlbumId, options); } @@ -103,7 +104,7 @@ import 'css!assets/css/videoosd'; function onDoubleClick(e) { const clientX = e.clientX; - if (null != clientX) { + if (clientX != null) { if (clientX < dom.getWindowSize().innerWidth / 2) { playbackManager.rewind(currentPlayer); } else { @@ -116,7 +117,7 @@ import 'css!assets/css/videoosd'; } function getDisplayItem(item) { - if ('TvChannel' === item.Type) { + if (item.Type === 'TvChannel') { const apiClient = connectionManager.getApiClient(item.ServerId); return apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (refreshedItem) { return { @@ -132,7 +133,7 @@ import 'css!assets/css/videoosd'; } function updateRecordingButton(item) { - if (!item || 'Program' !== item.Type) { + if (!item || item.Type !== 'Program') { if (recordingButtonManager) { recordingButtonManager.destroy(); recordingButtonManager = null; @@ -175,8 +176,8 @@ import 'css!assets/css/videoosd'; const osdTitle = view.querySelector('.osdTitle'); titleElement = osdTitle; let displayName = itemHelper.getDisplayName(displayItem, { - includeParentInfo: 'Program' !== displayItem.Type, - includeIndexNumber: 'Program' !== displayItem.Type + includeParentInfo: displayItem.Type !== 'Program', + includeIndexNumber: displayItem.Type !== 'Program' }); if (!displayName) { @@ -197,8 +198,8 @@ import 'css!assets/css/videoosd'; tomatoes: false, endsAt: false, episodeTitle: false, - originalAirDate: 'Program' !== displayItem.Type, - episodeTitleIndexNumber: 'Program' !== displayItem.Type, + originalAirDate: displayItem.Type !== 'Program', + episodeTitleIndexNumber: displayItem.Type !== 'Program', programIndicator: false }); const osdMediaInfo = view.querySelector('.osdMediaInfo'); @@ -270,7 +271,7 @@ import 'css!assets/css/videoosd'; } function shouldEnableProgressByTimeOfDay(item) { - return !('TvChannel' !== item.Type || !item.CurrentProgram); + return !(item.Type !== 'TvChannel' || !item.CurrentProgram); } function updateNowPlayingInfo(player, state) { @@ -329,24 +330,24 @@ import 'css!assets/css/videoosd'; if (item) { let imgUrl = seriesImageUrl(item, { - maxWidth: osdPoster.clientWidth * 2, + maxWidth: osdPoster.clientWidth, type: 'Primary' }) || seriesImageUrl(item, { - maxWidth: osdPoster.clientWidth * 2, + maxWidth: osdPoster.clientWidth, type: 'Thumb' }) || imageUrl(item, { - maxWidth: osdPoster.clientWidth * 2, + maxWidth: osdPoster.clientWidth, type: 'Primary' }); if (!imgUrl && secondaryItem && (imgUrl = seriesImageUrl(secondaryItem, { - maxWidth: osdPoster.clientWidth * 2, + maxWidth: osdPoster.clientWidth, type: 'Primary' }) || seriesImageUrl(secondaryItem, { - maxWidth: osdPoster.clientWidth * 2, + maxWidth: osdPoster.clientWidth, type: 'Thumb' }) || imageUrl(secondaryItem, { - maxWidth: osdPoster.clientWidth * 2, + maxWidth: osdPoster.clientWidth, type: 'Primary' })), imgUrl) { return void (osdPoster.innerHTML = ''); @@ -367,10 +368,11 @@ import 'css!assets/css/videoosd'; function hideOsd() { slideUpToHide(headerElement); hideMainOsdControls(); + mouseManager.hideCursor(); } function toggleOsd() { - if ('osd' === currentVisibleMenu) { + if (currentVisibleMenu === 'osd') { hideOsd(); } else if (!currentVisibleMenu) { showOsd(); @@ -431,10 +433,11 @@ import 'css!assets/css/videoosd'; } function hideMainOsdControls() { - if ('osd' === currentVisibleMenu) { + if (currentVisibleMenu === 'osd') { const elem = osdBottomElement; clearHideAnimationEventListeners(elem); elem.classList.add('videoOsdBottom-hidden'); + dom.addEventListener(elem, transitionEndEventName, onHideAnimationComplete, { once: true }); @@ -460,7 +463,7 @@ import 'css!assets/css/videoosd'; } function onPointerMove(e) { - if ('mouse' === (e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'))) { + if ((e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse')) === 'mouse') { const eventX = e.screenX || 0; const eventY = e.screenY || 0; const obj = lastPointerMoveData; @@ -488,7 +491,7 @@ import 'css!assets/css/videoosd'; switch (e.detail.command) { case 'left': - if ('osd' === currentVisibleMenu) { + if (currentVisibleMenu === 'osd') { showOsd(); } else { if (!currentVisibleMenu) { @@ -500,7 +503,7 @@ import 'css!assets/css/videoosd'; break; case 'right': - if ('osd' === currentVisibleMenu) { + if (currentVisibleMenu === 'osd') { showOsd(); } else if (!currentVisibleMenu) { e.preventDefault(); @@ -615,7 +618,7 @@ import 'css!assets/css/videoosd'; resetUpNextDialog(); console.debug('nowplaying event: ' + e.type); - if ('Video' !== state.NextMediaType) { + if (state.NextMediaType !== 'Video') { view.removeEventListener('viewbeforehide', onViewHideStopPlayback); Emby.Page.back(); } @@ -702,7 +705,7 @@ import 'css!assets/css/videoosd'; } function showComingUpNextIfNeeded(player, currentItem, currentTimeTicks, runtimeTicks) { - if (runtimeTicks && currentTimeTicks && !comingUpNextDisplayed && !currentVisibleMenu && 'Episode' === currentItem.Type && userSettings.enableNextVideoInfoOverlay()) { + if (runtimeTicks && currentTimeTicks && !comingUpNextDisplayed && !currentVisibleMenu && currentItem.Type === 'Episode' && userSettings.enableNextVideoInfoOverlay()) { const showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30; const showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4; const timeRemainingTicks = runtimeTicks - currentTimeTicks; @@ -714,7 +717,7 @@ import 'css!assets/css/videoosd'; } function onUpNextHidden() { - if ('upnext' === currentVisibleMenu) { + if (currentVisibleMenu === 'upnext') { currentVisibleMenu = null; } } @@ -737,7 +740,7 @@ import 'css!assets/css/videoosd'; } function refreshProgramInfoIfNeeded(player, item) { - if ('TvChannel' === item.Type) { + if (item.Type === 'TvChannel') { const program = item.CurrentProgram; if (program && program.EndDate) { @@ -778,7 +781,7 @@ import 'css!assets/css/videoosd'; updatePlayPauseState(playState.IsPaused); const supportedCommands = playbackManager.getSupportedCommands(player); currentPlayerSupportedCommands = supportedCommands; - supportsBrightnessChange = -1 !== supportedCommands.indexOf('SetBrightness'); + supportsBrightnessChange = supportedCommands.indexOf('SetBrightness') !== -1; updatePlayerVolumeState(player, playState.IsMuted, playState.VolumeLevel); if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) { @@ -792,13 +795,13 @@ import 'css!assets/css/videoosd'; updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playState.PlaybackStartTimeTicks, playState.BufferedRanges || []); updateNowPlayingInfo(player, state); - if (state.MediaSource && state.MediaSource.SupportsTranscoding && -1 !== supportedCommands.indexOf('SetMaxStreamingBitrate')) { + if (state.MediaSource && state.MediaSource.SupportsTranscoding && supportedCommands.indexOf('SetMaxStreamingBitrate') !== -1) { view.querySelector('.btnVideoOsdSettings').classList.remove('hide'); } else { view.querySelector('.btnVideoOsdSettings').classList.add('hide'); } - const isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks; + const isProgressClear = state.MediaSource && state.MediaSource.RunTimeTicks == null; nowPlayingPositionSlider.setIsClear(isProgressClear); if (nowPlayingItem.RunTimeTicks) { @@ -806,19 +809,19 @@ import 'css!assets/css/videoosd'; userSettings.skipForwardLength() * 1000000 / nowPlayingItem.RunTimeTicks); } - if (-1 === supportedCommands.indexOf('ToggleFullscreen') || player.isLocalPlayer && layoutManager.tv && playbackManager.isFullscreen(player)) { + if (supportedCommands.indexOf('ToggleFullscreen') === -1 || player.isLocalPlayer && layoutManager.tv && playbackManager.isFullscreen(player)) { view.querySelector('.btnFullscreen').classList.add('hide'); } else { view.querySelector('.btnFullscreen').classList.remove('hide'); } - if (-1 === supportedCommands.indexOf('PictureInPicture')) { + if (supportedCommands.indexOf('PictureInPicture') === -1) { view.querySelector('.btnPip').classList.add('hide'); } else { view.querySelector('.btnPip').classList.remove('hide'); } - if (-1 === supportedCommands.indexOf('AirPlay')) { + if (supportedCommands.indexOf('AirPlay') === -1) { view.querySelector('.btnAirPlay').classList.add('hide'); } else { view.querySelector('.btnAirPlay').classList.remove('hide'); @@ -866,7 +869,7 @@ import 'css!assets/css/videoosd'; nowPlayingPositionSlider.value = 0; } - if (runtimeTicks && null != positionTicks && currentRuntimeTicks && !enableProgressByTimeOfDay && currentItem.RunTimeTicks && 'Recording' !== currentItem.Type) { + if (runtimeTicks && positionTicks != null && currentRuntimeTicks && !enableProgressByTimeOfDay && currentItem.RunTimeTicks && currentItem.Type !== 'Recording') { endsAtText.innerHTML = '  -  ' + mediaInfo.getEndsAtFromPosition(runtimeTicks, positionTicks, true); } else { endsAtText.innerHTML = ''; @@ -887,11 +890,11 @@ import 'css!assets/css/videoosd'; let showMuteButton = true; let showVolumeSlider = true; - if (-1 === supportedCommands.indexOf('Mute')) { + if (supportedCommands.indexOf('Mute') === -1) { showMuteButton = false; } - if (-1 === supportedCommands.indexOf('SetVolume')) { + if (supportedCommands.indexOf('SetVolume') === -1) { showVolumeSlider = false; } @@ -942,7 +945,7 @@ import 'css!assets/css/videoosd'; } function updateTimeText(elem, ticks, divider) { - if (null == ticks) { + if (ticks == null) { elem.innerHTML = ''; return; } @@ -963,7 +966,6 @@ import 'css!assets/css/videoosd'; const player = currentPlayer; if (player) { - // show subtitle offset feature only if player and media support it const showSubOffset = playbackManager.supportSubtitleOffset(player) && playbackManager.canHandleOffsetOnCurrentSubtitle(player); @@ -985,9 +987,9 @@ import 'css!assets/css/videoosd'; } function onSettingsOption(selectedOption) { - if ('stats' === selectedOption) { + if (selectedOption === 'stats') { toggleStats(); - } else if ('suboffset' === selectedOption) { + } else if (selectedOption === 'suboffset') { const player = currentPlayer; if (player) { playbackManager.enableShowingSubtitleOffset(player); @@ -1061,7 +1063,7 @@ import 'css!assets/css/videoosd'; const streams = playbackManager.subtitleTracks(player); let currentIndex = playbackManager.getSubtitleStreamIndex(player); - if (null == currentIndex) { + if (currentIndex == null) { currentIndex = -1; } @@ -1132,8 +1134,9 @@ import 'css!assets/css/videoosd'; clickedElement = e.target; const key = keyboardnavigation.getKeyName(e); + const isKeyModified = e.ctrlKey || e.altKey || e.metaKey; - if (!currentVisibleMenu && 32 === e.keyCode) { + if (!currentVisibleMenu && e.keyCode === 32) { playbackManager.playPause(currentPlayer); showOsd(); return; @@ -1236,8 +1239,10 @@ import 'css!assets/css/videoosd'; case '7': case '8': case '9': { - const percent = parseInt(key, 10) * 10; - playbackManager.seekPercent(percent, currentPlayer); + if (!isKeyModified) { + const percent = parseInt(key, 10) * 10; + playbackManager.seekPercent(percent, currentPlayer); + } break; } } diff --git a/src/controllers/searchpage.js b/src/controllers/searchpage.js index 8ce3e8afe8..ffb7fbac0b 100644 --- a/src/controllers/searchpage.js +++ b/src/controllers/searchpage.js @@ -1,4 +1,3 @@ -import focusManager from 'focusManager'; import SearchFields from 'searchFields'; import SearchResults from 'searchResults'; import events from 'events'; diff --git a/src/addserver.html b/src/controllers/session/addServer/index.html similarity index 100% rename from src/addserver.html rename to src/controllers/session/addServer/index.html diff --git a/src/controllers/auth/addserver.js b/src/controllers/session/addServer/index.js similarity index 98% rename from src/controllers/auth/addserver.js rename to src/controllers/session/addServer/index.js index 1129283246..7d3ba7f471 100644 --- a/src/controllers/auth/addserver.js +++ b/src/controllers/session/addServer/index.js @@ -1,6 +1,5 @@ import appSettings from 'appSettings'; import loading from 'loading'; -import browser from 'browser'; import globalize from 'globalize'; import 'emby-button'; diff --git a/src/forgotpassword.html b/src/controllers/session/forgotPassword/index.html similarity index 94% rename from src/forgotpassword.html rename to src/controllers/session/forgotPassword/index.html index d4ed0d4170..80631564f8 100644 --- a/src/forgotpassword.html +++ b/src/controllers/session/forgotPassword/index.html @@ -1,5 +1,5 @@
    -
    +

    ${HeaderForgotPassword}

    diff --git a/src/controllers/auth/forgotpassword.js b/src/controllers/session/forgotPassword/index.js similarity index 92% rename from src/controllers/auth/forgotpassword.js rename to src/controllers/session/forgotPassword/index.js index ace5a3ec15..368642db35 100644 --- a/src/controllers/auth/forgotpassword.js +++ b/src/controllers/session/forgotPassword/index.js @@ -3,21 +3,21 @@ import globalize from 'globalize'; /* eslint-disable indent */ function processForgotPasswordResult(result) { - if ('ContactAdmin' == result.Action) { + if (result.Action == 'ContactAdmin') { return void Dashboard.alert({ message: globalize.translate('MessageContactAdminToResetPassword'), title: globalize.translate('HeaderForgotPassword') }); } - if ('InNetworkRequired' == result.Action) { + if (result.Action == 'InNetworkRequired') { return void Dashboard.alert({ message: globalize.translate('MessageForgotPasswordInNetworkRequired'), title: globalize.translate('HeaderForgotPassword') }); } - if ('PinCode' == result.Action) { + if (result.Action == 'PinCode') { let msg = globalize.translate('MessageForgotPasswordFileCreated'); msg += '
    '; msg += '
    '; diff --git a/src/login.html b/src/controllers/session/login/index.html similarity index 92% rename from src/login.html rename to src/controllers/session/login/index.html index fd52b4bf58..458ac7df3b 100644 --- a/src/login.html +++ b/src/controllers/session/login/index.html @@ -1,6 +1,6 @@ -
    -
    - +
    +
    +

    ${HeaderPleaseSignIn}

    diff --git a/src/controllers/auth/login.js b/src/controllers/session/login/index.js similarity index 100% rename from src/controllers/auth/login.js rename to src/controllers/session/login/index.js diff --git a/src/forgotpasswordpin.html b/src/controllers/session/resetPassword/index.html similarity index 93% rename from src/forgotpasswordpin.html rename to src/controllers/session/resetPassword/index.html index 3b1ba0d37b..ef915be788 100644 --- a/src/forgotpasswordpin.html +++ b/src/controllers/session/resetPassword/index.html @@ -1,5 +1,5 @@
    -
    +

    ${HeaderPasswordReset}

    diff --git a/src/controllers/auth/forgotpasswordpin.js b/src/controllers/session/resetPassword/index.js similarity index 100% rename from src/controllers/auth/forgotpasswordpin.js rename to src/controllers/session/resetPassword/index.js diff --git a/src/controllers/session/selectServer/index.html b/src/controllers/session/selectServer/index.html new file mode 100644 index 0000000000..0a14e7fa03 --- /dev/null +++ b/src/controllers/session/selectServer/index.html @@ -0,0 +1,17 @@ +
    +
    +
    +
    +

    ${HeaderSelectServer}

    +
    +
    +
    +
    +
    + +
    +
    diff --git a/src/controllers/auth/selectserver.js b/src/controllers/session/selectServer/index.js similarity index 97% rename from src/controllers/auth/selectserver.js rename to src/controllers/session/selectServer/index.js index 3e36b74859..b7d7b9d221 100644 --- a/src/controllers/auth/selectserver.js +++ b/src/controllers/session/selectServer/index.js @@ -3,7 +3,6 @@ import appRouter from 'appRouter'; import layoutManager from 'layoutManager'; import libraryMenu from 'libraryMenu'; import appSettings from 'appSettings'; -import appHost from 'apphost'; import focusManager from 'focusManager'; import connectionManager from 'connectionManager'; import globalize from 'globalize'; @@ -95,11 +94,6 @@ import 'emby-button'; } } - function showGeneralError() { - loading.hide(); - alertText(globalize.translate('DefaultErrorMessage')); - } - function alertText(text) { alertTextWithOptions({ text: text diff --git a/src/controllers/shows/episodes.js b/src/controllers/shows/episodes.js index 1e067a7674..5fe70d7be0 100644 --- a/src/controllers/shows/episodes.js +++ b/src/controllers/shows/episodes.js @@ -58,7 +58,7 @@ import 'emby-itemscontainer'; const viewStyle = self.getCurrentViewStyle(); const itemsContainer = tabContent.querySelector('.itemsContainer'); - if ('List' == viewStyle) { + if (viewStyle == 'List') { itemsContainer.classList.add('vertical-list'); itemsContainer.classList.remove('vertical-wrap'); } else { diff --git a/src/controllers/shows/tvgenres.js b/src/controllers/shows/tvgenres.js index d686a62197..3a17fd7997 100644 --- a/src/controllers/shows/tvgenres.js +++ b/src/controllers/shows/tvgenres.js @@ -3,10 +3,8 @@ import loading from 'loading'; import libraryBrowser from 'libraryBrowser'; import cardBuilder from 'cardBuilder'; import lazyLoader from 'lazyLoader'; -import appHost from 'apphost'; import globalize from 'globalize'; import appRouter from 'appRouter'; -import dom from 'dom'; import 'emby-button'; /* eslint-disable indent */ @@ -64,13 +62,13 @@ import 'emby-button'; const elem = entry.target; const id = elem.getAttribute('data-id'); const viewStyle = self.getCurrentViewStyle(); - let limit = 'Thumb' == viewStyle || 'ThumbCard' == viewStyle ? 5 : 9; + let limit = viewStyle == 'Thumb' || viewStyle == 'ThumbCard' ? 5 : 9; if (enableScrollX()) { limit = 10; } - const enableImageTypes = 'Thumb' == viewStyle || 'ThumbCard' == viewStyle ? 'Primary,Backdrop,Thumb' : 'Primary'; + const enableImageTypes = viewStyle == 'Thumb' || viewStyle == 'ThumbCard' ? 'Primary,Backdrop,Thumb' : 'Primary'; const query = { SortBy: 'SortName', SortOrder: 'Ascending', @@ -85,8 +83,6 @@ import 'emby-button'; ParentId: params.topParentId }; ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) { - const supportsImageAnalysis = appHost.supports('imageanalysis'); - if (viewStyle == 'Thumb') { cardBuilder.buildCards(result.Items, { itemsContainer: elem, diff --git a/src/controllers/shows/tvlatest.js b/src/controllers/shows/tvlatest.js index c08f3d5a15..2f768f352a 100644 --- a/src/controllers/shows/tvlatest.js +++ b/src/controllers/shows/tvlatest.js @@ -1,7 +1,6 @@ import loading from 'loading'; import groupedcards from 'components/groupedcards'; import cardBuilder from 'cardBuilder'; -import appHost from 'apphost'; import imageLoader from 'imageLoader'; /* eslint-disable indent */ @@ -24,7 +23,6 @@ import imageLoader from 'imageLoader'; function loadLatest(context, params, promise) { promise.then(function (items) { let html = ''; - appHost.supports('imageanalysis'); html += cardBuilder.getCardsHtml({ items: items, shape: 'backdrop', diff --git a/src/controllers/shows/tvrecommended.js b/src/controllers/shows/tvrecommended.js index 7edd2ab501..4aab69e978 100644 --- a/src/controllers/shows/tvrecommended.js +++ b/src/controllers/shows/tvrecommended.js @@ -269,8 +269,6 @@ import 'emby-button'; function loadTab(page, index) { currentTabIndex = index; getTabController(page, index, function (controller) { - initialTabIndex = null; - if (renderedTabs.indexOf(index) == -1) { renderedTabs.push(index); controller.renderTab(); @@ -301,10 +299,8 @@ import 'emby-button'; } } - let isViewRestored; const self = this; let currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)); - let initialTabIndex = currentTabIndex; self.initTab = function () { const tabContent = self.tabContent; @@ -319,7 +315,6 @@ import 'emby-button'; let renderedTabs = []; setScrollClasses(view.querySelector('#resumableItems'), enableScrollX()); view.addEventListener('viewshow', function (e) { - isViewRestored = e.detail.isRestored; initTabs(); if (!view.getAttribute('data-title')) { const parentId = params.topParentId; diff --git a/src/controllers/shows/tvshows.js b/src/controllers/shows/tvshows.js index cde5ae5058..281c921e48 100644 --- a/src/controllers/shows/tvshows.js +++ b/src/controllers/shows/tvshows.js @@ -1,4 +1,3 @@ -import layoutManager from 'layoutManager'; import loading from 'loading'; import events from 'events'; import libraryBrowser from 'libraryBrowser'; @@ -59,7 +58,7 @@ import 'emby-itemscontainer'; const viewStyle = self.getCurrentViewStyle(); const itemsContainer = tabContent.querySelector('.itemsContainer'); - if ('List' == viewStyle) { + if (viewStyle == 'List') { itemsContainer.classList.add('vertical-list'); itemsContainer.classList.remove('vertical-wrap'); } else { diff --git a/src/controllers/shows/tvstudios.js b/src/controllers/shows/tvstudios.js index ba7fdfaf78..4be717fb7f 100644 --- a/src/controllers/shows/tvstudios.js +++ b/src/controllers/shows/tvstudios.js @@ -1,7 +1,6 @@ import loading from 'loading'; import libraryBrowser from 'libraryBrowser'; import cardBuilder from 'cardBuilder'; -import appHost from 'apphost'; /* eslint-disable indent */ diff --git a/src/controllers/shows/tvupcoming.js b/src/controllers/shows/tvupcoming.js index a2016279b8..f9df3df343 100644 --- a/src/controllers/shows/tvupcoming.js +++ b/src/controllers/shows/tvupcoming.js @@ -1,9 +1,7 @@ import layoutManager from 'layoutManager'; import loading from 'loading'; import datetime from 'datetime'; -import libraryBrowser from 'libraryBrowser'; import cardBuilder from 'cardBuilder'; -import appHost from 'apphost'; import imageLoader from 'imageLoader'; import globalize from 'globalize'; import 'scrollStyles'; @@ -106,8 +104,6 @@ import 'emby-itemscontainer'; html += '
    '; } - let supportsImageAnalysis = appHost.supports('imageanalysis'); - supportsImageAnalysis = false; html += cardBuilder.getCardsHtml({ items: group.items, showLocationTypeIndicator: false, @@ -116,11 +112,11 @@ import 'emby-itemscontainer'; preferThumb: true, lazy: true, showDetailsMenu: true, - centerText: !supportsImageAnalysis, + centerText: true, showParentTitle: true, overlayText: false, allowBottomPadding: allowBottomPadding, - cardLayout: supportsImageAnalysis, + cardLayout: false, overlayMoreButton: true, missingIndicator: false }); diff --git a/src/mypreferencesdisplay.html b/src/controllers/user/display/index.html similarity index 100% rename from src/mypreferencesdisplay.html rename to src/controllers/user/display/index.html diff --git a/src/controllers/user/display.js b/src/controllers/user/display/index.js similarity index 100% rename from src/controllers/user/display.js rename to src/controllers/user/display/index.js diff --git a/src/mypreferenceshome.html b/src/controllers/user/home/index.html similarity index 100% rename from src/mypreferenceshome.html rename to src/controllers/user/home/index.html diff --git a/src/controllers/user/home.js b/src/controllers/user/home/index.js similarity index 95% rename from src/controllers/user/home.js rename to src/controllers/user/home/index.js index e7058fd3ac..f811aa52b9 100644 --- a/src/controllers/user/home.js +++ b/src/controllers/user/home/index.js @@ -1,7 +1,4 @@ import HomescreenSettings from 'homescreenSettings'; -import dom from 'dom'; -import globalize from 'globalize'; -import loading from 'loading'; import * as userSettings from 'userSettings'; import autoFocuser from 'autoFocuser'; import 'listViewStyle'; diff --git a/src/mypreferencesmenu.html b/src/controllers/user/menu/index.html similarity index 100% rename from src/mypreferencesmenu.html rename to src/controllers/user/menu/index.html diff --git a/src/controllers/user/menu.js b/src/controllers/user/menu/index.js similarity index 96% rename from src/controllers/user/menu.js rename to src/controllers/user/menu/index.js index ef4b3b21c8..f44a193a52 100644 --- a/src/controllers/user/menu.js +++ b/src/controllers/user/menu/index.js @@ -1,6 +1,4 @@ import appHost from 'apphost'; -import connectionManager from 'connectionManager'; -import layoutManager from 'layoutManager'; import 'listViewStyle'; import 'emby-button'; diff --git a/src/mypreferencesplayback.html b/src/controllers/user/playback/index.html similarity index 100% rename from src/mypreferencesplayback.html rename to src/controllers/user/playback/index.html diff --git a/src/controllers/user/playback.js b/src/controllers/user/playback/index.js similarity index 95% rename from src/controllers/user/playback.js rename to src/controllers/user/playback/index.js index 5bcf055cd3..16c50a1980 100644 --- a/src/controllers/user/playback.js +++ b/src/controllers/user/playback/index.js @@ -1,7 +1,4 @@ import PlaybackSettings from 'playbackSettings'; -import dom from 'dom'; -import globalize from 'globalize'; -import loading from 'loading'; import * as userSettings from 'userSettings'; import autoFocuser from 'autoFocuser'; import 'listViewStyle'; diff --git a/src/myprofile.html b/src/controllers/user/profile/index.html similarity index 100% rename from src/myprofile.html rename to src/controllers/user/profile/index.html diff --git a/src/controllers/user/profile.js b/src/controllers/user/profile/index.js similarity index 100% rename from src/controllers/user/profile.js rename to src/controllers/user/profile/index.js diff --git a/src/mypreferencessubtitles.html b/src/controllers/user/subtitles/index.html similarity index 100% rename from src/mypreferencessubtitles.html rename to src/controllers/user/subtitles/index.html diff --git a/src/controllers/user/subtitles.js b/src/controllers/user/subtitles/index.js similarity index 100% rename from src/controllers/user/subtitles.js rename to src/controllers/user/subtitles/index.js diff --git a/src/wizardfinish.html b/src/controllers/wizard/finish/index.html similarity index 100% rename from src/wizardfinish.html rename to src/controllers/wizard/finish/index.html diff --git a/src/controllers/wizard/finish.js b/src/controllers/wizard/finish/index.js similarity index 100% rename from src/controllers/wizard/finish.js rename to src/controllers/wizard/finish/index.js diff --git a/src/wizardremoteaccess.html b/src/controllers/wizard/remote/index.html similarity index 100% rename from src/wizardremoteaccess.html rename to src/controllers/wizard/remote/index.html diff --git a/src/controllers/wizard/remoteaccess.js b/src/controllers/wizard/remote/index.js similarity index 100% rename from src/controllers/wizard/remoteaccess.js rename to src/controllers/wizard/remote/index.js diff --git a/src/wizardsettings.html b/src/controllers/wizard/settings/index.html similarity index 100% rename from src/wizardsettings.html rename to src/controllers/wizard/settings/index.html diff --git a/src/controllers/wizard/settings.js b/src/controllers/wizard/settings/index.js similarity index 100% rename from src/controllers/wizard/settings.js rename to src/controllers/wizard/settings/index.js diff --git a/src/wizardstart.html b/src/controllers/wizard/start/index.html similarity index 100% rename from src/wizardstart.html rename to src/controllers/wizard/start/index.html diff --git a/src/controllers/wizard/start.js b/src/controllers/wizard/start/index.js similarity index 100% rename from src/controllers/wizard/start.js rename to src/controllers/wizard/start/index.js diff --git a/src/wizarduser.html b/src/controllers/wizard/user/index.html similarity index 100% rename from src/wizarduser.html rename to src/controllers/wizard/user/index.html diff --git a/src/controllers/wizard/user.js b/src/controllers/wizard/user/index.js similarity index 100% rename from src/controllers/wizard/user.js rename to src/controllers/wizard/user/index.js diff --git a/src/dlnaprofile.html b/src/dlnaprofile.html index e960d97a0f..01636e6019 100644 --- a/src/dlnaprofile.html +++ b/src/dlnaprofile.html @@ -5,7 +5,6 @@

    ${HeaderProfileInformation}

    - ${Help}
    diff --git a/src/dlnaprofiles.html b/src/dlnaprofiles.html index b47b2fd6bf..615bb59ee8 100644 --- a/src/dlnaprofiles.html +++ b/src/dlnaprofiles.html @@ -11,7 +11,6 @@ - ${Help}

    ${CustomDlnaProfilesHelp}

    diff --git a/src/elements/emby-collapse/emby-collapse.js b/src/elements/emby-collapse/emby-collapse.js index f980f19af0..c87e73d48f 100644 --- a/src/elements/emby-collapse/emby-collapse.js +++ b/src/elements/emby-collapse/emby-collapse.js @@ -7,55 +7,54 @@ import 'emby-button'; const EmbyButtonPrototype = Object.create(HTMLDivElement.prototype); function slideDownToShow(button, elem) { - - elem.classList.remove('hide'); - elem.classList.add('expanded'); - elem.style.height = 'auto'; - const height = elem.offsetHeight + 'px'; - elem.style.height = '0'; - - // trigger reflow - const newHeight = elem.offsetHeight; - elem.style.height = height; - - setTimeout(function () { - if (elem.classList.contains('expanded')) { - elem.classList.remove('hide'); - } else { - elem.classList.add('hide'); - } + requestAnimationFrame(() => { + elem.classList.remove('hide'); + elem.classList.add('expanded'); elem.style.height = 'auto'; - }, 300); + const height = elem.offsetHeight + 'px'; + elem.style.height = '0'; + // trigger reflow + // TODO: Find a better way to do this + const newHeight = elem.offsetHeight; /* eslint-disable-line no-unused-vars */ + elem.style.height = height; - const icon = button.querySelector('.material-icons'); - //icon.innerHTML = 'expand_less'; - icon.classList.add('emby-collapse-expandIconExpanded'); + setTimeout(function () { + if (elem.classList.contains('expanded')) { + elem.classList.remove('hide'); + } else { + elem.classList.add('hide'); + } + elem.style.height = 'auto'; + }, 300); + + const icon = button.querySelector('.material-icons'); + icon.classList.add('emby-collapse-expandIconExpanded'); + }); } function slideUpToHide(button, elem) { + requestAnimationFrame(() => { + elem.style.height = elem.offsetHeight + 'px'; + // trigger reflow + // TODO: Find a better way to do this + const newHeight = elem.offsetHeight; /* eslint-disable-line no-unused-vars */ + elem.classList.remove('expanded'); + elem.style.height = '0'; - elem.style.height = elem.offsetHeight + 'px'; - // trigger reflow - const newHeight = elem.offsetHeight; + setTimeout(function () { + if (elem.classList.contains('expanded')) { + elem.classList.remove('hide'); + } else { + elem.classList.add('hide'); + } + }, 300); - elem.classList.remove('expanded'); - elem.style.height = '0'; - - setTimeout(function () { - if (elem.classList.contains('expanded')) { - elem.classList.remove('hide'); - } else { - elem.classList.add('hide'); - } - }, 300); - - const icon = button.querySelector('.material-icons'); - //icon.innerHTML = 'expand_more'; - icon.classList.remove('emby-collapse-expandIconExpanded'); + const icon = button.querySelector('.material-icons'); + icon.classList.remove('emby-collapse-expandIconExpanded'); + }); } function onButtonClick(e) { - const button = this; const collapseContent = button.parentNode.querySelector('.collapseContent'); @@ -69,7 +68,6 @@ import 'emby-button'; } EmbyButtonPrototype.attachedCallback = function () { - if (this.classList.contains('emby-collapse')) { return; } diff --git a/src/elements/emby-input/emby-input.js b/src/elements/emby-input/emby-input.js index d27cc71564..3a71e29a6f 100644 --- a/src/elements/emby-input/emby-input.js +++ b/src/elements/emby-input/emby-input.js @@ -11,7 +11,6 @@ import 'webcomponents'; let supportsFloatingLabel = false; if (Object.getOwnPropertyDescriptor && Object.defineProperty) { - const descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value'); // descriptor returning null in webos @@ -94,16 +93,13 @@ import 'webcomponents'; } } } - }; function onChange() { - const label = this.labelElement; if (this.value) { label.classList.remove('inputLabel-float'); } else { - const instanceSupportsFloat = supportsFloatingLabel && this.type !== 'date' && this.type !== 'time'; if (instanceSupportsFloat) { diff --git a/src/elements/emby-itemrefreshindicator/emby-itemrefreshindicator.js b/src/elements/emby-itemrefreshindicator/emby-itemrefreshindicator.js index b1f8c4f4cf..67eacf3db9 100644 --- a/src/elements/emby-itemrefreshindicator/emby-itemrefreshindicator.js +++ b/src/elements/emby-itemrefreshindicator/emby-itemrefreshindicator.js @@ -7,14 +7,12 @@ import 'webcomponents'; /* eslint-disable indent */ function addNotificationEvent(instance, name, handler) { - const localHandler = handler.bind(instance); events.on(serverNotifications, name, localHandler); instance[name] = localHandler; } function removeNotificationEvent(instance, name) { - const handler = instance[name]; if (handler) { events.off(serverNotifications, name, handler); @@ -23,7 +21,6 @@ import 'webcomponents'; } function onRefreshProgress(e, apiClient, info) { - const indicator = this; if (!indicator.itemId) { @@ -31,7 +28,6 @@ import 'webcomponents'; } if (info.ItemId === indicator.itemId) { - const progress = parseFloat(info.Progress); if (progress && progress < 100) { @@ -40,14 +36,13 @@ import 'webcomponents'; this.classList.add('hide'); } - this.setProgress(progress); + this.setAttribute('data-progress', progress); } } let EmbyItemRefreshIndicatorPrototype = Object.create(EmbyProgressRing); EmbyItemRefreshIndicatorPrototype.createdCallback = function () { - // base method if (EmbyProgressRing.createdCallback) { EmbyProgressRing.createdCallback.call(this); @@ -57,7 +52,6 @@ import 'webcomponents'; }; EmbyItemRefreshIndicatorPrototype.attachedCallback = function () { - // base method if (EmbyProgressRing.attachedCallback) { EmbyProgressRing.attachedCallback.call(this); @@ -65,7 +59,6 @@ import 'webcomponents'; }; EmbyItemRefreshIndicatorPrototype.detachedCallback = function () { - // base method if (EmbyProgressRing.detachedCallback) { EmbyProgressRing.detachedCallback.call(this); diff --git a/src/elements/emby-itemscontainer/emby-itemscontainer.js b/src/elements/emby-itemscontainer/emby-itemscontainer.js index 1d4a67717a..691552c074 100644 --- a/src/elements/emby-itemscontainer/emby-itemscontainer.js +++ b/src/elements/emby-itemscontainer/emby-itemscontainer.js @@ -18,7 +18,6 @@ import 'webcomponents'; function onClick(e) { const itemsContainer = this; - const target = e.target; let multiSelect = itemsContainer.multiSelect; if (multiSelect) { @@ -148,7 +147,6 @@ import 'webcomponents'; }; function onUserDataChanged(e, apiClient, userData) { - const itemsContainer = this; import('cardBuilder').then(({default: cardBuilder}) => { @@ -175,7 +173,6 @@ import 'webcomponents'; } function onTimerCreated(e, apiClient, data) { - const itemsContainer = this; if (getEventsToMonitor(itemsContainer).indexOf('timers') !== -1) { @@ -361,7 +358,6 @@ import 'webcomponents'; let refreshIntervalEndTime = this.refreshIntervalEndTime; if (refreshIntervalEndTime) { - const remainingMs = refreshIntervalEndTime - new Date().getTime(); if (remainingMs > 0 && !this.needsRefresh) { resetRefreshInterval(this, remainingMs); diff --git a/src/elements/emby-playstatebutton/emby-playstatebutton.js b/src/elements/emby-playstatebutton/emby-playstatebutton.js index e1b34318b8..7b5c344095 100644 --- a/src/elements/emby-playstatebutton/emby-playstatebutton.js +++ b/src/elements/emby-playstatebutton/emby-playstatebutton.js @@ -21,7 +21,6 @@ import EmbyButtonPrototype from 'emby-button'; } function onClick(e) { - const button = this; const id = button.getAttribute('data-id'); const serverId = button.getAttribute('data-serverid'); @@ -70,7 +69,6 @@ import EmbyButtonPrototype from 'emby-button'; } function setTitle(button, itemType) { - if (itemType !== 'AudioBook' && itemType !== 'AudioPodcast') { button.title = globalize.translate('Watched'); } else { @@ -84,13 +82,11 @@ import EmbyButtonPrototype from 'emby-button'; } function clearEvents(button) { - button.removeEventListener('click', onClick); removeNotificationEvent(button, 'UserDataChanged'); } function bindEvents(button) { - clearEvents(button); button.addEventListener('click', onClick); @@ -100,7 +96,6 @@ import EmbyButtonPrototype from 'emby-button'; const EmbyPlaystateButtonPrototype = Object.create(EmbyButtonPrototype); EmbyPlaystateButtonPrototype.createdCallback = function () { - // base method if (EmbyButtonPrototype.createdCallback) { EmbyButtonPrototype.createdCallback.call(this); @@ -108,7 +103,6 @@ import EmbyButtonPrototype from 'emby-button'; }; EmbyPlaystateButtonPrototype.attachedCallback = function () { - // base method if (EmbyButtonPrototype.attachedCallback) { EmbyButtonPrototype.attachedCallback.call(this); @@ -117,7 +111,6 @@ import EmbyButtonPrototype from 'emby-button'; const itemId = this.getAttribute('data-id'); const serverId = this.getAttribute('data-serverid'); if (itemId && serverId) { - setState(this, this.getAttribute('data-played') === 'true', false); bindEvents(this); setTitle(this, this.getAttribute('data-type')); @@ -125,7 +118,6 @@ import EmbyButtonPrototype from 'emby-button'; }; EmbyPlaystateButtonPrototype.detachedCallback = function () { - // base method if (EmbyButtonPrototype.detachedCallback) { EmbyButtonPrototype.detachedCallback.call(this); @@ -136,9 +128,7 @@ import EmbyButtonPrototype from 'emby-button'; }; EmbyPlaystateButtonPrototype.setItem = function (item) { - if (item) { - this.setAttribute('data-id', item.Id); this.setAttribute('data-serverid', item.ServerId); @@ -147,9 +137,7 @@ import EmbyButtonPrototype from 'emby-button'; bindEvents(this); setTitle(this, item.Type); - } else { - this.removeAttribute('data-id'); this.removeAttribute('data-serverid'); this.removeAttribute('data-played'); diff --git a/src/elements/emby-progressring/emby-progressring.js b/src/elements/emby-progressring/emby-progressring.js index 062f64d78b..10db8b9a27 100644 --- a/src/elements/emby-progressring/emby-progressring.js +++ b/src/elements/emby-progressring/emby-progressring.js @@ -6,37 +6,34 @@ import 'webcomponents'; let EmbyProgressRing = Object.create(HTMLDivElement.prototype); EmbyProgressRing.createdCallback = function () { - this.classList.add('progressring'); const instance = this; import('text!./emby-progressring.template.html').then(({default: template}) => { instance.innerHTML = template; - //if (window.MutationObserver) { - // // create an observer instance - // var observer = new MutationObserver(function (mutations) { - // mutations.forEach(function (mutation) { + if (window.MutationObserver) { + // create an observer instance + var observer = new MutationObserver(function (mutations) { + mutations.forEach(function (mutation) { + instance.setProgress(parseFloat(instance.getAttribute('data-progress') || '0')); + }); + }); - // instance.setProgress(parseFloat(instance.getAttribute('data-progress') || '0')); - // }); - // }); + // configuration of the observer: + var config = { attributes: true, childList: false, characterData: false }; - // // configuration of the observer: - // var config = { attributes: true, childList: false, characterData: false }; + // pass in the target node, as well as the observer options + observer.observe(instance, config); - // // pass in the target node, as well as the observer options - // observer.observe(instance, config); - - // instance.observer = observer; - //} + instance.observer = observer; + } instance.setProgress(parseFloat(instance.getAttribute('data-progress') || '0')); }); }; EmbyProgressRing.setProgress = function (progress) { - progress = Math.floor(progress); let angle; @@ -50,7 +47,6 @@ import 'webcomponents'; this.querySelector('.animate-50-75-b').style.transform = 'rotate(-90deg)'; this.querySelector('.animate-75-100-b').style.transform = 'rotate(-90deg)'; } else if (progress >= 25 && progress < 50) { - angle = -90 + ((progress - 25) / 100) * 360; this.querySelector('.animate-0-25-b').style.transform = 'none'; @@ -83,7 +79,6 @@ import 'webcomponents'; }; EmbyProgressRing.detachedCallback = function () { - let observer = this.observer; if (observer) { diff --git a/src/elements/emby-radio/emby-radio.js b/src/elements/emby-radio/emby-radio.js index c8437d77e3..b31d436444 100644 --- a/src/elements/emby-radio/emby-radio.js +++ b/src/elements/emby-radio/emby-radio.js @@ -7,7 +7,6 @@ import 'webcomponents'; let EmbyRadioPrototype = Object.create(HTMLInputElement.prototype); function onKeyDown(e) { - // Don't submit form on enter // Real (non-emulator) Tizen does nothing on Space if (e.keyCode === 13 || e.keyCode === 32) { @@ -37,7 +36,6 @@ import 'webcomponents'; this.classList.add('mdl-radio__button'); let labelElement = this.parentNode; - //labelElement.classList.add('"mdl-radio mdl-js-radio mdl-js-ripple-effect'); labelElement.classList.add('mdl-radio'); labelElement.classList.add('mdl-js-radio'); labelElement.classList.add('mdl-js-ripple-effect'); diff --git a/src/elements/emby-ratingbutton/emby-ratingbutton.js b/src/elements/emby-ratingbutton/emby-ratingbutton.js index b455495a2e..06a88e6ea1 100644 --- a/src/elements/emby-ratingbutton/emby-ratingbutton.js +++ b/src/elements/emby-ratingbutton/emby-ratingbutton.js @@ -7,14 +7,12 @@ import EmbyButtonPrototype from 'emby-button'; /* eslint-disable indent */ function addNotificationEvent(instance, name, handler) { - const localHandler = handler.bind(instance); events.on(serverNotifications, name, localHandler); instance[name] = localHandler; } function removeNotificationEvent(instance, name) { - const handler = instance[name]; if (handler) { events.off(serverNotifications, name, handler); @@ -23,12 +21,10 @@ import EmbyButtonPrototype from 'emby-button'; } function showPicker(button, apiClient, itemId, likes, isFavorite) { - return apiClient.updateFavoriteStatus(apiClient.getCurrentUserId(), itemId, !isFavorite); } function onClick(e) { - const button = this; const id = button.getAttribute('data-id'); const serverId = button.getAttribute('data-serverid'); @@ -45,58 +41,44 @@ import EmbyButtonPrototype from 'emby-button'; } showPicker(button, apiClient, id, likes, isFavorite).then(function (userData) { - setState(button, userData.Likes, userData.IsFavorite); }); } function onUserDataChanged(e, apiClient, userData) { - const button = this; if (userData.ItemId === button.getAttribute('data-id')) { - setState(button, userData.Likes, userData.IsFavorite); } } function setState(button, likes, isFavorite, updateAttribute) { - const icon = button.querySelector('.material-icons'); if (isFavorite) { - if (icon) { icon.classList.add('favorite'); icon.classList.add('ratingbutton-icon-withrating'); } button.classList.add('ratingbutton-withrating'); - } else if (likes) { - if (icon) { icon.classList.add('favorite'); icon.classList.remove('ratingbutton-icon-withrating'); - //icon.innerHTML = 'thumb_up'; } button.classList.remove('ratingbutton-withrating'); - } else if (likes === false) { - if (icon) { icon.classList.add('favorite'); icon.classList.remove('ratingbutton-icon-withrating'); - //icon.innerHTML = 'thumb_down'; } button.classList.remove('ratingbutton-withrating'); - } else { - if (icon) { icon.classList.add('favorite'); icon.classList.remove('ratingbutton-icon-withrating'); - //icon.innerHTML = 'thumbs_up_down'; } button.classList.remove('ratingbutton-withrating'); } @@ -118,13 +100,11 @@ import EmbyButtonPrototype from 'emby-button'; } function clearEvents(button) { - button.removeEventListener('click', onClick); removeNotificationEvent(button, 'UserDataChanged'); } function bindEvents(button) { - clearEvents(button); button.addEventListener('click', onClick); @@ -134,7 +114,6 @@ import EmbyButtonPrototype from 'emby-button'; const EmbyRatingButtonPrototype = Object.create(EmbyButtonPrototype); EmbyRatingButtonPrototype.createdCallback = function () { - // base method if (EmbyButtonPrototype.createdCallback) { EmbyButtonPrototype.createdCallback.call(this); @@ -142,7 +121,6 @@ import EmbyButtonPrototype from 'emby-button'; }; EmbyRatingButtonPrototype.attachedCallback = function () { - // base method if (EmbyButtonPrototype.attachedCallback) { EmbyButtonPrototype.attachedCallback.call(this); @@ -151,7 +129,6 @@ import EmbyButtonPrototype from 'emby-button'; const itemId = this.getAttribute('data-id'); const serverId = this.getAttribute('data-serverid'); if (itemId && serverId) { - let likes = this.getAttribute('data-likes'); const isFavorite = this.getAttribute('data-isfavorite') === 'true'; if (likes === 'true') { @@ -170,7 +147,6 @@ import EmbyButtonPrototype from 'emby-button'; }; EmbyRatingButtonPrototype.detachedCallback = function () { - // base method if (EmbyButtonPrototype.detachedCallback) { EmbyButtonPrototype.detachedCallback.call(this); @@ -180,18 +156,14 @@ import EmbyButtonPrototype from 'emby-button'; }; EmbyRatingButtonPrototype.setItem = function (item) { - if (item) { - this.setAttribute('data-id', item.Id); this.setAttribute('data-serverid', item.ServerId); const userData = item.UserData || {}; setState(this, userData.Likes, userData.IsFavorite); bindEvents(this); - } else { - this.removeAttribute('data-id'); this.removeAttribute('data-serverid'); this.removeAttribute('data-likes'); diff --git a/src/elements/emby-scrollbuttons/emby-scrollbuttons.js b/src/elements/emby-scrollbuttons/emby-scrollbuttons.js index 239fbcfcda..fcff587392 100644 --- a/src/elements/emby-scrollbuttons/emby-scrollbuttons.js +++ b/src/elements/emby-scrollbuttons/emby-scrollbuttons.js @@ -36,6 +36,7 @@ const EmbyScrollButtonsPrototype = Object.create(HTMLDivElement.prototype); } function updateScrollButtons(scrollButtons, scrollSize, scrollPos, scrollWidth) { + // TODO: Check if hack is really needed // hack alert add twenty for rounding errors if (scrollWidth <= scrollSize + 20) { scrollButtons.scrollButtonsLeft.classList.add('hide'); @@ -122,7 +123,6 @@ const EmbyScrollButtonsPrototype = Object.create(HTMLDivElement.prototype); const direction = this.getAttribute('data-direction'); const scrollSize = getScrollSize(scroller); const scrollPos = getScrollPosition(scroller); - const scrollWidth = getScrollWidth(scroller); let newPos; if (direction === 'left') { diff --git a/src/elements/emby-select/emby-select.js b/src/elements/emby-select/emby-select.js index d45e7ef7a7..0629a74e52 100644 --- a/src/elements/emby-select/emby-select.js +++ b/src/elements/emby-select/emby-select.js @@ -9,7 +9,6 @@ import 'webcomponents'; const EmbySelectPrototype = Object.create(HTMLSelectElement.prototype); function enableNativeMenu() { - if (browser.edgeUwp || browser.xboxOne) { return true; } @@ -38,12 +37,10 @@ import 'webcomponents'; } function setValue(select, value) { - select.value = value; } function showActionSheet(select) { - const labelElem = getLabel(select); const title = labelElem ? (labelElem.textContent || labelElem.innerText) : null; @@ -112,7 +109,6 @@ import 'webcomponents'; let inputId = 0; EmbySelectPrototype.createdCallback = function () { - if (!this.id) { this.id = 'embyselect' + inputId; inputId++; @@ -132,7 +128,6 @@ import 'webcomponents'; }; EmbySelectPrototype.attachedCallback = function () { - if (this.classList.contains('emby-select')) { return; } @@ -151,7 +146,6 @@ import 'webcomponents'; }; EmbySelectPrototype.setLabel = function (text) { - const label = this.parentNode.querySelector('label'); label.innerHTML = text; diff --git a/src/elements/emby-slider/emby-slider.js b/src/elements/emby-slider/emby-slider.js index e872f6c78b..2439331144 100644 --- a/src/elements/emby-slider/emby-slider.js +++ b/src/elements/emby-slider/emby-slider.js @@ -12,10 +12,7 @@ import 'emby-input'; let supportsValueSetOverride = false; - let enableWidthWithTransform; - if (Object.getOwnPropertyDescriptor && Object.defineProperty) { - const descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value'); // descriptor returning null in webos if (descriptor && descriptor.configurable) { @@ -85,7 +82,6 @@ import 'emby-input'; * @param {boolean} [isValueSet] update by 'valueset' event or by timer */ function updateValues(isValueSet) { - // Do not update values by 'valueset' in case of soft-implemented dragging if (!!isValueSet && (!!this.keyboardDragging || !!this.touched)) { return; @@ -98,24 +94,18 @@ import 'emby-input'; // Keep only one per slider frame request cancelAnimationFrame(range.updateValuesFrame); range.updateValuesFrame = requestAnimationFrame(function () { - let backgroundLower = range.backgroundLower; if (backgroundLower) { let fraction = (value - range.min) / (range.max - range.min); - if (enableWidthWithTransform) { - backgroundLower.style.transform = 'scaleX(' + (fraction) + ')'; - } else { - fraction *= 100; - backgroundLower.style.width = fraction + '%'; - } + fraction *= 100; + backgroundLower.style.width = fraction + '%'; } }); } function updateBubble(range, value, bubble, bubbleText) { - requestAnimationFrame(function () { const bubbleTrackRect = range.sliderBubbleTrack.getBoundingClientRect(); const bubbleRect = bubble.getBoundingClientRect(); @@ -141,15 +131,10 @@ import 'emby-input'; } EmbySliderPrototype.attachedCallback = function () { - if (this.getAttribute('data-embyslider') === 'true') { return; } - if (enableWidthWithTransform == null) { - //enableWidthWithTransform = browser.supportsCssAnimation(); - } - this.setAttribute('data-embyslider', 'true'); this.classList.add('mdl-slider'); @@ -177,11 +162,7 @@ import 'emby-input'; // the more of these, the more ranges we can display htmlToInsert += '
    '; - if (enableWidthWithTransform) { - htmlToInsert += '
    '; - } else { - htmlToInsert += '
    '; - } + htmlToInsert += '
    '; htmlToInsert += '
    '; htmlToInsert += '
    '; @@ -225,14 +206,12 @@ import 'emby-input'; sliderBubble.classList.add('hide'); hasHideClass = true; - }, { passive: true }); /* eslint-disable-next-line compat/compat */ dom.addEventListener(this, (window.PointerEvent ? 'pointermove' : 'mousemove'), function (e) { - if (!this.dragging) { const bubbleValue = mapClientToFraction(this, e.clientX) * 100; @@ -243,7 +222,6 @@ import 'emby-input'; hasHideClass = false; } } - }, { passive: true }); @@ -422,7 +400,6 @@ import 'emby-input'; }; function setRange(elem, startPercent, endPercent) { - const style = elem.style; style.left = Math.max(startPercent, 0) + '%'; @@ -431,13 +408,11 @@ import 'emby-input'; } function mapRangesFromRuntimeToPercent(ranges, runtime) { - if (!runtime) { return []; } return ranges.map(function (r) { - return { start: (r.start / runtime) * 100, end: (r.end / runtime) * 100 @@ -446,7 +421,6 @@ import 'emby-input'; } EmbySliderPrototype.setBufferedRanges = function (ranges, runtime, position) { - const elem = this.backgroundUpper; if (!elem) { return; @@ -459,7 +433,6 @@ import 'emby-input'; } for (const range in ranges) { - if (position != null) { if (position >= range.end) { continue; @@ -474,7 +447,6 @@ import 'emby-input'; }; EmbySliderPrototype.setIsClear = function (isClear) { - const backgroundLower = this.backgroundLower; if (backgroundLower) { if (isClear) { @@ -494,7 +466,6 @@ import 'emby-input'; } EmbySliderPrototype.detachedCallback = function () { - const interval = this.interval; if (interval) { clearInterval(interval); diff --git a/src/elements/emby-tabs/emby-tabs.js b/src/elements/emby-tabs/emby-tabs.js index f3cd9d38cc..320a14e2cb 100644 --- a/src/elements/emby-tabs/emby-tabs.js +++ b/src/elements/emby-tabs/emby-tabs.js @@ -13,12 +13,10 @@ import 'scrollStyles'; const activeButtonClass = buttonClass + '-active'; function setActiveTabButton(tabs, newButton, oldButton, animate) { - newButton.classList.add(activeButtonClass); } function getTabPanel(tabs, index) { - return null; } @@ -29,15 +27,7 @@ import 'scrollStyles'; } } - function addActivePanelClass(tabs, index) { - let tabPanel = getTabPanel(tabs, index); - if (tabPanel) { - tabPanel.classList.add('is-active'); - } - } - function fadeInRight(elem) { - const pct = browser.mobile ? '4%' : '0.5%'; const keyframes = [ @@ -52,7 +42,6 @@ import 'scrollStyles'; } function triggerBeforeTabChange(tabs, index, previousIndex) { - tabs.dispatchEvent(new CustomEvent('beforetabchange', { detail: { selectedTabIndex: index, @@ -76,14 +65,12 @@ import 'scrollStyles'; } function onClick(e) { - const tabs = this; const current = tabs.querySelector('.' + activeButtonClass); const tabButton = dom.parentWithClass(e.target, buttonClass); if (tabButton && tabButton !== current) { - if (current) { current.classList.remove(activeButtonClass); } @@ -98,7 +85,6 @@ import 'scrollStyles'; // If toCenter is called syncronously within the click event, it sometimes ends up canceling it setTimeout(function () { - tabs.selectedTabIndex = index; tabs.dispatchEvent(new CustomEvent('tabchange', { @@ -112,12 +98,10 @@ import 'scrollStyles'; if (tabs.scroller) { tabs.scroller.toCenter(tabButton, false); } - } } function initScroller(tabs) { - if (tabs.scroller) { return; } @@ -153,7 +137,6 @@ import 'scrollStyles'; } EmbyTabs.createdCallback = function () { - if (this.classList.contains('emby-tabs')) { return; } @@ -166,7 +149,6 @@ import 'scrollStyles'; }; EmbyTabs.focus = function () { - const selected = this.querySelector('.' + activeButtonClass); if (selected) { @@ -177,21 +159,18 @@ import 'scrollStyles'; }; EmbyTabs.refresh = function () { - if (this.scroller) { this.scroller.reload(); } }; EmbyTabs.attachedCallback = function () { - initScroller(this); const current = this.querySelector('.' + activeButtonClass); const currentIndex = current ? parseInt(current.getAttribute('data-index')) : parseInt(this.getAttribute('data-index') || '0'); if (currentIndex !== -1) { - this.selectedTabIndex = currentIndex; const tabButtons = this.querySelectorAll('.' + buttonClass); @@ -210,7 +189,6 @@ import 'scrollStyles'; }; EmbyTabs.detachedCallback = function () { - if (this.scroller) { this.scroller.destroy(); this.scroller = null; @@ -222,16 +200,13 @@ import 'scrollStyles'; }; function getSelectedTabButton(elem) { - return elem.querySelector('.' + activeButtonClass); } EmbyTabs.selectedIndex = function (selected, triggerEvent) { - const tabs = this; if (selected == null) { - return tabs.selectedTabIndex || 0; } @@ -242,7 +217,6 @@ import 'scrollStyles'; const tabButtons = tabs.querySelectorAll('.' + buttonClass); if (current === selected || triggerEvent === false) { - triggerBeforeTabChange(tabs, selected, current); tabs.dispatchEvent(new CustomEvent('tabchange', { @@ -257,23 +231,18 @@ import 'scrollStyles'; if (current !== selected && currentTabButton) { currentTabButton.classList.remove(activeButtonClass); } - } else { - onClick.call(tabs, { target: tabButtons[selected] }); - //tabButtons[selected].click(); } }; function getSibling(elem, method) { - let sibling = elem[method]; while (sibling) { if (sibling.classList.contains(buttonClass)) { - if (!sibling.classList.contains('hide')) { return sibling; } @@ -286,7 +255,6 @@ import 'scrollStyles'; } EmbyTabs.selectNext = function () { - const current = getSelectedTabButton(this); const sibling = getSibling(current, 'nextSibling'); @@ -299,7 +267,6 @@ import 'scrollStyles'; }; EmbyTabs.selectPrevious = function () { - const current = getSelectedTabButton(this); const sibling = getSibling(current, 'previousSibling'); @@ -312,14 +279,12 @@ import 'scrollStyles'; }; EmbyTabs.triggerBeforeTabChange = function (selected) { - const tabs = this; triggerBeforeTabChange(tabs, tabs.selectedIndex()); }; EmbyTabs.triggerTabChange = function (selected) { - const tabs = this; tabs.dispatchEvent(new CustomEvent('tabchange', { @@ -330,8 +295,6 @@ import 'scrollStyles'; }; EmbyTabs.setTabEnabled = function (index, enabled) { - - const tabs = this; const btn = this.querySelector('.emby-tab-button[data-index="' + index + '"]'); if (enabled) { diff --git a/src/elements/emby-textarea/emby-textarea.js b/src/elements/emby-textarea/emby-textarea.js index d98cc8c07e..c14724346a 100644 --- a/src/elements/emby-textarea/emby-textarea.js +++ b/src/elements/emby-textarea/emby-textarea.js @@ -47,7 +47,6 @@ import 'emby-input'; return; } let newHeight = 0; - let hasGrown = false; if ((textarea.scrollHeight - offset) > self.maxAllowedHeight) { textarea.style.overflowY = 'scroll'; @@ -56,7 +55,6 @@ import 'emby-input'; textarea.style.overflowY = 'hidden'; textarea.style.height = 'auto'; newHeight = textarea.scrollHeight/* - offset*/; - hasGrown = true; } $('.customCssContainer').css('height', newHeight + 'px'); textarea.style.height = newHeight + 'px'; @@ -75,7 +73,6 @@ import 'emby-input'; let elementId = 0; if (Object.getOwnPropertyDescriptor && Object.defineProperty) { - const descriptor = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value'); // descriptor returning null in webos @@ -95,7 +92,6 @@ import 'emby-input'; } EmbyTextAreaPrototype.createdCallback = function () { - if (!this.id) { this.id = 'embytextarea' + elementId; elementId++; @@ -103,7 +99,6 @@ import 'emby-input'; }; EmbyTextAreaPrototype.attachedCallback = function () { - if (this.classList.contains('emby-textarea')) { return; } diff --git a/src/elements/emby-toggle/emby-toggle.js b/src/elements/emby-toggle/emby-toggle.js index 8e82160806..5e78b38dd3 100644 --- a/src/elements/emby-toggle/emby-toggle.js +++ b/src/elements/emby-toggle/emby-toggle.js @@ -6,7 +6,6 @@ import 'webcomponents'; const EmbyTogglePrototype = Object.create(HTMLInputElement.prototype); function onKeyDown(e) { - // Don't submit form on enter if (e.keyCode === 13) { e.preventDefault(); @@ -22,7 +21,6 @@ import 'webcomponents'; } EmbyTogglePrototype.attachedCallback = function () { - if (this.getAttribute('data-embytoggle') === 'true') { return; } diff --git a/src/index.html b/src/index.html index f8d867cb1a..797fce8a94 100644 --- a/src/index.html +++ b/src/index.html @@ -1,13 +1,11 @@ - - @@ -15,10 +13,9 @@ - - + + - @@ -64,7 +61,6 @@ - Jellyfin @@ -129,7 +125,7 @@ animation: fadein 0.5s; width: 30%; height: 30%; - background-image: url(assets/img/banner-light.png); + background-image: url(assets/img/icon-transparent.png); background-position: center center; background-repeat: no-repeat; background-size: contain; @@ -139,6 +135,14 @@ -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); } + + @media screen + and (min-device-width: 992px) + and (-webkit-min-device-pixel-ratio: 1) { + .splashLogo { + background-image: url(assets/img/banner-light.png); + } + } diff --git a/src/legacy/focusPreventScroll.js b/src/legacy/focusPreventScroll.js index 93f53dca29..97d6b0b120 100644 --- a/src/legacy/focusPreventScroll.js +++ b/src/legacy/focusPreventScroll.js @@ -1,3 +1,4 @@ +// TODO: Move to external library (https://github.com/calvellido/focus-options-polyfill) // Polyfill to add support for preventScroll by focus function if (HTMLElement.prototype.nativeFocus === undefined) { diff --git a/src/libraries/navdrawer/navdrawer.js b/src/libraries/navdrawer/navdrawer.js index d9c246b406..4733c617f3 100644 --- a/src/libraries/navdrawer/navdrawer.js +++ b/src/libraries/navdrawer/navdrawer.js @@ -1,6 +1,8 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, dom) { "use strict"; + browser = browser.default || browser; + return function (options) { function getTouches(e) { return e.changedTouches || e.targetTouches || e.touches; diff --git a/src/libraries/screensavermanager.js b/src/libraries/screensavermanager.js index b9d7082850..557b31e0f4 100644 --- a/src/libraries/screensavermanager.js +++ b/src/libraries/screensavermanager.js @@ -1,6 +1,8 @@ define(["events", "playbackManager", "pluginManager", "inputManager", "connectionManager", "userSettings"], function (events, playbackManager, pluginManager, inputManager, connectionManager, userSettings) { "use strict"; + playbackManager = playbackManager.default || playbackManager; + function getMinIdleTime() { // Returns the minimum amount of idle time required before the screen saver can be displayed //time units used Millisecond diff --git a/src/libraries/scroller.js b/src/libraries/scroller.js index 8c67127eb3..c0cb3e557c 100644 --- a/src/libraries/scroller.js +++ b/src/libraries/scroller.js @@ -1,6 +1,8 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'scrollStyles'], function (browser, layoutManager, dom, focusManager, ResizeObserver) { 'use strict'; + browser = browser.default || browser; + /** * Return type of the value. * @@ -872,13 +874,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc if (item === undefined) { this.slideTo(this._pos[location], immediate); } else { - - //if (!transform) { - - // item.scrollIntoView(); - // return; - //} - var itemPos = this.getPos(item); if (itemPos) { diff --git a/src/manifest.json b/src/manifest.json index fed1177e24..5b5ecd5516 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,6 +1,6 @@ { "name": "Jellyfin", - "description": "Jellyfin: the Free Software Media System.", + "description": "The Free Software Media System", "lang": "en-US", "short_name": "Jellyfin", "start_url": "index.html#!/home.html", diff --git a/src/plugins/backdropScreensaver/plugin.js b/src/plugins/backdropScreensaver/plugin.js index 88bfa1f4b7..61b5b808a5 100644 --- a/src/plugins/backdropScreensaver/plugin.js +++ b/src/plugins/backdropScreensaver/plugin.js @@ -23,9 +23,7 @@ class BackdropScreensaver { const apiClient = connectionManager.currentApiClient(); apiClient.getItems(apiClient.getCurrentUserId(), query).then((result) => { - if (result.Items.length) { - import('slideshow').then(({default: Slideshow}) => { const newSlideShow = new Slideshow({ showTitle: true, diff --git a/src/plugins/bookPlayer/plugin.js b/src/plugins/bookPlayer/plugin.js index db6c344dad..c167046cb9 100644 --- a/src/plugins/bookPlayer/plugin.js +++ b/src/plugins/bookPlayer/plugin.js @@ -2,6 +2,7 @@ import connectionManager from 'connectionManager'; import loading from 'loading'; import keyboardnavigation from 'keyboardnavigation'; import dialogHelper from 'dialogHelper'; +import dom from 'dom'; import events from 'events'; import 'css!./style'; import 'material-icons'; @@ -93,23 +94,22 @@ export class BookPlayer { onWindowKeyUp(e) { let key = keyboardnavigation.getKeyName(e); - let rendition = this._rendition; + + // TODO: depending on the event this can be the document or the rendition itself + let rendition = this._rendition || this; let book = rendition.book; + if (this._loaded === false) return; switch (key) { case 'l': case 'ArrowRight': case 'Right': - if (this._loaded) { - book.package.metadata.direction === 'rtl' ? rendition.prev() : rendition.next(); - } + book.package.metadata.direction === 'rtl' ? rendition.prev() : rendition.next(); break; case 'j': case 'ArrowLeft': case 'Left': - if (this._loaded) { - book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev(); - } + book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev(); break; case 'Escape': if (this._tocElement) { @@ -123,6 +123,25 @@ export class BookPlayer { } } + onTouchStart(e) { + // TODO: depending on the event this can be the document or the rendition itself + let rendition = this._rendition || this; + let book = rendition.book; + + // check that the event is from the book or the document + if (!book || this._loaded === false) return; + + // epubjs stores pages off the screen or something for preloading + // get the modulus of the touch event to account for the increased width + if (!e.touches || e.touches.length === 0) return; + let touch = e.touches[0].clientX % dom.getWindowSize().innerWidth; + if (touch < dom.getWindowSize().innerWidth / 2) { + book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev(); + } else { + book.package.metadata.direction === 'rtl' ? rendition.prev() : rendition.next(); + } + } + onDialogClosed() { this.stop(); } @@ -139,8 +158,11 @@ export class BookPlayer { this.bindMediaElementEvents(); document.addEventListener('keyup', this.onWindowKeyUp); + document.addEventListener('touchstart', this.onTouchStart); + // FIXME: I don't really get why document keyup event is not triggered when epub is in focus this._rendition.on('keyup', this.onWindowKeyUp); + this._rendition.on('touchstart', this.onTouchStart); } unbindMediaElementEvents() { @@ -155,9 +177,13 @@ export class BookPlayer { if (this._mediaElement) { this.unbindMediaElementEvents(); } + document.removeEventListener('keyup', this.onWindowKeyUp); + document.removeEventListener('touchstart', this.onTouchStart); + if (this._rendition) { this._rendition.off('keyup', this.onWindowKeyUp); + this._rendition.off('touchstart', this.onTouchStart); } } @@ -169,13 +195,11 @@ export class BookPlayer { createMediaElement() { let elem = this._mediaElement; - if (elem) { return elem; } elem = document.getElementById('bookPlayer'); - if (!elem) { elem = dialogHelper.createDialog({ exitAnimationDuration: 400, @@ -185,6 +209,7 @@ export class BookPlayer { exitAnimation: 'fadeout', removeOnClose: true }); + elem.id = 'bookPlayer'; let html = ''; @@ -222,7 +247,7 @@ export class BookPlayer { return new Promise((resolve, reject) => { import('epubjs').then(({default: epubjs}) => { let downloadHref = apiClient.getItemDownloadUrl(item.Id); - let book = epubjs.default(downloadHref, {openAs: 'epub'}); + let book = epubjs(downloadHref, {openAs: 'epub'}); let rendition = book.renderTo(elem, {width: '100%', height: '97%'}); this._currentSrc = downloadHref; @@ -230,6 +255,7 @@ export class BookPlayer { let cancellationToken = { shouldCancel: false }; + this._cancellationToken = cancellationToken; return rendition.display().then(() => { @@ -253,7 +279,6 @@ export class BookPlayer { epubElem.style.display = 'block'; rendition.on('relocated', (locations) => { this._progress = book.locations.percentageFromCfi(locations.start.cfi); - events.trigger(this, 'timeupdate'); }); @@ -262,7 +287,7 @@ export class BookPlayer { return resolve(); }); }, () => { - console.error('Failed to display epub'); + console.error('failed to display epub'); return reject(); }); }); diff --git a/src/plugins/chromecastPlayer/chromecastHelpers.js b/src/plugins/chromecastPlayer/chromecastHelper.js similarity index 99% rename from src/plugins/chromecastPlayer/chromecastHelpers.js rename to src/plugins/chromecastPlayer/chromecastHelper.js index ca2d27c977..3fbff5507b 100644 --- a/src/plugins/chromecastPlayer/chromecastHelpers.js +++ b/src/plugins/chromecastPlayer/chromecastHelper.js @@ -11,7 +11,6 @@ define(['events'], function (events) { // This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. // http://creativecommons.org/licenses/by-sa/4.0/ (function () { - // Original URL regex from the Android android.text.util.Linkify function, found here: // http://stackoverflow.com/a/19696443 // @@ -152,14 +151,12 @@ define(['events'], function (events) { var cache = {}; function isValidIpAddress(address) { - var links = LinkParser.parse(address); return links.length == 1; } function isLocalIpAddress(address) { - address = address.toLowerCase(); if (address.indexOf('127.0.0.1') !== -1) { @@ -173,7 +170,6 @@ define(['events'], function (events) { } function getServerAddress(apiClient) { - var serverAddress = apiClient.serverAddress(); if (isValidIpAddress(serverAddress) && !isLocalIpAddress(serverAddress)) { @@ -215,7 +211,6 @@ define(['events'], function (events) { } function getCachedValue(key) { - var obj = cache[key]; if (obj && (new Date().getTime() - obj.time) < 180000) { diff --git a/src/plugins/chromecastPlayer/plugin.js b/src/plugins/chromecastPlayer/plugin.js index 3d4f293cc8..2741a6f0e3 100644 --- a/src/plugins/chromecastPlayer/plugin.js +++ b/src/plugins/chromecastPlayer/plugin.js @@ -1,6 +1,8 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', 'globalize', 'events', 'require', 'castSenderApiLoader'], function (appSettings, userSettings, playbackManager, connectionManager, globalize, events, require, castSenderApiLoader) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + // Based on https://github.com/googlecast/CastVideos-chrome/blob/master/CastVideos.js var currentResolve; var currentReject; @@ -8,7 +10,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' var PlayerName = 'Google Cast'; function sendConnectionResult(isOk) { - var resolve = currentResolve; var reject = currentReject; @@ -55,12 +56,11 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' // production version registered with google // replace this value if you want to test changes on another instance var applicationStable = 'F007D354'; - var applicationNightly = '6F511C87'; + var applicationUnstable = '6F511C87'; var messageNamespace = 'urn:x-cast:com.connectsdk'; var CastPlayer = function () { - /* device variables */ // @type {DEVICE_STATE} A state for device this.deviceState = DEVICE_STATE.IDLE; @@ -101,8 +101,8 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' } var applicationID = applicationStable; - if (userSettings.chromecastVersion() === 'nightly') { - applicationID = applicationNightly; + if (userSettings.chromecastVersion() === 'unstable') { + applicationID = applicationUnstable; } // request session @@ -325,7 +325,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; CastPlayer.prototype.sendMessage = function (message) { - var player = this; var receiverName = null; @@ -366,7 +365,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' } return new Promise(function (resolve, reject) { - require(['chromecastHelper'], function (chromecastHelper) { + require(['./chromecastHelper'], function (chromecastHelper) { chromecastHelper.getServerAddress(apiClient).then(function (serverAddress) { message.serverAddress = serverAddress; player.sendMessageInternal(message).then(resolve, reject); @@ -391,7 +390,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' * @param {Object} mediaSession A new media object. */ CastPlayer.prototype.onMediaDiscovered = function (how, mediaSession) { - console.debug('chromecast new media session ID:' + mediaSession.mediaSessionId + ' (' + how + ')'); this.currentMediaSession = mediaSession; @@ -453,9 +451,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; function normalizeImages(state) { - if (state && state.NowPlayingItem) { - var item = state.NowPlayingItem; if (!item.ImageTags || !item.ImageTags.Primary) { @@ -475,7 +471,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' } function getItemsForPlayback(apiClient, query) { - var userId = apiClient.getCurrentUserId(); if (query.Ids && query.Ids.split(',').length === 1) { @@ -486,7 +481,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; }); } else { - query.Limit = query.Limit || 100; query.ExcludeLocationTypes = 'Virtual'; query.EnableTotalRecordCount = false; @@ -496,9 +490,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' } function bindEventForRelay(instance, eventName) { - events.on(instance._castPlayer, eventName, function (e, data) { - console.debug('cc: ' + eventName); var state = instance.getPlayerStateInternal(data); @@ -507,7 +499,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' } function initializeChromecast() { - var instance = this; instance._castPlayer = new CastPlayer(); @@ -519,7 +510,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' })); events.on(instance._castPlayer, 'connect', function (e) { - if (currentResolve) { sendConnectionResult(true); } else { @@ -532,7 +522,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }); events.on(instance._castPlayer, 'playbackstart', function (e, data) { - console.debug('cc: playbackstart'); instance._castPlayer.initializeCastPlayer(); @@ -542,7 +531,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }); events.on(instance._castPlayer, 'playbackstop', function (e, data) { - console.debug('cc: playbackstop'); var state = instance.getPlayerStateInternal(data); @@ -560,7 +548,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }); events.on(instance._castPlayer, 'playbackprogress', function (e, data) { - console.debug('cc: positionchange'); var state = instance.getPlayerStateInternal(data); @@ -575,7 +562,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' bindEventForRelay(instance, 'shufflequeuemodechange'); events.on(instance._castPlayer, 'playstatechange', function (e, data) { - console.debug('cc: playstatechange'); var state = instance.getPlayerStateInternal(data); @@ -584,7 +570,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' } function ChromecastPlayer() { - // playbackManager needs this this.name = PlayerName; this.type = 'mediaplayer'; @@ -624,7 +609,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' // This is a privately used method ChromecastPlayer.prototype.getCurrentTargetInfo = function () { - var appName = null; var castPlayer = this._castPlayer; @@ -661,7 +645,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.getPlayerStateInternal = function (data) { - var triggerStateChange = false; if (data && !this.lastPlayerData) { triggerStateChange = true; @@ -682,13 +665,11 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.playWithCommand = function (options, command) { - if (!options.items) { var apiClient = connectionManager.getApiClient(options.serverId); var instance = this; return apiClient.getItem(apiClient.getCurrentUserId(), options.ids[0]).then(function (item) { - options.items = [item]; return instance.playWithCommand(options, command); }); @@ -705,7 +686,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.seek = function (position) { - position = parseInt(position); position = position / 10000000; @@ -737,7 +717,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.setMaxStreamingBitrate = function (options) { - this._castPlayer.sendMessage({ options: options, command: 'SetMaxStreamingBitrate' @@ -773,11 +752,9 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' vol = Math.max(vol, 0); this._castPlayer.session.setReceiverVolumeLevel(vol); - }; ChromecastPlayer.prototype.endSession = function () { - var instance = this; this.stop().then(function () { @@ -799,7 +776,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.setVolume = function (vol) { - vol = Math.min(vol, 100); vol = Math.max(vol, 0); vol = vol / 100; @@ -836,7 +812,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.displayContent = function (options) { - this._castPlayer.sendMessage({ options: options, command: 'DisplayContent' @@ -844,7 +819,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.setMute = function (isMuted) { - var castPlayer = this._castPlayer; if (isMuted) { @@ -873,7 +847,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.playTrailers = function (item) { - this._castPlayer.sendMessage({ options: { ItemId: item.Id, @@ -902,7 +875,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.toggleMute = function () { - this._castPlayer.sendMessage({ options: {}, command: 'ToggleMute' @@ -946,7 +918,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.getVolume = function () { - var state = this.lastPlayerData || {}; state = state.PlayState || {}; @@ -971,7 +942,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.currentTime = function (val) { - if (val != null) { return this.seek(val); } @@ -1008,45 +978,36 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.shuffle = function (item) { - var apiClient = connectionManager.getApiClient(item.ServerId); var userId = apiClient.getCurrentUserId(); var instance = this; apiClient.getItem(userId, item.Id).then(function (item) { - instance.playWithCommand({ items: [item] }, 'Shuffle'); - }); - }; ChromecastPlayer.prototype.instantMix = function (item) { - var apiClient = connectionManager.getApiClient(item.ServerId); var userId = apiClient.getCurrentUserId(); var instance = this; apiClient.getItem(userId, item.Id).then(function (item) { - instance.playWithCommand({ items: [item] }, 'InstantMix'); - }); - }; ChromecastPlayer.prototype.canPlayMediaType = function (mediaType) { - mediaType = (mediaType || '').toLowerCase(); return mediaType === 'audio' || mediaType === 'video'; }; @@ -1064,13 +1025,9 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.play = function (options) { - if (options.items) { - return this.playWithCommand(options, 'PlayNow'); - } else { - if (!options.serverId) { throw new Error('serverId required!'); } @@ -1083,10 +1040,8 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' Ids: options.ids.join(',') }).then(function (result) { - options.items = result.Items; return instance.playWithCommand(options, 'PlayNow'); - }); } }; @@ -1119,7 +1074,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.getPlayerState = function () { - return this.getPlayerStateInternal() || {}; }; diff --git a/src/plugins/experimentalWarnings/plugin.js b/src/plugins/experimentalWarnings/plugin.js index 632e38208c..c39612d45b 100644 --- a/src/plugins/experimentalWarnings/plugin.js +++ b/src/plugins/experimentalWarnings/plugin.js @@ -1,14 +1,7 @@ define(['connectionManager', 'globalize', 'userSettings', 'apphost'], function (connectionManager, globalize, userSettings, appHost) { 'use strict'; - function getRequirePromise(deps) { - - return new Promise(function (resolve, reject) { - - require(deps, resolve); - }); - } - + // TODO: Replace with date-fns // https://stackoverflow.com/questions/6117814/get-week-of-year-in-javascript-like-in-php function getWeek(date) { var d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())); @@ -19,13 +12,13 @@ define(['connectionManager', 'globalize', 'userSettings', 'apphost'], function ( } function showMessage(text, userSettingsKey, appHostFeature) { - if (appHost.supports(appHostFeature)) { return Promise.resolve(); } var now = new Date(); + // TODO: Use date-fns userSettingsKey += now.getFullYear() + '-w' + getWeek(now); if (userSettings.get(userSettingsKey, false) === '1') { @@ -33,11 +26,9 @@ define(['connectionManager', 'globalize', 'userSettings', 'apphost'], function ( } return new Promise(function (resolve, reject) { - userSettings.set(userSettingsKey, '1', false); require(['alert'], function (alert) { - return alert(text).then(resolve, resolve); }); }); @@ -56,14 +47,12 @@ define(['connectionManager', 'globalize', 'userSettings', 'apphost'], function ( } function ExpirementalPlaybackWarnings() { - this.name = 'Experimental playback warnings'; this.type = 'preplayintercept'; this.id = 'expirementalplaybackwarnings'; } ExpirementalPlaybackWarnings.prototype.intercept = function (options) { - var item = options.item; if (!item) { return Promise.resolve(); diff --git a/src/plugins/htmlAudioPlayer/plugin.js b/src/plugins/htmlAudioPlayer/plugin.js index 8265987e28..16fce8c9d1 100644 --- a/src/plugins/htmlAudioPlayer/plugin.js +++ b/src/plugins/htmlAudioPlayer/plugin.js @@ -68,7 +68,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp // issue head request to get content type return new Promise(function (resolve, reject) { - require(['fetchHelper'], function (fetchHelper) { fetchHelper.ajax({ url: url, @@ -96,7 +95,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp self.priority = 1; self.play = function (options) { - self._started = false; self._timeUpdated = false; self._currentTime = null; @@ -106,7 +104,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp }; function setCurrentSrc(elem, options) { - elem.removeEventListener('error', onError); unBindEvents(elem); @@ -131,17 +128,13 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp } return enableHlsPlayer(val, options.item, options.mediaSource, 'Audio').then(function () { - return new Promise(function (resolve, reject) { - requireHlsPlayer(function () { var hls = new Hls({ manifestLoadingTimeOut: 20000, xhrSetup: function(xhr, url) { xhr.withCredentials = true; } - //appendErrorMaxRetry: 6, - //debug: true }); hls.loadSource(val); hls.attachMedia(elem); @@ -153,16 +146,13 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp self._currentSrc = val; }); }); - }, function () { - elem.autoplay = true; // Safari will not send cookies without this elem.crossOrigin = 'use-credentials'; return htmlMediaHelper.applySrc(elem, val, options).then(function () { - self._currentSrc = val; return htmlMediaHelper.playWithPromise(elem, onError); @@ -191,16 +181,13 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp } self.stop = function (destroyPlayer) { - cancelFadeTimeout(); var elem = self._mediaElement; var src = self._currentSrc; if (elem && src) { - if (!destroyPlayer || !supportsFade()) { - elem.pause(); htmlMediaHelper.onEndedInternal(self, elem, onError); @@ -214,7 +201,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp var originalVolume = elem.volume; return fade(self, elem, elem.volume).then(function () { - elem.pause(); elem.volume = originalVolume; @@ -233,7 +219,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp }; function createMediaElement() { - var elem = self._mediaElement; if (elem) { @@ -258,12 +243,10 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp } function onEnded() { - htmlMediaHelper.onEndedInternal(self, this, onError); } function onTimeUpdate() { - // Get the player position + the transcoding offset var time = this.currentTime; @@ -275,7 +258,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp } function onVolumeChange() { - if (!self._isFadingOut) { htmlMediaHelper.saveVolume(this.volume); events.trigger(self, 'volumechange'); @@ -283,7 +265,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp } function onPlaying(e) { - if (!self._started) { self._started = true; this.removeAttribute('controls'); @@ -294,7 +275,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp } function onPlay(e) { - events.trigger(self, 'unpause'); } @@ -307,7 +287,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp } function onError() { - var errorCode = this.error ? (this.error.code || 0) : 0; var errorMessage = this.error ? (this.error.message || '') : ''; console.error('media element error: ' + errorCode.toString() + ' ' + errorMessage); @@ -351,12 +330,10 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp }; HtmlAudioPlayer.prototype.canPlayMediaType = function (mediaType) { - return (mediaType || '').toLowerCase() === 'audio'; }; HtmlAudioPlayer.prototype.getDeviceProfile = function (item) { - if (appHost.getDeviceProfile) { return appHost.getDeviceProfile(item); } @@ -366,7 +343,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp // Save this for when playback stops, because querying the time at that point might return 0 HtmlAudioPlayer.prototype.currentTime = function (val) { - var mediaElement = this._mediaElement; if (mediaElement) { if (val != null) { @@ -384,7 +360,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp }; HtmlAudioPlayer.prototype.duration = function (val) { - var mediaElement = this._mediaElement; if (mediaElement) { var duration = mediaElement.duration; @@ -399,10 +374,8 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp HtmlAudioPlayer.prototype.seekable = function () { var mediaElement = this._mediaElement; if (mediaElement) { - var seekable = mediaElement.seekable; if (seekable && seekable.length) { - var start = seekable.start(0); var end = seekable.end(0); @@ -423,7 +396,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp HtmlAudioPlayer.prototype.getBufferedRanges = function () { var mediaElement = this._mediaElement; if (mediaElement) { - return htmlMediaHelper.getBufferedRanges(this, mediaElement); } @@ -453,7 +425,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp }; HtmlAudioPlayer.prototype.paused = function () { - var mediaElement = this._mediaElement; if (mediaElement) { return mediaElement.paused; @@ -487,7 +458,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp HtmlAudioPlayer.prototype.getVolume = function () { var mediaElement = this._mediaElement; if (mediaElement) { - return Math.min(Math.round(mediaElement.volume * 100), 100); } }; @@ -501,7 +471,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp }; HtmlAudioPlayer.prototype.setMute = function (mute) { - var mediaElement = this._mediaElement; if (mediaElement) { mediaElement.muted = mute; diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index cc312bb956..d52f0eb5b3 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -1,43 +1,48 @@ -define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackManager', 'appRouter', 'appSettings', 'connectionManager', 'htmlMediaHelper', 'itemHelper', 'screenfull', 'globalize'], function (browser, require, events, appHost, loading, dom, playbackManager, appRouter, appSettings, connectionManager, htmlMediaHelper, itemHelper, screenfull, globalize) { - 'use strict'; - /* globals cast */ +import browser from 'browser'; +import events from 'events'; +import appHost from 'apphost'; +import loading from 'loading'; +import dom from 'dom'; +import playbackManager from 'playbackManager'; +import appRouter from 'appRouter'; +import connectionManager from 'connectionManager'; +import { + bindEventsToHlsPlayer, + destroyHlsPlayer, + destroyFlvPlayer, + destroyCastPlayer, + getCrossOriginValue, + enableHlsJsPlayer, + applySrc, + playWithPromise, + onEndedInternal, + saveVolume, + seekOnPlaybackStart, + onErrorInternal, + handleHlsJsMediaError, + getSavedVolume, + isValidDuration, + getBufferedRanges +} from 'htmlMediaHelper'; +import itemHelper from 'itemHelper'; +import screenfull from 'screenfull'; +import globalize from 'globalize'; - var mediaManager; +/* eslint-disable indent */ - function tryRemoveElement(elem) { - var parentNode = elem.parentNode; +function tryRemoveElement(elem) { + const parentNode = elem.parentNode; if (parentNode) { - // Seeing crashes in edge webview try { parentNode.removeChild(elem); } catch (err) { - console.error('error removing dialog element: ' + err); + console.error(`error removing dialog element: ${err}`); } } } - var _supportsTextTracks; - function supportsTextTracks() { - - if (_supportsTextTracks == null) { - _supportsTextTracks = document.createElement('video').textTracks != null; - } - - // For now, until ready - return _supportsTextTracks; - } - - function supportsCanvas() { - return !!document.createElement('canvas').getContext; - } - - function supportsWebWorkers() { - return !!window.Worker; - } - function enableNativeTrackSupport(currentSrc, track) { - if (track) { if (track.DeliveryMethod === 'Embed') { return true; @@ -45,14 +50,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } if (browser.firefox) { - if ((currentSrc || '').toLowerCase().indexOf('.m3u8') !== -1) { - return false; - } - } - - // subs getting blocked due to CORS - if (browser.chromecast) { - if ((currentSrc || '').toLowerCase().indexOf('.m3u8') !== -1) { + if ((currentSrc || '').toLowerCase().includes('.m3u8')) { return false; } } @@ -78,7 +76,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } if (track) { - var format = (track.Codec || '').toLowerCase(); + const format = (track.Codec || '').toLowerCase(); if (format === 'ssa' || format === 'ass') { return false; } @@ -88,7 +86,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } function requireHlsPlayer(callback) { - require(['hlsjs'], function (hls) { + import('hlsjs').then(({default: hls}) => { window.Hls = hls; callback(); }); @@ -114,9 +112,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } function zoomIn(elem) { - return new Promise(function (resolve, reject) { - var duration = 240; - elem.style.animation = 'htmlvideoplayer-zoomin ' + duration + 'ms ease-in normal'; + return new Promise(resolve => { + const duration = 240; + elem.style.animation = `htmlvideoplayer-zoomin ${duration}ms ease-in normal`; hidePrePlaybackPage(); dom.addEventListener(elem, dom.whichAnimationEvent(), resolve, { once: true @@ -125,22 +123,16 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } function normalizeTrackEventText(text, useHtml) { - var result = text.replace(/\\N/gi, '\n').replace(/\r/gi, ''); + const result = text.replace(/\\N/gi, '\n').replace(/\r/gi, ''); return useHtml ? result.replace(/\n/gi, '
    ') : result; } - function setTracks(elem, tracks, item, mediaSource) { - - elem.innerHTML = getTracksHtml(tracks, item, mediaSource); - } - function getTextTrackUrl(track, item, format) { - if (itemHelper.isLocalItem(item) && track.Path) { return track.Path; } - var url = playbackManager.getSubtitleUrl(track, item.ServerId); + let url = playbackManager.getSubtitleUrl(track, item.ServerId); if (format) { url = url.replace('.vtt', format); } @@ -148,110 +140,190 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return url; } - function getTracksHtml(tracks, item, mediaSource) { - return tracks.map(function (t) { - - if (t.DeliveryMethod !== 'External') { - return ''; - } - - var defaultAttribute = mediaSource.DefaultSubtitleStreamIndex === t.Index ? ' default' : ''; - - var language = t.Language || 'und'; - var label = t.Language || 'und'; - return ''; - - }).join(''); - } - function getDefaultProfile() { - - return new Promise(function (resolve, reject) { - - require(['browserdeviceprofile'], function (profileBuilder) { - - resolve(profileBuilder({})); - }); + return import('browserdeviceprofile').then(({default: profileBuilder}) => { + return profileBuilder({}); }); } - function HtmlVideoPlayer() { + export class HtmlVideoPlayer { + /** + * @type {string} + */ + name + /** + * @type {string} + */ + type = 'mediaplayer'; + /** + * @type {string} + */ + id = 'htmlvideoplayer'; + /** + * Let any players created by plugins take priority + * + * @type {number} + */ + priority = 1; + /** + * @type {boolean} + */ + isFetching = false; - if (browser.edgeUwp) { - this.name = 'Windows Video Player'; - } else { - this.name = 'Html Video Player'; - } + /** + * @type {HTMLDivElement | null | undefined} + */ + #videoDialog; + /** + * @type {number | undefined} + */ + #subtitleTrackIndexToSetOnPlaying; + /** + * @type {number | null} + */ + #audioTrackIndexToSetOnPlaying; + /** + * @type {null | undefined} + */ + #currentClock; + /** + * @type {any | null | undefined} + */ + #currentSubtitlesOctopus; + /** + * @type {null | undefined} + */ + #currentAssRenderer; + /** + * @type {number | undefined} + */ + #customTrackIndex; + /** + * @type {boolean | undefined} + */ + #showTrackOffset; + /** + * @type {number | undefined} + */ + #currentTrackOffset; + /** + * @type {HTMLElement | null | undefined} + */ + #videoSubtitlesElem; + /** + * @type {any | null | undefined} + */ + #currentTrackEvents; + /** + * @type {string[] | undefined} + */ + #supportedFeatures; + /** + * @type {HTMLVideoElement | null | undefined} + */ + #mediaElement; + /** + * @type {number} + */ + #fetchQueue = 0; + /** + * @type {string | undefined} + */ + #currentSrc; + /** + * @type {boolean | undefined} + */ + #started; + /** + * @type {boolean | undefined} + */ + #timeUpdated; + /** + * @type {number | null | undefined} + */ + #currentTime; + /** + * @type {any | undefined} + */ + #flvPlayer; + /** + * @private (used in other files) + * @type {any | undefined} + */ + _hlsPlayer; + /** + * @private (used in other files) + * @type {any | null | undefined} + */ + _castPlayer; + /** + * @private (used in other files) + * @type {any | undefined} + */ + _currentPlayOptions; + /** + * @type {any | undefined} + */ + #lastProfile; + /** + * @type {MutationObserver | IntersectionObserver | undefined} (Unclear observer typing) + */ + #resizeObserver; - this.type = 'mediaplayer'; - this.id = 'htmlvideoplayer'; - - // Let any players created by plugins take priority - this.priority = 1; - - var videoDialog; - - var winJsPlaybackItem; - - var subtitleTrackIndexToSetOnPlaying; - var audioTrackIndexToSetOnPlaying; - - var lastCustomTrackMs = 0; - var currentClock; - var currentSubtitlesOctopus; - var currentAssRenderer; - var customTrackIndex = -1; - - var showTrackOffset; - var currentTrackOffset; - - var videoSubtitlesElem; - var currentTrackEvents; - - var self = this; - - self.currentSrc = function () { - return self._currentSrc; - }; - - self._fetchQueue = 0; - self.isFetching = false; - - function incrementFetchQueue() { - if (self._fetchQueue <= 0) { - self.isFetching = true; - events.trigger(self, 'beginFetch'); - } - - self._fetchQueue++; - } - - function decrementFetchQueue() { - self._fetchQueue--; - - if (self._fetchQueue <= 0) { - self.isFetching = false; - events.trigger(self, 'endFetch'); + constructor() { + if (browser.edgeUwp) { + this.name = 'Windows Video Player'; + } else { + this.name = 'Html Video Player'; } } - function updateVideoUrl(streamInfo) { + currentSrc() { + return this.#currentSrc; + } - var isHls = streamInfo.url.toLowerCase().indexOf('.m3u8') !== -1; + /** + * @private + */ + incrementFetchQueue() { + if (this.#fetchQueue <= 0) { + this.isFetching = true; + events.trigger(this, 'beginFetch'); + } - var mediaSource = streamInfo.mediaSource; - var item = streamInfo.item; + this.#fetchQueue++; + } + + /** + * @private + */ + decrementFetchQueue() { + this.#fetchQueue--; + + if (this.#fetchQueue <= 0) { + this.isFetching = false; + events.trigger(this, 'endFetch'); + } + } + + /** + * @private + */ + updateVideoUrl(streamInfo) { + const isHls = streamInfo.url.toLowerCase().includes('.m3u8'); + + const mediaSource = streamInfo.mediaSource; + const item = streamInfo.item; // Huge hack alert. Safari doesn't seem to like if the segments aren't available right away when playback starts // This will start the transcoding process before actually feeding the video url into the player // Edit: Also seeing stalls from hls.js if (mediaSource && item && !mediaSource.RunTimeTicks && isHls && streamInfo.playMethod === 'Transcode' && (browser.iOS || browser.osx)) { - - var hlsPlaylistUrl = streamInfo.url.replace('master.m3u8', 'live.m3u8'); + const hlsPlaylistUrl = streamInfo.url.replace('master.m3u8', 'live.m3u8'); loading.show(); - console.debug('prefetching hls playlist: ' + hlsPlaylistUrl); + console.debug(`prefetching hls playlist: ${hlsPlaylistUrl}`); return connectionManager.getApiClient(item.ServerId).ajax({ @@ -259,50 +331,41 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa url: hlsPlaylistUrl }).then(function () { - - console.debug('completed prefetching hls playlist: ' + hlsPlaylistUrl); + console.debug(`completed prefetching hls playlist: ${hlsPlaylistUrl}`); loading.hide(); streamInfo.url = hlsPlaylistUrl; - - return Promise.resolve(); - }, function () { - - console.error('error prefetching hls playlist: ' + hlsPlaylistUrl); + console.error(`error prefetching hls playlist: ${hlsPlaylistUrl}`); loading.hide(); - return Promise.resolve(); }); - } else { return Promise.resolve(); } } - self.play = function (options) { - self._started = false; - self._timeUpdated = false; + play(options) { + this.#started = false; + this.#timeUpdated = false; - self._currentTime = null; + this.#currentTime = null; - self.resetSubtitleOffset(); + this.resetSubtitleOffset(); - return createMediaElement(options).then(function (elem) { - - return updateVideoUrl(options).then(function () { - return setCurrentSrc(elem, options); + return this.createMediaElement(options).then(elem => { + return this.updateVideoUrl(options).then(() => { + return this.setCurrentSrc(elem, options); }); }); - }; + } - function setSrcWithFlvJs(instance, elem, options, url) { - - return new Promise(function (resolve, reject) { - - require(['flvjs'], function (flvjs) { - - var flvPlayer = flvjs.createPlayer({ + /** + * @private + */ + setSrcWithFlvJs(elem, options, url) { + return import('flvjs').then(({default: flvjs}) => { + const flvPlayer = flvjs.createPlayer({ type: 'flv', url: url }, @@ -311,288 +374,126 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa lazyLoad: false }); - flvPlayer.attachMediaElement(elem); - flvPlayer.load(); + flvPlayer.attachMediaElement(elem); + flvPlayer.load(); - flvPlayer.play().then(resolve, reject); - instance._flvPlayer = flvPlayer; + this.#flvPlayer = flvPlayer; - // This is needed in setCurrentTrackElement - self._currentSrc = url; - }); + // This is needed in setCurrentTrackElement + this.#currentSrc = url; + + return flvPlayer.play(); }); } - function setSrcWithHlsJs(instance, elem, options, url) { - - return new Promise(function (resolve, reject) { - - requireHlsPlayer(function () { - - var hls = new Hls({ + /** + * @private + */ + setSrcWithHlsJs(elem, options, url) { + return new Promise((resolve, reject) => { + requireHlsPlayer(() => { + const hls = new Hls({ manifestLoadingTimeOut: 20000, - xhrSetup: function(xhr, xhr_url) { + xhrSetup(xhr) { xhr.withCredentials = true; } - //appendErrorMaxRetry: 6, - //debug: true }); hls.loadSource(url); hls.attachMedia(elem); - htmlMediaHelper.bindEventsToHlsPlayer(self, hls, elem, onError, resolve, reject); + bindEventsToHlsPlayer(this, hls, elem, this.onError, resolve, reject); - self._hlsPlayer = hls; + this._hlsPlayer = hls; // This is needed in setCurrentTrackElement - self._currentSrc = url; + this.#currentSrc = url; }); }); } - function onShakaError(event) { + /** + * @private + */ + setCurrentSrc(elem, options) { + elem.removeEventListener('error', this.onError); - var error = event.detail; - console.error('Error code', error.code, 'object', error); - } - - function setSrcWithShakaPlayer(instance, elem, options, url) { - - return new Promise(function (resolve, reject) { - - require(['shaka'], function () { - /* globals shaka */ - - var player = new shaka.Player(elem); - - //player.configure({ - // abr: { - // enabled: false - // }, - // streaming: { - - // failureCallback: function () { - // alert(2); - // } - // } - //}); - - //shaka.log.setLevel(6); - - // Listen for error events. - player.addEventListener('error', onShakaError); - - // Try to load a manifest. - // This is an asynchronous process. - player.load(url).then(function () { - - // This runs if the asynchronous load is successful. - resolve(); - - }, reject); - - self._shakaPlayer = player; - - // This is needed in setCurrentTrackElement - self._currentSrc = url; - }); - }); - } - - function setCurrentSrcChromecast(instance, elem, options, url) { - - elem.autoplay = true; - - var lrd = new cast.receiver.MediaManager.LoadRequestData(); - lrd.currentTime = (options.playerStartPositionTicks || 0) / 10000000; - lrd.autoplay = true; - lrd.media = new cast.receiver.media.MediaInformation(); - - lrd.media.contentId = url; - lrd.media.contentType = options.mimeType; - lrd.media.streamType = cast.receiver.media.StreamType.OTHER; - lrd.media.customData = options; - - console.debug('loading media url into media manager'); - - try { - mediaManager.load(lrd); - // This is needed in setCurrentTrackElement - self._currentSrc = url; - - return Promise.resolve(); - } catch (err) { - - console.debug('media manager error: ' + err); - return Promise.reject(); - } - } - - // Adapted from : https://github.com/googlecast/CastReferencePlayer/blob/master/player.js - function onMediaManagerLoadMedia(event) { - - if (self._castPlayer) { - self._castPlayer.unload(); // Must unload before starting again. - } - self._castPlayer = null; - - var data = event.data; - - var media = event.data.media || {}; - var url = media.contentId; - var contentType = media.contentType.toLowerCase(); - var options = media.customData; - - var protocol; - var ext = 'm3u8'; - - var mediaElement = self._mediaElement; - - var host = new cast.player.api.Host({ - 'url': url, - 'mediaElement': mediaElement - }); - - if (ext === 'm3u8' || - contentType === 'application/x-mpegurl' || - contentType === 'application/vnd.apple.mpegurl') { - protocol = cast.player.api.CreateHlsStreamingProtocol(host); - } else if (ext === 'mpd' || - contentType === 'application/dash+xml') { - protocol = cast.player.api.CreateDashStreamingProtocol(host); - } else if (url.indexOf('.ism') > -1 || - contentType === 'application/vnd.ms-sstr+xml') { - protocol = cast.player.api.CreateSmoothStreamingProtocol(host); - } - - console.debug('loading playback url: ' + url); - console.debug('content type: ' + contentType); - - host.onError = function (errorCode) { - console.error('fatal Error - ' + errorCode); - }; - - mediaElement.autoplay = false; - - self._castPlayer = new cast.player.api.Player(host); - - self._castPlayer.load(protocol, data.currentTime || 0); - - self._castPlayer.playWhenHaveEnoughData(); - } - - function initMediaManager() { - - mediaManager.defaultOnLoad = mediaManager.onLoad.bind(mediaManager); - mediaManager.onLoad = onMediaManagerLoadMedia.bind(self); - - //mediaManager.defaultOnPlay = mediaManager.onPlay.bind(mediaManager); - //mediaManager.onPlay = function (event) { - // // TODO ??? - // mediaManager.defaultOnPlay(event); - //}; - - mediaManager.defaultOnStop = mediaManager.onStop.bind(mediaManager); - mediaManager.onStop = function (event) { - playbackManager.stop(); - mediaManager.defaultOnStop(event); - }; - } - - function setCurrentSrc(elem, options) { - - elem.removeEventListener('error', onError); - - var val = options.url; - console.debug('playing url: ' + val); + let val = options.url; + console.debug(`playing url: ${val}`); // Convert to seconds - var seconds = (options.playerStartPositionTicks || 0) / 10000000; + const seconds = (options.playerStartPositionTicks || 0) / 10000000; if (seconds) { - val += '#t=' + seconds; + val += `#t=${seconds}`; } - htmlMediaHelper.destroyHlsPlayer(self); - htmlMediaHelper.destroyFlvPlayer(self); - htmlMediaHelper.destroyCastPlayer(self); + destroyHlsPlayer(this); + destroyFlvPlayer(this); + destroyCastPlayer(this); - var tracks = getMediaStreamTextTracks(options.mediaSource); - - subtitleTrackIndexToSetOnPlaying = options.mediaSource.DefaultSubtitleStreamIndex == null ? -1 : options.mediaSource.DefaultSubtitleStreamIndex; - if (subtitleTrackIndexToSetOnPlaying != null && subtitleTrackIndexToSetOnPlaying >= 0) { - var initialSubtitleStream = options.mediaSource.MediaStreams[subtitleTrackIndexToSetOnPlaying]; + this.#subtitleTrackIndexToSetOnPlaying = options.mediaSource.DefaultSubtitleStreamIndex == null ? -1 : options.mediaSource.DefaultSubtitleStreamIndex; + if (this.#subtitleTrackIndexToSetOnPlaying != null && this.#subtitleTrackIndexToSetOnPlaying >= 0) { + const initialSubtitleStream = options.mediaSource.MediaStreams[this.#subtitleTrackIndexToSetOnPlaying]; if (!initialSubtitleStream || initialSubtitleStream.DeliveryMethod === 'Encode') { - subtitleTrackIndexToSetOnPlaying = -1; + this.#subtitleTrackIndexToSetOnPlaying = -1; } } - audioTrackIndexToSetOnPlaying = options.playMethod === 'Transcode' ? null : options.mediaSource.DefaultAudioStreamIndex; + this.#audioTrackIndexToSetOnPlaying = options.playMethod === 'Transcode' ? null : options.mediaSource.DefaultAudioStreamIndex; - self._currentPlayOptions = options; + this._currentPlayOptions = options; - var crossOrigin = htmlMediaHelper.getCrossOriginValue(options.mediaSource); + const crossOrigin = getCrossOriginValue(options.mediaSource); if (crossOrigin) { elem.crossOrigin = crossOrigin; } - /*if (htmlMediaHelper.enableHlsShakaPlayer(options.item, options.mediaSource, 'Video') && val.indexOf('.m3u8') !== -1) { - - setTracks(elem, tracks, options.item, options.mediaSource); - - return setSrcWithShakaPlayer(self, elem, options, val); - - } else*/ if (browser.chromecast && val.indexOf('.m3u8') !== -1 && options.mediaSource.RunTimeTicks) { - - return setCurrentSrcChromecast(self, elem, options, val); - } else if (htmlMediaHelper.enableHlsJsPlayer(options.mediaSource.RunTimeTicks, 'Video') && val.indexOf('.m3u8') !== -1) { - return setSrcWithHlsJs(self, elem, options, val); + if (enableHlsJsPlayer(options.mediaSource.RunTimeTicks, 'Video') && val.includes('.m3u8')) { + return this.setSrcWithHlsJs(elem, options, val); } else if (options.playMethod !== 'Transcode' && options.mediaSource.Container === 'flv') { - - return setSrcWithFlvJs(self, elem, options, val); - + return this.setSrcWithFlvJs(elem, options, val); } else { - elem.autoplay = true; // Safari will not send cookies without this elem.crossOrigin = 'use-credentials'; - return htmlMediaHelper.applySrc(elem, val, options).then(function () { + return applySrc(elem, val, options).then(() => { + this.#currentSrc = val; - self._currentSrc = val; - - return htmlMediaHelper.playWithPromise(elem, onError); + return playWithPromise(elem, this.onError); }); } } - self.setSubtitleStreamIndex = function (index) { + setSubtitleStreamIndex(index) { + this.setCurrentTrackElement(index); + } - setCurrentTrackElement(index); - }; + resetSubtitleOffset() { + this.#currentTrackOffset = 0; + this.#showTrackOffset = false; + } - self.resetSubtitleOffset = function() { - currentTrackOffset = 0; - showTrackOffset = false; - }; + enableShowingSubtitleOffset() { + this.#showTrackOffset = true; + } - self.enableShowingSubtitleOffset = function() { - showTrackOffset = true; - }; + disableShowingSubtitleOffset() { + this.#showTrackOffset = false; + } - self.disableShowingSubtitleOffset = function() { - showTrackOffset = false; - }; + isShowingSubtitleOffsetEnabled() { + return this.#showTrackOffset; + } - self.isShowingSubtitleOffsetEnabled = function() { - return showTrackOffset; - }; - - function getTextTrack() { - var videoElement = self._mediaElement; + /** + * @private + */ + getTextTrack() { + const videoElement = this.#mediaElement; if (videoElement) { return Array.from(videoElement.textTracks) - .find(function(trackElement) { + .find(function (trackElement) { // get showing .vtt textTack return trackElement.mode === 'showing'; }); @@ -601,69 +502,79 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } } - self.setSubtitleOffset = function(offset) { - - var offsetValue = parseFloat(offset); + /** + * @private + */ + setSubtitleOffset(offset) { + const offsetValue = parseFloat(offset); // if .ass currently rendering - if (currentSubtitlesOctopus) { - updateCurrentTrackOffset(offsetValue); - currentSubtitlesOctopus.timeOffset = (self._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000 + offsetValue; + if (this.#currentSubtitlesOctopus) { + this.updateCurrentTrackOffset(offsetValue); + this.#currentSubtitlesOctopus.timeOffset = (this._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000 + offsetValue; } else { - var trackElement = getTextTrack(); + const trackElement = this.getTextTrack(); // if .vtt currently rendering if (trackElement) { - setTextTrackSubtitleOffset(trackElement, offsetValue); - } else if (currentTrackEvents) { - setTrackEventsSubtitleOffset(currentTrackEvents, offsetValue); + this.setTextTrackSubtitleOffset(trackElement, offsetValue); + } else if (this.#currentTrackEvents) { + this.setTrackEventsSubtitleOffset(this.#currentTrackEvents, offsetValue); } else { console.debug('No available track, cannot apply offset: ', offsetValue); } } - }; + } - function updateCurrentTrackOffset(offsetValue) { - - var relativeOffset = offsetValue; - var newTrackOffset = offsetValue; - if (currentTrackOffset) { - relativeOffset -= currentTrackOffset; + /** + * @private + */ + updateCurrentTrackOffset(offsetValue) { + let relativeOffset = offsetValue; + const newTrackOffset = offsetValue; + if (this.#currentTrackOffset) { + relativeOffset -= this.#currentTrackOffset; } - currentTrackOffset = newTrackOffset; + this.#currentTrackOffset = newTrackOffset; // relative to currentTrackOffset return relativeOffset; } - function setTextTrackSubtitleOffset(currentTrack, offsetValue) { - + /** + * @private + */ + setTextTrackSubtitleOffset(currentTrack, offsetValue) { if (currentTrack.cues) { - offsetValue = updateCurrentTrackOffset(offsetValue); + offsetValue = this.updateCurrentTrackOffset(offsetValue); Array.from(currentTrack.cues) - .forEach(function(cue) { + .forEach(function (cue) { cue.startTime -= offsetValue; cue.endTime -= offsetValue; }); } } - function setTrackEventsSubtitleOffset(trackEvents, offsetValue) { - + /** + * @private + */ + setTrackEventsSubtitleOffset(trackEvents, offsetValue) { if (Array.isArray(trackEvents)) { - offsetValue = updateCurrentTrackOffset(offsetValue) * 1e7; // ticks - trackEvents.forEach(function(trackEvent) { + offsetValue = this.updateCurrentTrackOffset(offsetValue) * 1e7; // ticks + trackEvents.forEach(function (trackEvent) { trackEvent.StartPositionTicks -= offsetValue; trackEvent.EndPositionTicks -= offsetValue; }); } } - self.getSubtitleOffset = function() { - return currentTrackOffset; - }; + getSubtitleOffset() { + return this.#currentTrackOffset; + } - function isAudioStreamSupported(stream, deviceProfile) { - - var codec = (stream.Codec || '').toLowerCase(); + /** + * @private + */ + isAudioStreamSupported(stream, deviceProfile) { + const codec = (stream.Codec || '').toLowerCase(); if (!codec) { return true; @@ -674,49 +585,43 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return true; } - var profiles = deviceProfile.DirectPlayProfiles || []; + const profiles = deviceProfile.DirectPlayProfiles || []; return profiles.filter(function (p) { - if (p.Type === 'Video') { - if (!p.AudioCodec) { return true; } - return p.AudioCodec.toLowerCase().indexOf(codec) !== -1; + return p.AudioCodec.toLowerCase().includes(codec); } return false; - }).length > 0; } - function getSupportedAudioStreams() { - var profile = self._lastProfile; + /** + * @private + */ + getSupportedAudioStreams() { + const profile = this.#lastProfile; - return getMediaStreamAudioTracks(self._currentPlayOptions.mediaSource).filter(function (stream) { - return isAudioStreamSupported(stream, profile); + return getMediaStreamAudioTracks(this._currentPlayOptions.mediaSource).filter((stream) => { + return this.isAudioStreamSupported(stream, profile); }); } - self.setAudioStreamIndex = function (index) { - - var streams = getSupportedAudioStreams(); + setAudioStreamIndex(index) { + const streams = this.getSupportedAudioStreams(); if (streams.length < 2) { // If there's only one supported stream then trust that the player will handle it on it's own return; } - var audioIndex = -1; - var i; - var length; - var stream; - - for (i = 0, length = streams.length; i < length; i++) { - stream = streams[i]; + let audioIndex = -1; + for (const stream of streams) { audioIndex++; if (stream.Index === index) { @@ -728,208 +633,272 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return; } - var elem = self._mediaElement; + const elem = this.#mediaElement; if (!elem) { return; } - // https://msdn.microsoft.com/en-us/library/hh772507(v=vs.85).aspx + // https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/audioTracks - var elemAudioTracks = elem.audioTracks || []; - console.debug('found ' + elemAudioTracks.length + ' audio tracks'); - - for (i = 0, length = elemAudioTracks.length; i < length; i++) { + /** + * @type {ArrayLike|any[]} + */ + const elemAudioTracks = elem.audioTracks || []; + console.debug(`found ${elemAudioTracks.length} audio tracks`); + for (const [i, audioTrack] of Array.from(elemAudioTracks).entries()) { if (audioIndex === i) { - console.debug('setting audio track ' + i + ' to enabled'); - elemAudioTracks[i].enabled = true; + console.debug(`setting audio track ${i} to enabled`); + audioTrack.enabled = true; } else { - console.debug('setting audio track ' + i + ' to disabled'); - elemAudioTracks[i].enabled = false; + console.debug(`setting audio track ${i} to disabled`); + audioTrack.enabled = false; } } - }; + } - self.stop = function (destroyPlayer) { - var elem = self._mediaElement; - var src = self._currentSrc; + stop(destroyPlayer) { + const elem = this.#mediaElement; + const src = this.#currentSrc; if (elem) { if (src) { elem.pause(); } - htmlMediaHelper.onEndedInternal(self, elem, onError); + onEndedInternal(this, elem, this.onError); if (destroyPlayer) { - self.destroy(); + this.destroy(); } } - destroyCustomTrack(elem); + this.destroyCustomTrack(elem); return Promise.resolve(); - }; + } - self.destroy = function () { - htmlMediaHelper.destroyHlsPlayer(self); - htmlMediaHelper.destroyFlvPlayer(self); + destroy() { + destroyHlsPlayer(this); + destroyFlvPlayer(this); appRouter.setTransparency('none'); - var videoElement = self._mediaElement; + const videoElement = this.#mediaElement; if (videoElement) { - self._mediaElement = null; + this.#mediaElement = null; - destroyCustomTrack(videoElement); - videoElement.removeEventListener('timeupdate', onTimeUpdate); - videoElement.removeEventListener('ended', onEnded); - videoElement.removeEventListener('volumechange', onVolumeChange); - videoElement.removeEventListener('pause', onPause); - videoElement.removeEventListener('playing', onPlaying); - videoElement.removeEventListener('play', onPlay); - videoElement.removeEventListener('click', onClick); - videoElement.removeEventListener('dblclick', onDblClick); - videoElement.removeEventListener('waiting', onWaiting); + this.destroyCustomTrack(videoElement); + videoElement.removeEventListener('timeupdate', this.onTimeUpdate); + videoElement.removeEventListener('ended', this.onEnded); + videoElement.removeEventListener('volumechange', this.onVolumeChange); + videoElement.removeEventListener('pause', this.onPause); + videoElement.removeEventListener('playing', this.onPlaying); + videoElement.removeEventListener('play', this.onPlay); + videoElement.removeEventListener('click', this.onClick); + videoElement.removeEventListener('dblclick', this.onDblClick); + videoElement.removeEventListener('waiting', this.onWaiting); videoElement.parentNode.removeChild(videoElement); } - var dlg = videoDialog; + const dlg = this.#videoDialog; if (dlg) { - videoDialog = null; + this.#videoDialog = null; dlg.parentNode.removeChild(dlg); } if (screenfull.isEnabled) { screenfull.exit(); + } else { + // iOS Safari + if (document.webkitIsFullScreen && document.webkitCancelFullscreen) { + document.webkitCancelFullscreen(); + } } - }; - - function onEnded() { - - destroyCustomTrack(this); - htmlMediaHelper.onEndedInternal(self, this, onError); } - function onTimeUpdate(e) { - // get the player position and the transcoding offset - var time = this.currentTime; + /** + * @private + * @param e {Event} The event received from the `